feat(agent): move mobile ask to unified agent

This commit is contained in:
2026-07-24 22:36:14 +08:00
parent 6ba4e06a2f
commit 5b7c5613f5
12 changed files with 368 additions and 62 deletions
+120
View File
@@ -0,0 +1,120 @@
import type {
AgentResponse,
KnowledgeConversationState,
KnowledgeMediaSelectedFile,
KnowledgeSearchResponse,
MemoryCandidate
} from '@/types/api';
import { apiRequest, apiUrl, authHeaders, readTextPayload } from './api';
interface AgentMessageOptions {
conversation?: KnowledgeConversationState;
projectCode?: string;
broadcastMessageId?: number;
externalConsent?: boolean;
}
export const askAgent = async (question: string, options: AgentMessageOptions = {}) =>
normalizeAgentResponse(await apiRequest<AgentResponse>({
url: '/api/aihr/agent/messages',
method: 'POST',
data: {
question,
conversationId: options.conversation?.conversationId,
contextVersion: options.conversation?.contextVersion,
projectCode: options.projectCode,
broadcastMessageId: options.broadcastMessageId,
externalConsent: Boolean(options.externalConsent)
},
timeout: 45000
}), question);
export const askAgentWithMedia = (
file: KnowledgeMediaSelectedFile,
question: string,
options: AgentMessageOptions = {},
onUploadTask?: (task: ReturnType<typeof uni.uploadFile> | null) => void
) => new Promise<KnowledgeSearchResponse>((resolve, reject) => {
const task = uni.uploadFile({
url: apiUrl('/api/aihr/agent/messages/media'),
filePath: file.path,
name: 'file',
header: authHeaders(false),
formData: {
question,
...(options.conversation ? {
conversationId: options.conversation.conversationId,
contextVersion: String(options.conversation.contextVersion)
} : {}),
...(options.projectCode ? { projectCode: options.projectCode } : {}),
...(typeof options.broadcastMessageId === 'number'
? { broadcastMessageId: String(options.broadcastMessageId) }
: {}),
externalConsent: String(Boolean(options.externalConsent))
},
timeout: 360000,
success: (result) => {
try {
resolve(normalizeAgentResponse(
readTextPayload<AgentResponse>(result.statusCode, result.data),
question
));
} catch (error) {
reject(error);
}
},
fail: () => reject(new Error(file.kind === 'video' ? '视频上传或分析超时' : '图片上传失败')),
complete: () => onUploadTask?.(null)
});
onUploadTask?.(task);
});
export const normalizeAgentResponse = (
response: AgentResponse,
question: string
): KnowledgeSearchResponse => {
const memoryCandidate = response.actionDraft?.payload
? {
...(response.actionDraft.payload as MemoryCandidate),
agentDraftId: response.actionDraft.draftId
}
: null;
const snippets = (response.citations || []).map((citation) => ({
docTitle: citation.title,
content: citation.snippet,
docId: citation.docId,
fragmentId: citation.fragmentId,
spaceCode: citation.spaceCode,
sourceType: citation.sourceType,
domain: citation.domain,
status: citation.status,
occurredAt: citation.occurredAt,
updatedAt: citation.updatedAt
}));
return {
requestId: response.runId,
queryText: question,
category: 'sop',
answer: response.answer || response.clarification?.prompt || '',
reference: (response.sourceSummary || []).map((source) => source.label).filter(Boolean).join('、'),
docs: [],
snippets,
training: [],
records: [],
citations: response.citations || [],
usedSpaceCodes: [],
noEvidence: response.status === 'NO_EVIDENCE',
data: response.data,
conversationId: response.conversationId,
contextVersion: response.contextVersion,
intent: response.intent,
rewrittenQuery: question,
resources: response.resources || [],
memoryCandidate,
broadcastContext: null,
agentStatus: response.status,
agentIntent: response.intent,
sourceSummary: response.sourceSummary || [],
clarification: response.clarification || null
};
};
@@ -44,17 +44,21 @@ export const getMemoryCandidates = async (status = 'DRAFT') =>
timeout: 15000
}));
export const confirmMemoryCandidate = (candidateId: number, request: MemoryConfirmRequest) =>
export const confirmMemoryCandidate = (candidateRef: number | string, request: MemoryConfirmRequest) =>
apiRequest<MemoryConfirmResult>({
url: `${candidateBase}/${candidateId}/confirm`,
url: typeof candidateRef === 'string'
? `/api/aihr/agent/actions/${encodeURIComponent(String(candidateRef))}/confirm`
: `${candidateBase}/${candidateRef}/confirm`,
method: 'POST',
data: request,
timeout: 15000
});
export const dismissMemoryCandidate = (candidateId: number) =>
export const dismissMemoryCandidate = (candidateRef: number | string) =>
apiRequest<{ id: number; status: string }>({
url: `${candidateBase}/${candidateId}/dismiss`,
url: typeof candidateRef === 'string'
? `/api/aihr/agent/actions/${encodeURIComponent(String(candidateRef))}/dismiss`
: `${candidateBase}/${candidateRef}/dismiss`,
method: 'POST',
timeout: 15000
});