dsh-data-domain-knowledge 0.1.0-alpha.1
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/LICENSE +21 -0
- package/README.md +360 -0
- package/cordis.patch.yml +410 -0
- package/eval/README.md +76 -0
- package/eval/evaluate-retrieval.mjs +121 -0
- package/eval/queries.example.jsonl +2 -0
- package/lib/client.js +111415 -0
- package/lib/types/config-schema.d.ts +35 -0
- package/lib/types/config-schema.d.ts.map +1 -0
- package/lib/types/config-schema.js +34 -0
- package/lib/types/config-schema.js.map +1 -0
- package/lib/types/convert/core-loader.d.ts +32 -0
- package/lib/types/convert/core-loader.d.ts.map +1 -0
- package/lib/types/convert/core-loader.js +60 -0
- package/lib/types/convert/core-loader.js.map +1 -0
- package/lib/types/convert/host.d.ts +88 -0
- package/lib/types/convert/host.d.ts.map +1 -0
- package/lib/types/convert/host.js +479 -0
- package/lib/types/convert/host.js.map +1 -0
- package/lib/types/convert/ingest.d.ts +125 -0
- package/lib/types/convert/ingest.d.ts.map +1 -0
- package/lib/types/convert/ingest.js +228 -0
- package/lib/types/convert/ingest.js.map +1 -0
- package/lib/types/convert/settings-schema.d.ts +18 -0
- package/lib/types/convert/settings-schema.d.ts.map +1 -0
- package/lib/types/convert/settings-schema.js +26 -0
- package/lib/types/convert/settings-schema.js.map +1 -0
- package/lib/types/convert/types.d.ts +46 -0
- package/lib/types/convert/types.d.ts.map +1 -0
- package/lib/types/convert/types.js +41 -0
- package/lib/types/convert/types.js.map +1 -0
- package/lib/types/diagnosis/cards.d.ts +71 -0
- package/lib/types/diagnosis/cards.d.ts.map +1 -0
- package/lib/types/diagnosis/cards.js +482 -0
- package/lib/types/diagnosis/cards.js.map +1 -0
- package/lib/types/diagnosis/problem-classes.d.ts +51 -0
- package/lib/types/diagnosis/problem-classes.d.ts.map +1 -0
- package/lib/types/diagnosis/problem-classes.js +66 -0
- package/lib/types/diagnosis/problem-classes.js.map +1 -0
- package/lib/types/diagnosis/schema.d.ts +65 -0
- package/lib/types/diagnosis/schema.d.ts.map +1 -0
- package/lib/types/diagnosis/schema.js +208 -0
- package/lib/types/diagnosis/schema.js.map +1 -0
- package/lib/types/diagnosis/seed-source.d.ts +20 -0
- package/lib/types/diagnosis/seed-source.d.ts.map +1 -0
- package/lib/types/diagnosis/seed-source.js +96 -0
- package/lib/types/diagnosis/seed-source.js.map +1 -0
- package/lib/types/diagnosis/seed.d.ts +50 -0
- package/lib/types/diagnosis/seed.d.ts.map +1 -0
- package/lib/types/diagnosis/seed.js +242 -0
- package/lib/types/diagnosis/seed.js.map +1 -0
- package/lib/types/diagnosis/store.d.ts +81 -0
- package/lib/types/diagnosis/store.d.ts.map +1 -0
- package/lib/types/diagnosis/store.js +409 -0
- package/lib/types/diagnosis/store.js.map +1 -0
- package/lib/types/diagnosis/types.d.ts +124 -0
- package/lib/types/diagnosis/types.d.ts.map +1 -0
- package/lib/types/diagnosis/types.js +13 -0
- package/lib/types/diagnosis/types.js.map +1 -0
- package/lib/types/directory-picker.d.ts +94 -0
- package/lib/types/directory-picker.d.ts.map +1 -0
- package/lib/types/directory-picker.js +110 -0
- package/lib/types/directory-picker.js.map +1 -0
- package/lib/types/extract-model.d.ts +76 -0
- package/lib/types/extract-model.d.ts.map +1 -0
- package/lib/types/extract-model.js +193 -0
- package/lib/types/extract-model.js.map +1 -0
- package/lib/types/extract.d.ts +121 -0
- package/lib/types/extract.d.ts.map +1 -0
- package/lib/types/extract.js +549 -0
- package/lib/types/extract.js.map +1 -0
- package/lib/types/fts.d.ts +96 -0
- package/lib/types/fts.d.ts.map +1 -0
- package/lib/types/fts.js +184 -0
- package/lib/types/fts.js.map +1 -0
- package/lib/types/index.d.ts +39 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +1112 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/intent/engine.d.ts +108 -0
- package/lib/types/intent/engine.d.ts.map +1 -0
- package/lib/types/intent/engine.js +501 -0
- package/lib/types/intent/engine.js.map +1 -0
- package/lib/types/intent/host.d.ts +88 -0
- package/lib/types/intent/host.d.ts.map +1 -0
- package/lib/types/intent/host.js +389 -0
- package/lib/types/intent/host.js.map +1 -0
- package/lib/types/intent/preset-tools.d.ts +37 -0
- package/lib/types/intent/preset-tools.d.ts.map +1 -0
- package/lib/types/intent/preset-tools.js +45 -0
- package/lib/types/intent/preset-tools.js.map +1 -0
- package/lib/types/intent/settings-schema.d.ts +59 -0
- package/lib/types/intent/settings-schema.d.ts.map +1 -0
- package/lib/types/intent/settings-schema.js +57 -0
- package/lib/types/intent/settings-schema.js.map +1 -0
- package/lib/types/intent/store.d.ts +75 -0
- package/lib/types/intent/store.d.ts.map +1 -0
- package/lib/types/intent/store.js +139 -0
- package/lib/types/intent/store.js.map +1 -0
- package/lib/types/intent/tools.d.ts +63 -0
- package/lib/types/intent/tools.d.ts.map +1 -0
- package/lib/types/intent/tools.js +108 -0
- package/lib/types/intent/tools.js.map +1 -0
- package/lib/types/intent/types.d.ts +189 -0
- package/lib/types/intent/types.d.ts.map +1 -0
- package/lib/types/intent/types.js +62 -0
- package/lib/types/intent/types.js.map +1 -0
- package/lib/types/knowledge-bases.d.ts +266 -0
- package/lib/types/knowledge-bases.d.ts.map +1 -0
- package/lib/types/knowledge-bases.js +1107 -0
- package/lib/types/knowledge-bases.js.map +1 -0
- package/lib/types/layout.d.ts +262 -0
- package/lib/types/layout.d.ts.map +1 -0
- package/lib/types/layout.js +312 -0
- package/lib/types/layout.js.map +1 -0
- package/lib/types/migrate.d.ts +110 -0
- package/lib/types/migrate.d.ts.map +1 -0
- package/lib/types/migrate.js +280 -0
- package/lib/types/migrate.js.map +1 -0
- package/lib/types/recall-rank.d.ts +158 -0
- package/lib/types/recall-rank.d.ts.map +1 -0
- package/lib/types/recall-rank.js +261 -0
- package/lib/types/recall-rank.js.map +1 -0
- package/lib/types/runtime.d.ts +568 -0
- package/lib/types/runtime.d.ts.map +1 -0
- package/lib/types/runtime.js +3045 -0
- package/lib/types/runtime.js.map +1 -0
- package/lib/types/settings-schema.d.ts +117 -0
- package/lib/types/settings-schema.d.ts.map +1 -0
- package/lib/types/settings-schema.js +92 -0
- package/lib/types/settings-schema.js.map +1 -0
- package/lib/types/settings-volatile.d.ts +102 -0
- package/lib/types/settings-volatile.d.ts.map +1 -0
- package/lib/types/settings-volatile.js +114 -0
- package/lib/types/settings-volatile.js.map +1 -0
- package/lib/types/types.d.ts +799 -0
- package/lib/types/types.d.ts.map +1 -0
- package/lib/types/types.js +387 -0
- package/lib/types/types.js.map +1 -0
- package/lib/types/wiki-types.d.ts +68 -0
- package/lib/types/wiki-types.d.ts.map +1 -0
- package/lib/types/wiki-types.js +322 -0
- package/lib/types/wiki-types.js.map +1 -0
- package/package.json +101 -0
- package/preset/tita-data-agent/agent.cordis.yml +376 -0
- package/preset/tita-data-agent/preset.yml +3 -0
- package/python/requirements.txt +8 -0
- package/scripts/doctor.mjs +70 -0
- package/scripts/e2e-pipeline.mjs +355 -0
- package/scripts/install-agent-preset.mjs +92 -0
- package/scripts/setup-embedding.sh +34 -0
- package/scripts/sync-agent-preset.mjs +188 -0
- package/src/client/AgentPresetCard.tsx +247 -0
- package/src/client/DirectoryPicker.tsx +357 -0
- package/src/client/InfoHint.tsx +65 -0
- package/src/client/IntentLogicTab.tsx +185 -0
- package/src/client/IntentTab.tsx +715 -0
- package/src/client/KnowledgeBaseTab.tsx +1454 -0
- package/src/client/KnowledgeGraphView.tsx +306 -0
- package/src/client/KnowledgePanel.tsx +381 -0
- package/src/client/KnowledgeStepRail.tsx +60 -0
- package/src/client/NodeSettings.tsx +392 -0
- package/src/client/PreviewSections.tsx +116 -0
- package/src/client/RecallPanel.tsx +399 -0
- package/src/client/TypeDefinitionDrawer.tsx +215 -0
- package/src/client/WikiFlowCard.tsx +226 -0
- package/src/client/WikiTypeEditor.tsx +332 -0
- package/src/client/agent-preset.ts +121 -0
- package/src/client/arch/AgentArchitectureGraph.tsx +219 -0
- package/src/client/arch/NodeLogicPanel.tsx +133 -0
- package/src/client/arch/ProblemDetailPanel.tsx +88 -0
- package/src/client/arch/model.ts +691 -0
- package/src/client/architecture.css +191 -0
- package/src/client/architecture.tsx +530 -0
- package/src/client/attribution/AttributionGraph.tsx +104 -0
- package/src/client/attribution/AttributionTab.tsx +332 -0
- package/src/client/attribution/CaseView.tsx +102 -0
- package/src/client/attribution/GraphStage.tsx +87 -0
- package/src/client/attribution/RunView.tsx +184 -0
- package/src/client/attribution/StageChrome.tsx +403 -0
- package/src/client/attribution/ViewSwitch.tsx +107 -0
- package/src/client/attribution/graph-options.ts +381 -0
- package/src/client/attribution/model.ts +462 -0
- package/src/client/config-scope.ts +119 -0
- package/src/client/convert/ConvertPanel.tsx +594 -0
- package/src/client/convert/styles.css +138 -0
- package/src/client/convert/styles.ts +49 -0
- package/src/client/format.ts +39 -0
- package/src/client/graph/layout.ts +181 -0
- package/src/client/graph.css +113 -0
- package/src/client/index.ts +98 -0
- package/src/client/problem-domains.ts +114 -0
- package/src/client/styles.css +940 -0
- package/src/client/styles.ts +11 -0
- package/src/client/useFitScale.ts +68 -0
- package/src/config-schema.ts +45 -0
- package/src/convert/core-loader.ts +68 -0
- package/src/convert/host.ts +579 -0
- package/src/convert/ingest.ts +367 -0
- package/src/convert/settings-schema.ts +27 -0
- package/src/convert/types.ts +65 -0
- package/src/diagnosis/cards.ts +498 -0
- package/src/diagnosis/problem-classes.ts +117 -0
- package/src/diagnosis/schema.ts +260 -0
- package/src/diagnosis/seed-source.ts +107 -0
- package/src/diagnosis/seed.ts +291 -0
- package/src/diagnosis/store.ts +432 -0
- package/src/diagnosis/types.ts +152 -0
- package/src/directory-picker.ts +164 -0
- package/src/extract-model.ts +227 -0
- package/src/extract.ts +632 -0
- package/src/fts.ts +203 -0
- package/src/index.ts +1091 -0
- package/src/intent/README.md +63 -0
- package/src/intent/engine.ts +527 -0
- package/src/intent/host.ts +462 -0
- package/src/intent/preset-tools.ts +48 -0
- package/src/intent/settings-schema.ts +63 -0
- package/src/intent/store.ts +143 -0
- package/src/intent/tools.ts +139 -0
- package/src/intent/types.ts +245 -0
- package/src/knowledge-bases.ts +1160 -0
- package/src/layout.ts +350 -0
- package/src/migrate.ts +262 -0
- package/src/python/embedding_worker.py +471 -0
- package/src/recall-rank.ts +299 -0
- package/src/runtime.ts +3069 -0
- package/src/settings-schema.ts +94 -0
- package/src/settings-volatile.ts +122 -0
- package/src/types.ts +1140 -0
- package/src/wiki-types.ts +357 -0
|
@@ -0,0 +1,799 @@
|
|
|
1
|
+
export type KnowledgeStatus = 'unreviewed' | 'draft' | 'reviewed' | 'active' | 'deprecated' | 'problem';
|
|
2
|
+
/**
|
|
3
|
+
* 内置来源业务分类的 id(0013 注册表)。
|
|
4
|
+
*
|
|
5
|
+
* 注册表允许用户追加自定义分类,所以**运行时一律按 `string` 处理**
|
|
6
|
+
* (见 `SourceType`);这个字面量联合只用来标记哪些 id 是内置的。
|
|
7
|
+
*/
|
|
8
|
+
export type BuiltinSourceType = 'chat_message' | 'ai_chat_message' | 'document' | 'book' | 'article' | 'prd' | 'question';
|
|
9
|
+
/** 来源业务分类 id。自定义分类是开放集合,所以不是字面量联合。 */
|
|
10
|
+
export type SourceType = string;
|
|
11
|
+
/**
|
|
12
|
+
* 知识卡片的 entity_type 白名单。
|
|
13
|
+
*
|
|
14
|
+
* **智能归因的五类也在这里**,这不是放宽而是纠错:排查思路本来就应该是一张 wiki 卡片
|
|
15
|
+
* (0021 §6.4 定了五类实体与三段式卡片),但白名单里没有它们的时候,`writeCard` 会直接
|
|
16
|
+
* 返回 `SCHEMA_TYPE_INVALID`,`readCards` 也会跳过 —— 于是排查思路**永远进不了 wikiNotes,
|
|
17
|
+
* 也就永远召不回来**。列表本身在 `diagnosis/schema.ts` 里定义一次,这里只做联合。
|
|
18
|
+
*/
|
|
19
|
+
export type SchemaType = 'concept' | 'metric' | 'table' | 'event' | 'playbook' | 'case' | 'diagnosis/symptom' | 'diagnosis/hypothesis' | 'diagnosis/check' | 'diagnosis/failure-mode' | 'diagnosis/case';
|
|
20
|
+
export type EmbeddingProvider = 'wemm-python' | 'ollama' | 'none';
|
|
21
|
+
export type EmbeddingDevice = 'auto' | 'mps' | 'cpu';
|
|
22
|
+
export type RerankProvider = 'bert-python' | 'none';
|
|
23
|
+
/** 真正跑起来的召回路线。`graph` 是 0021 加入的知识图谱路。 */
|
|
24
|
+
export type RecallRoute = 'fts' | 'vector' | 'graph';
|
|
25
|
+
/**
|
|
26
|
+
* 召回路线选择(0031 起语义有变)。
|
|
27
|
+
*
|
|
28
|
+
* `graph` 与 `hybrid` **同义**:知识图谱从「第三路」降成了 boost,它不能凭自己制造
|
|
29
|
+
* 候选,只给已经在候选池里的条目加权(见 `recallBoost`/`graphBoost`)。所以「只靠图谱」
|
|
30
|
+
* 的召回在设计上不成立,保留这个取值只为兼容已存的设置与调用方。
|
|
31
|
+
*/
|
|
32
|
+
export type RecallMode = 'fts' | 'vector' | 'graph' | 'hybrid';
|
|
33
|
+
import type { DataError, Envelope as WireEnvelope } from 'dsh-data-contracts/envelope';
|
|
34
|
+
import type { LineageContext, LineageRef } from 'dsh-data-contracts/refs';
|
|
35
|
+
export interface KnowledgeError extends DataError {
|
|
36
|
+
code: string;
|
|
37
|
+
message: string;
|
|
38
|
+
retryable: boolean;
|
|
39
|
+
suggestion?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* This plugin's envelope: the shared five-key wire contract
|
|
43
|
+
* (`spec/contracts/envelope.json`) with the error narrowed to `KnowledgeError`,
|
|
44
|
+
* so `retryable` / `suggestion` stay visible to callers and the panel.
|
|
45
|
+
*
|
|
46
|
+
* The shape itself lives in `dsh-data-contracts` — the status rule
|
|
47
|
+
* "warnings make it partial" is defined once there, not re-spelled here.
|
|
48
|
+
*/
|
|
49
|
+
export type Envelope<T> = WireEnvelope<T, KnowledgeError>;
|
|
50
|
+
export interface KnowledgeConfig {
|
|
51
|
+
/**
|
|
52
|
+
* **Tita Agent 根路径** —— 用户唯一要设的那个路径(0029)。
|
|
53
|
+
*
|
|
54
|
+
* 根路径下固定四段:`domain_knowledge/`(知识树,按知识库 id 分叉)、
|
|
55
|
+
* `output/`(交付物,二级按日期)、`tmp/`(运行期临时文件,二级按日期)、
|
|
56
|
+
* `resource/`(模型、Python 环境、注册表)。
|
|
57
|
+
* 四段为什么这么分,见 `layout.ts` 顶部的四条原理。
|
|
58
|
+
*/
|
|
59
|
+
agentRoot: string;
|
|
60
|
+
/**
|
|
61
|
+
* @deprecated 0029:这是**旧布局**的知识树根(`01_source_truth` 直接躺在它
|
|
62
|
+
* 下面)。它不再可设置,也不再决定任何路径 —— 只作为一次性的迁移来源存在:
|
|
63
|
+
* 值非空且新位置还是空的时,把旧树搬进 `<agentRoot>/domain_knowledge/default`。
|
|
64
|
+
* 搬完(或本来就没有)它就不再有意义。
|
|
65
|
+
*/
|
|
66
|
+
rootDir: string;
|
|
67
|
+
schemaTypes: SchemaType[];
|
|
68
|
+
/**
|
|
69
|
+
* @deprecated 0013:来源分类改为**按知识库持久化的注册表**
|
|
70
|
+
* (`KnowledgeBase.sourceTypes` / `00_schema/source-types.json` 语义)。
|
|
71
|
+
* 这个字段只是历史 settings JSON 的兼容壳,既不参与 `addSource` 校验,
|
|
72
|
+
* 也不再暴露在设置面板里;判定与校验一律走注册表。
|
|
73
|
+
*/
|
|
74
|
+
sourceAppendTypes: SourceType[];
|
|
75
|
+
allowSourceTruth: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Pass 0(候选抽取 + 归一)的总开关。
|
|
78
|
+
*
|
|
79
|
+
* 默认**开**:它是「SourceRaw → Wiki」这条链上唯一不依赖模型的一步,关掉之后
|
|
80
|
+
* 知识库就只能靠 Agent 逐张 `write_knowledge_card` 长大。关掉的场景是真实存在的
|
|
81
|
+
* (批量导入时不想让每份文档都自动长出一张未审核卡片),所以它必须可关,
|
|
82
|
+
* 但关掉不等于删除:计数器会如实回 0,而不是假装抽过了。
|
|
83
|
+
*/
|
|
84
|
+
extractCandidates: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* #3b:用模型做**实体抽取与归并**(`extract-model.ts`)。
|
|
87
|
+
*
|
|
88
|
+
* 开着时,`rebuild` 把「这份来源里有哪些实体、其中哪些 wiki 里已经有了」交给模型;
|
|
89
|
+
* 关系候选仍由规则抽取补上,模型不可用则整轮退回规则。所以它是**增强**而不是依赖 ——
|
|
90
|
+
* 关掉它链路照跑,只是同一实体横跨两份文档时可能落成两张卡(实测过)。
|
|
91
|
+
*
|
|
92
|
+
* 触发时机跟着来源走:只有**变化的来源**才进这一轮(增量复用没变的不重跑),
|
|
93
|
+
* 所以成本与「改了多少来源」成正比,而不是与库的大小成正比。
|
|
94
|
+
*/
|
|
95
|
+
extractWithModel: boolean;
|
|
96
|
+
/** Python 解释器。空串 = 自动(`<agentRoot>/resource/python/bin/python`,退回旧家当目录,再退回 `python3`)。 */
|
|
97
|
+
python: string;
|
|
98
|
+
embeddingProvider: EmbeddingProvider;
|
|
99
|
+
embeddingBaseUrl: string;
|
|
100
|
+
/** 嵌入模型:一个本地目录或一个 HF 模型名。空串 = 自动(根路径下的本地模型,退回旧家当目录,再退回 HF 名)。 */
|
|
101
|
+
embeddingModel: string;
|
|
102
|
+
embeddingDimension: number;
|
|
103
|
+
embeddingBatchSize: number;
|
|
104
|
+
embeddingTimeoutMs: number;
|
|
105
|
+
embeddingDevice: EmbeddingDevice;
|
|
106
|
+
/** Stage 3 recall: how many wikiNotes the multi-route recall may return. */
|
|
107
|
+
recallTopK: number;
|
|
108
|
+
/**
|
|
109
|
+
* Stage 3 的**候选池**深度:融合之前每一路各自超采多少条(0031)。
|
|
110
|
+
*
|
|
111
|
+
* 它和 `recallTopK` 是两件事,0014 早就点明过:前者是「先粗召回多少」,
|
|
112
|
+
* 后者是「最终给模型多少」。两者共用一个数时,重排只能给已经截断的列表换顺序,
|
|
113
|
+
* 永远救不回被融合排到窗口外的那一条。默认 50(与 WeKnora 的 `EmbeddingTopK` 一致)。
|
|
114
|
+
*/
|
|
115
|
+
recallCandidatePool: number;
|
|
116
|
+
/** Stage 3 recall: default route when a caller does not pass `mode`. */
|
|
117
|
+
recallMode: RecallMode;
|
|
118
|
+
/**
|
|
119
|
+
* 关键词路的最低分(归一化 BM25,0..1)。低于它不进候选池。
|
|
120
|
+
*
|
|
121
|
+
* 注意它是**相对**阈值(按本次查询的最高分归一),所以它挡得住「弱命中」,
|
|
122
|
+
* 挡不住「整批都弱」;真正的绝对闸门是 `rerankThreshold`。
|
|
123
|
+
*/
|
|
124
|
+
keywordThreshold: number;
|
|
125
|
+
/** 向量路的最低相似度(原始余弦,−1..1)。这是**绝对**阈值,可直接用于弃答。 */
|
|
126
|
+
vectorThreshold: number;
|
|
127
|
+
/** Stage 4 rerank: how many reranked wikiNotes enter the model context. */
|
|
128
|
+
contextTopN: number;
|
|
129
|
+
/**
|
|
130
|
+
* Stage 4 重排后的最低分(0..1,sigmoid 之后的 cross-encoder 分)。
|
|
131
|
+
*
|
|
132
|
+
* 它是整条链路里唯一**跨查询可比**的相关性判据,所以「弃答」主要靠它。
|
|
133
|
+
*/
|
|
134
|
+
rerankThreshold: number;
|
|
135
|
+
/** Stage 4 rerank: BERT cross-encoder provider, or `none` to skip reranking. */
|
|
136
|
+
rerankProvider: RerankProvider;
|
|
137
|
+
/** 重排模型:同上。空串 = 自动。 */
|
|
138
|
+
rerankModel: string;
|
|
139
|
+
rerankTimeoutMs: number;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 旧的「家当」目录(0029 之前模型与虚拟环境住在这里)。
|
|
143
|
+
*
|
|
144
|
+
* 现在它们是**兜底**:路径解析优先看 `<agentRoot>/resource/`,找不到再回这里,
|
|
145
|
+
* 最后才退回裸的模型名(从 HuggingFace 拉)。这样搬完家当、或还没搬完家当,
|
|
146
|
+
* 行为都对;而 `TITA_DATA_AGENT_HOME` 仍然是覆盖它的入口。
|
|
147
|
+
*/
|
|
148
|
+
export declare const legacyResourceHome: () => string;
|
|
149
|
+
/** 本地模型目录名。与 `layout.ts` 的 `resourceModels()` 拼在一起就是主位置。 */
|
|
150
|
+
export declare const LOCAL_EMBEDDING_MODEL_DIR = "WeMM-Embedding-2B-Quantized";
|
|
151
|
+
export declare const LOCAL_RERANK_MODEL_DIR = "bge-reranker-base";
|
|
152
|
+
/** 裸模型名:本地没有时从 HuggingFace 拉。 */
|
|
153
|
+
export declare const FALLBACK_EMBEDDING_MODEL = "ewin-reg/WeMM-Embedding-2B-Quantized";
|
|
154
|
+
export declare const FALLBACK_RERANK_MODEL = "BAAI/bge-reranker-base";
|
|
155
|
+
/**
|
|
156
|
+
* 一个**知识库运行时**需要的那部分配置。
|
|
157
|
+
*
|
|
158
|
+
* 去掉的是两个**路径**字段:运行时是「一个知识库」的视角,它的根由构造参数单独
|
|
159
|
+
* 传入(`rootDir`),而 `agentRoot` 是整个部署的根路径 —— 运行时既不该拥有它,
|
|
160
|
+
* 也不该从它推自己的位置。两个字段留在 `KnowledgeConfig` 里,是因为设置面板要
|
|
161
|
+
* 编辑 `agentRoot`、迁移要读旧的 `rootDir`。
|
|
162
|
+
*/
|
|
163
|
+
export type RuntimeKnowledgeConfig = Omit<KnowledgeConfig, 'rootDir' | 'agentRoot'>;
|
|
164
|
+
/**
|
|
165
|
+
* 除两个路径字段以外的全部默认值。
|
|
166
|
+
*
|
|
167
|
+
* `agentRoot` / `rootDir` 由 `index.ts` 用 `layout.ts` 算出来再合进来 —— 它们是
|
|
168
|
+
* 环境与磁盘事实(桌面在哪、旧树在不在),不是这张常量表能自己回答的。
|
|
169
|
+
*/
|
|
170
|
+
export declare const DEFAULT_KNOWLEDGE_CONFIG: RuntimeKnowledgeConfig;
|
|
171
|
+
/** 一条原始可追溯文档(SourceRaw)。磁盘布局沿用 `01_source_truth`。 */
|
|
172
|
+
export interface SourceRaw {
|
|
173
|
+
sourceId: string;
|
|
174
|
+
sourceType: SourceType;
|
|
175
|
+
title: string;
|
|
176
|
+
content: string;
|
|
177
|
+
externalId?: string;
|
|
178
|
+
metadata: Record<string, unknown>;
|
|
179
|
+
lineage?: LineageContext;
|
|
180
|
+
createdAt: string;
|
|
181
|
+
updatedAt: string;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* `query_source_truth` 读回来的一条来源:`SourceRaw` + **它在磁盘上的位置**。
|
|
185
|
+
*
|
|
186
|
+
* ## 为什么必须带 `path`
|
|
187
|
+
*
|
|
188
|
+
* 读取有配额(一次最多 `max_chars`,上限 40000 字符),而且配额是**跨多条来源共享**
|
|
189
|
+
* 的 —— 一份长文档很容易只回来一个开头。被截断时 `content` 是**不完整**的,而「不完整」
|
|
190
|
+
* 如果只能靠调用方拿长度自己猜,就会出最坏的那种错:以为读到了全文,其实只有前 4 万字符。
|
|
191
|
+
*
|
|
192
|
+
* 所以每条都给出绝对路径与全长:Agent 看到 `returnedChars < totalChars` 就知道该去读
|
|
193
|
+
* 文件原文(它本来就有读文件的能力),而不是基于半份文档下结论。这个路径是知识库里的
|
|
194
|
+
* **真实文件**,读它与读这里的内容是同一份数据。
|
|
195
|
+
*/
|
|
196
|
+
export interface SourceRawRead extends SourceRaw {
|
|
197
|
+
/** 这份来源在磁盘上的绝对路径。 */
|
|
198
|
+
path: string;
|
|
199
|
+
/** 本次实际返回的字符数。 */
|
|
200
|
+
returnedChars: number;
|
|
201
|
+
/** 这份来源正文的完整字符数。`returnedChars < totalChars` 即被截断。 */
|
|
202
|
+
totalChars: number;
|
|
203
|
+
}
|
|
204
|
+
export interface KnowledgeCard {
|
|
205
|
+
entityId: string;
|
|
206
|
+
entityType: SchemaType;
|
|
207
|
+
title: string;
|
|
208
|
+
status: KnowledgeStatus;
|
|
209
|
+
summary?: string;
|
|
210
|
+
content: string;
|
|
211
|
+
sourceRefs: string[];
|
|
212
|
+
provenance?: LineageRef[];
|
|
213
|
+
metadata: Record<string, unknown>;
|
|
214
|
+
updatedAt: string;
|
|
215
|
+
/** Resolved local markdown image references used by the multimodal embedder. */
|
|
216
|
+
imagePaths?: string[];
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* A compiled recall unit. Stage 2 turns every wiki card into one or more
|
|
220
|
+
* wikiNotes; stage 3 recalls wikiNotes (never the wiki directly) and resolves
|
|
221
|
+
* each hit back to its parent wiki.
|
|
222
|
+
*/
|
|
223
|
+
export interface WikiNote {
|
|
224
|
+
/**
|
|
225
|
+
* Stable recall id. The first note of a wiki reuses `<entityType>:<entityId>`
|
|
226
|
+
* so historical qrels keep working; later notes append `#<n>`.
|
|
227
|
+
*/
|
|
228
|
+
unitId: string;
|
|
229
|
+
/** Alias of `unitId`, in wikiNotes vocabulary. */
|
|
230
|
+
noteId: string;
|
|
231
|
+
entityId: string;
|
|
232
|
+
/** The wiki card this note was compiled from (alias of `entityId`). */
|
|
233
|
+
wikiId: string;
|
|
234
|
+
entityType: SchemaType;
|
|
235
|
+
title: string;
|
|
236
|
+
/** Section heading when a long wiki card was split into several notes. */
|
|
237
|
+
heading?: string;
|
|
238
|
+
content: string;
|
|
239
|
+
sourceRefs: string[];
|
|
240
|
+
sourceTypes: SourceType[];
|
|
241
|
+
provenance?: LineageRef[];
|
|
242
|
+
status: KnowledgeStatus;
|
|
243
|
+
/** Local markdown image references are embedded with the text when possible. */
|
|
244
|
+
imagePaths?: string[];
|
|
245
|
+
}
|
|
246
|
+
/** Backwards-compatible alias: compiled retrieval units are now wikiNotes. */
|
|
247
|
+
export type KnowledgeUnit = WikiNote;
|
|
248
|
+
/**
|
|
249
|
+
* One historical revision of a wiki card.
|
|
250
|
+
*
|
|
251
|
+
* Mirrors `DocumentVersion` on purpose: SourceRaw and wiki are the two content
|
|
252
|
+
* layers in this plugin, and a user who can roll a document back must be able to
|
|
253
|
+
* roll the card compiled from it back too. Snapshots live under
|
|
254
|
+
* `04_memory/card-versions/<entityType>/<entityId>/`, hold the *original card
|
|
255
|
+
* markdown bytes*, and are append-only — reverting snapshots the pre-revert head
|
|
256
|
+
* as well, so a rollback is itself reversible.
|
|
257
|
+
*/
|
|
258
|
+
export interface WikiCardVersion {
|
|
259
|
+
versionId: string;
|
|
260
|
+
createdAt: string;
|
|
261
|
+
contentHash: string;
|
|
262
|
+
bytes: number;
|
|
263
|
+
title: string;
|
|
264
|
+
status: string;
|
|
265
|
+
label: string;
|
|
266
|
+
isCurrent: boolean;
|
|
267
|
+
}
|
|
268
|
+
export interface SearchHit extends WikiNote {
|
|
269
|
+
score: number;
|
|
270
|
+
match: 'fts' | 'vector' | 'graph' | 'hybrid';
|
|
271
|
+
/**
|
|
272
|
+
* 这个命中在每一路里的**名次**(1 起,0031)。
|
|
273
|
+
*
|
|
274
|
+
* 融合改用 RRF 之后,名次是唯一进入融合的量 —— 所以它必须留痕:界面上的
|
|
275
|
+
* 「三路状态」、`match` 的推导、以及「为什么这条排第一」都读它。
|
|
276
|
+
* 缺失 = 那一路没有召回它。
|
|
277
|
+
*/
|
|
278
|
+
ranks?: Partial<Record<RecallRoute, number>>;
|
|
279
|
+
/** 该命中引用的 SourceRaw 证据片段(0031)。可追溯从卡片级下沉到段落级。 */
|
|
280
|
+
evidence?: RecallEvidence[];
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* 一条命中的**证据片段**:它引用的 SourceRaw 里,与查询最相关的那一段原文。
|
|
284
|
+
*
|
|
285
|
+
* 为什么要有它:`context` 原来只带 wiki 卡片,模型要核对原文还得自己再调一次工具。
|
|
286
|
+
* 把证据放进上下文,「每一个数字都能指回它的口径定义与原始文档」才在**上下文层面**
|
|
287
|
+
* 成立,而不是靠模型自觉。
|
|
288
|
+
*/
|
|
289
|
+
export interface RecallEvidence {
|
|
290
|
+
sourceId: string;
|
|
291
|
+
title?: string;
|
|
292
|
+
/** 覆盖查询词最多的那一段原文(已按上限截断)。 */
|
|
293
|
+
excerpt: string;
|
|
294
|
+
/** 该段在原文正文里的字符偏移,便于回跳。 */
|
|
295
|
+
offset: number;
|
|
296
|
+
/** 这一段覆盖了查询词的比例(0..1)。 */
|
|
297
|
+
coverage: number;
|
|
298
|
+
}
|
|
299
|
+
export interface RecallHit extends SearchHit {
|
|
300
|
+
/** Cross-encoder score after stage 4 rerank; absent when rerank is skipped. */
|
|
301
|
+
rerankScore?: number;
|
|
302
|
+
}
|
|
303
|
+
export interface RerankResult {
|
|
304
|
+
status: 'ready' | 'unavailable' | 'skipped';
|
|
305
|
+
provider: RerankProvider;
|
|
306
|
+
model?: string;
|
|
307
|
+
scored?: number;
|
|
308
|
+
error?: string;
|
|
309
|
+
/** 这一轮生效的最低分(0031)。**原始 logit 刻度**,低于它的一律不进上下文。 */
|
|
310
|
+
threshold?: number;
|
|
311
|
+
/** 被阈值丢掉的条数 —— 「弃答」能不能发生,看的就是它。 */
|
|
312
|
+
dropped?: number;
|
|
313
|
+
/**
|
|
314
|
+
* 候选池里最高的 logit(0031)。
|
|
315
|
+
*
|
|
316
|
+
* 与 `dropped` 一起回答「这一批到底有多相关」:`dropped: 0` 有两种可能 ——
|
|
317
|
+
* 全都相关(topLogit 高),或者阈值根本没在工作(topLogit 贴近阈值)。
|
|
318
|
+
* 只报 `dropped` 会把这两种情况混成一个。
|
|
319
|
+
*/
|
|
320
|
+
topLogit?: number;
|
|
321
|
+
/**
|
|
322
|
+
* cross-encoder 分词器的词表大小(0031)。
|
|
323
|
+
*
|
|
324
|
+
* 存在的理由是**回归可见性**:词表退化成 5 个特殊 token 时,模型照样返回分数、
|
|
325
|
+
* 照样 `status: ready`,只是所有输入都变成 `<unk>`(实测三条无关文本 0.998–0.9994)。
|
|
326
|
+
* 现在 worker 会在加载时直接报 `RERANK_TOKENIZER_DEGENERATE`,这个字段则让
|
|
327
|
+
* 「真的加载了 250002 条词表」在面板上看得见。
|
|
328
|
+
*/
|
|
329
|
+
vocabSize?: number;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* 一路在**这一轮**里的真实状态(0031)。
|
|
333
|
+
*
|
|
334
|
+
* 「降级不谎报」原来只体现在 `routes` 数组里,但 `routes` 只回答「跑没跑」,
|
|
335
|
+
* 回答不了「为什么没结果」。诊断把阈值、候选数、最高分一起给出,于是弃答
|
|
336
|
+
* (`insufficientEvidence`)不再是黑箱。
|
|
337
|
+
*/
|
|
338
|
+
export interface RecallRouteDiagnostic {
|
|
339
|
+
route: RecallRoute;
|
|
340
|
+
status: 'ran' | 'degraded' | 'skipped';
|
|
341
|
+
/** 过滤前该路超采到的候选数。 */
|
|
342
|
+
candidates?: number;
|
|
343
|
+
/** 过阈值之后剩下的条数。 */
|
|
344
|
+
kept?: number;
|
|
345
|
+
/** 该路的最高分(解释「为什么弃答」时最有用的一格)。 */
|
|
346
|
+
topScore?: number;
|
|
347
|
+
threshold?: number;
|
|
348
|
+
/** 降级 / 跳过的原因,直接给用户看。 */
|
|
349
|
+
reason?: string;
|
|
350
|
+
}
|
|
351
|
+
export interface RecallDiagnostics {
|
|
352
|
+
routes: RecallRouteDiagnostic[];
|
|
353
|
+
fusion: {
|
|
354
|
+
method: 'rrf';
|
|
355
|
+
k: number;
|
|
356
|
+
weights: Partial<Record<RecallRoute, number>>;
|
|
357
|
+
};
|
|
358
|
+
/** 图谱 boost 命中了多少条、权重多少。 */
|
|
359
|
+
graphBoost: {
|
|
360
|
+
applied: number;
|
|
361
|
+
weight: number;
|
|
362
|
+
};
|
|
363
|
+
/**
|
|
364
|
+
* 弃答判据的强度,如实标注:
|
|
365
|
+
* - `rerank-threshold`:重排跑通且**真的丢了东西** —— 跨查询可比的绝对判据;
|
|
366
|
+
* - `vector-threshold`:向量余弦阈值丢的(原始余弦也是绝对量);
|
|
367
|
+
* - `relative-only`:只剩「按本次最高分归一」的相对阈值 —— 挡得住弱命中,挡不住
|
|
368
|
+
* 「整批都弱」;
|
|
369
|
+
* - `not-needed`:有结果且不需要判弃答。
|
|
370
|
+
*/
|
|
371
|
+
abstention: 'rerank-threshold' | 'vector-threshold' | 'relative-only' | 'not-needed';
|
|
372
|
+
/** 向量索引与编码器的健康检查结论(0031 的 P0 门)。 */
|
|
373
|
+
encoder?: {
|
|
374
|
+
ok: boolean;
|
|
375
|
+
reason?: string;
|
|
376
|
+
};
|
|
377
|
+
/** 弃答时的一句话原因。 */
|
|
378
|
+
reason?: string;
|
|
379
|
+
}
|
|
380
|
+
export interface ContextGraph {
|
|
381
|
+
nodes: Array<Record<string, unknown>>;
|
|
382
|
+
edges: Array<Record<string, unknown>>;
|
|
383
|
+
}
|
|
384
|
+
export interface ContextItem {
|
|
385
|
+
note: RecallHit;
|
|
386
|
+
wiki: KnowledgeCard | null;
|
|
387
|
+
/** 1-hop subgraph around the hit's wiki card. */
|
|
388
|
+
graph: ContextGraph;
|
|
389
|
+
/**
|
|
390
|
+
* 这条命中引用的 SourceRaw 证据片段(0031)。
|
|
391
|
+
*
|
|
392
|
+
* 与 `note.evidence` 同源,放在这里是为了让「上下文包」自包含:读到 `context`
|
|
393
|
+
* 就拿到了「片段(为什么召回)→ 卡片(结论)→ 原文(证据)」三层。
|
|
394
|
+
*/
|
|
395
|
+
evidence?: RecallEvidence[];
|
|
396
|
+
}
|
|
397
|
+
export interface RecallResult {
|
|
398
|
+
/** Stage 3: 融合(+ 重排)之后的 wikiNotes,最多 `recallTopK`。 */
|
|
399
|
+
hits: RecallHit[];
|
|
400
|
+
/** Stage 4: the `contextTopN` notes expanded to their wiki + 1-hop graph. */
|
|
401
|
+
context: ContextItem[];
|
|
402
|
+
/** Distinct wiki cards hit by the recalled notes. */
|
|
403
|
+
wiki: KnowledgeCard[];
|
|
404
|
+
/** Union of the 1-hop subgraphs of the recalled wiki cards. */
|
|
405
|
+
graph: ContextGraph;
|
|
406
|
+
backend: string;
|
|
407
|
+
routes: RecallRoute[];
|
|
408
|
+
/** Route actually used (caller override or the configured default). */
|
|
409
|
+
recallMode: RecallMode;
|
|
410
|
+
rerank: RerankResult;
|
|
411
|
+
recallTopK: number;
|
|
412
|
+
/** 融合之前每一路的超采深度(0031)。 */
|
|
413
|
+
candidatePool: number;
|
|
414
|
+
contextTopN: number;
|
|
415
|
+
/**
|
|
416
|
+
* 一路都没过阈值 = 这个知识库里没有能回答这个问题的东西(0031)。
|
|
417
|
+
*
|
|
418
|
+
* 它是产品诚实性的一部分:与其凑满 5 条噪声让模型编,不如明确说「没有」。
|
|
419
|
+
* 消费方(Agent 工具 / 面板)看到 true 就该如实转述,而不是把 `hits: []`
|
|
420
|
+
* 当成一次失败。
|
|
421
|
+
*/
|
|
422
|
+
insufficientEvidence: boolean;
|
|
423
|
+
/** 每一路在这一轮里发生了什么(阈值、候选数、最高分、降级原因)。 */
|
|
424
|
+
diagnostics: RecallDiagnostics;
|
|
425
|
+
recallId: string;
|
|
426
|
+
indexVersion?: number;
|
|
427
|
+
compileRunId?: string;
|
|
428
|
+
lineage?: LineageContext;
|
|
429
|
+
}
|
|
430
|
+
/** 一个知识库 = 独立配置 + 独立内容根目录。 */
|
|
431
|
+
export interface KnowledgeBase {
|
|
432
|
+
id: string;
|
|
433
|
+
name: string;
|
|
434
|
+
description: string;
|
|
435
|
+
rootDir: string;
|
|
436
|
+
isDefault: boolean;
|
|
437
|
+
/**
|
|
438
|
+
* 来源业务分类注册表(0013),与 `wikiTypes` 平级、同样按库持久化。
|
|
439
|
+
* `fileCount` / `sourceCount` 这类计算字段由 refresh 实时算出。
|
|
440
|
+
*/
|
|
441
|
+
sourceTypes: SourceTypeDef[];
|
|
442
|
+
/**
|
|
443
|
+
* Wiki 卡片类型注册表(0024):决定"SourceRaw → Wiki"这一段能生成哪些类型的卡片、
|
|
444
|
+
* 每类卡片必须有哪些小节与字段。与 `sourceTypes` 同处持久化,理由见 0013 §7.1。
|
|
445
|
+
*/
|
|
446
|
+
wikiTypes: WikiTypeDef[];
|
|
447
|
+
/**
|
|
448
|
+
* 卡片 schema 的生效方式:`report` 只把问题写进卡片并回报,`strict` 直接拒绝不合规的写入。
|
|
449
|
+
* 默认 `report`,避免存量卡片在升级后被挡在门外。
|
|
450
|
+
*/
|
|
451
|
+
wikiSchemaMode: WikiSchemaMode;
|
|
452
|
+
/**
|
|
453
|
+
* 计算字段:当前 `wikiTypes` 是否已偏离出厂定义。界面据此决定「恢复默认」是否可点,
|
|
454
|
+
* 也让人一眼看出这套 schema 是本库自己调过的。
|
|
455
|
+
*/
|
|
456
|
+
wikiTypesCustomized: boolean;
|
|
457
|
+
createdAt: string;
|
|
458
|
+
updatedAt: string;
|
|
459
|
+
sourceCount: number;
|
|
460
|
+
cardCount: number;
|
|
461
|
+
noteCount: number;
|
|
462
|
+
buildVersion: number;
|
|
463
|
+
}
|
|
464
|
+
/** 文档列表项(SourceRaw 的对外投影,不含正文)。 */
|
|
465
|
+
export interface KnowledgeDocument {
|
|
466
|
+
/** = SourceRaw.sourceId */
|
|
467
|
+
docId: string;
|
|
468
|
+
title: string;
|
|
469
|
+
sourceType: string;
|
|
470
|
+
/**
|
|
471
|
+
* `sourceType` 是否仍在当前知识库的注册表里。
|
|
472
|
+
*
|
|
473
|
+
* 0013 之前 `loadSources()` 会把未知分类**静默丢弃**,文档凭空消失;
|
|
474
|
+
* 现在一律保留并把这个标记交给前端渲染成「未知分类」徽标。
|
|
475
|
+
*/
|
|
476
|
+
sourceTypeKnown: boolean;
|
|
477
|
+
sourceFormat: string;
|
|
478
|
+
parser: string;
|
|
479
|
+
externalId: string;
|
|
480
|
+
contentHash: string;
|
|
481
|
+
bytes: number;
|
|
482
|
+
assetCount: number;
|
|
483
|
+
createdAt: string;
|
|
484
|
+
updatedAt: string;
|
|
485
|
+
versionCount: number;
|
|
486
|
+
/** 相对知识库根目录,如 `01_source_truth/<slug>.md`。 */
|
|
487
|
+
relativePath: string;
|
|
488
|
+
ext: string;
|
|
489
|
+
}
|
|
490
|
+
/** 详情页要展示的资产引用;`url` 直接指向 `/knowledge/assets/<kbId>/<rel>`。 */
|
|
491
|
+
export interface KnowledgeAssetRef {
|
|
492
|
+
rel: string;
|
|
493
|
+
bytes: number;
|
|
494
|
+
url: string;
|
|
495
|
+
}
|
|
496
|
+
export interface KnowledgeDocumentDetail extends KnowledgeDocument {
|
|
497
|
+
content: string;
|
|
498
|
+
frontmatter: Record<string, unknown>;
|
|
499
|
+
assets: KnowledgeAssetRef[];
|
|
500
|
+
lineage?: Record<string, string>;
|
|
501
|
+
}
|
|
502
|
+
/** 文档版本:`isCurrent` 的那条是当前 head,其余是历史快照。 */
|
|
503
|
+
export interface DocumentVersion {
|
|
504
|
+
versionId: string;
|
|
505
|
+
createdAt: string;
|
|
506
|
+
contentHash: string;
|
|
507
|
+
bytes: number;
|
|
508
|
+
sourceFormat: string;
|
|
509
|
+
label: string;
|
|
510
|
+
isCurrent: boolean;
|
|
511
|
+
}
|
|
512
|
+
/** 默认「文件类型 → 解析引擎」规则的内容,不含 `fileCount`。 */
|
|
513
|
+
/**
|
|
514
|
+
* 从 SourceRaw 的 `metadata` 推导文档扩展名。
|
|
515
|
+
*
|
|
516
|
+
* **这个推导是有损的。** SourceRaw 只保存正文与 metadata,并不保存原始文件名;
|
|
517
|
+
* 因此只有上游(`src/convert/ingest.ts`)显式写了 `metadata.source_path` 时才能拿到
|
|
518
|
+
* 真实扩展名。回退链是启发式的:
|
|
519
|
+
*
|
|
520
|
+
* 1. `metadata.source_path` 的 basename 扩展名(最可信);
|
|
521
|
+
* 2. `metadata.source_format === 'markdown'` → `.md`;
|
|
522
|
+
* 3. `metadata.source_format === 'office'` → `.docx`(office 是容器格式的粗粒度标记,
|
|
523
|
+
* 真实的 .doc/.xls/.ppt 会被误报为 `.docx`);
|
|
524
|
+
* 4. 其余 `source_format` → `.` + source_format(当它本身就是一个扩展名时才对);
|
|
525
|
+
* 5. 都没有 → `.md`(知识库里最常见的形态)。
|
|
526
|
+
*
|
|
527
|
+
* 因此 `fileCount` 与按扩展名过滤都只是近似值;要精确统计需要在入库时写 `source_path`。
|
|
528
|
+
*/
|
|
529
|
+
export declare function deriveSourceExt(metadata: Record<string, unknown> | undefined): string;
|
|
530
|
+
export interface RebuildReport {
|
|
531
|
+
runId: string;
|
|
532
|
+
version: number;
|
|
533
|
+
only: string;
|
|
534
|
+
cards: number;
|
|
535
|
+
units: number;
|
|
536
|
+
/** Compiled wikiNotes count (stage 2 output). */
|
|
537
|
+
notes: number;
|
|
538
|
+
graphNodes: number;
|
|
539
|
+
graphEdges: number;
|
|
540
|
+
embedding: 'ready' | 'unavailable' | 'skipped';
|
|
541
|
+
embeddingItems?: number;
|
|
542
|
+
embeddingReused?: number;
|
|
543
|
+
embeddingDimension?: number;
|
|
544
|
+
vectorQuantization?: 'binary+hamming+int8';
|
|
545
|
+
embeddingError?: string;
|
|
546
|
+
/**
|
|
547
|
+
* 关键词索引(FTS5)的构建结论(0031)。
|
|
548
|
+
*
|
|
549
|
+
* 与 `embedding` 并列而不是塞进它:两者可以一个成一个败(编码器坏了但关键词索引照样
|
|
550
|
+
* 能建),而「哪一路现在是活的」必须一眼看得出。
|
|
551
|
+
*/
|
|
552
|
+
fts?: 'ready' | 'unavailable';
|
|
553
|
+
lineage?: LineageContext;
|
|
554
|
+
compileRunId?: string;
|
|
555
|
+
startedAt: string;
|
|
556
|
+
finishedAt: string;
|
|
557
|
+
/**
|
|
558
|
+
* Stage-2 incrementality. `compileNotes` is deterministic, so recompiling is
|
|
559
|
+
* cheap — what is *not* cheap is invalidating a stable corpus: a rebuild that
|
|
560
|
+
* renumbers notes forces a full re-embedding and breaks existing qrels.
|
|
561
|
+
* These counters make the reuse visible instead of implicit.
|
|
562
|
+
*/
|
|
563
|
+
cardsReused?: number;
|
|
564
|
+
cardsRecompiled?: number;
|
|
565
|
+
cardsAdded?: number;
|
|
566
|
+
cardsRemoved?: number;
|
|
567
|
+
notesReused?: number;
|
|
568
|
+
notesRecompiled?: number;
|
|
569
|
+
/** Nothing changed: knowledge artifacts were left byte-identical. */
|
|
570
|
+
incremental?: boolean;
|
|
571
|
+
/** The run was a no-op (a `wiki`-only rebuild over an unchanged corpus). */
|
|
572
|
+
skipped?: boolean;
|
|
573
|
+
/**
|
|
574
|
+
* 「SourceRaw → Wiki」第一段的诚实计数。
|
|
575
|
+
*
|
|
576
|
+
* 这八个数**每一个都来自真实发生过的事件**,没有一个是估算出来的:抽取了几个
|
|
577
|
+
* 候选、其中几个被类型闸门拒了、建了几张卡、并进几张卡、几条关系真的连上了、
|
|
578
|
+
* 几条因为端点不存在被丢掉、几份来源这次被重抽、几份因为指纹没变被跳过。
|
|
579
|
+
* `extractCandidates` 关掉时它们全部回 0,而不是从响应里消失 —— 「跳过」和
|
|
580
|
+
* 「没有这个能力」是两件事,用缺字段表达会让人分不清。
|
|
581
|
+
*/
|
|
582
|
+
candidatesExtracted: number;
|
|
583
|
+
candidatesRejected: number;
|
|
584
|
+
cardsCreated: number;
|
|
585
|
+
cardsMerged: number;
|
|
586
|
+
relationsExtracted: number;
|
|
587
|
+
relationsDropped: number;
|
|
588
|
+
sourcesExtracted: number;
|
|
589
|
+
sourcesSkipped: number;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* 一条来源业务分类。
|
|
593
|
+
*
|
|
594
|
+
* 设计原则:`source_type` 描述**业务场景**,不描述载体格式;载体走
|
|
595
|
+
* `source_format` / `parser`(见 `deriveSourceExt`)。三个「判定档位」是刻意
|
|
596
|
+
* 分开的,UI 与 Agent 都按这个契约消费:
|
|
597
|
+
*
|
|
598
|
+
* - 必填且不可动(`fallback`):兜底分类必须存在且始终启用;
|
|
599
|
+
* - 内置可调(`builtin && !fallback`):可改文案、可停用,但不可删除、不可改 id;
|
|
600
|
+
* - 自定义(`!builtin`):可增可删,但新建时必须提交完整判定文案。
|
|
601
|
+
*/
|
|
602
|
+
export interface SourceTypeDef {
|
|
603
|
+
/** 稳定 id,`^[a-z][a-z0-9_]{1,40}$`,创建后不可修改。 */
|
|
604
|
+
id: string;
|
|
605
|
+
label: string;
|
|
606
|
+
/** 一句话定义,同时是 Agent 的判定依据。 */
|
|
607
|
+
description: string;
|
|
608
|
+
/** 典型信号,至少 2 条;与 `description` 一起拼进判定提示词。 */
|
|
609
|
+
signals: string[];
|
|
610
|
+
/** 明确排除项,至少 1 条,每条必须指向一个已存在的分类。 */
|
|
611
|
+
excludes: string[];
|
|
612
|
+
/** 停用后不再出现在选择器与判定提示词里,历史引用仍能解析。 */
|
|
613
|
+
enabled: boolean;
|
|
614
|
+
/** 内置分类只允许停用,不允许删除。 */
|
|
615
|
+
builtin: boolean;
|
|
616
|
+
/** 兜底分类(`document`):必须存在且不可停用,判定链最后一步落在它上。 */
|
|
617
|
+
fallback: boolean;
|
|
618
|
+
/** 计算字段:该库中引用该分类的来源数,由 `refresh` 实时算出,不参与持久化。 */
|
|
619
|
+
sourceCount: number;
|
|
620
|
+
}
|
|
621
|
+
/** 分类 id 的形状约束;与 0013 规范第 1 节一致。 */
|
|
622
|
+
export declare const SOURCE_TYPE_ID_PATTERN: RegExp;
|
|
623
|
+
/** 兜底分类 id;判定链全不命中时落它,因此它不可停用、不可删除。 */
|
|
624
|
+
export declare const FALLBACK_SOURCE_TYPE = "document";
|
|
625
|
+
/** 单库自定义分类数量上限,防止注册表无界膨胀。 */
|
|
626
|
+
export declare const MAX_SOURCE_TYPES = 50;
|
|
627
|
+
/**
|
|
628
|
+
* 内置分类的出厂默认值(0013 规范第 7 节的 `source-types.json` 内容)。
|
|
629
|
+
*
|
|
630
|
+
* 这些值**可以改**(label / description / signals / excludes / enabled),
|
|
631
|
+
* 但条目本身不可删除——`normalizeSourceTypes()` 会把缺失的内置条目补回来。
|
|
632
|
+
*/
|
|
633
|
+
export declare const BUILTIN_SOURCE_TYPES: ReadonlyArray<Omit<SourceTypeDef, 'sourceCount'>>;
|
|
634
|
+
export declare function isBuiltinSourceType(id: string): boolean;
|
|
635
|
+
/** 出厂默认注册表(全部启用,`sourceCount` 待算)。 */
|
|
636
|
+
export declare function defaultSourceTypes(): SourceTypeDef[];
|
|
637
|
+
/**
|
|
638
|
+
* 内置只读判定提示词。
|
|
639
|
+
*
|
|
640
|
+
* **它不允许被用户修改**——注册表里没有任何字段能覆盖它;但它必须**被暴露
|
|
641
|
+
* 出来**:`list_source_types` 工具、`GET /knowledge/source-types` 与设置面板的
|
|
642
|
+
* 「判定规则(内置,只读)」都原样返回它,让用户看得见 Agent 到底按什么判。
|
|
643
|
+
* 用户能写的只有每个分类自己的 `description` / `signals` / `excludes`。
|
|
644
|
+
*/
|
|
645
|
+
export interface SourceClassifierStep {
|
|
646
|
+
/** 该步落到哪个分类;`user` 表示"用户显式指定"这个非分类入口。 */
|
|
647
|
+
type: string;
|
|
648
|
+
rule: string;
|
|
649
|
+
}
|
|
650
|
+
export interface SourceClassifierPrompt {
|
|
651
|
+
readonly: true;
|
|
652
|
+
version: number;
|
|
653
|
+
title: string;
|
|
654
|
+
/** 从最特征化走到最泛化;全不命中落 `fallback.type`。 */
|
|
655
|
+
priority: SourceClassifierStep[];
|
|
656
|
+
confidenceRule: string;
|
|
657
|
+
fallback: {
|
|
658
|
+
type: string;
|
|
659
|
+
note: string;
|
|
660
|
+
};
|
|
661
|
+
escalation: {
|
|
662
|
+
code: string;
|
|
663
|
+
note: string;
|
|
664
|
+
};
|
|
665
|
+
/** 自定义分类由用户撰写的判定文案如何参与判定。 */
|
|
666
|
+
extensionRule: string;
|
|
667
|
+
}
|
|
668
|
+
export declare const SOURCE_CLASSIFIER_PROMPT: SourceClassifierPrompt;
|
|
669
|
+
/** 判定提示词 + 每个分类当前是否启用;停用的分类标注出来而不是从提示词里删掉。 */
|
|
670
|
+
export interface SourceClassifierPromptView extends SourceClassifierPrompt {
|
|
671
|
+
steps: ReadonlyArray<Readonly<SourceClassifierStep & {
|
|
672
|
+
label: string;
|
|
673
|
+
enabled: boolean;
|
|
674
|
+
exists: boolean;
|
|
675
|
+
}>>;
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* 展开成"每步带 label / enabled / exists"的视图。
|
|
679
|
+
*
|
|
680
|
+
* `priority` 直接复用被冻结的原数组(不复制),所以视图也无法被就地改写;
|
|
681
|
+
* 每次调用只新建 `steps`,并把它一并冻结。注册表怎么改,提示词骨架都不变。
|
|
682
|
+
*/
|
|
683
|
+
export declare function classifierPromptView(defs: SourceTypeDef[]): SourceClassifierPromptView;
|
|
684
|
+
/** 一个知识库的完整分类目录:注册表 + 内置只读提示词。 */
|
|
685
|
+
export interface SourceTypeCatalog {
|
|
686
|
+
types: SourceTypeDef[];
|
|
687
|
+
classifierPrompt: SourceClassifierPromptView;
|
|
688
|
+
fallbackTypeId: string;
|
|
689
|
+
builtinIds: string[];
|
|
690
|
+
}
|
|
691
|
+
export declare function buildSourceTypeCatalog(defs: SourceTypeDef[]): SourceTypeCatalog;
|
|
692
|
+
/** 新建 / 编辑分类时提交的草稿。 */
|
|
693
|
+
export interface SourceTypeDraft {
|
|
694
|
+
id?: string;
|
|
695
|
+
label?: string;
|
|
696
|
+
description?: string;
|
|
697
|
+
signals?: unknown;
|
|
698
|
+
excludes?: unknown;
|
|
699
|
+
enabled?: boolean;
|
|
700
|
+
}
|
|
701
|
+
export interface SourceTypeDraftProblem {
|
|
702
|
+
ok: false;
|
|
703
|
+
code: string;
|
|
704
|
+
message: string;
|
|
705
|
+
suggestion?: string;
|
|
706
|
+
/** 出错的字段,供表单高亮。 */
|
|
707
|
+
field: 'id' | 'label' | 'description' | 'signals' | 'excludes' | 'enabled';
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* 校验一份自定义分类草稿。
|
|
711
|
+
*
|
|
712
|
+
* 这是在守「用户追加新类型时,必须用文字标明怎么判断」这条要求:光给个名字
|
|
713
|
+
* 是不允许入库的——入库的 `description` 会直接变成 Agent 的判定依据。
|
|
714
|
+
*/
|
|
715
|
+
export declare function validateSourceTypeDraft(draft: SourceTypeDraft, knownIds: ReadonlySet<string>): {
|
|
716
|
+
ok: true;
|
|
717
|
+
} | SourceTypeDraftProblem;
|
|
718
|
+
/**
|
|
719
|
+
* 只校验判定文案(label / description / signals / excludes),不碰 id。
|
|
720
|
+
*
|
|
721
|
+
* 内置分类改文案走这里:id 锁定,但「必须写得能判」的标准一样严。
|
|
722
|
+
*/
|
|
723
|
+
export declare function validateSourceTypeText(draft: SourceTypeDraft, knownIds: ReadonlySet<string>): {
|
|
724
|
+
ok: true;
|
|
725
|
+
} | SourceTypeDraftProblem;
|
|
726
|
+
/**
|
|
727
|
+
* Wiki 卡片类型的一条正文小节要求。
|
|
728
|
+
*
|
|
729
|
+
* 「正文小节」是给人读的部分:0021 的判断是"序和枚举一旦写进散文,归并算法就再也读不到
|
|
730
|
+
* 它们了",所以小节名要固定,模板卡照着它生成。
|
|
731
|
+
*/
|
|
732
|
+
export interface WikiSectionSpec {
|
|
733
|
+
/** 小节名,同时是模板卡里的 Markdown 标题。 */
|
|
734
|
+
label: string;
|
|
735
|
+
required: boolean;
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* 一条 front matter / metadata 字段要求(机器读的部分)。
|
|
739
|
+
*
|
|
740
|
+
* `name` 对应 `write_knowledge_card` 的顶层字段(`owner` / `summary`)或 `metadata` 里的键。
|
|
741
|
+
*/
|
|
742
|
+
export interface WikiFieldSpec {
|
|
743
|
+
name: string;
|
|
744
|
+
required: boolean;
|
|
745
|
+
note: string;
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* 一个 wiki 卡片类型(0024)。
|
|
749
|
+
*
|
|
750
|
+
* 它是"SourceRaw → Wiki"这一段的**约束**:哪些类型能生成、每类必须有哪些小节与字段、
|
|
751
|
+
* 期望来自哪些来源分类、模板长什么样。判定与生成仍交给模型,这里给的是**判据与骨架**。
|
|
752
|
+
*/
|
|
753
|
+
export interface WikiTypeDef {
|
|
754
|
+
/** 稳定 id,`^[a-z][a-z0-9_/-]{1,60}$`(允许 `diagnosis/symptom` 这类命名空间)。 */
|
|
755
|
+
id: string;
|
|
756
|
+
label: string;
|
|
757
|
+
description: string;
|
|
758
|
+
/** 借 0021 的分层:类型层可复用上千次(假设/口径),实例层只发生过一次(案例)。 */
|
|
759
|
+
layer: 'type' | 'instance';
|
|
760
|
+
sections: WikiSectionSpec[];
|
|
761
|
+
fields: WikiFieldSpec[];
|
|
762
|
+
/** 期望的来源业务分类 id(0013 的 `source_type`);空数组表示不限制。 */
|
|
763
|
+
sourceTypes: string[];
|
|
764
|
+
/** few-shot:用户会怎么提到这种卡片。随工具描述下发。 */
|
|
765
|
+
examples: string[];
|
|
766
|
+
/** 模板卡(Markdown 骨架),新建卡片时照抄。 */
|
|
767
|
+
template: string;
|
|
768
|
+
enabled: boolean;
|
|
769
|
+
/** 内置类型只允许停用,不允许删除。 */
|
|
770
|
+
builtin: boolean;
|
|
771
|
+
/** 计算字段:该库中该类型的卡片数,由 refresh 实时算出。 */
|
|
772
|
+
cardCount: number;
|
|
773
|
+
}
|
|
774
|
+
/** 卡片 schema 的生效方式。 */
|
|
775
|
+
export type WikiSchemaMode = 'strict' | 'report';
|
|
776
|
+
/** 卡片校验问题的一层。混成同一个「校验失败」,人就学不会怎么写卡片(0021 §1)。 */
|
|
777
|
+
export type CardIssueLevel = 'format' | 'reference' | 'semantic';
|
|
778
|
+
export interface CardSchemaIssue {
|
|
779
|
+
level: CardIssueLevel;
|
|
780
|
+
/** 出问题的小节名或字段名。 */
|
|
781
|
+
field?: string;
|
|
782
|
+
message: string;
|
|
783
|
+
}
|
|
784
|
+
/** 卡片类型目录:注册表 + 生效方式 + 内置只读判定规则 + 当前卡片的问题清单。 */
|
|
785
|
+
export interface WikiTypeCatalog {
|
|
786
|
+
types: WikiTypeDef[];
|
|
787
|
+
mode: WikiSchemaMode;
|
|
788
|
+
/** 内置只读的判定规则:模型该按什么顺序挑类型。 */
|
|
789
|
+
rules: string;
|
|
790
|
+
/** 已落库卡片的三层校验结果(前 N 条)。 */
|
|
791
|
+
issues: Array<CardSchemaIssue & {
|
|
792
|
+
entityId: string;
|
|
793
|
+
entityType: string;
|
|
794
|
+
}>;
|
|
795
|
+
issueCount: number;
|
|
796
|
+
}
|
|
797
|
+
/** 卡片类型 id 的形状;允许 `diagnosis/symptom` 这类带命名空间的 id。 */
|
|
798
|
+
export declare const WIKI_TYPE_ID_PATTERN: RegExp;
|
|
799
|
+
//# sourceMappingURL=types.d.ts.map
|