@jangts/agent-core 0.3.5 → 0.5.0

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 (288) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +33 -31
  3. package/development/docs/README.en.md +2 -2
  4. package/development/docs/acceptance.en.md +2 -2
  5. package/development/docs/agent-development.en.md +1 -1
  6. package/development/docs/api/README.en.md +6 -2
  7. package/development/docs/api/README.md +4 -0
  8. package/development/docs/api/configuration-in-workflow.en.md +403 -0
  9. package/development/docs/api/configuration-in-workflow.md +403 -0
  10. package/development/docs/api/core.en.md +7 -7
  11. package/development/docs/api/core.md +6 -6
  12. package/development/docs/api/decorators.en.md +20 -0
  13. package/development/docs/api/decorators.md +20 -0
  14. package/development/docs/api/examples.en.md +1 -1
  15. package/development/docs/api/examples.md +1 -1
  16. package/development/docs/api/kits.en.md +22 -4
  17. package/development/docs/api/kits.md +22 -4
  18. package/development/docs/api/knowledge-answering.en.md +4 -1
  19. package/development/docs/api/knowledge-answering.md +4 -1
  20. package/development/docs/api/mock.en.md +2 -0
  21. package/development/docs/api/mock.md +2 -0
  22. package/development/docs/api/observability.en.md +37 -11
  23. package/development/docs/api/observability.md +64 -11
  24. package/development/docs/api/reference.en.md +876 -657
  25. package/development/docs/api/reference.md +662 -508
  26. package/development/docs/api/support.en.md +55 -9
  27. package/development/docs/api/support.md +53 -7
  28. package/development/docs/api/types.en.md +36 -1
  29. package/development/docs/api/types.md +44 -0
  30. package/development/docs/api/workflow-views.en.md +64 -0
  31. package/development/docs/api/workflow-views.md +78 -0
  32. package/development/docs/api/workflow.en.md +6 -2
  33. package/development/docs/api/workflow.md +6 -2
  34. package/development/docs/basic-usage.en.md +1 -1
  35. package/development/docs/basic-usage.md +1 -1
  36. package/development/docs/create-app.en.md +1 -1
  37. package/development/docs/examples/registration/associated.mjs +8 -0
  38. package/development/docs/examples/registration/independent.mjs +20 -0
  39. package/development/docs/examples/registration/protocol.mjs +48 -0
  40. package/development/docs/examples/registration/run.mjs +47 -0
  41. package/development/docs/examples/registration/tools.mjs +75 -0
  42. package/development/docs/examples/registration/workflow.mjs +109 -0
  43. package/development/docs/flows/knowledge-maintenance.en.md +1 -1
  44. package/development/docs/materials.en.md +1 -1
  45. package/development/docs/mechanisms.en.md +2 -2
  46. package/development/docs/mechanisms.md +1 -1
  47. package/development/docs/operations.en.md +1 -1
  48. package/development/docs/records.en.md +1 -1
  49. package/development/docs/registration.en.md +4 -4
  50. package/development/docs/registration.md +2 -2
  51. package/development/skills/agent-core-app/SKILL.md +16 -4
  52. package/development/skills/agent-core-app/templates/node-ts/README.md.tpl +1 -1
  53. package/development/skills/agent-core-app/templates/node-ts/src/catalog.ts.tpl +2 -2
  54. package/development/skills/agent-core-app/templates/node-ts/test/app.test.mjs.tpl +1 -1
  55. package/dist/cjs/capabilities/index.js +5 -12
  56. package/dist/cjs/capabilities/invocation.js +21 -1
  57. package/dist/cjs/capabilities/model.js +56 -12
  58. package/dist/cjs/capabilities/tool-conditions.js +65 -0
  59. package/dist/cjs/capabilities/tool-runtime.js +18 -4
  60. package/dist/cjs/capabilities/tools.js +12 -17
  61. package/dist/cjs/context/audit.js +5 -8
  62. package/dist/cjs/context/index.js +3 -4
  63. package/dist/cjs/diagnostics/index.js +51 -3
  64. package/dist/cjs/diagnostics/native-sub-flow.js +106 -0
  65. package/dist/cjs/diagnostics/sub-flow.js +278 -32
  66. package/dist/cjs/execution/engine.js +3 -2
  67. package/dist/cjs/execution/events.js +5 -5
  68. package/dist/cjs/execution/reporting.js +18 -28
  69. package/dist/cjs/execution/workflow-chain.js +211 -0
  70. package/dist/cjs/execution/workflow-graph.js +72 -0
  71. package/dist/cjs/execution/workflow.js +34 -6
  72. package/dist/cjs/index.js +21 -17
  73. package/dist/cjs/kits/aggregation.js +17 -14
  74. package/dist/cjs/kits/answering/checks.js +2 -1
  75. package/dist/cjs/kits/answering/flow.js +24 -21
  76. package/dist/cjs/kits/answering/tasks.js +30 -25
  77. package/dist/cjs/kits/delivery.js +36 -24
  78. package/dist/cjs/kits/domains/catalog.js +113 -0
  79. package/dist/cjs/kits/domains/index.js +20 -0
  80. package/dist/cjs/kits/{intents → domains}/registry.js +77 -31
  81. package/dist/cjs/kits/{intents → domains}/scopes.js +21 -21
  82. package/dist/cjs/kits/index.js +14 -13
  83. package/dist/cjs/kits/knowledge/catalog.js +33 -30
  84. package/dist/cjs/kits/policies.js +3 -2
  85. package/dist/cjs/kits/presentation/formats.js +110 -0
  86. package/dist/cjs/kits/presentation/index.js +10 -5
  87. package/dist/cjs/kits/presentation/outputs.js +2 -1
  88. package/dist/cjs/kits/reflection.js +2 -2
  89. package/dist/cjs/kits/retrieval.js +7 -1
  90. package/dist/cjs/kits/text-blocks.js +101 -0
  91. package/dist/cjs/kits/tools.js +247 -158
  92. package/dist/cjs/model/decision-retry.js +2 -1
  93. package/dist/cjs/model/index.js +2 -6
  94. package/dist/cjs/model/interactions/calls.js +61 -0
  95. package/dist/cjs/model/interactions/json-object.js +11 -11
  96. package/dist/cjs/model/interactions/native-functions.js +17 -23
  97. package/dist/cjs/model/message-diagnostics.js +13 -3
  98. package/dist/cjs/model/options.js +2 -0
  99. package/dist/cjs/model/preparation.js +39 -6
  100. package/dist/cjs/model/runner.js +34 -5
  101. package/dist/cjs/model/selection-transport.js +4 -4
  102. package/dist/cjs/model/token-budget.js +3 -0
  103. package/dist/cjs/model/transports.js +3 -2
  104. package/dist/cjs/structs/index.js +7 -6
  105. package/dist/cjs/structs/kits/domains/scopes.js +2 -0
  106. package/dist/cjs/structs/kits/presentation/formats.js +2 -0
  107. package/dist/cjs/structs/kits/text-blocks.js +11 -0
  108. package/dist/cjs/structs/model/session.js +11 -0
  109. package/dist/cjs/structs/support/associations.js +2 -0
  110. package/dist/cjs/support/associations.js +79 -0
  111. package/dist/cjs/support/context/nodes.js +48 -45
  112. package/dist/cjs/support/context/processing.js +6 -3
  113. package/dist/cjs/support/context/snapshot.js +11 -1
  114. package/dist/cjs/support/decorators/index.js +45 -3
  115. package/dist/cjs/support/index.js +1 -0
  116. package/dist/cjs/support/model/capabilities.js +35 -5
  117. package/dist/cjs/support/model/chat-completions.js +11 -2
  118. package/dist/cjs/support/model/completion/calls.js +10 -56
  119. package/dist/cjs/support/model/preview-rules.js +11 -11
  120. package/dist/cjs/support/model/reply-preview.js +3 -3
  121. package/dist/cjs/support/model/session.js +152 -0
  122. package/dist/cjs/support/model/stage-transport.js +8 -8
  123. package/dist/cjs/support/model/transports.js +5 -2
  124. package/dist/cjs/support/tools.js +42 -17
  125. package/dist/cjs/utils/invocation.js +1 -0
  126. package/dist/esm/capabilities/index.d.ts +5 -10
  127. package/dist/esm/capabilities/index.js +5 -9
  128. package/dist/esm/capabilities/invocation.js +21 -1
  129. package/dist/esm/capabilities/model.d.ts +17 -13
  130. package/dist/esm/capabilities/model.js +54 -10
  131. package/dist/esm/capabilities/tool-conditions.d.ts +9 -0
  132. package/dist/esm/capabilities/tool-conditions.js +59 -0
  133. package/dist/esm/capabilities/tool-runtime.js +18 -4
  134. package/dist/esm/capabilities/tools.d.ts +3 -3
  135. package/dist/esm/capabilities/tools.js +12 -17
  136. package/dist/esm/context/audit.js +5 -8
  137. package/dist/esm/context/index.d.ts +3 -4
  138. package/dist/esm/context/index.js +3 -4
  139. package/dist/esm/diagnostics/index.d.ts +1 -0
  140. package/dist/esm/diagnostics/index.js +48 -2
  141. package/dist/esm/diagnostics/native-sub-flow.d.ts +94 -0
  142. package/dist/esm/diagnostics/native-sub-flow.js +101 -0
  143. package/dist/esm/diagnostics/sub-flow.d.ts +56 -4
  144. package/dist/esm/diagnostics/sub-flow.js +271 -32
  145. package/dist/esm/execution/engine.d.ts +1 -0
  146. package/dist/esm/execution/engine.js +3 -2
  147. package/dist/esm/execution/events.js +5 -5
  148. package/dist/esm/execution/reporting.d.ts +6 -12
  149. package/dist/esm/execution/reporting.js +19 -29
  150. package/dist/esm/execution/workflow-chain.d.ts +3 -0
  151. package/dist/esm/execution/workflow-chain.js +208 -0
  152. package/dist/esm/execution/workflow-graph.d.ts +7 -0
  153. package/dist/esm/execution/workflow-graph.js +68 -0
  154. package/dist/esm/execution/workflow.d.ts +6 -0
  155. package/dist/esm/execution/workflow.js +34 -6
  156. package/dist/esm/index.d.ts +19 -13
  157. package/dist/esm/index.js +18 -15
  158. package/dist/esm/kits/aggregation.d.ts +1 -1
  159. package/dist/esm/kits/aggregation.js +17 -14
  160. package/dist/esm/kits/answering/checks.js +2 -1
  161. package/dist/esm/kits/answering/flow.js +24 -21
  162. package/dist/esm/kits/answering/tasks.d.ts +6 -6
  163. package/dist/esm/kits/answering/tasks.js +30 -25
  164. package/dist/esm/kits/delivery.d.ts +0 -9
  165. package/dist/esm/kits/delivery.js +36 -24
  166. package/dist/esm/kits/domains/catalog.d.ts +42 -0
  167. package/dist/esm/kits/domains/catalog.js +110 -0
  168. package/dist/esm/kits/domains/index.d.ts +4 -0
  169. package/dist/esm/kits/domains/index.js +4 -0
  170. package/dist/esm/kits/domains/registry.d.ts +100 -0
  171. package/dist/esm/kits/{intents → domains}/registry.js +77 -31
  172. package/dist/esm/kits/{intents → domains}/scopes.d.ts +18 -18
  173. package/dist/esm/kits/{intents → domains}/scopes.js +21 -21
  174. package/dist/esm/kits/index.d.ts +6 -5
  175. package/dist/esm/kits/index.js +6 -5
  176. package/dist/esm/kits/knowledge/catalog.js +33 -30
  177. package/dist/esm/kits/policies.d.ts +1 -1
  178. package/dist/esm/kits/policies.js +3 -2
  179. package/dist/esm/kits/presentation/formats.d.ts +42 -0
  180. package/dist/esm/kits/presentation/formats.js +105 -0
  181. package/dist/esm/kits/presentation/index.d.ts +14 -5
  182. package/dist/esm/kits/presentation/index.js +10 -5
  183. package/dist/esm/kits/presentation/outputs.js +2 -1
  184. package/dist/esm/kits/reflection.js +3 -3
  185. package/dist/esm/kits/retrieval.js +7 -1
  186. package/dist/esm/kits/text-blocks.d.ts +24 -0
  187. package/dist/esm/kits/text-blocks.js +97 -0
  188. package/dist/esm/kits/tools.d.ts +69 -52
  189. package/dist/esm/kits/tools.js +247 -158
  190. package/dist/esm/model/decision-retry.d.ts +2 -0
  191. package/dist/esm/model/decision-retry.js +2 -1
  192. package/dist/esm/model/index.d.ts +2 -6
  193. package/dist/esm/model/index.js +2 -6
  194. package/dist/esm/model/interactions/calls.d.ts +40 -0
  195. package/dist/esm/model/interactions/calls.js +58 -0
  196. package/dist/esm/model/interactions/json-object.js +11 -11
  197. package/dist/esm/model/interactions/native-functions.js +17 -23
  198. package/dist/esm/model/message-diagnostics.d.ts +6 -5
  199. package/dist/esm/model/message-diagnostics.js +13 -3
  200. package/dist/esm/model/options.js +2 -0
  201. package/dist/esm/model/preparation.js +39 -6
  202. package/dist/esm/model/runner.d.ts +2 -0
  203. package/dist/esm/model/runner.js +34 -5
  204. package/dist/esm/model/selection-transport.js +4 -4
  205. package/dist/esm/model/token-budget.js +3 -0
  206. package/dist/esm/model/transports.d.ts +2 -1
  207. package/dist/esm/model/transports.js +3 -2
  208. package/dist/esm/structs/capabilities/invocation.d.ts +3 -1
  209. package/dist/esm/structs/capabilities/model.d.ts +42 -11
  210. package/dist/esm/structs/capabilities/tools.d.ts +16 -7
  211. package/dist/esm/structs/common.d.ts +3 -1
  212. package/dist/esm/structs/debug.d.ts +36 -20
  213. package/dist/esm/structs/execution/workflow-views.d.ts +123 -0
  214. package/dist/esm/structs/execution/workflow.d.ts +4 -3
  215. package/dist/esm/structs/index.d.ts +8 -6
  216. package/dist/esm/structs/index.js +7 -6
  217. package/dist/esm/structs/kits/answering/tasks.d.ts +2 -2
  218. package/dist/esm/structs/kits/{intents → domains}/catalog.d.ts +20 -20
  219. package/dist/esm/structs/kits/{intents → domains}/registry.d.ts +24 -21
  220. package/dist/esm/structs/kits/{intents → domains}/scopes.d.ts +9 -9
  221. package/dist/esm/structs/kits/domains/scopes.js +1 -0
  222. package/dist/esm/structs/kits/presentation/formats.d.ts +42 -0
  223. package/dist/esm/structs/kits/presentation/formats.js +1 -0
  224. package/dist/esm/structs/kits/text-blocks.d.ts +25 -0
  225. package/dist/esm/structs/kits/text-blocks.js +10 -0
  226. package/dist/esm/structs/kits/tools.d.ts +82 -83
  227. package/dist/esm/structs/model/interactions.d.ts +18 -11
  228. package/dist/esm/structs/model/messages.d.ts +34 -2
  229. package/dist/esm/structs/model/runtime.d.ts +9 -0
  230. package/dist/esm/structs/model/session.d.ts +29 -0
  231. package/dist/esm/structs/model/session.js +10 -0
  232. package/dist/esm/structs/support/associations.d.ts +22 -0
  233. package/dist/esm/structs/support/associations.js +1 -0
  234. package/dist/esm/structs/support/model/interactions.d.ts +2 -2
  235. package/dist/esm/structs/support/model/messages.d.ts +6 -13
  236. package/dist/esm/structs/support/tools.d.ts +23 -23
  237. package/dist/esm/support/associations.d.ts +26 -0
  238. package/dist/esm/support/associations.js +76 -0
  239. package/dist/esm/support/context/nodes.js +48 -45
  240. package/dist/esm/support/context/processing.js +6 -3
  241. package/dist/esm/support/context/snapshot.js +11 -1
  242. package/dist/esm/support/decorators/index.d.ts +13 -2
  243. package/dist/esm/support/decorators/index.js +40 -3
  244. package/dist/esm/support/decorators/pool.d.ts +6 -5
  245. package/dist/esm/support/decorators/types.d.ts +3 -1
  246. package/dist/esm/support/index.d.ts +1 -0
  247. package/dist/esm/support/index.js +1 -0
  248. package/dist/esm/support/model/capabilities.d.ts +8 -3
  249. package/dist/esm/support/model/capabilities.js +35 -5
  250. package/dist/esm/support/model/chat-completions.js +11 -2
  251. package/dist/esm/support/model/completion/calls.d.ts +6 -34
  252. package/dist/esm/support/model/completion/calls.js +8 -55
  253. package/dist/esm/support/model/index.d.ts +1 -1
  254. package/dist/esm/support/model/preview-rules.d.ts +13 -8
  255. package/dist/esm/support/model/preview-rules.js +11 -11
  256. package/dist/esm/support/model/reply-preview.d.ts +2 -2
  257. package/dist/esm/support/model/reply-preview.js +3 -3
  258. package/dist/esm/support/model/session.d.ts +61 -0
  259. package/dist/esm/support/model/session.js +148 -0
  260. package/dist/esm/support/model/stage-transport.d.ts +1 -1
  261. package/dist/esm/support/model/stage-transport.js +9 -9
  262. package/dist/esm/support/model/transports.d.ts +2 -0
  263. package/dist/esm/support/model/transports.js +2 -1
  264. package/dist/esm/support/tools.d.ts +11 -3
  265. package/dist/esm/support/tools.js +43 -18
  266. package/dist/esm/utils/catalog.d.ts +1 -1
  267. package/dist/esm/utils/invocation.d.ts +1 -0
  268. package/dist/esm/utils/invocation.js +1 -0
  269. package/package.json +20 -6
  270. package/dist/cjs/execution/index.js +0 -30
  271. package/dist/cjs/kits/intents/catalog.js +0 -82
  272. package/dist/cjs/kits/intents/index.js +0 -35
  273. package/dist/cjs/utils/debug.js +0 -30
  274. package/dist/esm/execution/index.d.ts +0 -11
  275. package/dist/esm/execution/index.js +0 -11
  276. package/dist/esm/kits/intents/catalog.d.ts +0 -39
  277. package/dist/esm/kits/intents/catalog.js +0 -79
  278. package/dist/esm/kits/intents/index.d.ts +0 -22
  279. package/dist/esm/kits/intents/index.js +0 -18
  280. package/dist/esm/kits/intents/registry.d.ts +0 -88
  281. package/dist/esm/utils/debug.d.ts +0 -27
  282. package/dist/esm/utils/debug.js +0 -27
  283. /package/dist/cjs/structs/{kits/intents/catalog.js → execution/workflow-views.js} +0 -0
  284. /package/dist/cjs/structs/kits/{intents/registry.js → domains/catalog.js} +0 -0
  285. /package/dist/cjs/structs/kits/{intents/scopes.js → domains/registry.js} +0 -0
  286. /package/dist/esm/structs/{kits/intents/catalog.js → execution/workflow-views.js} +0 -0
  287. /package/dist/esm/structs/kits/{intents/registry.js → domains/catalog.js} +0 -0
  288. /package/dist/esm/structs/kits/{intents/scopes.js → domains/registry.js} +0 -0
@@ -2,13 +2,15 @@
2
2
 
3
3
  [共同类型](types.md) · [返回首页](README.md)。每个 Kit 从自己的子路径导入具名函数/构造器,静态声明与每次运行上下文分离。
4
4
 
5
- ## Intents、Interaction、Tools
5
+ ## Domain Tools、Scope、Interaction、Tools
6
+
7
+ IntentRegistry 注册继承 ModelTool 的 IntentTool,保留 scopePolicy、targetPolicy 和任务约束。asIntent.delegates 可覆盖推导结果;delegates 是可选允许集合,不是顺序。不存在独立 Intent 实体或 Intent ID;Scope 的 goalIds 引用真实 Tool ID。可选注册辅助从 `@jangts/agent-core/kits/domains` 导入。
6
8
 
7
9
  | 能力 | 首选接口/关键合同 |
8
10
  | --- | --- |
9
11
  | IntentRegistry | 定义主键 id,使用 scopePolicy/targetPolicy,实现共同 Registry 合同 |
10
- | ScopeRegistry | id、intentIds、toolIds、queryScopeIds、knowledgeTopicIds;aliases保留,查询方法使用scopeId |
11
- | defineAgentCatalog | 由实际登记投影关系;当前任务为`{ intentId, scopeId? }`,不能同时用scope指策略和引用 |
12
+ | ScopeRegistry | id、goalIds、toolIds、queryScopeIds、knowledgeTopicIds;aliases保留,查询方法使用scopeId |
13
+ | defineAgentCatalog | 由实际登记投影关系;当前任务为`{ goalId, scopeId? }`,不能同时用scope指策略和引用 |
12
14
  | defineInteractionProtocol | 一份commands声明编译协议,commandField由App拥有,不强制其wire字段叫type或kind |
13
15
  | defineCommandCatalog | commands闭集可用Record书写;公开definitions为数组,toRecord()为明确映射 |
14
16
  | bindInteraction | 对齐协议与具名handler;dispatch(input, context),不执行未登记命令 |
@@ -20,7 +22,7 @@
20
22
 
21
23
  InteractionProtocol、CommandCatalog 是公开构造器;Interaction 与 Interaction.Commands 分别提供它们的命名空间入口。
22
24
 
23
- Tools Kit保留全局检查→选中检查→授权→resume/execute→完成→finalize的真实次序。生命周期和contribution是本Kit局部协议。接收者字段叫receiver,不与OutputField.owner混用;请求内journal沿用Core分配的invocationId。
25
+ Tools Kit 保留全局检查→授权→resume/execute→完成→finalize 的真实次序。每个工具只声明一个 lifecycle 块:inspect、finalize 等钩子对全部工具运行,id/protocol/call 与 authorize/resume/complete 只由被选中的工具运行。接收者字段叫receiver,不与OutputField.owner混用;请求内journal沿用Core分配的invocationId。
24
26
 
25
27
  ## Evidence 与 Retrieval
26
28
 
@@ -72,6 +74,22 @@ TextSkill 定义使用 id、entry、toolIds 和 kind=text-workflow。目录项
72
74
 
73
75
  TextSkillLoader 接受 load({ entries }, { read })。注册 ID、路径、工具引用和重复项检查先于对应文件读取,read 与自定义解析器均须同步。读取端口、注册项和错误工厂可以由类实现,原型 getter 与原方法接收者保留。工具回执的 App 自有字段由 App 显式投影。
74
76
 
77
+ ## TextBlocks
78
+
79
+ ```ts
80
+ interface TextBlock {
81
+ readonly number: number
82
+ readonly text: string
83
+ readonly start: number
84
+ readonly end: number
85
+ }
86
+ TextBlocks.split(text, { targetChars }): readonly TextBlock[]
87
+ ```
88
+
89
+ `split` 只切分已解码的纯文本:标题与分隔线起新块,空行结束当前块,其余在换行处按 `targetChars` 断开。超过目标长度的单行保留为一个块,由分页读取再切片段,避免同一行被拆成互不相关的两段。各块按顺序拼回与原文逐字一致,保留全部空白与 CRLF;`number` 从 1 开始,`start`/`end` 是原文 UTF-16 偏移。`targetChars` 必须为正整数,空文本返回空数组。
90
+
91
+ Kit 不读写文件、不分页、不访问模型或存储;分页窗口、索引、摘要与提示词由 App 决定。块边界是结构边界,不与固定字符窗口对齐,需要覆盖范围时使用 `start`/`end`。
92
+
75
93
  ## TextSearch、VectorSearch、RRF、ModelCalls
76
94
 
77
95
  ```ts
@@ -43,7 +43,7 @@ interface AnswerTaskDefinition<Input, Metadata> {
43
43
  readonly id: string;
44
44
  readonly description: string;
45
45
  readonly inputSchema: SchemaAdapter<Input>;
46
- readonly intentIds: readonly string[];
46
+ readonly goalIds: readonly string[];
47
47
  readonly scopeId?: string;
48
48
  readonly readerId: string;
49
49
  readonly outputId: string;
@@ -145,6 +145,9 @@ OutputResult is `{ outputId, kind, value }`. Group children use program-assigned
145
145
  | --- | --- |
146
146
  | defineTextTemplate(master, options) | Pure compilation; render(values) substitutes once synchronously; errors.missingField creates an error |
147
147
  | defineSemanticSlots(definition) | namespace, keys, maxOccurrences; isValid(text): boolean |
148
+ | defineReplyFormats({ formats, checks }) | Compiles template-bound reply formats; resolve(context) returns an inspected format only on a match and undefined otherwise |
149
+ | replyFormatChecks.bubbles(totalLimit) / textBudget(maxChars) | Shared bubble count, blank-bubble and text-length checks; the app declares the limits |
150
+ | mergeReplyBubbles(bubbles, limit) | Program normalization for replies without a template: drops blank bubbles and merges overflow into the last one |
148
151
  | replyBubbleTexts(input) | Keeps the existing plain-text/bubble extraction responsibility and returns readonly string[]; count and length limits are enforced by the registered output contract |
149
152
  | publishReplyEvents({ text, delivery }, context) | Returns AsyncIterable<AgentOutputEvent>, preserving backpressure and cancellation as consumers pull; pacing continues to use *Ms |
150
153
  | serializeOutputEvents(events) / textOutputEvents(chunks) | Preserves explicit conversion between events and text streams and is not an invoke return mode |
@@ -43,7 +43,7 @@ interface AnswerTaskDefinition<Input, Metadata> {
43
43
  readonly id: string;
44
44
  readonly description: string;
45
45
  readonly inputSchema: SchemaAdapter<Input>;
46
- readonly intentIds: readonly string[];
46
+ readonly goalIds: readonly string[];
47
47
  readonly scopeId?: string;
48
48
  readonly readerId: string;
49
49
  readonly outputId: string;
@@ -145,6 +145,9 @@ OutputResult为`{ outputId, kind, value }`。group子项使用程序分配的id
145
145
  | --- | --- |
146
146
  | defineTextTemplate(master, options) | 纯编译;render(values)同步替换一次;errors.missingField创建错误 |
147
147
  | defineSemanticSlots(definition) | namespace、keys、maxOccurrences;isValid(text): boolean |
148
+ | defineReplyFormats({ formats, checks }) | 编译模板绑定的回复格式;resolve(context)仅命中时返回带inspect的格式,其余返回undefined |
149
+ | replyFormatChecks.bubbles(totalLimit) / textBudget(maxChars) | 通用气泡数量、空白气泡与正文长度检查,限额由应用声明 |
150
+ | mergeReplyBubbles(bubbles, limit) | 无模板回复的程序归一:丢弃空白气泡并把超出部分并入最后一条 |
148
151
  | replyBubbleTexts(input) | 保留现有纯文本/气泡提取职责,返回readonly string[];数量与长度限制由已登记输出合同执行 |
149
152
  | publishReplyEvents({ text, delivery }, context) | 返回AsyncIterable<AgentOutputEvent>,保留消费者拉取时的背压及取消;pacing继续使用*Ms |
150
153
  | serializeOutputEvents(events) / textOutputEvents(chunks) | 保留事件与文本流的显式转换,不作为invoke返回模式 |
@@ -2,6 +2,8 @@
2
2
 
3
3
  MockGPT simulates model replies with fixed data, functions and lightweight text algorithms, and is suited to debugging protocols, tool selection, streaming output, failure and cancellation. It does not perform real LLM inference. Ordinary rules do not use the network; the web source is an explicit optional network capability.
4
4
 
5
+ Install `@jangts/mock-gpt` before using the `/mock`, `/mock/node` or `/mock/web` entries; it is an optional peer dependency and is not installed with this package.
6
+
5
7
  ## Entry points and public exports
6
8
 
7
9
  | Entry | Runtime exports | Type exports |
@@ -2,6 +2,8 @@
2
2
 
3
3
  MockGPT 用固定数据、函数及轻量文本算法模拟模型回复,适合调试协议、工具选择、流式输出、失败与取消。它不执行真实 LLM 推理。普通规则不联网;网页来源是显式的可选网络能力。
4
4
 
5
+ 使用 `/mock`、`/mock/node`、`/mock/web` 前需安装 `@jangts/mock-gpt`;它是可选 peer 依赖,不会随本包自动安装。
6
+
5
7
  ## 入口与公开导出
6
8
 
7
9
  | 入口 | 运行时导出 | 类型导出 |
@@ -83,13 +83,13 @@ await agent.run(state);
83
83
  | execution.observe.event | Loop/Workflow, model.start/end, tool start/end and permitted dynamic reports | Side channel; a synchronous throw, async rejection or hang does not change execution; still effective when persistent logging is closed |
84
84
  | execution.diagnostics → CoreLogOutput.write | Optional persistent projection of the same fact | The App decides fields, body, storage and retention; it gains no content authorization from other listeners |
85
85
  | ModelRunner.sink.output | model.start/output/parsed of the same outer layer, plus model.end on success, failure or cancellation | Body waits in order, propagates failures and preserves backpressure; the end notification is limited to 250 milliseconds independently, and its failure does not override the result or the original exception |
86
- | context.report({ usedModel, payload, subs }) | Immediate report during the current node's run | usedModel is optional boolean metadata, payload/subs are read only when content is permitted; Core fills in identity, time and sequence, and reports after the node ends or is cancelled are dropped |
87
- | node report(update, context) | usedModel/payload/subs on completion/transition | Evaluated only when content is permitted; does not replace immediate reports during the run |
86
+ | context.report({ usedModel, payload }) | Immediate report during the current node's run | usedModel is optional boolean metadata, payload are read only when content is permitted; Core fills in identity, time and sequence, and reports after the node ends or is cancelled are dropped |
87
+ | node report(update, context) | usedModel/payload on completion/transition | Evaluated only when content is permitted; does not replace immediate reports during the run |
88
88
  | context.createSubFlowLogger() | Sub-log instance bound to this execution | write records first, fix completes later, readAll obtains a fixed-format snapshot; reuses the existing node.progress outlet |
89
89
 
90
90
  Listeners can filter by metadata such as event, nodeId and workflowNodeId. workflowNodeId keeps the owning Workflow node, while model/tool boundaries still have their own nodeId and invocationId. Repeated visits to the same node have different spans, and concurrent runs do not correlate through lastCall or a shared "current request". `withObserver` can be called on an existing request scope to add a listener, inherited along sub-scopes; this is immutable wiring and leaves the original scope unaffected. Canonical methods are bound to their original receivers at assembly time. When a reusable Engine has no request scope configured, each run is assigned an independent identity.
91
91
 
92
- Listeners without accepts receive metadata only. Content events, payload and subs are collected only after the corresponding consumer explicitly accepts them; other metadata consumers do not gain the body as a side effect. Each consumer receives an independent copy. The result snapshot is isolated from the actual return value, so preview edits do not rewrite the final value; model results must still satisfy the existing Journal snapshot contract.
92
+ Listeners without accepts receive metadata only. Content events, payload and sub-log content are collected only after the corresponding consumer explicitly accepts them; other metadata consumers do not gain the body as a side effect. Each consumer receives an independent copy. The result snapshot is isolated from the actual return value, so preview edits do not rewrite the final value; model results must still satisfy the existing Journal snapshot contract.
93
93
 
94
94
  ModelPart does not provide separate reasoning content chunks. State, process notes explicitly provided by the model, tool facts, transient previews and the final answer each keep their own meaning; internal hidden reasoning or the raw protocol must not be treated as a user reply. Selection, compression and assembly can be registered as ordinary nodes separately and use real lifecycle facts; algorithmic reports are delivered as permitted node.progress.
95
95
 
@@ -97,7 +97,7 @@ Adding a listener only changes assembly configuration; the original Workflow, ru
97
97
 
98
98
  ## Sub-log instances and record-first-then-complete
99
99
 
100
- Workflow nodes, simple run(step), ToolRegistry/Support tools and the execution context of executeInvocation all provide `createSubFlowLogger()` and `report()`. Each node visit or call has one instance, and repeated create returns the same instance; no global logger is shared. subs accepts only SubFlowLogger instances belonging to that execution; plain objects, objects imitating readAll, hand-written arrays and readAll() snapshots are rejected; invalid material does not become a main execution fact. The normalized stored field subSteps is still an array, so reading historical data does not require re-creating a logger.
100
+ Workflow nodes, simple run(step), ToolRegistry/Support tools and the execution context of executeInvocation all provide `createSubFlowLogger()` and `report()`. Each node visit or call has one instance, and repeated create returns the same instance; no global logger is shared. The factory is already bound to the execution context; no context argument is required. Identity inherits the App diagnostic scope and identifies the Engine definition, run and node visit without retaining App service objects. The Loop owns the lifecycle: each accepted write/fix immediately commits an immutable snapshot to runtime before publishing node.progress to observers and the log outlet. Nodes never submit a logger or readAll() result. Terminal events use the committed runtime snapshot without reading the logger. Node completion detaches writes and releases the runtime reference; failure and cancellation preserve prior records. A later visit gets a new instance. readAll() remains readable by any holder and emits nothing. Nodes, Apps and external code may retain or lend the instance; Core does not prescribe its use. A later visit receives a new logger and may consult the previous flow through a retained old instance. Apps apply each appended fix to the original write view using operation/targetStepId and order revisions with revision. Stored subSteps remain fixed-format arrays.
101
101
 
102
102
  ```ts
103
103
  async run(state, context) {
@@ -116,23 +116,49 @@ async run(state, context) {
116
116
  if (!context.signal.aborted) subs.fix(id, { status: 'error' });
117
117
  throw error;
118
118
  }
119
- context.report({ usedModel: false, subs });
119
+ context.report({ usedModel: false });
120
120
  }
121
121
  ```
122
122
 
123
123
  | Method | Fixed contract |
124
124
  | --- | --- |
125
- | write(input): string | name and kind are required, status defaults to planned; stepId, sequence, createdAtMs and initial revision=1 are allocated automatically. Optional parentStepId, relatedDefinitionId, caseId, nextStepIds, status, time, summary, payload and usedModel. startedAtMs is recorded automatically only when running is reported explicitly, so planned time does not pass for an actual start. |
126
- | fix(stepId, patch): void | Completes status, model usage, pending times, summary, successors or payload fields for a record in the same instance; a terminal state cannot be reopened, but missing result fields can still be filled while execution is active. Keeps the ID, first order and original times, incrementing revision each time. payload merges missing keys recursively and existing facts cannot be overwritten; a given summary, time or successor cannot be rewritten. |
127
- | readAll(): readonly RecordedSubStep[] | Returns an immutable snapshot in first-write order; later fix calls do not change an earlier snapshot. With no steps it is [], and the snapshot remains readable after the execution is closed. |
125
+ | write(input): string \| -1 | name and kind are required, status defaults to planned; stepId, sequence, createdAtMs and initial revision=1 are allocated automatically. Optional parentStepId, relatedDefinitionId, caseId, nextStepIds, status, time, summary, payload and usedModel. startedAtMs is recorded automatically only when running is reported explicitly, so planned time does not pass for an actual start. |
126
+ | fix(stepId: string \| -1, patch): boolean | Completes status, model usage, pending times, summary, successors or payload fields for a record in the same instance; a terminal state cannot be reopened, but missing result fields can still be filled while execution is active. Every successful fix appends an independent record with operation=fix, a new stepId, sequence and createdAtMs. targetStepId references the original write and revision increases for that original. Each fix carries the resulting state without changing any earlier row. payload merges missing keys recursively and existing facts cannot be overwritten; a given summary, time or successor cannot be rewritten. |
127
+ | readAll(): readonly RecordedSubStep[] | Returns all write/fix records in append order; repeated fixes create separate rows and never mutate earlier rows or snapshots. With no steps it is [], and the snapshot remains readable after the execution is closed. |
128
128
 
129
- The fixed record fields are origin=reported, stepId, sequence, name, kind, status, createdAtMs and revision, plus the optional fields above. planned/unknown can advance to an actual status, while running cannot go back to planned or skipped; success/error/cancelled/skipped are terminal, the status and established facts cannot be rewritten, but pending result fields can still be filled while the owning node is active. Statuses and legal transitions come from the same reportedStepStatusCatalog. A retry writes another record and does not reopen a terminal state. The parent and successors must belong to the same logger; when the successor ID is not yet available, nextStepIds can be completed in one later fix. Pending payload fields are omitted first and are not represented by null or an empty array as an overwritable placeholder. By default at most 256 records, 65536 JSON characters for the full snapshot and 1024 write/fix calls; payload accepts only bounded-depth JSON data and does not accept functions, service instances, circular references or internal getters.
129
+ Records have origin=reported, operation=write/fix, unique stepId, append sequence, name, kind, status, createdAtMs and revision. Fix records reference the original write with targetStepId; fixing a fix ID is rejected. Historical projected snapshots may omit operation. planned/unknown can advance to an actual status, while running cannot go back to planned or skipped; success/error/cancelled/skipped are terminal, the status and established facts cannot be rewritten, but pending result fields can still be filled while the owning node is active. Statuses and legal transitions come from the same reportedStepStatusCatalog. A retry writes another record and does not reopen a terminal state. The parent and successors must belong to the same logger; when the successor ID is not yet available, nextStepIds can be completed in one later fix. Pending payload fields are omitted first and are not represented by null or an empty array as an overwritable placeholder. By default at most 256 original writes, 1024 total write/fix records and 65536 JSON characters for the complete ledger; payload accepts only bounded-depth JSON data and does not accept functions, service instances, circular references or internal getters.
130
130
 
131
- write and fix emit the initial/completion event through the existing node.progress at that moment, with payload.subStep holding operation, stepId, sequence, revision, createdAtMs, status and optional usedModel metadata. When content is permitted, the event carries the fixed-format subSteps snapshot at that point; node end/failure events also carry the last snapshot. The log appends revisions, and events already emitted are not updated in place. Results returning out of order do not change the initial order, and replay can distinguish "only a plan at the time" from "a result later". When only a plan or start was received without a result, the original status is kept; success, failure or an actual model call cannot be inferred.
131
+ write and fix emit the initial/completion event through the existing node.progress at that moment, with payload.subStep holding operation, current record stepId, targetStepId for fixes, sequence, revision, createdAtMs, status and optional usedModel metadata. When content is permitted, the event carries the fixed-format subSteps snapshot at that point; node end/failure events also carry the last snapshot. The log appends revisions, and events already emitted are not updated in place. Results returning out of order do not change the initial order, and replay can distinguish "only a plan at the time" from "a result later". When only a plan or start was received without a result, the original status is kept; success, failure or an actual model call cannot be inferred.
132
132
 
133
133
  The main node reports through context.report({ usedModel: true | false }) whether it used the model this time, and the outer usedModel in the log is kept as metadata; sub-steps report their own usedModel through write/fix. Unreported stays unknown and does not default to false; a reported true cannot change back to false. A child's true is not automatically aggregated into the main node's original marker. This is a node report: a field of true does not fabricate model.start/end or call counts, and model internal hidden reasoning is not collected. The end report(update, context) is still evaluated only when content collection is permitted; markers that must be kept in metadata mode should be submitted during the run with context.report.
134
134
 
135
- Content permission continues to be decided per event and per consumer. Without content authorization, payload/summary getters are not read, nor are the private payload/subs getters in reports; only permitted status, revision and boolean metadata are kept. The instance closes when execution ends or is cancelled, and write/fix reject late modifications. Log shutdown, outlet failure or a process crash still follow the original failure isolation and incomplete mechanism; recording intent first does not constitute a transactional audit guarantee.
135
+ Content permission continues to be decided per event and per consumer. Without content authorization, payload/summary getters are not read, nor are the private payload getters in reports; only permitted status, revision and boolean metadata are kept. The instance closes when execution ends or is cancelled, and write returns numeric -1 and fix returns false without throwing, inspecting arguments, recording or emitting. readAll remains readable. fix returns true on success; invalid IDs, invalid input, forbidden revisions and detachment all return false without throwing, changing the record or emitting a revision. write returns the new ID on success and -1 on any failure, including invalid input, limits and detachment, without throwing, recording or emitting. Log shutdown, outlet failure or a process crash still follow the original failure isolation and incomplete mechanism; recording intent first does not constitute a transactional audit guarantee.
136
+
137
+ ## Subnode grouping and restricted delegation
138
+
139
+ subnodeId groups multiple records within one node visit. It is independent of stepId, which identifies a log record. A group can contain multiple writes and multiple fixes per write; ungrouped logs belong to the parent node. Grouping does not imply dispatch, contiguous phases, scheduling or dependencies.
140
+
141
+ SubFlowLogger and ScopedSubFlowLogger are independent, non-inheriting classes implementing SubFlowLog. The full class owns storage/lifecycle, accepts subnodeId directly on write, and may fork(subnodeId). A scoped instance holds only the original logger and bound ID: write adds the ID, fix checks original-record ownership and delegates. It cannot override its group, fork or be supplied to native invoke. Both readAll methods return the same complete immutable ledger, including other groups.
142
+
143
+ Business type is an arbitrary string; operation is the separate write/fix enum. type and the compatible kind classification fill each other's omitted default. Fix uses the explicit SubFlowStepFix whitelist (status, usedModel, times, summary, nextStepIds, payload), not Partial of the write input. Identity, group, business type and label cannot be revised. A rejected fix returns false; rejected writes return -1. Safe console warnings explain fixed reasons, deduplicated per logger, without payloads or arbitrary error text; console failures do not change results.
144
+
145
+ Registered subnode IDs are local to one node visit: kind:encodedDefinitionId:ordinal, for example tool:product.references:1. Definition IDs are URL-encoded. The owning logger allocates ordinals per kind/definition at call start; failure and cancellation never reuse them, and a new node visit starts from 1. Parent identity stays in its existing fields. relatedInvocationId separately retains the real call identity for correlation with model/tool events; a short ordinal never replaces invocationId. App-owned custom groups need no business enum. Direct write({subnodeId, type, name}) and fork(subnodeId).write({type, name}) are equivalent grouping choices. fork validates its ID and native invoke rejects scoped/forged logger inputs at the boundary.
146
+
147
+ ## Optional native call records
148
+
149
+ logger is a per-call choice. Omission creates no native sub-log; passing it produces a fixed write followed by a separate fix on success, error or cancellation. Components do not create owning logger storage or implicitly forward full logging authority. Tools expose a scoped delegate bound by Core to the actual invocation. It may be lent to business helpers but cannot fork or be passed to another invoke. Business steps remain App-owned.
150
+
151
+ | Entry | Explicit logger location |
152
+ | --- | --- |
153
+ | ModelRunner / Workflow model.invoke; ToolRegistry / Support tool invocation | request.logger |
154
+ | executeInvocation / Tools lifecycle | ports.logger(context) |
155
+ | Retrieval.run; Answering task.read/readAsync, checks.check, flow.run; output.compose | context.logger |
156
+ | Knowledge.read; recovery chain tryRecover | Optional second context argument |
157
+ | Support.processContext / context node run | ports.logger / explicitly supplied context.logger |
158
+ | retryMultipleModelCalls | request.logger; records only an actual fallback attempt |
159
+ | Delivery.deliver; Aggregation.collect | execution.logger; optional third execution argument respectively |
160
+
161
+ Fixed records contain producer/definition identity and execution status, never automatic copies of prompts, results, tool arguments or customer material. A checker returning a rejection or a recovery returning unhandled still completed normally; callers choose whether to record the business result. Existing Core events and receipts remain unchanged. Pure configuration, lookup and formatting functions do not record.
136
162
 
137
163
  ## File adaptation and relational table mapping
138
164
 
@@ -83,13 +83,13 @@ await agent.run(state);
83
83
  | execution.observe.event | Loop/Workflow、model.start/end、工具开始/结束及获准的动态报告 | 旁路;同步抛错、异步拒绝或悬挂不改变执行;关闭持久日志仍有效 |
84
84
  | execution.diagnostics → CoreLogOutput.write | 同一事实的可选持久投影 | App 决定字段、正文、存储和保留期;不获得其他监听器的内容授权 |
85
85
  | ModelRunner.sink.output | 同一外层的 model.start/output/parsed,以及成功、失败或取消时 model.end | 正文按序等待、传播失败、保留背压;结束通知独立限时250毫秒,其失败不覆盖结果或原始异常 |
86
- | context.report({ usedModel, payload, subs }) | 当前节点运行中的即时报告 | usedModel 为可选布尔元数据,payload/subs 仅内容获准才读取;Core 补齐身份、时间和序号,节点结束或取消后的报告丢弃 |
87
- | 节点 report(update, context) | 完成/跳转时的 usedModel/payload/subs | 内容获准才求值,不替代运行中的即时报告 |
86
+ | context.report({ usedModel, payload }) | 当前节点运行中的即时报告 | usedModel 为可选布尔元数据,payload 仅内容获准才读取;Core 补齐身份、时间和序号,节点结束或取消后的报告丢弃 |
87
+ | 节点 report(update, context) | 完成/跳转时的 usedModel/payload | 内容获准才求值,不替代运行中的即时报告 |
88
88
  | context.createSubFlowLogger() | 绑定本次执行的子日志实例 | write 先留记录,fix 随后补全,readAll 取得固定格式快照;复用既有 node.progress 出口 |
89
89
 
90
90
  监听器可用 event、nodeId、workflowNodeId 等元数据过滤。workflowNodeId 保留所属 Workflow 节点,模型/工具边界自身仍有 nodeId 和 invocationId。重复访问同一节点有不同 span,并发运行不借助 lastCall 或共享“当前请求”关联。可在已有请求作用域上调用 `withObserver` 增加监听,沿子作用域继承;这是不可变的接线,原作用域不受影响。规范方法在装配时绑定原接收者。可复用 Engine 未配置请求作用域时,每次 run 分配独立身份。
91
91
 
92
- 无 accepts 的监听器仅接元数据。内容事件、payload 和 subs 只在对应消费者明确接纳后采集;其他元数据消费者不会连带获得正文。消费者拿到独立副本。结果快照与实际返回值隔离,不因预览修改而改写最终值;模型结果仍须符合既有 Journal 快照合同。
92
+ 无 accepts 的监听器仅接元数据。内容事件、payload 和子日志正文 只在对应消费者明确接纳后采集;其他元数据消费者不会连带获得正文。消费者拿到独立副本。结果快照与实际返回值隔离,不因预览修改而改写最终值;模型结果仍须符合既有 Journal 快照合同。
93
93
 
94
94
  ModelPart 不提供独立推理内容分片。状态、模型明确提供的过程说明、工具事实、暂态预览和最终答案各自保持含义,不能把内部隐藏推理或原始协议当用户回复。选择、压缩与装配可分别注册普通节点,使用真实生命周期事实;算法报告按获准的 node.progress 交付。
95
95
 
@@ -97,7 +97,7 @@ ModelPart 不提供独立推理内容分片。状态、模型明确提供的过
97
97
 
98
98
  ## 子日志实例与先记后补
99
99
 
100
- Workflow 节点、简易 run(step)、ToolRegistry/Support 工具及 executeInvocation 的执行 context 均提供 `createSubFlowLogger()` 和 `report()`。每次节点访问或调用各有一个实例,多次 create 返回同一实例;不共用全局 logger。subs 只接受所属执行的 SubFlowLogger 实例,普通对象、仿造 readAll 的对象、手写数组和 readAll() 快照均会拒收;非法材料不成为主执行事实。规范化后的存储字段 subSteps 仍为数组,读取历史数据不需要重新创建 logger。
100
+ Workflow 节点、简易 run(step)、ToolRegistry/Support 工具及 executeInvocation 的执行 context 均提供 `createSubFlowLogger()` 和 `report()`。每次节点访问或调用各有一个实例,多次 create 返回同一实例;不共用全局 logger。创建入口已绑定执行 context,无需再次传参;身份沿 App 装配的诊断作用域继承,自动关联当前 Engine 定义、run 与 node 访问,不保存 App 服务对象。Loop 接管生命周期,write/fix 接受后立即把不可变快照交给 runtime,再通过 node.progress 通知 App 与日志出口。节点不提交 logger 或 readAll() 的结果;终态事件使用 runtime 已接收的快照,不回读 logger。节点结束时解绑写入并释放 runtime 的实例引用,失败与取消保留此前记录;再次访问同一节点创建独立实例。readAll() 向任何持有者提供持续只读查询,不产生事件或提交。实例可由节点、App 或外部代码保留并借用,Core 不限制用途;后续节点访问获得新实例,旧实例可用于读取上次 flow。App 按 operation 与 targetStepId 将追加的 fix 应用到原 write 对应的界面视图,按 revision 判断修订顺序。存储字段 subSteps 为固定格式数组。
101
101
 
102
102
  ```ts
103
103
  async run(state, context) {
@@ -116,23 +116,76 @@ async run(state, context) {
116
116
  if (!context.signal.aborted) subs.fix(id, { status: 'error' });
117
117
  throw error;
118
118
  }
119
- context.report({ usedModel: false, subs });
119
+ context.report({ usedModel: false });
120
120
  }
121
121
  ```
122
122
 
123
123
  | 方法 | 固定合同 |
124
124
  | --- | --- |
125
- | write(input): string | name、kind 必填,status 默认 planned;自动分配 stepId、sequence、createdAtMs 和初始 revision=1。可选 parentStepId、relatedDefinitionId、caseId、nextStepIds、状态、时间、摘要、payload 和 usedModel。只有明确报告 running 才自动记 startedAtMs,计划时间不冒充实际开始。 |
126
- | fix(stepId, patch): void | 给同一实例内的记录补状态、模型使用、待定时间、摘要、后继或 payload 字段;终态不能重开,但执行仍活跃时可补缺失的结果字段。保留 ID、首次顺序和原时间,每次增加 revision。payload 递归补缺失键,已有事实不能覆盖;已给定的摘要、时间和后继不能改写。 |
127
- | readAll(): readonly RecordedSubStep[] | 按首次 write 顺序返回不可变快照;之后的 fix 不改变先前快照。没有步骤为 [],执行关闭后仍可读快照。 |
125
+ | write(input): string \| -1 | name 必填,type 为自定义业务类型;兼容的 kind 分类与 type 至少提供一项,缺省时互为补足,status 默认 planned;自动分配 stepId、sequence、createdAtMs 和初始 revision=1。可选 parentStepId、relatedDefinitionId、caseId、nextStepIds、状态、时间、摘要、payload 和 usedModel。只有明确报告 running 才自动记 startedAtMs,计划时间不冒充实际开始。 |
126
+ | fix(stepId: string \| -1, patch): boolean | 给同一实例内的记录补状态、模型使用、待定时间、摘要、后继或 payload 字段;终态不能重开,但执行仍活跃时可补缺失的结果字段。每次成功均追加独立记录,operation=fix,分配新 stepId、sequence、createdAtMs;targetStepId 指向原 write 的 ID,revision 按该原记录递增。记录携带本次修订后的完整状态,不修改原 write 或先前 fix。payload 递归补缺失键,已有事实不能覆盖;已给定的摘要、时间和后继不能改写。 |
127
+ | readAll(): readonly RecordedSubStep[] | 按实际追加顺序返回全部 write/fix 记录;多次 fix 对应多条记录,旧行和旧快照保持不变。没有步骤为 [],执行关闭后仍可读快照。 |
128
128
 
129
- 记录的固定字段为 origin=reported、stepId、sequence、name、kind、status、createdAtMs、revision,及上述可选字段。planned/unknown 可推进到实际状态,running 不能退回计划或 skipped;success/error/cancelled/skipped 为终态,状态和已确定的事实不能改写,但所属节点仍活跃时可以继续填入等待中的结果字段。状态及合法推进关系来自同一 reportedStepStatusCatalog。重试另 write 一条,不重开终态。父、后继必须属于同一 logger;尚未取得后继 ID 时可在后续 fix 中一次补齐 nextStepIds。待填 payload 字段先省略,不以 null 或空数组冒充可覆盖的占位。默认最多256条、全部快照65536个JSON字符、1024次 write/fix;payload 只收有限深度的 JSON 数据,不接受函数、服务实例、循环引用或内部 getter。
129
+ 记录的固定字段为 origin=reported、operation=write/fix、唯一 stepId、追加序号 sequence、name、kind、status、createdAtMs、revision;fix 另有 targetStepId,始终关联原 write,不能以 fix 记录的 ID 再修订。历史投影快照可缺省 operation。planned/unknown 可推进到实际状态,running 不能退回计划或 skipped;success/error/cancelled/skipped 为终态,状态和已确定的事实不能改写,但所属节点仍活跃时可以继续填入等待中的结果字段。状态及合法推进关系来自同一 reportedStepStatusCatalog。重试另 write 一条,不重开终态。父、后继必须属于同一 logger;尚未取得后继 ID 时可在后续 fix 中一次补齐 nextStepIds。待填 payload 字段先省略,不以 null 或空数组冒充可覆盖的占位。默认最多256条原始 write、总计1024条 write/fix 记录、全部序列65536个JSON字符;payload 只收有限深度的 JSON 数据,不接受函数、服务实例、循环引用或内部 getter。
130
130
 
131
- write 和 fix 当时就经既有 node.progress 发射初始/补全事件,payload.subStep 保存 operation、stepId、sequence、revision、createdAtMs、status 和可选 usedModel 元数据。内容获准时,事件附带该时点的固定格式 subSteps 快照;节点结束/失败事件也附带最后快照。日志追加修订,已经输出的事件不原地更新。结果乱序返回不改变初始顺序,回放可区分“当时只有计划”和“后来有了结果”。只收到计划或开始而没有结果时保持原状态;不能推断已经成功、失败或实际调用了模型。
131
+ write 和 fix 当时就经既有 node.progress 发射初始/补全事件,payload.subStep 保存 operation、当前记录 stepId、fix 的 targetStepId、sequence、revision、createdAtMs、status 和可选 usedModel 元数据。内容获准时,事件附带该时点的固定格式 subSteps 快照;节点结束/失败事件也附带最后快照。日志追加修订,已经输出的事件不原地更新。原始 write 不因乱序结果而重新排序;fix 按实际接收顺序追加,回放可区分“当时只有计划”和“后来有了结果”。只收到计划或开始而没有结果时保持原状态;不能推断已经成功、失败或实际调用了模型。
132
132
 
133
133
  主节点通过 context.report({ usedModel: true | false }) 上报本次自身是否使用模型,日志外层 usedModel 作为元数据保留;子步骤通过 write/fix 上报自身的 usedModel。未上报保持未知,不默认 false;已报告 true 不能改回 false。子节点的 true 不自动汇总进主节点原始标记。此为节点报告,不因字段为 true 而补造 model.start/end 或调用次数,也不采集模型内部隐藏推理。结束 report(update, context) 仍仅在内容采集获准时求值,需在元数据模式保留的标记应在运行中用 context.report 提交。
134
134
 
135
- 内容权限继续按事件和消费者分别判断。未获内容授权时不读取 payload/summary getter,也不读取报告中的私有 payload/subs getter;只保留已获准的状态、修订和布尔元数据。执行结束或取消后实例关闭,write/fix 拒绝迟到修改。日志关闭、出口失败或进程崩溃仍遵守原失败隔离及 incomplete 机制,先记意图不构成事务审计保证。
135
+ 内容权限继续按事件和消费者分别判断。未获内容授权时不读取 payload/summary getter,也不读取报告中的私有 payload getter;只保留已获准的状态、修订和布尔元数据。执行结束或取消后实例关闭,write 固定返回数字 -1,fix 返回 false,不报错、不校验或读取入参、不入账或发事件;readAll 持续可读。fix 成功返回 true;无效 ID、非法输入、禁止的修订及解绑等失败统一返回 false,不抛错、不改变原记录或产生修订事件。write 成功返回新 ID,非法输入、容量限制、解绑等任何失败统一返回 -1,不抛错、不入账或发事件。日志关闭、出口失败或进程崩溃仍遵守原失败隔离及 incomplete 机制,先记意图不构成事务审计保证。
136
+
137
+ ## 子节点归集与受限委托
138
+
139
+ `subnodeId` 是同次 node 执行内的逻辑归集身份,不是某条日志的 ID。一个子节点可以拥有多条 write,以及每条 write 的多次 fix;未指定 subnodeId 的记录直接归父 node。它不规定分发、连续分段、执行顺序或依赖关系。App 按实际职责组织自定义子节点,无需为了日志增加调度节点。
140
+
141
+ - `SubFlowLogger` 是完整类,独占记录存储与生命周期。write 可直接填写任意非空字符串 subnodeId,无业务枚举;也可通过 fork(subnodeId) 创建另一个实例。
142
+ - `ScopedSubFlowLogger` 是独立且不继承完整类的委托类,只持有原 logger 与绑定 ID,不保存记录。write 自动补归属并拒绝覆盖;fix 只能修订该子节点的原记录,越界返回 false。没有 fork,不能作为原生 invoke 的 logger。
143
+ - 两类实现共同读写接口 `SubFlowLog`;它们的 readAll 返回同一份全量不可变记录,包括其他分组。读权限不会扩大受限实例的写权限。
144
+ - fix 使用独立 `SubFlowStepFix`,不是 Partial<write参数>。只接受 status、usedModel、startedAtMs、endedAtMs、summary、nextStepIds、payload,仍受状态推进和已有事实保护。不能改变 subnodeId、type、kind、name、stepId 或其他身份字段。
145
+ - type 是可自定义的业务日志类型,operation 才是 write/fix。fix 继承原记录的业务类型和归属;每次成功都追加独立记录。
146
+
147
+ ```ts
148
+ const logger = context.createSubFlowLogger();
149
+ // 可直接指定分组,fork 不是必需步骤。
150
+ logger.write({ subnodeId: 'prepare', type: 'source.read', name: '读取资料' });
151
+ const logs: SubFlowLog = logger.fork('prepare');
152
+ prepareMaterials(logs); // 子函数只需要公共读写接口。
153
+ await context.tools.invoke({ toolId: 'read', input: {}, logger });
154
+ // Core 传给真实工具的 execution.logger 是 ScopedSubFlowLogger。
155
+ ```
156
+
157
+ 注册子节点 ID 只在本次 node 执行内唯一,格式为 kind:encodedDefinitionId:ordinal,例如 tool:product.references:1。定义 ID 使用 URL 编码,计数按能力种类与定义 ID 分开,在调用开始时分配;失败、取消不复用,下一次 node 访问从1开始。父级访问身份已有独立字段,不重复拼入子节点 ID。真实调用身份单独保存在 relatedInvocationId,用于对应模型/工具主事件,不以短序号代替 invocationId。重复/并发调用分别归集,同次调用的多条日志保持相同 subnodeId。自定义子节点由 node 自行命名,两种归集都没有业务枚举约束。
158
+
159
+ fix 的失败统一返回 false,write 的失败统一返回 -1;调试控制台使用固定原因输出 warn,同一 logger 同类原因去重,不包含入参、正文或任意错误文本。控制台自身异常不改变返回值。fork 对无效 ID 的参数检查与 invoke 对非完整 logger 的边界检查仍保留。
160
+
161
+ ## 原生调用的可选记录
162
+
163
+ logger 是调用级参数,不是全局开关。未传入时不产生原生子日志,开发者可以自行组织全部记录;显式传入时原生组件统一 write 一条运行记录,并在成功、失败或取消时 fix,形成两条独立记录。不自动创建完整 logger 存储或向所有下游传播完整 logger 权限,不改变它所属的 App、Engine、node 或生命周期。Tool handler 取得 Core 为本次调用绑定的 execution.logger,可把该受限委托交给内部业务函数;不能继续 fork 或传给另一次 invoke。
164
+
165
+ | 原生入口 | 显式传入位置 | 固定记录 |
166
+ | --- | --- | --- |
167
+ | ModelRunner.invoke/Workflow model.invoke | request.logger | Model call,关联阶段 ID |
168
+ | ToolRegistry.invoke/invokeAsync、Support 工具 | request.logger | Tool call,关联工具 ID |
169
+ | executeInvocation/Tools Kit 生命周期 | ports.logger(context) | Invocation,关联 handler ID |
170
+ | Retrieval.run | context.logger | Retrieval |
171
+ | Answering task.read/readAsync、checks.check、flow.run | context.logger | 证据读取、每个实际 checker、完整答复流程 |
172
+ | Knowledge.read | 可选第二参数的 logger | Read knowledge |
173
+ | Presentation outputs.compose | context.logger | Compose output |
174
+ | Support.processContext、上下文节点 run | ports.logger/显式提供的 context.logger | Process context |
175
+ | Support.retryMultipleModelCalls | request.logger | 只在实际降级重试时记录 Retry model proposal |
176
+ | Policies 恢复链 tryRecover | 可选第二参数的 logger | 每个实际尝试的恢复策略 |
177
+ | Delivery.deliver | execution.logger | Deliver result |
178
+ | Aggregation.collect | 可选第三参数的 logger | Aggregate queries |
179
+
180
+ 固定记录只描述执行边界,不自动复制模型输入输出、工具参数或客户材料。检查正常返回不通过、恢复正常返回未处理,都属于函数成功返回;业务结果由开发者按需补充。已有 Core 主事件继续提供原有调用事实;可选子日志用于节点内部编排展示,不替代主事件、回执或权限检查。纯配置、清单查询和格式化函数不追加日志。
181
+
182
+ ```ts
183
+ const logger = context.createSubFlowLogger();
184
+ await context.model.invoke({ input: '简要说明', logger });
185
+ await context.tools.invoke({ toolId: 'read', input: {}, logger });
186
+ // 此次调用未传 logger,不追加原生子日志。
187
+ await context.tools.invoke({ toolId: 'read', input: {} });
188
+ ```
136
189
 
137
190
  ## 文件适配与关系表映射
138
191