feat: 修改ai学习助手接口
This commit is contained in:
@@ -5,6 +5,18 @@ export type LearningAssistantSession = {
|
||||
title?: string
|
||||
}
|
||||
|
||||
type WorkflowRunResponse = {
|
||||
workflow_run_id?: string
|
||||
task_id?: string
|
||||
data?: {
|
||||
status?: string
|
||||
outputs?: unknown
|
||||
error?: string
|
||||
[key: string]: unknown
|
||||
}
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
type ChatStreamPayload = {
|
||||
question: string
|
||||
top_k?: number
|
||||
@@ -16,6 +28,12 @@ type StreamCallbacks = {
|
||||
onDone?: (meta: Record<string, unknown>) => void
|
||||
}
|
||||
|
||||
const CLINICAL_BOOK_WORKFLOW_URL = import.meta.env.DEV
|
||||
? '/dify/v1/workflows/run'
|
||||
: 'http://8.160.178.88:8088/v1/workflows/run'
|
||||
const CLINICAL_BOOK_WORKFLOW_API_KEY = 'app-9BapxGXgF2qQi9HHkq4R95Y7'
|
||||
const CLINICAL_BOOK_WORKFLOW_TRIGGER = '临床思维训练书籍'
|
||||
|
||||
export async function createLearningAssistantSession(title?: string) {
|
||||
const body = title?.trim()
|
||||
? {
|
||||
@@ -49,6 +67,41 @@ export async function createLearningAssistantSession(title?: string) {
|
||||
} as LearningAssistantSession
|
||||
}
|
||||
|
||||
export async function runClinicalThinkingBooksWorkflow(signal?: AbortSignal) {
|
||||
const response = await fetch(CLINICAL_BOOK_WORKFLOW_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${CLINICAL_BOOK_WORKFLOW_API_KEY}`
|
||||
},
|
||||
body: JSON.stringify({
|
||||
inputs: {
|
||||
input: CLINICAL_BOOK_WORKFLOW_TRIGGER
|
||||
},
|
||||
response_mode: 'blocking',
|
||||
user: readWorkflowUserId()
|
||||
}),
|
||||
signal
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(await readWorkflowError(response))
|
||||
}
|
||||
|
||||
const result = (await response.json()) as WorkflowRunResponse
|
||||
if (result.data?.status && result.data.status !== 'succeeded') {
|
||||
throw new Error(result.data.error || '临床思维训练书籍生成失败')
|
||||
}
|
||||
|
||||
const output = readWorkflowOutput(result)
|
||||
if (!output) {
|
||||
throw new Error('临床思维训练书籍内容为空,请稍后重试')
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
export async function streamLearningAssistantChat(
|
||||
assistantSessionId: number | string,
|
||||
payload: ChatStreamPayload,
|
||||
@@ -94,6 +147,68 @@ function readAssistantSessionId(data: Record<string, unknown>) {
|
||||
return ''
|
||||
}
|
||||
|
||||
function readWorkflowUserId() {
|
||||
const storageKey = 'clinical-thinking-workflow-user-id'
|
||||
const stored = uni.getStorageSync(storageKey)
|
||||
if (typeof stored === 'string' && stored.trim()) return stored
|
||||
|
||||
const generated = `clinical-thinking-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
|
||||
uni.setStorageSync(storageKey, generated)
|
||||
return generated
|
||||
}
|
||||
|
||||
async function readWorkflowError(response: Response) {
|
||||
const text = await response.text().catch(() => '')
|
||||
if (!text) return `临床思维训练书籍请求失败(${response.status})`
|
||||
try {
|
||||
const payload = JSON.parse(text) as Record<string, unknown>
|
||||
const message = payload.message || payload.detail || payload.error
|
||||
if (typeof message === 'string' && message.trim()) return message
|
||||
} catch {}
|
||||
return text
|
||||
}
|
||||
|
||||
function readWorkflowOutput(result: WorkflowRunResponse) {
|
||||
const data = result.data
|
||||
if (data && typeof data === 'object') {
|
||||
const output = readOutputText(data.outputs)
|
||||
|| readOutputText(data.output)
|
||||
|| readOutputText(data.answer)
|
||||
|| readOutputText(data.text)
|
||||
|| readOutputText(data.result)
|
||||
if (output) return output
|
||||
}
|
||||
|
||||
return readOutputText(result.output)
|
||||
|| readOutputText(result.answer)
|
||||
|| readOutputText(result.text)
|
||||
|| readOutputText(result.result)
|
||||
}
|
||||
|
||||
function readOutputText(value: unknown): string {
|
||||
if (typeof value === 'string') return value.trim()
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(readOutputText).filter(Boolean).join('\n')
|
||||
}
|
||||
if (!value || typeof value !== 'object') return ''
|
||||
|
||||
const payload = value as Record<string, unknown>
|
||||
const preferredKeys = ['answer', 'text', 'result', 'output', 'content', 'markdown', 'data']
|
||||
for (const key of preferredKeys) {
|
||||
const text = readOutputText(payload[key])
|
||||
if (text) return text
|
||||
}
|
||||
|
||||
const entries = Object.entries(payload)
|
||||
.map(([key, entry]) => {
|
||||
const text = readOutputText(entry)
|
||||
return text ? `${key}:${text}` : ''
|
||||
})
|
||||
.filter(Boolean)
|
||||
|
||||
return entries.join('\n')
|
||||
}
|
||||
|
||||
function handleStreamBlock(block: string, callbacks: StreamCallbacks) {
|
||||
const event = block.match(/^event:\s*(.+)$/m)?.[1] || ''
|
||||
const rawLines = block
|
||||
|
||||
Reference in New Issue
Block a user