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.
Files changed (231) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +360 -0
  3. package/cordis.patch.yml +410 -0
  4. package/eval/README.md +76 -0
  5. package/eval/evaluate-retrieval.mjs +121 -0
  6. package/eval/queries.example.jsonl +2 -0
  7. package/lib/client.js +111415 -0
  8. package/lib/types/config-schema.d.ts +35 -0
  9. package/lib/types/config-schema.d.ts.map +1 -0
  10. package/lib/types/config-schema.js +34 -0
  11. package/lib/types/config-schema.js.map +1 -0
  12. package/lib/types/convert/core-loader.d.ts +32 -0
  13. package/lib/types/convert/core-loader.d.ts.map +1 -0
  14. package/lib/types/convert/core-loader.js +60 -0
  15. package/lib/types/convert/core-loader.js.map +1 -0
  16. package/lib/types/convert/host.d.ts +88 -0
  17. package/lib/types/convert/host.d.ts.map +1 -0
  18. package/lib/types/convert/host.js +479 -0
  19. package/lib/types/convert/host.js.map +1 -0
  20. package/lib/types/convert/ingest.d.ts +125 -0
  21. package/lib/types/convert/ingest.d.ts.map +1 -0
  22. package/lib/types/convert/ingest.js +228 -0
  23. package/lib/types/convert/ingest.js.map +1 -0
  24. package/lib/types/convert/settings-schema.d.ts +18 -0
  25. package/lib/types/convert/settings-schema.d.ts.map +1 -0
  26. package/lib/types/convert/settings-schema.js +26 -0
  27. package/lib/types/convert/settings-schema.js.map +1 -0
  28. package/lib/types/convert/types.d.ts +46 -0
  29. package/lib/types/convert/types.d.ts.map +1 -0
  30. package/lib/types/convert/types.js +41 -0
  31. package/lib/types/convert/types.js.map +1 -0
  32. package/lib/types/diagnosis/cards.d.ts +71 -0
  33. package/lib/types/diagnosis/cards.d.ts.map +1 -0
  34. package/lib/types/diagnosis/cards.js +482 -0
  35. package/lib/types/diagnosis/cards.js.map +1 -0
  36. package/lib/types/diagnosis/problem-classes.d.ts +51 -0
  37. package/lib/types/diagnosis/problem-classes.d.ts.map +1 -0
  38. package/lib/types/diagnosis/problem-classes.js +66 -0
  39. package/lib/types/diagnosis/problem-classes.js.map +1 -0
  40. package/lib/types/diagnosis/schema.d.ts +65 -0
  41. package/lib/types/diagnosis/schema.d.ts.map +1 -0
  42. package/lib/types/diagnosis/schema.js +208 -0
  43. package/lib/types/diagnosis/schema.js.map +1 -0
  44. package/lib/types/diagnosis/seed-source.d.ts +20 -0
  45. package/lib/types/diagnosis/seed-source.d.ts.map +1 -0
  46. package/lib/types/diagnosis/seed-source.js +96 -0
  47. package/lib/types/diagnosis/seed-source.js.map +1 -0
  48. package/lib/types/diagnosis/seed.d.ts +50 -0
  49. package/lib/types/diagnosis/seed.d.ts.map +1 -0
  50. package/lib/types/diagnosis/seed.js +242 -0
  51. package/lib/types/diagnosis/seed.js.map +1 -0
  52. package/lib/types/diagnosis/store.d.ts +81 -0
  53. package/lib/types/diagnosis/store.d.ts.map +1 -0
  54. package/lib/types/diagnosis/store.js +409 -0
  55. package/lib/types/diagnosis/store.js.map +1 -0
  56. package/lib/types/diagnosis/types.d.ts +124 -0
  57. package/lib/types/diagnosis/types.d.ts.map +1 -0
  58. package/lib/types/diagnosis/types.js +13 -0
  59. package/lib/types/diagnosis/types.js.map +1 -0
  60. package/lib/types/directory-picker.d.ts +94 -0
  61. package/lib/types/directory-picker.d.ts.map +1 -0
  62. package/lib/types/directory-picker.js +110 -0
  63. package/lib/types/directory-picker.js.map +1 -0
  64. package/lib/types/extract-model.d.ts +76 -0
  65. package/lib/types/extract-model.d.ts.map +1 -0
  66. package/lib/types/extract-model.js +193 -0
  67. package/lib/types/extract-model.js.map +1 -0
  68. package/lib/types/extract.d.ts +121 -0
  69. package/lib/types/extract.d.ts.map +1 -0
  70. package/lib/types/extract.js +549 -0
  71. package/lib/types/extract.js.map +1 -0
  72. package/lib/types/fts.d.ts +96 -0
  73. package/lib/types/fts.d.ts.map +1 -0
  74. package/lib/types/fts.js +184 -0
  75. package/lib/types/fts.js.map +1 -0
  76. package/lib/types/index.d.ts +39 -0
  77. package/lib/types/index.d.ts.map +1 -0
  78. package/lib/types/index.js +1112 -0
  79. package/lib/types/index.js.map +1 -0
  80. package/lib/types/intent/engine.d.ts +108 -0
  81. package/lib/types/intent/engine.d.ts.map +1 -0
  82. package/lib/types/intent/engine.js +501 -0
  83. package/lib/types/intent/engine.js.map +1 -0
  84. package/lib/types/intent/host.d.ts +88 -0
  85. package/lib/types/intent/host.d.ts.map +1 -0
  86. package/lib/types/intent/host.js +389 -0
  87. package/lib/types/intent/host.js.map +1 -0
  88. package/lib/types/intent/preset-tools.d.ts +37 -0
  89. package/lib/types/intent/preset-tools.d.ts.map +1 -0
  90. package/lib/types/intent/preset-tools.js +45 -0
  91. package/lib/types/intent/preset-tools.js.map +1 -0
  92. package/lib/types/intent/settings-schema.d.ts +59 -0
  93. package/lib/types/intent/settings-schema.d.ts.map +1 -0
  94. package/lib/types/intent/settings-schema.js +57 -0
  95. package/lib/types/intent/settings-schema.js.map +1 -0
  96. package/lib/types/intent/store.d.ts +75 -0
  97. package/lib/types/intent/store.d.ts.map +1 -0
  98. package/lib/types/intent/store.js +139 -0
  99. package/lib/types/intent/store.js.map +1 -0
  100. package/lib/types/intent/tools.d.ts +63 -0
  101. package/lib/types/intent/tools.d.ts.map +1 -0
  102. package/lib/types/intent/tools.js +108 -0
  103. package/lib/types/intent/tools.js.map +1 -0
  104. package/lib/types/intent/types.d.ts +189 -0
  105. package/lib/types/intent/types.d.ts.map +1 -0
  106. package/lib/types/intent/types.js +62 -0
  107. package/lib/types/intent/types.js.map +1 -0
  108. package/lib/types/knowledge-bases.d.ts +266 -0
  109. package/lib/types/knowledge-bases.d.ts.map +1 -0
  110. package/lib/types/knowledge-bases.js +1107 -0
  111. package/lib/types/knowledge-bases.js.map +1 -0
  112. package/lib/types/layout.d.ts +262 -0
  113. package/lib/types/layout.d.ts.map +1 -0
  114. package/lib/types/layout.js +312 -0
  115. package/lib/types/layout.js.map +1 -0
  116. package/lib/types/migrate.d.ts +110 -0
  117. package/lib/types/migrate.d.ts.map +1 -0
  118. package/lib/types/migrate.js +280 -0
  119. package/lib/types/migrate.js.map +1 -0
  120. package/lib/types/recall-rank.d.ts +158 -0
  121. package/lib/types/recall-rank.d.ts.map +1 -0
  122. package/lib/types/recall-rank.js +261 -0
  123. package/lib/types/recall-rank.js.map +1 -0
  124. package/lib/types/runtime.d.ts +568 -0
  125. package/lib/types/runtime.d.ts.map +1 -0
  126. package/lib/types/runtime.js +3045 -0
  127. package/lib/types/runtime.js.map +1 -0
  128. package/lib/types/settings-schema.d.ts +117 -0
  129. package/lib/types/settings-schema.d.ts.map +1 -0
  130. package/lib/types/settings-schema.js +92 -0
  131. package/lib/types/settings-schema.js.map +1 -0
  132. package/lib/types/settings-volatile.d.ts +102 -0
  133. package/lib/types/settings-volatile.d.ts.map +1 -0
  134. package/lib/types/settings-volatile.js +114 -0
  135. package/lib/types/settings-volatile.js.map +1 -0
  136. package/lib/types/types.d.ts +799 -0
  137. package/lib/types/types.d.ts.map +1 -0
  138. package/lib/types/types.js +387 -0
  139. package/lib/types/types.js.map +1 -0
  140. package/lib/types/wiki-types.d.ts +68 -0
  141. package/lib/types/wiki-types.d.ts.map +1 -0
  142. package/lib/types/wiki-types.js +322 -0
  143. package/lib/types/wiki-types.js.map +1 -0
  144. package/package.json +101 -0
  145. package/preset/tita-data-agent/agent.cordis.yml +376 -0
  146. package/preset/tita-data-agent/preset.yml +3 -0
  147. package/python/requirements.txt +8 -0
  148. package/scripts/doctor.mjs +70 -0
  149. package/scripts/e2e-pipeline.mjs +355 -0
  150. package/scripts/install-agent-preset.mjs +92 -0
  151. package/scripts/setup-embedding.sh +34 -0
  152. package/scripts/sync-agent-preset.mjs +188 -0
  153. package/src/client/AgentPresetCard.tsx +247 -0
  154. package/src/client/DirectoryPicker.tsx +357 -0
  155. package/src/client/InfoHint.tsx +65 -0
  156. package/src/client/IntentLogicTab.tsx +185 -0
  157. package/src/client/IntentTab.tsx +715 -0
  158. package/src/client/KnowledgeBaseTab.tsx +1454 -0
  159. package/src/client/KnowledgeGraphView.tsx +306 -0
  160. package/src/client/KnowledgePanel.tsx +381 -0
  161. package/src/client/KnowledgeStepRail.tsx +60 -0
  162. package/src/client/NodeSettings.tsx +392 -0
  163. package/src/client/PreviewSections.tsx +116 -0
  164. package/src/client/RecallPanel.tsx +399 -0
  165. package/src/client/TypeDefinitionDrawer.tsx +215 -0
  166. package/src/client/WikiFlowCard.tsx +226 -0
  167. package/src/client/WikiTypeEditor.tsx +332 -0
  168. package/src/client/agent-preset.ts +121 -0
  169. package/src/client/arch/AgentArchitectureGraph.tsx +219 -0
  170. package/src/client/arch/NodeLogicPanel.tsx +133 -0
  171. package/src/client/arch/ProblemDetailPanel.tsx +88 -0
  172. package/src/client/arch/model.ts +691 -0
  173. package/src/client/architecture.css +191 -0
  174. package/src/client/architecture.tsx +530 -0
  175. package/src/client/attribution/AttributionGraph.tsx +104 -0
  176. package/src/client/attribution/AttributionTab.tsx +332 -0
  177. package/src/client/attribution/CaseView.tsx +102 -0
  178. package/src/client/attribution/GraphStage.tsx +87 -0
  179. package/src/client/attribution/RunView.tsx +184 -0
  180. package/src/client/attribution/StageChrome.tsx +403 -0
  181. package/src/client/attribution/ViewSwitch.tsx +107 -0
  182. package/src/client/attribution/graph-options.ts +381 -0
  183. package/src/client/attribution/model.ts +462 -0
  184. package/src/client/config-scope.ts +119 -0
  185. package/src/client/convert/ConvertPanel.tsx +594 -0
  186. package/src/client/convert/styles.css +138 -0
  187. package/src/client/convert/styles.ts +49 -0
  188. package/src/client/format.ts +39 -0
  189. package/src/client/graph/layout.ts +181 -0
  190. package/src/client/graph.css +113 -0
  191. package/src/client/index.ts +98 -0
  192. package/src/client/problem-domains.ts +114 -0
  193. package/src/client/styles.css +940 -0
  194. package/src/client/styles.ts +11 -0
  195. package/src/client/useFitScale.ts +68 -0
  196. package/src/config-schema.ts +45 -0
  197. package/src/convert/core-loader.ts +68 -0
  198. package/src/convert/host.ts +579 -0
  199. package/src/convert/ingest.ts +367 -0
  200. package/src/convert/settings-schema.ts +27 -0
  201. package/src/convert/types.ts +65 -0
  202. package/src/diagnosis/cards.ts +498 -0
  203. package/src/diagnosis/problem-classes.ts +117 -0
  204. package/src/diagnosis/schema.ts +260 -0
  205. package/src/diagnosis/seed-source.ts +107 -0
  206. package/src/diagnosis/seed.ts +291 -0
  207. package/src/diagnosis/store.ts +432 -0
  208. package/src/diagnosis/types.ts +152 -0
  209. package/src/directory-picker.ts +164 -0
  210. package/src/extract-model.ts +227 -0
  211. package/src/extract.ts +632 -0
  212. package/src/fts.ts +203 -0
  213. package/src/index.ts +1091 -0
  214. package/src/intent/README.md +63 -0
  215. package/src/intent/engine.ts +527 -0
  216. package/src/intent/host.ts +462 -0
  217. package/src/intent/preset-tools.ts +48 -0
  218. package/src/intent/settings-schema.ts +63 -0
  219. package/src/intent/store.ts +143 -0
  220. package/src/intent/tools.ts +139 -0
  221. package/src/intent/types.ts +245 -0
  222. package/src/knowledge-bases.ts +1160 -0
  223. package/src/layout.ts +350 -0
  224. package/src/migrate.ts +262 -0
  225. package/src/python/embedding_worker.py +471 -0
  226. package/src/recall-rank.ts +299 -0
  227. package/src/runtime.ts +3069 -0
  228. package/src/settings-schema.ts +94 -0
  229. package/src/settings-volatile.ts +122 -0
  230. package/src/types.ts +1140 -0
  231. package/src/wiki-types.ts +357 -0
@@ -0,0 +1,75 @@
1
+ /**
2
+ * 意图的**落盘**(0033)。
3
+ *
4
+ * ## 为什么需要它
5
+ *
6
+ * 0033 之前,意图的两半都不在磁盘上属于这个 Agent 的地方:
7
+ *
8
+ * - **分类 / act 注册表**住在宿主的 settings 文档(`settings.yaml`)里。它确实落盘了,
9
+ * 但那是**宿主的配置**,不是这个 Agent 的文件 —— 备份知识库不会带上它,换一台机器
10
+ * 也不跟着走,而它恰恰决定了「同一句话被理解成什么」。
11
+ * - **每轮记录**只在内存里(`IntentStore` 的 Map,TTL 600 秒)。重启即丢。而架构图上
12
+ * 写着「意图记录…都已落盘」——**那句话当时是假的**。
13
+ *
14
+ * 现在两份东西都在 `<agentRoot>/intent/`:
15
+ *
16
+ * ```
17
+ * <agentRoot>/intent/
18
+ * registry.json 分类 / act 词表(可编辑,面板就地改)
19
+ * records.ndjson 每轮一条记录,append-only
20
+ * ```
21
+ *
22
+ * ## 为什么记录是 append-only 而不是「覆盖写」
23
+ *
24
+ * 记录本身按 `sessionKey#turn` upsert(同一轮重复调用只算一条事实),但**文件是审计
25
+ * 留痕**:追加每一版比原地覆盖更能回答「这一轮改过什么」。读的时候按同一个 key 取
26
+ * 最后一条,于是内存里那份「一轮一条」的语义不变,而磁盘上留下了完整过程。
27
+ *
28
+ * 代价是文件会随使用增长。这是审计流的固有代价,且它是纯追加、没有读放大 ——
29
+ * 真到需要清理时应该按时间归档,而不是在这里改成覆盖写。
30
+ *
31
+ * @module
32
+ */
33
+ import type { IntentActDef, IntentRecord } from './types.js';
34
+ /** 注册表文件名。分类与 act 住一起:它们是一份词表的两半,分开存只会漂移。 */
35
+ export declare const INTENT_REGISTRY_FILE = "registry.json";
36
+ /** 记录文件名。NDJSON 而不是 JSON 数组:追加是 O(1),且半行坏数据只坏一行。 */
37
+ export declare const INTENT_RECORDS_FILE = "records.ndjson";
38
+ export interface IntentRegistryFile {
39
+ version: 1;
40
+ acts: IntentActDef[];
41
+ categories: Array<{
42
+ id: string;
43
+ label: string;
44
+ route: string;
45
+ description: string;
46
+ examples: string[];
47
+ enabled: boolean;
48
+ }>;
49
+ updatedAt?: string;
50
+ }
51
+ /**
52
+ * 读注册表文件。
53
+ *
54
+ * **不抛异常**:文件坏了、被手改坏了、写了一半 —— 都返回 `undefined`,调用方按
55
+ * 出厂预置启动。注册表读不出来不该让整个意图引擎起不来,更不该让插件起不来。
56
+ */
57
+ export declare function readIntentRegistry(root: string): IntentRegistryFile | undefined;
58
+ /** 写注册表文件。`updatedAt` 由调用方给,便于测试与审计对齐。 */
59
+ export declare function writeIntentRegistry(root: string, registry: {
60
+ acts: IntentActDef[];
61
+ categories: IntentRegistryFile['categories'];
62
+ }, updatedAt?: string): IntentRegistryFile;
63
+ /** 追加一条记录。失败不抛:留痕写不进去不该影响这一轮的回答。 */
64
+ export declare function appendIntentRecord(root: string, record: IntentRecord): Promise<void>;
65
+ /**
66
+ * 读记录(新→旧按时间,返回时升序)。
67
+ *
68
+ * 三条纪律:
69
+ * 1. **坏行只丢它自己。** 追加写天然会留下「最后一行写了一半」的可能(进程被杀),
70
+ * 一行 JSON.parse 失败不该让整份历史读不出来。
71
+ * 2. **按 `sessionKey#turnKey` 取最后一条。** 与内存里那份 upsert 语义一致。
72
+ * 3. `limit` 是**每个会话**的上限,不是总数:面板一次只显示一个会话。
73
+ */
74
+ export declare function readIntentRecords(root: string, sessionKey?: string, limit?: number): Promise<IntentRecord[]>;
75
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/intent/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE5D,6CAA6C;AAC7C,eAAO,MAAM,oBAAoB,kBAAkB,CAAA;AACnD,oDAAoD;AACpD,eAAO,MAAM,mBAAmB,mBAAmB,CAAA;AAEnD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,CAAC,CAAA;IACV,IAAI,EAAE,YAAY,EAAE,CAAA;IACpB,UAAU,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;IAC1H,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAqBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAgB/E;AAED,0CAA0C;AAC1C,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE;IAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAAC,UAAU,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAA;CAAE,EAAE,SAAS,SAA2B,GAAG,kBAAkB,CAI5L;AAED,oCAAoC;AACpC,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAK1F;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAyB/G"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * 意图的**落盘**(0033)。
3
+ *
4
+ * ## 为什么需要它
5
+ *
6
+ * 0033 之前,意图的两半都不在磁盘上属于这个 Agent 的地方:
7
+ *
8
+ * - **分类 / act 注册表**住在宿主的 settings 文档(`settings.yaml`)里。它确实落盘了,
9
+ * 但那是**宿主的配置**,不是这个 Agent 的文件 —— 备份知识库不会带上它,换一台机器
10
+ * 也不跟着走,而它恰恰决定了「同一句话被理解成什么」。
11
+ * - **每轮记录**只在内存里(`IntentStore` 的 Map,TTL 600 秒)。重启即丢。而架构图上
12
+ * 写着「意图记录…都已落盘」——**那句话当时是假的**。
13
+ *
14
+ * 现在两份东西都在 `<agentRoot>/intent/`:
15
+ *
16
+ * ```
17
+ * <agentRoot>/intent/
18
+ * registry.json 分类 / act 词表(可编辑,面板就地改)
19
+ * records.ndjson 每轮一条记录,append-only
20
+ * ```
21
+ *
22
+ * ## 为什么记录是 append-only 而不是「覆盖写」
23
+ *
24
+ * 记录本身按 `sessionKey#turn` upsert(同一轮重复调用只算一条事实),但**文件是审计
25
+ * 留痕**:追加每一版比原地覆盖更能回答「这一轮改过什么」。读的时候按同一个 key 取
26
+ * 最后一条,于是内存里那份「一轮一条」的语义不变,而磁盘上留下了完整过程。
27
+ *
28
+ * 代价是文件会随使用增长。这是审计流的固有代价,且它是纯追加、没有读放大 ——
29
+ * 真到需要清理时应该按时间归档,而不是在这里改成覆盖写。
30
+ *
31
+ * @module
32
+ */
33
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
34
+ import { appendFile, mkdir, readFile } from 'node:fs/promises';
35
+ import { dirname, join } from 'node:path';
36
+ /** 注册表文件名。分类与 act 住一起:它们是一份词表的两半,分开存只会漂移。 */
37
+ export const INTENT_REGISTRY_FILE = 'registry.json';
38
+ /** 记录文件名。NDJSON 而不是 JSON 数组:追加是 O(1),且半行坏数据只坏一行。 */
39
+ export const INTENT_RECORDS_FILE = 'records.ndjson';
40
+ /**
41
+ * 原子写:先写 `.tmp` 再 rename。半截的 registry.json 会让引擎按出厂预置启动。
42
+ *
43
+ * **同步**,与 `migrate.ts` 同一个理由:注册表的读发生在**设置解析的回调里**
44
+ * (`setSource` → `apply()` → 灌进引擎),而那条路径必须同步完成 —— 异步化会让
45
+ * 「设置改了,引擎还是旧的」重新出现,而且窗口期随磁盘快慢变化。文件只有几 KB,
46
+ * 一次启动读一次。
47
+ */
48
+ function writeAtomicSync(path, content) {
49
+ mkdirSync(dirname(path), { recursive: true });
50
+ const temp = `${path}.tmp`;
51
+ writeFileSync(temp, content, 'utf8');
52
+ renameSync(temp, path);
53
+ }
54
+ function isPlainObject(value) {
55
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
56
+ }
57
+ /**
58
+ * 读注册表文件。
59
+ *
60
+ * **不抛异常**:文件坏了、被手改坏了、写了一半 —— 都返回 `undefined`,调用方按
61
+ * 出厂预置启动。注册表读不出来不该让整个意图引擎起不来,更不该让插件起不来。
62
+ */
63
+ export function readIntentRegistry(root) {
64
+ const path = join(root, INTENT_REGISTRY_FILE);
65
+ if (!existsSync(path))
66
+ return undefined;
67
+ try {
68
+ const parsed = JSON.parse(readFileSync(path, 'utf8'));
69
+ if (!isPlainObject(parsed))
70
+ return undefined;
71
+ if (!Array.isArray(parsed.acts) || !Array.isArray(parsed.categories))
72
+ return undefined;
73
+ return {
74
+ version: 1,
75
+ acts: parsed.acts,
76
+ categories: parsed.categories,
77
+ ...(typeof parsed.updatedAt === 'string' ? { updatedAt: parsed.updatedAt } : {}),
78
+ };
79
+ }
80
+ catch {
81
+ return undefined;
82
+ }
83
+ }
84
+ /** 写注册表文件。`updatedAt` 由调用方给,便于测试与审计对齐。 */
85
+ export function writeIntentRegistry(root, registry, updatedAt = new Date().toISOString()) {
86
+ const payload = { version: 1, acts: registry.acts, categories: registry.categories, updatedAt };
87
+ writeAtomicSync(join(root, INTENT_REGISTRY_FILE), `${JSON.stringify(payload, null, 2)}\n`);
88
+ return payload;
89
+ }
90
+ /** 追加一条记录。失败不抛:留痕写不进去不该影响这一轮的回答。 */
91
+ export async function appendIntentRecord(root, record) {
92
+ try {
93
+ await mkdir(root, { recursive: true });
94
+ await appendFile(join(root, INTENT_RECORDS_FILE), `${JSON.stringify(record)}\n`, 'utf8');
95
+ }
96
+ catch { /* 磁盘满 / 只读卷:这一轮照常回答,留痕缺失 */ }
97
+ }
98
+ /**
99
+ * 读记录(新→旧按时间,返回时升序)。
100
+ *
101
+ * 三条纪律:
102
+ * 1. **坏行只丢它自己。** 追加写天然会留下「最后一行写了一半」的可能(进程被杀),
103
+ * 一行 JSON.parse 失败不该让整份历史读不出来。
104
+ * 2. **按 `sessionKey#turnKey` 取最后一条。** 与内存里那份 upsert 语义一致。
105
+ * 3. `limit` 是**每个会话**的上限,不是总数:面板一次只显示一个会话。
106
+ */
107
+ export async function readIntentRecords(root, sessionKey, limit = 200) {
108
+ const path = join(root, INTENT_RECORDS_FILE);
109
+ if (!existsSync(path))
110
+ return [];
111
+ let text;
112
+ try {
113
+ text = await readFile(path, 'utf8');
114
+ }
115
+ catch {
116
+ return [];
117
+ }
118
+ const latest = new Map();
119
+ for (const line of text.split(/\r?\n/)) {
120
+ if (!line.trim())
121
+ continue;
122
+ let record;
123
+ try {
124
+ record = JSON.parse(line);
125
+ }
126
+ catch {
127
+ continue;
128
+ }
129
+ if (!isPlainObject(record) || typeof record.sessionKey !== 'string' || typeof record.turnKey !== 'string')
130
+ continue;
131
+ if (sessionKey !== undefined && record.sessionKey !== sessionKey)
132
+ continue;
133
+ latest.set(`${record.sessionKey}#${record.turnKey}`, record);
134
+ }
135
+ return [...latest.values()]
136
+ .sort((left, right) => String(left.updatedAt ?? left.createdAt).localeCompare(String(right.updatedAt ?? right.createdAt)))
137
+ .slice(-limit);
138
+ }
139
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/intent/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * 三个 `intent_*` 工具的**注册器**:与「引擎住在哪个平面」解耦。
3
+ *
4
+ * ## 为什么要单独一个文件
5
+ *
6
+ * 0029 之前这三个工具由宿主平面的 `applyIntent` 直接 `ctx.tools.register(...)`,
7
+ * 于是它们是**全局工具**:任何 agent、任何 preset 的会话都会在提示词里看到
8
+ * `intent_record`,也都能调它。而意图记录是这个方案自己的东西 —— 只有跑
9
+ * TitaAgent 那套组合的会话才该有它,别的 agent 场景(别的 preset、临时会话)
10
+ * 不该被塞一个用不上的工具。
11
+ *
12
+ * DSH 里「只有某个 preset 能用」的**唯一**支持形态是**注册作用域**:注册在哪个
13
+ * 作用域,就只在哪个作用域可见(`dsh-tools` 的 `register` 是 scope-layered)。
14
+ * `ctx.tools.restrict()` 只能做减法(从继承来的工具里减掉),宿主平面调它还会
15
+ * 直接抛 —— 没有「只给某一个作用域」的正向开关。所以正确的做法是把注册搬到
16
+ * **agent 平面**:一个只被自定义 preset 的 `agent.cordis.yml` 挂载的行
17
+ * (`./preset-tools.ts`),它注册的工具只覆盖那个 preset 的会话。
18
+ *
19
+ * 注册逻辑本身与平面无关,所以它留在这里:宿主平面负责「引擎怎么跑」(设置、
20
+ * 轮次记账、HTTP 只读面),agent 平面负责「模型看到什么工具」。两边共用这一份,
21
+ * 不各写一套工具定义。
22
+ *
23
+ * @module
24
+ */
25
+ import { type ToolRunContext } from '@deepseek-ai/dsh-tools';
26
+ import type { LineageContext } from 'dsh-data-contracts/refs';
27
+ /**
28
+ * 注册这三个工具需要引擎提供的能力。
29
+ *
30
+ * 刻意是**结构化的最小面**而不是 `IntentEngine` 本身:宿主平面通过
31
+ * `INTENT_SERVICE` 提供它,agent 平面的行只按这个形状取用。这样 preset 行不必
32
+ * import 引擎、也不必知道引擎住在哪个模块里。
33
+ */
34
+ export interface IntentToolHost {
35
+ /** `intent_record` 的**工具描述就是路由提示词**(0023)。 */
36
+ routingPrompt(): string;
37
+ record(args: Record<string, unknown>, exec?: ToolRunContext): unknown;
38
+ view(sessionKey: string, includePrompt?: boolean): unknown;
39
+ registry(): unknown;
40
+ /** 提示词 / 词表变化时通知,返回取消订阅。 */
41
+ subscribe(listener: () => void): () => void;
42
+ }
43
+ /** 工具的最小注册面。测试替身与真实 `ctx` 都满足它。 */
44
+ export interface ToolRegistryLike {
45
+ register(definition: unknown): unknown;
46
+ }
47
+ export declare function jsonTool(name: string, description: string, parameters: Record<string, unknown>, execute: (args: any, exec?: ToolRunContext) => unknown): import("@deepseek-ai/dsh-tools").ToolDefinition;
48
+ export declare function lineageOf(args: Record<string, unknown>, exec?: ToolRunContext): Partial<LineageContext> | undefined;
49
+ export declare function sessionKeyOf(args: Record<string, unknown>, exec?: ToolRunContext): string;
50
+ /**
51
+ * 注册三个 `intent_*` 工具,返回一个把三者一起撤掉的 disposer。
52
+ *
53
+ * `intent_record` 的描述是**动态**的:分类 / act 词表可以在设置里改,而工具描述
54
+ * 是静态字符串。所以设置一变就 dispose 旧的、按新文本重新注册 —— 下一轮模型看到
55
+ * 的规则就是新的。这是「保存后下一轮生效」在工具这一侧的实现。
56
+ *
57
+ * 类型守卫(`typeof disposer === 'function'`)是因为测试替身的 `register` 不一定
58
+ * 返回 disposer。
59
+ */
60
+ export declare function registerIntentTools(ctx: {
61
+ tools: ToolRegistryLike;
62
+ }, host: IntentToolHost): () => void;
63
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/intent/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAE7D;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,aAAa,IAAI,MAAM,CAAA;IACvB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAA;IACrE,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;IAC1D,QAAQ,IAAI,OAAO,CAAA;IACnB,4BAA4B;IAC5B,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;CAC5C;AAsBD,mCAAmC;AACnC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAAA;CACvC;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,cAAc,KAAK,OAAO,mDAMtJ;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,CAUnH;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,MAAM,CAGzF;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE;IAAE,KAAK,EAAE,gBAAgB,CAAA;CAAE,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,IAAI,CAiCtG"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * 三个 `intent_*` 工具的**注册器**:与「引擎住在哪个平面」解耦。
3
+ *
4
+ * ## 为什么要单独一个文件
5
+ *
6
+ * 0029 之前这三个工具由宿主平面的 `applyIntent` 直接 `ctx.tools.register(...)`,
7
+ * 于是它们是**全局工具**:任何 agent、任何 preset 的会话都会在提示词里看到
8
+ * `intent_record`,也都能调它。而意图记录是这个方案自己的东西 —— 只有跑
9
+ * TitaAgent 那套组合的会话才该有它,别的 agent 场景(别的 preset、临时会话)
10
+ * 不该被塞一个用不上的工具。
11
+ *
12
+ * DSH 里「只有某个 preset 能用」的**唯一**支持形态是**注册作用域**:注册在哪个
13
+ * 作用域,就只在哪个作用域可见(`dsh-tools` 的 `register` 是 scope-layered)。
14
+ * `ctx.tools.restrict()` 只能做减法(从继承来的工具里减掉),宿主平面调它还会
15
+ * 直接抛 —— 没有「只给某一个作用域」的正向开关。所以正确的做法是把注册搬到
16
+ * **agent 平面**:一个只被自定义 preset 的 `agent.cordis.yml` 挂载的行
17
+ * (`./preset-tools.ts`),它注册的工具只覆盖那个 preset 的会话。
18
+ *
19
+ * 注册逻辑本身与平面无关,所以它留在这里:宿主平面负责「引擎怎么跑」(设置、
20
+ * 轮次记账、HTTP 只读面),agent 平面负责「模型看到什么工具」。两边共用这一份,
21
+ * 不各写一套工具定义。
22
+ *
23
+ * @module
24
+ */
25
+ import { defineTool } from '@deepseek-ai/dsh-tools';
26
+ /** `intent_record` 的参数表。描述是路由提示词(工具级),所以这里只声明字段。 */
27
+ const INTENT_RECORD_PARAMS = {
28
+ user_input: { type: 'string', required: true, description: '本轮用户原文' },
29
+ act: { type: 'string', description: '本轮动作 id,取自工具描述里的 act 词表' },
30
+ category: { type: 'string', description: '意图分类 id:先按预置分类匹配,命中就直接用它的 id;全不命中才自行新起一个 id 或落 unknown' },
31
+ predicate: { type: 'string', description: '要执行的动作,例如 query_babel_data' },
32
+ slots: { type: 'json', description: '从用户输入抽取的关键参数' },
33
+ confidence: { type: 'number', description: '0-1,用于标注 lowConfidence' },
34
+ refs: { type: 'array', description: '引用对象,例如 { id, kind, label }' },
35
+ relation: { type: 'string', enum: ['new_task', 'subtask_of'], description: '本轮是新任务还是已有任务的子任务' },
36
+ session_key: { type: 'string' },
37
+ turn_id: { type: 'string', description: '当前对话轮次 id;不传则由 Host 生成' },
38
+ task_id: { type: 'string', description: 'relation=subtask_of 时指向的已有业务任务 id;新任务不传' },
39
+ subtask_id: { type: 'string', description: '已有子任务 id;新子任务不传,由 Host 生成' },
40
+ parent_subtask_id: { type: 'string', description: '父任务节点 id;通常由 Host 生成' },
41
+ run_id: { type: 'string', description: '已有执行尝试 id;重试时传新值' },
42
+ trace_id: { type: 'string' },
43
+ domain: { type: 'string' },
44
+ };
45
+ export function jsonTool(name, description, parameters, execute) {
46
+ return defineTool({
47
+ name, description, parameters: parameters,
48
+ output: { schema: { type: 'json' }, render: (_args, value) => [{ type: 'text', text: JSON.stringify(value) }] },
49
+ execute: async (args, exec) => execute(args, exec),
50
+ });
51
+ }
52
+ export function lineageOf(args, exec) {
53
+ const lineage = {};
54
+ const sessionId = typeof args.session_key === 'string' && args.session_key.trim() ? args.session_key.trim() : exec?.agent?.session.header.id;
55
+ if (sessionId)
56
+ lineage.sessionId = sessionId;
57
+ const fields = [
58
+ ['turnId', 'turn_id'], ['taskId', 'task_id'], ['subtaskId', 'subtask_id'],
59
+ ['parentSubtaskId', 'parent_subtask_id'], ['runId', 'run_id'], ['traceId', 'trace_id'], ['domain', 'domain'],
60
+ ];
61
+ for (const [target, source] of fields)
62
+ if (typeof args[source] === 'string' && args[source].trim())
63
+ lineage[target] = args[source].trim();
64
+ return Object.keys(lineage).length > 0 ? lineage : undefined;
65
+ }
66
+ export function sessionKeyOf(args, exec) {
67
+ const explicit = typeof args.session_key === 'string' ? args.session_key.trim() : '';
68
+ return explicit || exec?.agent?.session.header.id || 'default';
69
+ }
70
+ /**
71
+ * 注册三个 `intent_*` 工具,返回一个把三者一起撤掉的 disposer。
72
+ *
73
+ * `intent_record` 的描述是**动态**的:分类 / act 词表可以在设置里改,而工具描述
74
+ * 是静态字符串。所以设置一变就 dispose 旧的、按新文本重新注册 —— 下一轮模型看到
75
+ * 的规则就是新的。这是「保存后下一轮生效」在工具这一侧的实现。
76
+ *
77
+ * 类型守卫(`typeof disposer === 'function'`)是因为测试替身的 `register` 不一定
78
+ * 返回 disposer。
79
+ */
80
+ export function registerIntentTools(ctx, host) {
81
+ let disposeRecord;
82
+ let registeredDescription = '';
83
+ const ensureRecordTool = () => {
84
+ const description = host.routingPrompt();
85
+ if (registeredDescription === description && disposeRecord)
86
+ return;
87
+ disposeRecord?.();
88
+ disposeRecord = undefined;
89
+ registeredDescription = description;
90
+ const disposer = ctx.tools.register(jsonTool('intent_record', description, INTENT_RECORD_PARAMS, (args, exec) => host.record(args, exec)));
91
+ if (typeof disposer === 'function')
92
+ disposeRecord = disposer;
93
+ };
94
+ ensureRecordTool();
95
+ const disposeView = ctx.tools.register(jsonTool('intent_store_view', 'View recent intent records and the active task ids for the current session.', { session_key: { type: 'string' }, include_prompt: { type: 'boolean' } }, (args, exec) => host.view(sessionKeyOf(args, exec), args.include_prompt)));
96
+ const disposeRegistry = ctx.tools.register(jsonTool('intent_registry_list', 'List the configured intent acts, categories and predicates together with the routing prompt that ships as the intent_record tool description.', {}, () => host.registry()));
97
+ const unsubscribe = host.subscribe(ensureRecordTool);
98
+ return () => {
99
+ unsubscribe();
100
+ disposeRecord?.();
101
+ disposeRecord = undefined;
102
+ if (typeof disposeView === 'function')
103
+ disposeView();
104
+ if (typeof disposeRegistry === 'function')
105
+ disposeRegistry();
106
+ };
107
+ }
108
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/intent/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,189 @@
1
+ import type { ToolStatus } from 'dsh-data-contracts/envelope';
2
+ import type { LineageContext } from 'dsh-data-contracts/refs';
3
+ export type { ToolStatus };
4
+ /**
5
+ * 一个动作类型(act)。
6
+ *
7
+ * act 回答"这一轮用户在**做什么**",与 category(做什么**业务**)正交:同一句
8
+ * "帮我看下上个月的 GMV" 是 `query` × `data_analysis`。光有 id 时模型只能猜
9
+ * `query` 和 `request` 的区别,所以每一类都带 label 与 description。
10
+ */
11
+ export interface IntentActDef {
12
+ id: string;
13
+ label: string;
14
+ description: string;
15
+ enabled: boolean;
16
+ }
17
+ /**
18
+ * 出厂 act 词表。16 个动作覆盖"提问 / 让做 / 补充 / 反馈 / 终止 / 闲聊"六种交互。
19
+ *
20
+ * 记录仍是自由文本(模型可以写没配置过的 act,只给 warning),这份词表是**先验**:
21
+ * 它进 routing prompt,也进设置页与 `intent_registry_list`。
22
+ */
23
+ export declare const DEFAULT_ACTS: IntentActDef[];
24
+ /** Free-form act id; configured in `IntentSettings.acts`. */
25
+ export type IntentAct = string;
26
+ /** How one turn relates to the session's existing tasks. */
27
+ export type IntentRelation = 'new_task' | 'subtask_of' | 'unknown';
28
+ /** `model` is a model-authored record; `fallback` is the Host's turn-end backfill. */
29
+ export type IntentSource = 'model' | 'fallback';
30
+ export interface IntentSlotMap {
31
+ [name: string]: unknown;
32
+ }
33
+ export interface IntentRef {
34
+ id: string;
35
+ kind?: string;
36
+ label?: string;
37
+ }
38
+ /**
39
+ * One configurable intent category; `route` names the act it usually maps to.
40
+ *
41
+ * 预置分类的作用是**把模型的自由判断收窄成一次匹配**:
42
+ * {@link description} 说明这一类"是什么",{@link examples} 给出用户可能怎么说。
43
+ * 两者都会被拼进 routing prompt,模型先按它们匹配,命中就直接用该 id。
44
+ */
45
+ export interface IntentCategory {
46
+ id: string;
47
+ label: string;
48
+ route: string;
49
+ description: string;
50
+ /**
51
+ * 预置说法(few-shot):用户可能怎么表达这一类意图,每行一条。
52
+ *
53
+ * 可选——0012 时代的持久化配置没有这个字段,缺省按空数组处理,注册表 schema
54
+ * 也会补默认值。
55
+ */
56
+ examples?: string[];
57
+ enabled: boolean;
58
+ }
59
+ /**
60
+ * Recorder settings. The classification vocabulary is user-editable: nothing
61
+ * here constrains what a model may record, it only describes the options the
62
+ * routing prompt offers and what `intent_registry_list` reports.
63
+ */
64
+ export interface IntentSettings {
65
+ /** Below this confidence a record is annotated lowConfidence; the model decides whether to clarify. */
66
+ clarifyThreshold: number;
67
+ ttlSeconds: number;
68
+ /**
69
+ * 0023:路由提示词**没有开关**。它随 `intent_record` 的工具描述一起下发,
70
+ * 分类规则必须始终在场——否则模型退化成每轮从零判断。
71
+ */
72
+ /** Backfill one `unknown` record when a turn ends without a model record. */
73
+ fallbackEnabled: boolean;
74
+ categories: IntentCategory[];
75
+ acts: IntentActDef[];
76
+ predicates: string[];
77
+ }
78
+ /**
79
+ * 出厂预置的意图分类。
80
+ *
81
+ * 每一项都**必须**带 `description` 与 `examples`:只给标签("数据分析")时模型
82
+ * 只能靠猜,同一句话在不同轮次会被分到不同类。这些文案是模型的匹配依据,全部
83
+ * 可以在「意图」页里改。
84
+ */
85
+ export declare const DEFAULT_CATEGORIES: Array<IntentCategory & {
86
+ examples: string[];
87
+ }>;
88
+ export declare const DEFAULT_PREDICATES: string[];
89
+ export declare const DEFAULT_INTENT_SETTINGS: IntentSettings;
90
+ /** One recorded intent. The record is an audit fact; it never drives control flow. */
91
+ export interface IntentRecord {
92
+ id: string;
93
+ sessionKey: string;
94
+ /** `sessionKey#turn` — the upsert key that keeps one record per turn. */
95
+ turnKey: string;
96
+ turnId: string;
97
+ userInput: string;
98
+ act: IntentAct;
99
+ category?: string;
100
+ predicate?: string;
101
+ slots: IntentSlotMap;
102
+ confidence?: number;
103
+ lowConfidence?: boolean;
104
+ refs: IntentRef[];
105
+ relation: IntentRelation;
106
+ source: IntentSource;
107
+ createdAt: string;
108
+ updatedAt: string;
109
+ lineage: LineageContext;
110
+ meta: Record<string, unknown>;
111
+ }
112
+ export interface IntentRecordInput {
113
+ userInput: string;
114
+ act?: string;
115
+ category?: string;
116
+ predicate?: string;
117
+ slots?: IntentSlotMap;
118
+ confidence?: number;
119
+ refs?: IntentRef[];
120
+ relation?: IntentRelation;
121
+ sessionKey: string;
122
+ turnId?: string;
123
+ lineage?: Partial<LineageContext>;
124
+ now?: number;
125
+ }
126
+ /** Compact task context returned to the model so it can pick the next relation. */
127
+ export interface IntentTaskSummary {
128
+ taskId: string;
129
+ lastSubtaskId?: string;
130
+ category?: string;
131
+ ageSeconds: number;
132
+ }
133
+ export interface IntentRegistry {
134
+ /** 可编辑的 act 词表(带 label / description),面板就地增删改。 */
135
+ acts: IntentActDef[];
136
+ /**
137
+ * 可用的意图分类。带 `description` / `examples`,因为「意图」页要就地编辑它们,
138
+ * 而不是只渲染成一组只读徽标。
139
+ */
140
+ categories: Array<{
141
+ id: string;
142
+ label: string;
143
+ route: string;
144
+ description: string;
145
+ examples: string[];
146
+ enabled: boolean;
147
+ }>;
148
+ predicates: string[];
149
+ }
150
+ export interface IntentStoreView {
151
+ sessionKey: string;
152
+ activeTaskId?: string;
153
+ activeIntentId?: string;
154
+ tasks: IntentTaskSummary[];
155
+ recent: IntentRecord[];
156
+ expiresAt?: string;
157
+ }
158
+ export interface IntentResultData {
159
+ intentId?: string;
160
+ taskId?: string;
161
+ subtaskId?: string;
162
+ parentSubtaskId?: string;
163
+ runId?: string;
164
+ turnId?: string;
165
+ act?: string;
166
+ category?: string;
167
+ relation?: IntentRelation;
168
+ source?: IntentSource;
169
+ lowConfidence?: boolean;
170
+ activeTasks?: IntentTaskSummary[];
171
+ store?: IntentStoreView;
172
+ registry?: IntentRegistry;
173
+ prompt?: string;
174
+ }
175
+ export interface IntentResult {
176
+ ok: boolean;
177
+ status: ToolStatus;
178
+ data: IntentResultData;
179
+ warnings: string[];
180
+ }
181
+ /** Live turn state: the provisional ids allocated before the model records. */
182
+ export interface IntentTurnState {
183
+ turn: number;
184
+ userInput: string;
185
+ subtaskId: string;
186
+ taskId?: string;
187
+ committed: boolean;
188
+ }
189
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/intent/types.ts"],"names":[],"mappings":"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"}