dsh-data-domain-knowledge 0.1.1-alpha.2 → 0.1.1-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -16
- package/lib/client.js +1042 -2097
- package/lib/contract-refs.d.ts +0 -1
- package/lib/doc-page.js +1 -1
- package/lib/pages.js +2489 -1060
- package/lib/types/agent-behavior-rules.d.ts.map +1 -1
- package/lib/types/agent-behavior-rules.js +3 -2
- package/lib/types/agent-behavior-rules.js.map +1 -1
- package/lib/types/axis-contract.js +1 -1
- package/lib/types/axis-contract.js.map +1 -1
- package/lib/types/card-organize.d.ts +2 -1
- package/lib/types/card-organize.d.ts.map +1 -1
- package/lib/types/card-organize.js +5 -3
- package/lib/types/card-organize.js.map +1 -1
- package/lib/types/config-schema.d.ts +1 -1
- package/lib/types/config-schema.js +1 -1
- package/lib/types/convert/host.d.ts +2 -3
- package/lib/types/convert/host.d.ts.map +1 -1
- package/lib/types/convert/host.js +11 -2
- package/lib/types/convert/host.js.map +1 -1
- package/lib/types/convert/ingest.d.ts +14 -20
- package/lib/types/convert/ingest.d.ts.map +1 -1
- package/lib/types/convert/ingest.js +8 -5
- package/lib/types/convert/ingest.js.map +1 -1
- package/lib/types/diagnosis/store.d.ts +2 -2
- package/lib/types/diagnosis/store.d.ts.map +1 -1
- package/lib/types/diagnosis/store.js +10 -2
- package/lib/types/diagnosis/store.js.map +1 -1
- package/lib/types/diagnosis/types.d.ts +1 -1
- package/lib/types/diagnosis/types.js +1 -1
- package/lib/types/extract-model.d.ts +3 -0
- package/lib/types/extract-model.d.ts.map +1 -1
- package/lib/types/extract-model.js.map +1 -1
- package/lib/types/images.js +1 -1
- package/lib/types/index.d.ts +0 -4
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +99 -91
- package/lib/types/index.js.map +1 -1
- package/lib/types/knowledge-bases.d.ts +3 -0
- package/lib/types/knowledge-bases.d.ts.map +1 -1
- package/lib/types/knowledge-bases.js +22 -2
- package/lib/types/knowledge-bases.js.map +1 -1
- package/lib/types/knowledge-contract.d.ts +6 -0
- package/lib/types/knowledge-contract.d.ts.map +1 -1
- package/lib/types/knowledge-contract.js +6 -2
- package/lib/types/knowledge-contract.js.map +1 -1
- package/lib/types/layout.d.ts +9 -26
- package/lib/types/layout.d.ts.map +1 -1
- package/lib/types/layout.js +10 -28
- package/lib/types/layout.js.map +1 -1
- package/lib/types/materialize-snapshot.d.ts +5 -0
- package/lib/types/materialize-snapshot.d.ts.map +1 -1
- package/lib/types/migrate.d.ts +3 -1
- package/lib/types/migrate.d.ts.map +1 -1
- package/lib/types/migrate.js +3 -1
- package/lib/types/migrate.js.map +1 -1
- package/lib/types/model-text.d.ts +7 -0
- package/lib/types/model-text.d.ts.map +1 -1
- package/lib/types/model-text.js +31 -9
- package/lib/types/model-text.js.map +1 -1
- package/lib/types/organize-contract.d.ts.map +1 -1
- package/lib/types/organize-contract.js +2 -1
- package/lib/types/organize-contract.js.map +1 -1
- package/lib/types/pipeline/engine.d.ts +28 -4
- package/lib/types/pipeline/engine.d.ts.map +1 -1
- package/lib/types/pipeline/engine.js +68 -15
- package/lib/types/pipeline/engine.js.map +1 -1
- package/lib/types/pipeline/progress.d.ts +12 -0
- package/lib/types/pipeline/progress.d.ts.map +1 -0
- package/lib/types/pipeline/progress.js +37 -0
- package/lib/types/pipeline/progress.js.map +1 -0
- package/lib/types/pipeline/resumable-extract.d.ts +45 -0
- package/lib/types/pipeline/resumable-extract.d.ts.map +1 -0
- package/lib/types/pipeline/resumable-extract.js +262 -0
- package/lib/types/pipeline/resumable-extract.js.map +1 -0
- package/lib/types/pipeline/store.d.ts +8 -2
- package/lib/types/pipeline/store.d.ts.map +1 -1
- package/lib/types/pipeline/store.js +27 -5
- package/lib/types/pipeline/store.js.map +1 -1
- package/lib/types/pipeline/types.d.ts +56 -0
- package/lib/types/pipeline/types.d.ts.map +1 -1
- package/lib/types/pipeline/types.js +18 -1
- package/lib/types/pipeline/types.js.map +1 -1
- package/lib/types/present.d.ts +1 -1
- package/lib/types/present.js +1 -1
- package/lib/types/preset-ids.d.ts +0 -1
- package/lib/types/preset-ids.d.ts.map +1 -1
- package/lib/types/preset-ids.js +0 -3
- package/lib/types/preset-ids.js.map +1 -1
- package/lib/types/query-analysis.d.ts +0 -5
- package/lib/types/query-analysis.d.ts.map +1 -1
- package/lib/types/query-analysis.js +0 -16
- package/lib/types/query-analysis.js.map +1 -1
- package/lib/types/recall-delivery.d.ts +36 -0
- package/lib/types/recall-delivery.d.ts.map +1 -0
- package/lib/types/recall-delivery.js +16 -0
- package/lib/types/recall-delivery.js.map +1 -0
- package/lib/types/retrieval/scope.d.ts +17 -0
- package/lib/types/retrieval/scope.d.ts.map +1 -0
- package/lib/types/retrieval/scope.js +11 -0
- package/lib/types/retrieval/scope.js.map +1 -0
- package/lib/types/runtime.d.ts +75 -14
- package/lib/types/runtime.d.ts.map +1 -1
- package/lib/types/runtime.js +454 -198
- package/lib/types/runtime.js.map +1 -1
- package/lib/types/settings-volatile.d.ts +0 -7
- package/lib/types/settings-volatile.d.ts.map +1 -1
- package/lib/types/settings-volatile.js +0 -7
- package/lib/types/settings-volatile.js.map +1 -1
- package/lib/types/source-identity.d.ts +34 -0
- package/lib/types/source-identity.d.ts.map +1 -0
- package/lib/types/source-identity.js +85 -0
- package/lib/types/source-identity.js.map +1 -0
- package/lib/types/source-read.d.ts +18 -0
- package/lib/types/source-read.d.ts.map +1 -0
- package/lib/types/source-read.js +49 -0
- package/lib/types/source-read.js.map +1 -0
- package/lib/types/store/axis-references.d.ts.map +1 -1
- package/lib/types/store/axis-references.js +5 -3
- package/lib/types/store/axis-references.js.map +1 -1
- package/lib/types/store/knowledge-db.d.ts +5 -29
- package/lib/types/store/knowledge-db.d.ts.map +1 -1
- package/lib/types/store/knowledge-db.js +57 -2
- package/lib/types/store/knowledge-db.js.map +1 -1
- package/lib/types/store/source-identity.d.ts +8 -0
- package/lib/types/store/source-identity.d.ts.map +1 -0
- package/lib/types/store/source-identity.js +56 -0
- package/lib/types/store/source-identity.js.map +1 -0
- package/lib/types/types.d.ts +46 -5
- package/lib/types/types.d.ts.map +1 -1
- package/lib/types/types.js +6 -3
- package/lib/types/types.js.map +1 -1
- package/lib/types/wiki-availability.d.ts +11 -0
- package/lib/types/wiki-availability.d.ts.map +1 -0
- package/lib/types/wiki-availability.js +39 -0
- package/lib/types/wiki-availability.js.map +1 -0
- package/lib/types/wiki-finalize.d.ts +4 -2
- package/lib/types/wiki-finalize.d.ts.map +1 -1
- package/lib/types/wiki-finalize.js +9 -27
- package/lib/types/wiki-finalize.js.map +1 -1
- package/lib/types/wiki-links.d.ts +35 -0
- package/lib/types/wiki-links.d.ts.map +1 -0
- package/lib/types/wiki-links.js +129 -0
- package/lib/types/wiki-links.js.map +1 -0
- package/lib/types/wiki-trial-types.d.ts +3 -0
- package/lib/types/wiki-trial-types.d.ts.map +1 -1
- package/lib/types/wiki-trial.d.ts +3 -3
- package/lib/types/wiki-trial.d.ts.map +1 -1
- package/lib/types/wiki-trial.js +14 -3
- package/lib/types/wiki-trial.js.map +1 -1
- package/package.json +16 -16
- package/scripts/doctor.mjs +0 -7
- package/scripts/setup-embedding.sh +0 -0
- package/src/agent-behavior-rules.ts +3 -2
- package/src/axis-contract.ts +1 -1
- package/src/card-organize.ts +5 -3
- package/src/client/AttributionEventGuide.tsx +3 -3
- package/src/client/AxisMatrix.tsx +86 -19
- package/src/client/AxisRegistrySection.tsx +1 -1
- package/src/client/CompileSettingsView.tsx +473 -0
- package/src/client/DirectoryPicker.tsx +0 -2
- package/src/client/ExtractionTasksPage.tsx +557 -423
- package/src/client/GuideArchitectureCanvas.tsx +5 -12
- package/src/client/ImportFilesDialog.tsx +1 -0
- package/src/client/InfoHint.tsx +1 -1
- package/src/client/KnowledgeBaseTab.tsx +141 -148
- package/src/client/KnowledgePanel.tsx +16 -9
- package/src/client/OperationLogTab.tsx +1 -1
- package/src/client/PipelineRunView.tsx +173 -0
- package/src/client/RecallPanel.tsx +5 -16
- package/src/client/TabGuide.tsx +3 -7
- package/src/client/WikiFlowPanel.tsx +10 -11
- package/src/client/arch/NodeLogicPanel.tsx +3 -3
- package/src/client/arch/model.ts +5 -113
- package/src/client/architecture.css +1 -1
- package/src/client/architecture.tsx +13 -27
- package/src/client/attribution/AttributionTab.tsx +141 -10
- package/src/client/pages.css +305 -180
- package/src/client/pages.tsx +7 -12
- package/src/client/styles.css +15 -96
- package/src/config-schema.ts +1 -1
- package/src/convert/host.ts +13 -5
- package/src/convert/ingest.ts +20 -7
- package/src/diagnosis/store.ts +7 -2
- package/src/diagnosis/types.ts +1 -1
- package/src/extract-model.ts +3 -0
- package/src/images.ts +1 -1
- package/src/index.ts +92 -97
- package/src/knowledge-bases.ts +23 -3
- package/src/knowledge-contract.ts +7 -2
- package/src/layout.ts +10 -32
- package/src/materialize-snapshot.ts +1 -0
- package/src/migrate.ts +3 -1
- package/src/model-text.ts +33 -11
- package/src/organize-contract.ts +2 -1
- package/src/pipeline/engine.ts +85 -22
- package/src/pipeline/progress.ts +40 -0
- package/src/pipeline/resumable-extract.ts +233 -0
- package/src/pipeline/store.ts +28 -6
- package/src/pipeline/types.ts +47 -2
- package/src/present.ts +1 -1
- package/src/preset-ids.ts +0 -4
- package/src/query-analysis.ts +0 -20
- package/src/recall-delivery.ts +19 -0
- package/src/retrieval/scope.ts +10 -0
- package/src/runtime.ts +412 -206
- package/src/settings-volatile.ts +0 -7
- package/src/source-identity.ts +85 -0
- package/src/source-read.ts +47 -0
- package/src/store/axis-references.ts +5 -3
- package/src/store/knowledge-db.ts +54 -2
- package/src/store/source-identity.ts +42 -0
- package/src/types.ts +18 -5
- package/src/wiki-availability.ts +37 -0
- package/src/wiki-finalize.ts +9 -25
- package/src/wiki-links.ts +120 -0
- package/src/wiki-trial-types.ts +3 -2
- package/src/wiki-trial.ts +17 -6
- package/lib/types/intent/engine.d.ts +0 -122
- package/lib/types/intent/engine.d.ts.map +0 -1
- package/lib/types/intent/engine.js +0 -488
- package/lib/types/intent/engine.js.map +0 -1
- package/lib/types/intent/host.d.ts +0 -68
- package/lib/types/intent/host.d.ts.map +0 -1
- package/lib/types/intent/host.js +0 -249
- package/lib/types/intent/host.js.map +0 -1
- package/lib/types/intent/scope.d.ts +0 -25
- package/lib/types/intent/scope.d.ts.map +0 -1
- package/lib/types/intent/scope.js +0 -116
- package/lib/types/intent/scope.js.map +0 -1
- package/lib/types/intent/store.d.ts +0 -33
- package/lib/types/intent/store.d.ts.map +0 -1
- package/lib/types/intent/store.js +0 -239
- package/lib/types/intent/store.js.map +0 -1
- package/lib/types/intent/tools.d.ts +0 -62
- package/lib/types/intent/tools.d.ts.map +0 -1
- package/lib/types/intent/tools.js +0 -130
- package/lib/types/intent/tools.js.map +0 -1
- package/lib/types/intent/types.d.ts +0 -170
- package/lib/types/intent/types.d.ts.map +0 -1
- package/lib/types/intent/types.js +0 -56
- package/lib/types/intent/types.js.map +0 -1
- package/src/client/IntentLogic.tsx +0 -192
- package/src/client/IntentTab.tsx +0 -343
- package/src/client/TypeDefinitionDrawer.tsx +0 -195
- package/src/intent/README.md +0 -42
- package/src/intent/engine.ts +0 -515
- package/src/intent/host.ts +0 -315
- package/src/intent/scope.ts +0 -125
- package/src/intent/store.ts +0 -218
- package/src/intent/tools.ts +0 -154
- package/src/intent/types.ts +0 -229
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 内置 act 词表。它是会话审计的固定提示,不是知识召回配置,也不提供编辑入口。
|
|
3
|
-
*/
|
|
4
|
-
export const DEFAULT_ACTS = [
|
|
5
|
-
{ id: 'query', label: '查询', description: '向数据或知识提问,要一个答案或一批结果。', enabled: true },
|
|
6
|
-
{ id: 'request', label: '执行请求', description: '让 Agent 做一件事并产生副作用:写入、发送、导出、修改。', enabled: true },
|
|
7
|
-
{ id: 'inform', label: '补充信息', description: '用户提供事实、参数或上下文,本身不要求动作。', enabled: true },
|
|
8
|
-
{ id: 'confirm', label: '确认', description: '用户认可某个提议或方案,允许继续。', enabled: true },
|
|
9
|
-
{ id: 'select', label: '选择', description: '在多个候选中指定一个。', enabled: true },
|
|
10
|
-
{ id: 'correct', label: '纠正', description: '指出前面的理解或结果不对,要求改。', enabled: true },
|
|
11
|
-
{ id: 'cancel', label: '取消', description: '终止或撤回正在进行的任务。', enabled: true },
|
|
12
|
-
{ id: 'review', label: '审阅', description: '对已产出的内容做检查、评估与把关。', enabled: true },
|
|
13
|
-
{ id: 'explain', label: '解释', description: '要求讲清原理、口径或原因,而不是要新数据。', enabled: true },
|
|
14
|
-
{ id: 'compare', label: '对比', description: '把两个及以上对象放在一起比较差异。', enabled: true },
|
|
15
|
-
{ id: 'recommend', label: '推荐', description: '要建议与取舍意见。', enabled: true },
|
|
16
|
-
{ id: 'resume', label: '继续', description: '回到之前中断的任务继续做。', enabled: true },
|
|
17
|
-
{ id: 'reject', label: '拒绝', description: '不接受某个提议或结果。', enabled: true },
|
|
18
|
-
{ id: 'greet', label: '问候', description: '打招呼、开场。', enabled: true },
|
|
19
|
-
{ id: 'chat', label: '闲聊', description: '非任务性的对话。', enabled: true },
|
|
20
|
-
{ id: 'unknown', label: '未判定', description: '无法归入以上任何一类,或本轮信息不足以判断。', enabled: true },
|
|
21
|
-
];
|
|
22
|
-
function category(id, label, route, description, examples) {
|
|
23
|
-
return { id, label, route, description, examples, enabled: true };
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* 出厂预置的意图分类。
|
|
27
|
-
*
|
|
28
|
-
* 每一项都**必须**带 `description` 与 `examples`:只给标签("数据分析")时模型
|
|
29
|
-
* 只能靠猜,同一句话在不同轮次会被分到不同类。这些文案是模型的匹配依据,全部
|
|
30
|
-
* 词表随代码发布,不通过知识库配置或 UI 修改。
|
|
31
|
-
*/
|
|
32
|
-
export const DEFAULT_CATEGORIES = [
|
|
33
|
-
category('data_analysis', '数据分析', 'query', '取数、算指标、拆口径的请求:给一个数或一段分析结论。', ['帮我算一下上个月的 GMV', '这个指标怎么拆', '跑个数看看环比']),
|
|
34
|
-
category('metadata_exploration', '元数据探索', 'query', '问"有哪些表/字段/口径"本身,要的是结构而不是数字。', ['这张表有哪些字段', '库里有几张订单表', '这些指标的口径是怎么定义的']),
|
|
35
|
-
category('data_validation', '数据校验', 'query', '核对数据是否可信:对不上、空值、重复、异常波动。', ['这两个数对不上,查一下', '帮我看下这列有没有重复', '空值率是不是偏高了']),
|
|
36
|
-
category('knowledge_consultation', '知识咨询', 'query', '问组织既有的结论、规则、流程或负责人,答案在知识库里。', ['我们去年是怎么定这个口径的', '知识库里有没有相关文档', '这个流程找谁确认']),
|
|
37
|
-
category('knowledge_building', '知识构建', 'request', '把材料沉淀进知识库:录入来源、写卡片、重建索引。', ['把这份文档存进知识库', '记一条:这个口径改成…', '帮我整理成一张知识卡片']),
|
|
38
|
-
category('document_research', '文档研究', 'query', '对一份或多份长文档做通读、归纳、对比、找证据。', ['把这份 PRD 读一遍,总结需求点', '这几篇文档有没有冲突', '从报告里找出支持这个结论的证据']),
|
|
39
|
-
category('message_collaboration', '消息协作', 'request', '替用户发消息、同步进度、在群里通知或拉人。', ['发条消息给张三', '在群里同步一下进度', '@一下负责人催确认']),
|
|
40
|
-
category('artifact_delivery', '产物交付', 'request', '要一个可交付的文件:表格、报告、周报、导出件。', ['导出一份 Excel', '生成这周的周报', '把结果做成表格发我']),
|
|
41
|
-
category('agent_engineering', 'Agent 工程', 'request', '改 Agent 自身:加工具、调提示词、改 skill、查它为什么这么答。', ['加一个工具', '这个 skill 怎么改', '它刚才为什么没调那个工具']),
|
|
42
|
-
category('tooling_operations', '工具运维', 'request', '运维动作:重启、看队列、清缓存、处理环境报错。', ['重启一下服务', '看看任务队列', '这个报错怎么修']),
|
|
43
|
-
category('personal_assistant', '个人助理', 'request', '个人日程与提醒类事务。', ['明天提醒我开会', '帮我约个会', '看下我今天的日程']),
|
|
44
|
-
category('conversation', '普通对话', 'chat', '寒暄、闲聊、对 Agent 本身的提问,没有数据或交付目标。', ['你好', '你是谁', '谢谢,先这样']),
|
|
45
|
-
];
|
|
46
|
-
export const DEFAULT_PREDICATES = [
|
|
47
|
-
'query_babel_data', 'query_knowledge', 'query_source_truth', 'query_metadata',
|
|
48
|
-
'query_graph', 'add_source', 'propose_wiki_cards', 'rebuild_knowledge',
|
|
49
|
-
'send_message', 'export_artifact', 'unknown',
|
|
50
|
-
];
|
|
51
|
-
export const DEFAULT_INTENT_SETTINGS = {
|
|
52
|
-
clarifyThreshold: 0.65,
|
|
53
|
-
ttlSeconds: 600,
|
|
54
|
-
fallbackEnabled: true,
|
|
55
|
-
};
|
|
56
|
-
//# sourceMappingURL=types.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/intent/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 「意图的逻辑」—— 把意图模型**讲清楚**,而不是只给一堆表单。
|
|
3
|
-
*
|
|
4
|
-
* 内容现在同时解释两套意图:会话审计里的 act / category,以及召回运行时的 Intent / OAS。
|
|
5
|
-
* 后者不是新增一套持久化记录,而是当前 Query 的解析结果。
|
|
6
|
-
*
|
|
7
|
-
* 这一页是**只读说明**:它不读引擎状态,也不写配置,所以可以独立阅读。
|
|
8
|
-
*
|
|
9
|
-
* 2026-10-05:它从面板里的说明变成**一份整页**(`/knowledge/pages/help/intent`)。
|
|
10
|
-
* 说明只解释会话审计与召回侧 Query 意图的边界,入口是意图页右侧那枚 `?`。
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import type { ReactNode } from 'react'
|
|
14
|
-
import { BrainCircuit, CircleHelp, ClipboardCheck, Library, ListTree, Shapes } from '@tita-agent/ui/icons'
|
|
15
|
-
import { Card } from '@tita-agent/ui/components'
|
|
16
|
-
import { styles } from './styles.ts'
|
|
17
|
-
|
|
18
|
-
/** 一张"字段含义"表。 */
|
|
19
|
-
interface FieldDoc {
|
|
20
|
-
name: string
|
|
21
|
-
required: boolean
|
|
22
|
-
meaning: string
|
|
23
|
-
where: string
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const RECORD_FIELDS: FieldDoc[] = [
|
|
27
|
-
{ name: 'sessionKey', required: true, meaning: '这条意图属于哪个会话。记录按 session + turn 分组,TTL 到期即释放。', where: 'Host 从会话头取,模型不用传' },
|
|
28
|
-
{ name: 'turnKey / turnId', required: true, meaning: '「哪一轮」。同一轮重复记录会 upsert 成一条,不会刷出多条流水。', where: 'Host 在 turn/start 时分配' },
|
|
29
|
-
{ name: 'userInput', required: true, meaning: '本轮用户原文(截断到 2000 字)。它是审计的证据,不是分类的输入。', where: '模型从本轮消息里复制' },
|
|
30
|
-
{ name: 'act', required: true, meaning: '用户在**做什么**:问、让做、补充、确认、取消……与 category 正交。', where: '模型按固定审计契约判断' },
|
|
31
|
-
{ name: 'category', required: false, meaning: '这一轮属于**哪个业务类别**。不命中固定分类时可记录 unknown。', where: '模型判断' },
|
|
32
|
-
{ name: 'predicate', required: false, meaning: '这轮最终要调的**工具/动作**,例如 query_babel_data。用来把意图和真实执行对齐。', where: '模型按可用工具填' },
|
|
33
|
-
{ name: 'slots', required: false, meaning: '从用户话里抽出的关键参数(时间范围、对象、指标……),自由 JSON。', where: '模型抽取' },
|
|
34
|
-
{ name: 'confidence', required: false, meaning: '模型自评把握度 0–1。低于澄清阈值只**标注** lowConfidence,不拦截请求。', where: '模型自评' },
|
|
35
|
-
{ name: 'refs', required: false, meaning: '引用了哪些对象(表、文档、指标),形如 { id, kind, label }。', where: '模型抽取' },
|
|
36
|
-
{ name: 'relation', required: true, meaning: '这轮与已有任务的关系:new_task(开新任务)/ subtask_of(续已有任务)/ unknown。', where: '模型判断,Host 校验 task 是否存在' },
|
|
37
|
-
{ name: 'lineage', required: true, meaning: 'intentId / taskId / subtaskId / runId 四个 id 的链路,下游工具与产物靠它回溯。', where: 'Host 分配,模型可显式续接' },
|
|
38
|
-
{ name: 'source', required: true, meaning: 'model = 模型记录;fallback = 数据轮次结束模型没记,Host 补的一条 unknown。', where: 'Host 标记' },
|
|
39
|
-
]
|
|
40
|
-
|
|
41
|
-
interface Paper {
|
|
42
|
-
title: string
|
|
43
|
-
authors: string
|
|
44
|
-
venue: string
|
|
45
|
-
url: string
|
|
46
|
-
/** 它对应本设计的哪一点。 */
|
|
47
|
-
relates: string
|
|
48
|
-
note?: string
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const PAPERS: Paper[] = [
|
|
52
|
-
{
|
|
53
|
-
title: 'An Evaluation Dataset for Intent Classification and Out-of-Scope Prediction',
|
|
54
|
-
authors: 'Stefan Larson, Anish Mahendran, Joseph J. Peper, Christopher Clarke, Andrew Lee, Parker Hill, Jonathan Kummerfeld, Kevin Leach, Michael A. Laurenzano, Lingjia Tang, Jason Mars',
|
|
55
|
-
venue: 'EMNLP 2019(CLINC150)',
|
|
56
|
-
url: 'https://aclanthology.org/D19-1131/',
|
|
57
|
-
relates: '「全不命中怎么办」的标准答案:真实流量里必然有落在词表之外的句子,把它硬塞进最近的一类,比多问一句代价大得多。对应本设计的第 2 段(自创 id 或落 unknown)与 lowConfidence 标注。',
|
|
58
|
-
note: 'CLINC150 给出了 150 类 + out-of-scope 的评测集;数据集的标签体系与本产品的 12 类无关。',
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
title: 'A Survey of Joint Intent Detection and Slot Filling Models in Natural Language Understanding',
|
|
62
|
-
authors: 'H. Weld, X. Huang, S. Long, J. Poon, S. C. Han',
|
|
63
|
-
venue: 'ACM Computing Surveys, 2022',
|
|
64
|
-
url: 'https://dl.acm.org/doi/10.1145/3547138',
|
|
65
|
-
relates: '说明 intent 与 slot 为什么要一起看:`category`(意图)与 `slots`(参数)是同一个判断的两面。本设计把它们放在同一条记录里,就是为了不让"分类对了但参数丢了"成为常态。',
|
|
66
|
-
note: '这里只借它的问题定义与术语,没有训练任何联合模型。',
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
title: 'Efficient Intent Detection with Dual Sentence Encoders',
|
|
70
|
-
authors: 'Iñigo Casanueva, Tadas Temčinas, Daniela Gerz, Matthew Henderson, Ivan Vulić',
|
|
71
|
-
venue: 'NLP4ConvAI @ ACL 2020',
|
|
72
|
-
url: 'https://aclanthology.org/2020.nlp4convai-1.5/',
|
|
73
|
-
relates: '小样本下"用一句自然语言描述一个类别"就能做分类:这正是本设计的做法——预置分类用 `description` + `examples` 描述,而不是训练一个分类头。',
|
|
74
|
-
note: '该论文用双句编码器 + 少量标注样例;本产品直接把描述喂给大模型,没有额外模型。',
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
title: 'IntentGPT: Few-shot Intent Discovery with Large Language Models',
|
|
78
|
-
authors: 'Juan Rodriguez, Nicholas Botzer, David Vazquez, Christopher Pal, Marco Pedersoli, Issam H. Laradji',
|
|
79
|
-
venue: 'arXiv:2411.10670, 2024',
|
|
80
|
-
url: 'https://arxiv.org/abs/2411.10670',
|
|
81
|
-
relates: '对应第 2 段"不命中就自己起一个 id":未知意图不应当被丢掉,而应当被发现为新类别。本设计把新 id 写进记录,后续可以据此把它提升为正式分类。',
|
|
82
|
-
note: '该论文用 LLM 做零样本意图发现并迭代扩展标签集;本产品只记录新 id,聚类/提升仍是人工动作。',
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
title: 'Recent Neural Methods on Dialogue State Tracking for Task-Oriented Dialogue Systems: A Survey',
|
|
86
|
-
authors: 'Vevake Balaraman, Seyedmostafa Sheikhalishahi, Bernhard Magnini',
|
|
87
|
-
venue: 'SIGDIAL 2021',
|
|
88
|
-
url: 'https://aclanthology.org/2021.sigdial-1.25/',
|
|
89
|
-
relates: '对应 `relation` 与任务链路:多轮对话里"这一轮是在续上一个任务还是开新任务"是对话状态的一部分,不是每轮独立判断。本设计把它显式建模为 new_task / subtask_of。',
|
|
90
|
-
note: '只借它的状态建模视角;本设计用规则 + 会话内已记录的任务集合来判定,没有跑 DST 模型。',
|
|
91
|
-
},
|
|
92
|
-
]
|
|
93
|
-
|
|
94
|
-
function Section({ icon: Icon, title, children }: { icon: typeof CircleHelp; title: string; children: ReactNode }): ReactNode {
|
|
95
|
-
return <Card className={styles.kbCard}>
|
|
96
|
-
<div className={styles.kbCardHead}>
|
|
97
|
-
<div><h3><Icon size={13} />{title}</h3></div>
|
|
98
|
-
</div>
|
|
99
|
-
{children}
|
|
100
|
-
</Card>
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function IntentLogic(): ReactNode {
|
|
104
|
-
return <div className={styles.viewStack}>
|
|
105
|
-
<Section icon={CircleHelp} title="什么是意图?">
|
|
106
|
-
<p className={styles.kbHint}>
|
|
107
|
-
这里说的「意图」不是要控制流程的指令,而是一条**审计事实**:这一轮用户在做什么、属于哪类业务、
|
|
108
|
-
要调什么动作、引用了哪些对象、和之前哪个任务同属一件事。
|
|
109
|
-
</p>
|
|
110
|
-
<ul className={styles.intentDocList}>
|
|
111
|
-
<li><b>判断完全交给大模型。</b>`intent_record` 只把模型给出的结论落成一条记录,不做关键词匹配、不做状态机、不反问、不阻断当前请求,也不会因为分类错了就让请求失败。</li>
|
|
112
|
-
<li><b>记录不驱动控制流。</b>它服务三件事:事后回溯(这轮到底想干什么)、链路串联(下游工具与产物继承 taskId / subtaskId)、质量观测(哪些轮次低置信度、哪些落到了 unknown)。</li>
|
|
113
|
-
<li><b>数据轮次漏了也不丢。</b>只有进入数据 / 知识域的轮次才需要记录;如果模型漏记,Host 补一条 <code>source: fallback</code> 的 unknown。普通 Agent 和闲聊不会生成意图记录。</li>
|
|
114
|
-
</ul>
|
|
115
|
-
</Section>
|
|
116
|
-
|
|
117
|
-
<Section icon={BrainCircuit} title="召回侧的意图识别">
|
|
118
|
-
<p className={styles.kbHint}>
|
|
119
|
-
召回侧的意图不是会话记录的替代品。每次用户查询进入知识库时,运行时都会先判断用户要完成的事,再从知识矩阵实体注册表解析 OAS;结果只服务本次候选生成和重排,不写入会话意图表。
|
|
120
|
-
</p>
|
|
121
|
-
<div className={styles.intentDocGrid}>
|
|
122
|
-
<div><strong>Intent</strong><span>lookup 查事实、explain 解释概念、procedure 执行步骤、troubleshoot 排查问题、compare 比较差异。</span></div>
|
|
123
|
-
<div><strong>Object</strong><span>用户正在问的对象,例如指标、表、业务概念;优先匹配注册表 canonical / alias。</span></div>
|
|
124
|
-
<div><strong>Action</strong><span>对象上的动作,例如计算、排查、配置、接入;它是坐标轴,不等于会话层 act。</span></div>
|
|
125
|
-
<div><strong>Scene</strong><span>问题发生的场景,例如日报、线上、异常、复盘;与 Object、Action 组成坐标。</span></div>
|
|
126
|
-
</div>
|
|
127
|
-
<p className={styles.kbHint}>
|
|
128
|
-
三个轴实体匹配后组成 Coordinate 候选:Coordinate 路先找到对应 WikiCard,再展开为 Section;FTS 与 Vector 仍然直接召回 Section,三路最终进入同一个 Section 候选池。
|
|
129
|
-
</p>
|
|
130
|
-
<div className={styles.intentOasLegend}>
|
|
131
|
-
<span><Shapes size={11} />OAS 是坐标先验</span>
|
|
132
|
-
<span><BrainCircuit size={11} />Intent 是任务目标</span>
|
|
133
|
-
<span>都不替代 Section 重排</span>
|
|
134
|
-
</div>
|
|
135
|
-
</Section>
|
|
136
|
-
|
|
137
|
-
<Section icon={ListTree} title="意图的描述是什么?">
|
|
138
|
-
<p className={styles.kbHint}>
|
|
139
|
-
一条意图记录把"这一轮"描述成四个维度,它们互相正交,缺一个都会让回溯变模糊:
|
|
140
|
-
</p>
|
|
141
|
-
<div className={styles.intentDocGrid}>
|
|
142
|
-
<div><strong>做什么(act)</strong><span>问 / 让做 / 补充 / 确认 / 取消 …… 固定审计分类。</span></div>
|
|
143
|
-
<div><strong>哪一类(category)</strong><span>数据分析 / 知识构建 / 产物交付 …… 固定审计分类。</span></div>
|
|
144
|
-
<div><strong>要调什么(predicate)</strong><span>最终落到哪个工具,例如 query_babel_data。</span></div>
|
|
145
|
-
<div><strong>和谁一起(relation + lineage)</strong><span>新任务还是续任务,以及 intentId / taskId / subtaskId / runId 链路。</span></div>
|
|
146
|
-
</div>
|
|
147
|
-
<p className={styles.kbHint}>
|
|
148
|
-
另一个维度是**把握度**:`confidence` 低于澄清阈值时记录被标成 lowConfidence。它只影响展示与筛选,
|
|
149
|
-
不改变这一轮的执行。
|
|
150
|
-
</p>
|
|
151
|
-
</Section>
|
|
152
|
-
|
|
153
|
-
<Section icon={ClipboardCheck} title="记录字段分别是什么含义?">
|
|
154
|
-
<div className={styles.intentDocTableWrap}>
|
|
155
|
-
<table className={styles.intentDocTable}>
|
|
156
|
-
<thead><tr><th>字段</th><th>必填</th><th>含义</th><th>谁来填</th></tr></thead>
|
|
157
|
-
<tbody>
|
|
158
|
-
{RECORD_FIELDS.map(field => <tr key={field.name}>
|
|
159
|
-
<td><code>{field.name}</code></td>
|
|
160
|
-
<td>{field.required ? '✓' : ''}</td>
|
|
161
|
-
<td>{field.meaning}</td>
|
|
162
|
-
<td>{field.where}</td>
|
|
163
|
-
</tr>)}
|
|
164
|
-
</tbody>
|
|
165
|
-
</table>
|
|
166
|
-
</div>
|
|
167
|
-
<p className={styles.kbHint}>
|
|
168
|
-
会话审计词表是固定契约,不属于知识库召回配置,也不在面板中编辑。模型写入未知的 act 或 category 时,
|
|
169
|
-
记录照样落库,只在 `warnings` 里说明;召回侧的 Intent / Object / Action / Scene 则由当前 Query 运行时解析。
|
|
170
|
-
</p>
|
|
171
|
-
</Section>
|
|
172
|
-
|
|
173
|
-
<Section icon={Library} title="引用了什么论文?">
|
|
174
|
-
<p className={styles.kbHint}>
|
|
175
|
-
诚实说明:**这套实现没有复现任何一篇论文的模型**。它是工程取舍的产物;下面是同一批问题的
|
|
176
|
-
公开研究,用来说明这些设计点不是凭空来的。每条都标了它对应哪一处设计。
|
|
177
|
-
</p>
|
|
178
|
-
<ul className={styles.intentPaperList}>
|
|
179
|
-
{PAPERS.map(paper => <li key={paper.url}>
|
|
180
|
-
<a href={paper.url} target="_blank" rel="noreferrer">{paper.title}</a>
|
|
181
|
-
<span className={styles.intentPaperMeta}>{paper.authors} · {paper.venue}</span>
|
|
182
|
-
<p>{paper.relates}</p>
|
|
183
|
-
{paper.note && <p className={styles.intentPaperNote}>注:{paper.note}</p>}
|
|
184
|
-
</li>)}
|
|
185
|
-
</ul>
|
|
186
|
-
<p className={styles.kbHint}>
|
|
187
|
-
另外两处术语来源不在论文里:<b>act / predicate</b> 的分法沿用本插件既有的意图契约(issue 0012),
|
|
188
|
-
<b>lineage</b> 是 DSH 自身的链路约定(session / turn / intent / task / subtask / run 六个 id)。
|
|
189
|
-
</p>
|
|
190
|
-
</Section>
|
|
191
|
-
</div>
|
|
192
|
-
}
|
package/src/client/IntentTab.tsx
DELETED
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 意图 Tab —— 会话意图审计。
|
|
3
|
-
*
|
|
4
|
-
* 这页只回答一个问题:用户刚才说的话,Agent 是怎么理解的。
|
|
5
|
-
* 它不是控制面板,也不展示召回侧的 Query Intent;召回解析在“召回 · 重排”里完成。
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { useCallback, useEffect, useMemo, useState, type ReactNode } from 'react'
|
|
9
|
-
import { AlertCircle, BrainCircuit, Clock3, RefreshCw, X } from '@tita-agent/ui/icons'
|
|
10
|
-
import { Badge, Button, Card, SelectMenu } from '@tita-agent/ui/components'
|
|
11
|
-
import { styles } from './styles.ts'
|
|
12
|
-
import { InfoHint } from './InfoHint.tsx'
|
|
13
|
-
|
|
14
|
-
interface IntentRecord {
|
|
15
|
-
id: string
|
|
16
|
-
act: string
|
|
17
|
-
category?: string
|
|
18
|
-
predicate?: string
|
|
19
|
-
confidence?: number
|
|
20
|
-
lowConfidence?: boolean
|
|
21
|
-
relation: string
|
|
22
|
-
source: 'model' | 'fallback'
|
|
23
|
-
userInput: string
|
|
24
|
-
createdAt: string
|
|
25
|
-
updatedAt: string
|
|
26
|
-
lineage: Record<string, string>
|
|
27
|
-
meta: Record<string, unknown>
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
interface SessionSummary {
|
|
31
|
-
sessionKey: string
|
|
32
|
-
recordCount: number
|
|
33
|
-
lastAt: string
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface StoreView {
|
|
37
|
-
sessionKey: string
|
|
38
|
-
activeTaskId?: string
|
|
39
|
-
activeIntentId?: string
|
|
40
|
-
expiresAt?: string
|
|
41
|
-
tasks: Array<{ taskId: string; lastSubtaskId?: string; category?: string; ageSeconds: number }>
|
|
42
|
-
recent: IntentRecord[]
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async function getJson<T>(url: string): Promise<T> {
|
|
46
|
-
const response = await fetch(url)
|
|
47
|
-
const text = await response.text()
|
|
48
|
-
if (!text.trim()) throw new Error(`服务端返回空响应(HTTP ${response.status})`)
|
|
49
|
-
const payload = JSON.parse(text) as { ok?: boolean; data?: T; error?: { message?: string } | null }
|
|
50
|
-
if (!response.ok || payload.ok === false) throw new Error(payload.error?.message ?? `请求失败(${response.status})`)
|
|
51
|
-
if (payload.data === undefined) throw new Error('响应缺少 data')
|
|
52
|
-
return payload.data
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function formatTime(value: string | undefined): string {
|
|
56
|
-
if (!value) return '—'
|
|
57
|
-
const date = new Date(value)
|
|
58
|
-
if (Number.isNaN(date.getTime())) return '—'
|
|
59
|
-
return date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit', second: '2-digit' })
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const ACT_LABEL: Record<string, string> = {
|
|
63
|
-
query: '查询', request: '执行请求', inform: '补充信息', confirm: '确认', select: '选择',
|
|
64
|
-
correct: '纠正', cancel: '取消', review: '审阅', explain: '解释', compare: '对比',
|
|
65
|
-
recommend: '推荐', resume: '继续', reject: '拒绝', greet: '问候', chat: '闲聊', unknown: '未判定',
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const CATEGORY_LABEL: Record<string, string> = {
|
|
69
|
-
data_analysis: '数据分析', metadata_exploration: '元数据探索', data_validation: '数据校验',
|
|
70
|
-
knowledge_consultation: '知识咨询', knowledge_building: '知识构建', document_research: '文档研究',
|
|
71
|
-
message_collaboration: '消息协作', artifact_delivery: '产物交付', agent_engineering: 'Agent 工程',
|
|
72
|
-
tooling_operations: '工具运维', personal_assistant: '个人助理', conversation: '普通对话',
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function humanize(value: string | undefined, labels: Record<string, string>): string | undefined {
|
|
76
|
-
if (!value) return undefined
|
|
77
|
-
return labels[value] ?? value.replaceAll('_', ' ')
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function relationLabel(value: string): string {
|
|
81
|
-
if (value === 'subtask_of') return '继续当前任务'
|
|
82
|
-
if (value === 'new_task') return '开启新任务'
|
|
83
|
-
return '任务关系未判定'
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function intentTitle(record: IntentRecord): string {
|
|
87
|
-
const act = humanize(record.act, ACT_LABEL) ?? '未判定'
|
|
88
|
-
const category = humanize(record.category, CATEGORY_LABEL)
|
|
89
|
-
return category ? `${act} · ${category}` : act
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const SOURCE_LABEL: Record<IntentRecord['source'], string> = { model: '模型判断', fallback: '系统兜底' }
|
|
93
|
-
|
|
94
|
-
function filterOptions(
|
|
95
|
-
records: IntentRecord[],
|
|
96
|
-
field: 'category' | 'act',
|
|
97
|
-
labels: Record<string, string>,
|
|
98
|
-
allLabel: string,
|
|
99
|
-
): Array<{ value: string; label: string }> {
|
|
100
|
-
const values = new Set(records.flatMap(record => {
|
|
101
|
-
const value = record[field]
|
|
102
|
-
return value ? [value] : []
|
|
103
|
-
}))
|
|
104
|
-
const known = Object.keys(labels).filter(value => values.has(value))
|
|
105
|
-
const unknown = [...values].filter(value => !(value in labels)).sort()
|
|
106
|
-
return [
|
|
107
|
-
{ value: '', label: allLabel },
|
|
108
|
-
...[...known, ...unknown].map(value => ({ value, label: humanize(value, labels) ?? value })),
|
|
109
|
-
]
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function DiagnosticDetails({ record }: { record: IntentRecord }): ReactNode {
|
|
113
|
-
return <details className={styles.intentDiagnostics}>
|
|
114
|
-
<summary>查看诊断信息</summary>
|
|
115
|
-
<div className={styles.intentDiagnosticsBody}>
|
|
116
|
-
<span>内部分类:{record.act}{record.category ? ` · ${record.category}` : ''}</span>
|
|
117
|
-
{record.predicate && <span>路由谓词:<code>{record.predicate}</code></span>}
|
|
118
|
-
{record.confidence !== undefined && <span>置信度:{record.confidence.toFixed(2)}{record.lowConfidence ? '(低于阈值)' : ''}</span>}
|
|
119
|
-
<span>来源:{SOURCE_LABEL[record.source]}</span>
|
|
120
|
-
{record.lineage.taskId && <span>任务 ID:<code>{record.lineage.taskId}</code></span>}
|
|
121
|
-
{record.lineage.subtaskId && <span>子任务 ID:<code>{record.lineage.subtaskId}</code></span>}
|
|
122
|
-
</div>
|
|
123
|
-
</details>
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function Interpretation({ record }: { record: IntentRecord }): ReactNode {
|
|
127
|
-
return <Card className={styles.intentInterpretation}>
|
|
128
|
-
<div className={styles.intentSectionHead}>
|
|
129
|
-
<div>
|
|
130
|
-
<h3>Agent 是这样理解的</h3>
|
|
131
|
-
<p className={styles.intentSectionSubhead}>最新一条判断 · 按时间倒序</p>
|
|
132
|
-
</div>
|
|
133
|
-
<time dateTime={record.updatedAt}>{formatTime(record.updatedAt)}</time>
|
|
134
|
-
</div>
|
|
135
|
-
|
|
136
|
-
<div className={styles.intentUserBlock}>
|
|
137
|
-
<span className={styles.intentStepLabel}>用户原话</span>
|
|
138
|
-
<p className={styles.intentUserInput}>{record.userInput.slice(0, 320) || '(无用户原文)'}</p>
|
|
139
|
-
</div>
|
|
140
|
-
|
|
141
|
-
<div className={styles.intentVerdict}>
|
|
142
|
-
<div className={styles.intentVerdictHead}>
|
|
143
|
-
<span className={styles.intentStepLabel}>Agent 判断</span>
|
|
144
|
-
{record.lowConfidence && <span className={styles.intentLowConfidence}>需要复核</span>}
|
|
145
|
-
</div>
|
|
146
|
-
<h4 className={styles.intentResultTitle}>{intentTitle(record)}</h4>
|
|
147
|
-
<p className={styles.intentResultText}>{relationLabel(record.relation)}。这条判断{record.lowConfidence ? '的把握较低,建议复核。' : '用于记录本轮对话走向。'}</p>
|
|
148
|
-
<div className={styles.intentResultTags}>
|
|
149
|
-
<Badge tone={record.lowConfidence ? 'warning' : 'blue'}>{humanize(record.act, ACT_LABEL) ?? '未判定'}</Badge>
|
|
150
|
-
{record.category && <Badge tone="violet">{humanize(record.category, CATEGORY_LABEL)}</Badge>}
|
|
151
|
-
</div>
|
|
152
|
-
</div>
|
|
153
|
-
|
|
154
|
-
<div className={styles.intentMetaGrid}>
|
|
155
|
-
<div className={styles.intentMetaCell}>
|
|
156
|
-
<span>任务关系</span>
|
|
157
|
-
<strong>{relationLabel(record.relation)}</strong>
|
|
158
|
-
</div>
|
|
159
|
-
<div className={styles.intentMetaCell}>
|
|
160
|
-
<span>记录来源</span>
|
|
161
|
-
<strong>{SOURCE_LABEL[record.source]}</strong>
|
|
162
|
-
</div>
|
|
163
|
-
</div>
|
|
164
|
-
|
|
165
|
-
<DiagnosticDetails record={record} />
|
|
166
|
-
</Card>
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function HistoryItem({ record }: { record: IntentRecord }): ReactNode {
|
|
170
|
-
return <li className={styles.intentHistoryItem}>
|
|
171
|
-
<div className={styles.intentHistoryPrimary}>
|
|
172
|
-
<strong>{intentTitle(record)}</strong>
|
|
173
|
-
<time dateTime={record.updatedAt}><Clock3 size={11} />{formatTime(record.updatedAt)}</time>
|
|
174
|
-
</div>
|
|
175
|
-
<p>{record.userInput.slice(0, 180) || '(无用户原文)'}</p>
|
|
176
|
-
<div className={styles.intentHistoryMeta}>
|
|
177
|
-
<span>{relationLabel(record.relation)}</span>
|
|
178
|
-
<span>{SOURCE_LABEL[record.source]}</span>
|
|
179
|
-
{record.lowConfidence && <span className={styles.intentHistoryWarning}>需复核</span>}
|
|
180
|
-
</div>
|
|
181
|
-
</li>
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
export function IntentTab({ visible }: { visible: boolean }): ReactNode {
|
|
185
|
-
const [sessions, setSessions] = useState<SessionSummary[]>([])
|
|
186
|
-
const [sessionKey, setSessionKey] = useState('')
|
|
187
|
-
const [categoryFilter, setCategoryFilter] = useState('')
|
|
188
|
-
const [actFilter, setActFilter] = useState('')
|
|
189
|
-
const [store, setStore] = useState<StoreView | null>(null)
|
|
190
|
-
const [loading, setLoading] = useState(false)
|
|
191
|
-
const [error, setError] = useState<string | null>(null)
|
|
192
|
-
const [pageNotice, setPageNotice] = useState<string | null>(null)
|
|
193
|
-
|
|
194
|
-
const load = useCallback(async (preferred?: string): Promise<void> => {
|
|
195
|
-
setLoading(true)
|
|
196
|
-
try {
|
|
197
|
-
const overview = await getJson<{ sessions: SessionSummary[] }>('/intent/overview')
|
|
198
|
-
const list = overview.sessions ?? []
|
|
199
|
-
setSessions(list)
|
|
200
|
-
const key = preferred && list.some(item => item.sessionKey === preferred)
|
|
201
|
-
? preferred
|
|
202
|
-
: list[0]?.sessionKey ?? ''
|
|
203
|
-
setSessionKey(key)
|
|
204
|
-
setStore(key ? await getJson<{ store: StoreView }>(`/intent/store?session_key=${encodeURIComponent(key)}`).then(payload => payload.store) : null)
|
|
205
|
-
setError(null)
|
|
206
|
-
} catch (cause) {
|
|
207
|
-
setError(cause instanceof Error ? cause.message : String(cause))
|
|
208
|
-
} finally {
|
|
209
|
-
setLoading(false)
|
|
210
|
-
}
|
|
211
|
-
}, [])
|
|
212
|
-
|
|
213
|
-
useEffect(() => { if (visible) void load(sessionKey || undefined) }, [visible]) // eslint-disable-line react-hooks/exhaustive-deps
|
|
214
|
-
|
|
215
|
-
const selectSession = async (key: string): Promise<void> => {
|
|
216
|
-
setSessionKey(key)
|
|
217
|
-
setCategoryFilter('')
|
|
218
|
-
setActFilter('')
|
|
219
|
-
setLoading(true)
|
|
220
|
-
try {
|
|
221
|
-
setStore((await getJson<{ store: StoreView }>(`/intent/store?session_key=${encodeURIComponent(key)}`)).store)
|
|
222
|
-
setError(null)
|
|
223
|
-
} catch (cause) {
|
|
224
|
-
setError(cause instanceof Error ? cause.message : String(cause))
|
|
225
|
-
} finally {
|
|
226
|
-
setLoading(false)
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const recent = store?.recent ?? []
|
|
231
|
-
const categoryOptions = useMemo(() => filterOptions(recent, 'category', CATEGORY_LABEL, '全部意图'), [recent])
|
|
232
|
-
const actOptions = useMemo(() => filterOptions(recent, 'act', ACT_LABEL, '全部动作'), [recent])
|
|
233
|
-
const filteredRecent = useMemo(() => recent.filter(record => (
|
|
234
|
-
(!categoryFilter || record.category === categoryFilter)
|
|
235
|
-
&& (!actFilter || record.act === actFilter)
|
|
236
|
-
)), [actFilter, categoryFilter, recent])
|
|
237
|
-
const latest = filteredRecent[0]
|
|
238
|
-
const history = filteredRecent.slice(1)
|
|
239
|
-
const hasFilter = Boolean(categoryFilter || actFilter)
|
|
240
|
-
const auditStats = useMemo(() => ({
|
|
241
|
-
lowConfidence: filteredRecent.filter(record => record.lowConfidence).length,
|
|
242
|
-
fallback: filteredRecent.filter(record => record.source === 'fallback').length,
|
|
243
|
-
}), [filteredRecent])
|
|
244
|
-
|
|
245
|
-
return <div className={styles.viewStack}>
|
|
246
|
-
<div className={styles.intentTop}>
|
|
247
|
-
<div>
|
|
248
|
-
<h2>意图记录</h2>
|
|
249
|
-
<p>先看意图结论,再核对用户原话和任务关系。这里只做审计,不参与召回或执行。</p>
|
|
250
|
-
</div>
|
|
251
|
-
<InfoHint
|
|
252
|
-
className={styles.kbToolbarHint}
|
|
253
|
-
href="/knowledge/pages/help/overview?node=intent"
|
|
254
|
-
text="查看会话意图与召回查询意图的边界"
|
|
255
|
-
onOpenFailed={message => setPageNotice(message)}
|
|
256
|
-
/>
|
|
257
|
-
</div>
|
|
258
|
-
|
|
259
|
-
<div className={styles.intentControls}>
|
|
260
|
-
<div className={styles.intentPrimaryFilter}>
|
|
261
|
-
<div className={styles.intentFilterHeading}>
|
|
262
|
-
<span className={styles.intentControlLabel}>意图</span>
|
|
263
|
-
<small>优先筛选</small>
|
|
264
|
-
</div>
|
|
265
|
-
<SelectMenu
|
|
266
|
-
value={categoryFilter}
|
|
267
|
-
onValueChange={setCategoryFilter}
|
|
268
|
-
disabled={recent.length === 0}
|
|
269
|
-
aria-label="按意图筛选"
|
|
270
|
-
options={categoryOptions}
|
|
271
|
-
/>
|
|
272
|
-
<span className={styles.intentFilterCount}>{filteredRecent.length} 条</span>
|
|
273
|
-
</div>
|
|
274
|
-
<div className={styles.intentSecondaryFilters}>
|
|
275
|
-
<span className={styles.intentControlLabel}>动作</span>
|
|
276
|
-
<SelectMenu
|
|
277
|
-
value={actFilter}
|
|
278
|
-
onValueChange={setActFilter}
|
|
279
|
-
className="w-full min-w-0"
|
|
280
|
-
size="sm"
|
|
281
|
-
disabled={recent.length === 0}
|
|
282
|
-
aria-label="按动作筛选"
|
|
283
|
-
options={actOptions}
|
|
284
|
-
/>
|
|
285
|
-
<span className={styles.intentControlLabel}>会话</span>
|
|
286
|
-
<SelectMenu
|
|
287
|
-
value={sessionKey}
|
|
288
|
-
onValueChange={next => void selectSession(next)}
|
|
289
|
-
className="w-full min-w-0"
|
|
290
|
-
size="sm"
|
|
291
|
-
disabled={sessions.length === 0}
|
|
292
|
-
aria-label="选择意图记录会话"
|
|
293
|
-
placeholder={sessions.length === 0 ? '还没有会话记录' : '选择会话'}
|
|
294
|
-
options={sessions.map(item => ({ value: item.sessionKey, label: `${item.sessionKey.slice(0, 18)} · ${item.recordCount} 条 · ${formatTime(item.lastAt)}` }))}
|
|
295
|
-
/>
|
|
296
|
-
<Button variant="ghost" size="icon" title="刷新" aria-label="刷新意图记录" onClick={() => void load(sessionKey)} disabled={loading}><RefreshCw size={14} /></Button>
|
|
297
|
-
</div>
|
|
298
|
-
<div className={styles.intentFilterSummary} aria-live="polite">
|
|
299
|
-
<span>当前会话显示 {filteredRecent.length} / {recent.length} 条</span>
|
|
300
|
-
{categoryFilter && <Badge tone="blue">{humanize(categoryFilter, CATEGORY_LABEL) ?? categoryFilter}</Badge>}
|
|
301
|
-
{actFilter && <Badge tone="violet">{humanize(actFilter, ACT_LABEL) ?? actFilter}</Badge>}
|
|
302
|
-
</div>
|
|
303
|
-
</div>
|
|
304
|
-
|
|
305
|
-
{pageNotice !== null && <p className={styles.kbNotice} role="alert">
|
|
306
|
-
<AlertCircle size={13} /><span>{pageNotice}</span>
|
|
307
|
-
{/* 这一枚原来是手写的 `<button>`,命中区只有 12px、图标用自己的字号档,焦点圈
|
|
308
|
-
也是另写的一条。现在用与面板里其余关闭动作同一枚共享控件。 */}
|
|
309
|
-
<Button className={styles.kbNoticeClose} variant="ghost" size="icon" aria-label="关闭提示" title="关闭提示" onClick={() => setPageNotice(null)}><X size={13} /></Button>
|
|
310
|
-
</p>}
|
|
311
|
-
{error && <p className={styles.kbNotice}><AlertCircle size={13} /><span>{error}</span></p>}
|
|
312
|
-
|
|
313
|
-
{latest
|
|
314
|
-
? <Interpretation record={latest} />
|
|
315
|
-
: <Card className={styles.intentEmptyCard}>
|
|
316
|
-
<BrainCircuit size={18} />
|
|
317
|
-
<strong>{hasFilter ? '当前筛选下没有判断' : '还没有可展示的判断'}</strong>
|
|
318
|
-
<p>{hasFilter ? '调整“意图”或“动作”筛选后再看。' : '选择一个有记录的会话后,这里会显示用户原话和 Agent 判断。'}</p>
|
|
319
|
-
</Card>}
|
|
320
|
-
|
|
321
|
-
<section className={styles.intentHistory}>
|
|
322
|
-
<div className={styles.intentSectionHead}>
|
|
323
|
-
<div>
|
|
324
|
-
<h3>历史判断</h3>
|
|
325
|
-
<p className={styles.intentSectionSubhead}>当前会话中更早的记录</p>
|
|
326
|
-
</div>
|
|
327
|
-
<span className={styles.intentSectionCount}>{history.length} 条</span>
|
|
328
|
-
</div>
|
|
329
|
-
{history.length === 0
|
|
330
|
-
? <p className={styles.intentEmpty}>{hasFilter ? '当前筛选下没有更早的判断。' : latest ? '这是当前会话的第一条判断。' : '暂无历史记录。'}</p>
|
|
331
|
-
: <ol className={styles.intentHistoryList}>
|
|
332
|
-
{history.map(record => <HistoryItem key={record.id} record={record} />)}
|
|
333
|
-
</ol>}
|
|
334
|
-
</section>
|
|
335
|
-
|
|
336
|
-
<div className={styles.intentFooter}>
|
|
337
|
-
<span>共 {filteredRecent.length} 条判断{hasFilter ? `(当前会话 ${recent.length} 条)` : ''}</span>
|
|
338
|
-
{auditStats.lowConfidence > 0 && <span>{auditStats.lowConfidence} 条需要复核</span>}
|
|
339
|
-
{auditStats.fallback > 0 && <span>{auditStats.fallback} 条系统兜底</span>}
|
|
340
|
-
{store?.expiresAt && <span>保留至 {formatTime(store.expiresAt)}</span>}
|
|
341
|
-
</div>
|
|
342
|
-
</div>
|
|
343
|
-
}
|