feat(mobile): render evidence levels and route actions in ask page

- normalize evidenceLevel/uncoveredPoints/nextActions from agent response
- GUIDANCE banner (reference experience, non-formal), PARTIAL uncovered
  points list, ROUTE compact action buttons (human help / direct channel /
  web research); legacy responses render unchanged
- one-tap human help on ROUTE: auto-submit down feedback (NO_ANSWER,
  fragment-less allowed by backend) then existing confirm + idempotent
  publish chain
- direct channel page supports ?channel= preselection
This commit is contained in:
2026-08-05 00:53:00 +08:00
parent 6cc2ac73e5
commit 1fc99293f6
4 changed files with 238 additions and 13 deletions
+11 -1
View File
@@ -3,7 +3,8 @@ import type {
KnowledgeConversationState,
KnowledgeMediaSelectedFile,
KnowledgeSearchResponse,
MemoryCandidate
MemoryCandidate,
NextAction
} from '@/types/api';
import { apiRequest, apiUrl, authHeaders, readTextPayload } from './api';
@@ -96,6 +97,10 @@ export const normalizeAgentResponse = (
detailRef: citation.detailRef,
locatorSummary: citation.locatorSummary
}));
// 旧版后端 nextActions 是 string[],无 UI 语义;只透传新契约的对象结构。
const nextActions = (Array.isArray(response.nextActions) ? response.nextActions : [])
.filter((action): action is NextAction =>
Boolean(action) && typeof action === 'object' && typeof action.type === 'string');
return {
requestId: response.runId,
queryText: question,
@@ -119,6 +124,11 @@ export const normalizeAgentResponse = (
broadcastContext: response.broadcastContext || null,
agentStatus: response.status,
agentIntent: response.intent,
evidenceLevel: response.evidenceLevel ?? null,
uncoveredPoints: Array.isArray(response.uncoveredPoints)
? response.uncoveredPoints.filter((point): point is string => typeof point === 'string' && Boolean(point.trim()))
: [],
nextActions,
sourceSummary: response.sourceSummary || [],
clarification: response.clarification || null,
keyPoints: response.keyPoints || [],