@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
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ModelCapabilityRegistry = exports.modelProtocolError = void 0;
3
+ exports.ModelToolRegistry = exports.modelProtocolError = void 0;
4
4
  /**
5
- * Declarative catalog of model capabilities for a request or one stage projection.
5
+ * Declarative catalog of model tools for a request or one stage projection.
6
6
  *
7
7
  * A capability pairs an id and description with an input schema and a synchronous resolver,
8
8
  * letting stage code parse model-supplied arguments and produce a typed value. Registration
@@ -12,15 +12,16 @@ exports.ModelCapabilityRegistry = exports.modelProtocolError = void 0;
12
12
  * The registry is mutable until `seal()`. `select()` derives a sealed subset for a stage and
13
13
  * shares the already-frozen entries rather than re-validating or re-wrapping them.
14
14
  *
15
- * Exports: `ModelCapabilityRegistry`, `modelProtocolError`, and the capability types.
15
+ * Exports: `ModelToolRegistry`, `modelProtocolError`, and the capability types.
16
16
  */
17
17
  const synchronous_js_1 = require("../utils/synchronous.js");
18
18
  const model_protocol_js_1 = require("../utils/model-protocol.js");
19
19
  const schema_adapter_js_1 = require("../utils/schema-adapter.js");
20
+ const tool_conditions_js_1 = require("./tool-conditions.js");
20
21
  var model_protocol_js_2 = require("../utils/model-protocol.js");
21
22
  Object.defineProperty(exports, "modelProtocolError", { enumerable: true, get: function () { return model_protocol_js_2.modelProtocolError; } });
22
23
  /** A request/stage projection is a sealed registry. Hosts filter availability before projection. */
23
- class ModelCapabilityRegistry {
24
+ class ModelToolRegistry {
24
25
  /** Insertion-ordered entries; iteration order is the declaration order of the catalog. */
25
26
  definitionsById = new Map();
26
27
  /** Sealing is one-way: stage-time code must never extend the catalog it is executing. */
@@ -51,13 +52,22 @@ class ModelCapabilityRegistry {
51
52
  if (!capability.id?.trim() ||
52
53
  !capability.description?.trim() ||
53
54
  schema?.type !== 'object' ||
54
- typeof capability.resolve !== 'function' ||
55
+ (capability.resolve !== undefined && typeof capability.resolve !== 'function') ||
56
+ (capability.active !== undefined &&
57
+ typeof capability.active !== 'function' &&
58
+ typeof capability.active !== 'boolean') ||
55
59
  this.definitionsById.has(capability.id))
56
60
  throw new TypeError('Invalid or duplicate model capability');
57
61
  // Clone and freeze the schema, and pin `parse`, so the stored entry is independent of
58
62
  // the definition object the host may keep mutating.
59
63
  const inputSchema = (0, schema_adapter_js_1.snapshotSchemaAdapter)(capability.inputSchema, 'Model input parsers must be synchronous');
60
- const resolver = capability.resolve.bind(capability);
64
+ const resolver = capability.resolve?.bind(capability) ?? ((value) => value);
65
+ const asIntent = (0, tool_conditions_js_1.bindIntent)((0, tool_conditions_js_1.snapshotIntent)(typeof capability.asIntent === 'function'
66
+ ? capability.asIntent.bind(capability)
67
+ : capability.asIntent), capability);
68
+ const active = typeof capability.active === 'function'
69
+ ? capability.active.bind(capability)
70
+ : capability.active;
61
71
  // Bind once here: a later caller cannot substitute its own receiver for the resolver.
62
72
  const resolve = (value, context) => (0, synchronous_js_1.synchronous)(resolver(value, context), 'Model capability resolvers must be synchronous');
63
73
  this.definitionsById.set(capability.id, Object.freeze({
@@ -65,6 +75,8 @@ class ModelCapabilityRegistry {
65
75
  description: capability.description,
66
76
  inputSchema,
67
77
  resolve,
78
+ ...(asIntent !== undefined ? { asIntent } : {}),
79
+ ...(active !== undefined ? { active } : {}),
68
80
  }));
69
81
  return this;
70
82
  }
@@ -81,7 +93,7 @@ class ModelCapabilityRegistry {
81
93
  return this.definitionsById.entries();
82
94
  }
83
95
  /**
84
- * Register several capabilities.
96
+ * Register several tools.
85
97
  *
86
98
  * @param definitions Declarations applied in iteration order.
87
99
  * @returns This registry, for chaining.
@@ -142,21 +154,53 @@ class ModelCapabilityRegistry {
142
154
  * @throws TypeError when the selection is empty or contains a duplicate id.
143
155
  * @throws Error when an id was never registered.
144
156
  */
145
- select(ids) {
157
+ select(ids, context) {
146
158
  if (!ids.length || new Set(ids).size !== ids.length)
147
159
  throw new TypeError('Invalid capability selection');
148
- const selected = new ModelCapabilityRegistry();
160
+ const selected = new ModelToolRegistry();
149
161
  for (const id of ids) {
150
162
  const capability = this.definitionsById.get(id);
151
163
  if (!capability)
152
164
  throw new Error(`Model capability is not registered: ${id}`);
165
+ if (arguments.length > 1) {
166
+ if (!(0, tool_conditions_js_1.toolActive)(capability.active, context))
167
+ continue;
168
+ }
169
+ else if (capability.active === false) {
170
+ // Boolean activation is evaluable without a host context; predicate activation still
171
+ // needs an explicit context projection.
172
+ continue;
173
+ }
153
174
  // Registration already detached/froze the schema and pinned its handlers.
154
175
  // Stage projections share those immutable entries, not another clone and
155
176
  // another layer of parser/resolver wrappers for every selection.
156
- selected.definitionsById.set(id, capability);
177
+ selected.definitionsById.set(id, arguments.length > 1 ? this.bound(capability, context) : capability);
157
178
  }
158
179
  return selected.seal();
159
180
  }
181
+ /** Discover active demand-facing tools without tying the projection to a workflow entry. */
182
+ withIntent(context) {
183
+ const selected = new ModelToolRegistry();
184
+ for (const tool of this.definitionsById.values()) {
185
+ if (!(0, tool_conditions_js_1.toolActive)(tool.active, context))
186
+ continue;
187
+ const description = (0, tool_conditions_js_1.intentDescription)(tool.asIntent, tool.description, context);
188
+ if (description !== undefined)
189
+ selected.definitionsById.set(tool.id, Object.freeze({ ...this.bound(tool, context), description }));
190
+ }
191
+ return selected.seal();
192
+ }
193
+ /** Pin the host context and recheck activation before accepting a model proposal. */
194
+ bound(tool, context) {
195
+ return Object.freeze({
196
+ ...tool,
197
+ resolve: (input, stage) => {
198
+ if (!(0, tool_conditions_js_1.toolActive)(tool.active, context))
199
+ (0, model_protocol_js_1.modelProtocolError)('Tool is inactive');
200
+ return tool.resolve(input, stage);
201
+ },
202
+ });
203
+ }
160
204
  /**
161
205
  * Parse model-supplied arguments and run the selected capability.
162
206
  *
@@ -171,11 +215,11 @@ class ModelCapabilityRegistry {
171
215
  const { stageId } = context;
172
216
  // Model output is untrusted: unknown ids and non-object arguments are protocol failures,
173
217
  // not ordinary `undefined` results.
174
- const capability = this.definitionsById.get(selection.capabilityId) ??
218
+ const capability = this.definitionsById.get(selection.toolId) ??
175
219
  (0, model_protocol_js_1.modelProtocolError)('Model capability is unavailable in this stage');
176
220
  if (!selection.input || typeof selection.input !== 'object' || Array.isArray(selection.input))
177
221
  (0, model_protocol_js_1.modelProtocolError)('Model capability input must be an object');
178
222
  return (0, synchronous_js_1.synchronous)(capability.resolve(capability.inputSchema.parse(selection.input), { stageId }), 'Model capability parsers must be synchronous');
179
223
  }
180
224
  }
181
- exports.ModelCapabilityRegistry = ModelCapabilityRegistry;
225
+ exports.ModelToolRegistry = ModelToolRegistry;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.snapshotIntent = snapshotIntent;
4
+ exports.bindIntent = bindIntent;
5
+ exports.toolActive = toolActive;
6
+ exports.intentDescription = intentDescription;
7
+ /** Tool metadata validation and synchronous activation shared by registration and execution. */
8
+ const synchronous_js_1 = require("../utils/synchronous.js");
9
+ /** Validate and snapshot discovery metadata without evaluating host predicates. */
10
+ function snapshotIntent(value) {
11
+ if (value === undefined || value === true || typeof value === 'function')
12
+ return value;
13
+ if (typeof value === 'string') {
14
+ if (!value.trim())
15
+ throw new TypeError('Intent description must not be blank');
16
+ return value;
17
+ }
18
+ if (!value || typeof value !== 'object' || Array.isArray(value))
19
+ throw new TypeError('Invalid asIntent metadata');
20
+ if (value.description !== undefined &&
21
+ (typeof value.description !== 'string' || !value.description.trim()))
22
+ throw new TypeError('Invalid intent description');
23
+ if (value.when !== undefined && typeof value.when !== 'function')
24
+ throw new TypeError('Invalid intent predicate');
25
+ const delegates = value.delegates;
26
+ if (delegates !== undefined &&
27
+ (!Array.isArray(delegates) ||
28
+ !delegates.length ||
29
+ delegates.some((id) => typeof id !== 'string' || !id.trim()) ||
30
+ new Set(delegates).size !== delegates.length))
31
+ throw new TypeError('Invalid intent delegates');
32
+ return Object.freeze({
33
+ description: value.description,
34
+ ...(value.when !== undefined ? { when: value.when } : {}),
35
+ ...(delegates ? { delegates: Object.freeze([...delegates]) } : {}),
36
+ });
37
+ }
38
+ /** Bind an optional object-form predicate to its owning Tool, without touching other forms. */
39
+ function bindIntent(value, owner) {
40
+ if (!value || typeof value !== 'object' || typeof value.when !== 'function')
41
+ return value;
42
+ return Object.freeze({ ...value, when: value.when.bind(owner) });
43
+ }
44
+ /** Check activation and reject asynchronous or nonboolean predicate results. */
45
+ function toolActive(condition, context) {
46
+ if (condition === undefined)
47
+ return true;
48
+ if (typeof condition === 'boolean')
49
+ return condition;
50
+ if (typeof condition !== 'function')
51
+ throw new TypeError('Invalid tool active condition');
52
+ return (0, synchronous_js_1.booleanResult)(condition(context), 'Tool predicates must be synchronous', 'Tool predicates must return boolean');
53
+ }
54
+ /** Resolve the demand-facing description only when discovery is enabled. */
55
+ function intentDescription(metadata, fallback, context) {
56
+ if (metadata === undefined)
57
+ return undefined;
58
+ if (typeof metadata === 'string')
59
+ return metadata;
60
+ if (metadata === true)
61
+ return fallback;
62
+ if (typeof metadata === 'function')
63
+ return toolActive(metadata, context) ? fallback : undefined;
64
+ return toolActive(metadata.when, context) ? (metadata.description ?? fallback) : undefined;
65
+ }
@@ -6,13 +6,14 @@ exports.createToolRegistry = createToolRegistry;
6
6
  *
7
7
  * A `ToolDefinition` is the App-facing declaration: a schema adapter plus authorize, execute
8
8
  * and parseOutput handlers. This module pins those handlers to their definition and adapts
9
- * them to the lower-level `ExecutableTool` contract, while keeping the synchronous and
9
+ * them to the lower-level `ErasedTool` contract, while keeping the synchronous and
10
10
  * asynchronous boundaries explicit: `invokeAsync` awaits authorization and execution,
11
11
  * `invoke` rejects a promise from either.
12
12
  *
13
13
  * Exports: `createToolRegistry`.
14
14
  */
15
15
  const synchronous_js_1 = require("../utils/synchronous.js");
16
+ const tool_conditions_js_1 = require("./tool-conditions.js");
16
17
  const tools_js_1 = require("./tools.js");
17
18
  /**
18
19
  * Run authorization and execution for one call, in that order.
@@ -21,16 +22,25 @@ const tools_js_1 = require("./tools.js");
21
22
  * violation instead of being silently ignored. Cancellation is checked before and after each
22
23
  * phase so an aborted request never produces a successful value.
23
24
  */
24
- function execute(definition, input, context, execution) {
25
+ function execute(definition, input, context, execution, unavailable) {
25
26
  const { signal, mode, diagnostics, report, createSubFlowLogger } = execution;
26
27
  signal.throwIfAborted();
28
+ if (!(0, tool_conditions_js_1.toolActive)(definition.active, context))
29
+ throw unavailable?.(definition.id) ?? new Error(`Tool is inactive: ${definition.id}`);
27
30
  // Re-check after the handler returned: work that completed during cancellation must not be
28
31
  // reported as a success.
29
32
  const complete = (value) => {
30
33
  signal.throwIfAborted();
31
34
  return value;
32
35
  };
33
- const operation = { app: context, signal, diagnostics, report, createSubFlowLogger };
36
+ const operation = {
37
+ app: context,
38
+ signal,
39
+ diagnostics,
40
+ logger: execution.logger,
41
+ report,
42
+ createSubFlowLogger,
43
+ };
34
44
  const authorized = (result) => {
35
45
  (0, synchronous_js_1.assertion)(result, 'Tool authorization must return void');
36
46
  signal.throwIfAborted();
@@ -61,6 +71,7 @@ function execute(definition, input, context, execution) {
61
71
  */
62
72
  function createToolRegistry(definitions, context, options) {
63
73
  const registry = new tools_js_1.ToolRegistry(options);
74
+ const unavailable = options.errors?.unavailable?.bind(options.errors);
64
75
  registry.registerAll(definitions.map((definition) => {
65
76
  // Every entry point pins the same canonical handlers, including callers
66
77
  // that use this creator directly rather than defineToolCatalog.
@@ -70,6 +81,9 @@ function createToolRegistry(definitions, context, options) {
70
81
  kind,
71
82
  description,
72
83
  inputSchema,
84
+ active: typeof definition.active === 'function'
85
+ ? definition.active.bind(definition)
86
+ : definition.active,
73
87
  authorize: authorize.bind(definition),
74
88
  execute: handle.bind(definition),
75
89
  parseOutput: parseOutput.bind(definition),
@@ -83,7 +97,7 @@ function createToolRegistry(definitions, context, options) {
83
97
  // definition cannot change what this registry validates.
84
98
  parseInput: inputSchema.parse.bind(inputSchema),
85
99
  parseOutput: bound.parseOutput,
86
- execute: (input, execution) => execute(bound, input, context, execution),
100
+ execute: (input, execution) => execute(bound, input, context, execution, unavailable),
87
101
  };
88
102
  }));
89
103
  registry.seal();
@@ -14,6 +14,7 @@ exports.executeInvocation = exports.ToolRegistry = void 0;
14
14
  *
15
15
  * Exports: `ToolRegistry`, `executeInvocation`, and the tool/invocation contracts.
16
16
  */
17
+ const native_sub_flow_js_1 = require("../diagnostics/native-sub-flow.js");
17
18
  const events_js_1 = require("../execution/events.js");
18
19
  const invocation_js_1 = require("../utils/invocation.js");
19
20
  const synchronous_js_1 = require("../utils/synchronous.js");
@@ -119,7 +120,8 @@ class ToolRegistry {
119
120
  */
120
121
  invoke(request) {
121
122
  const call = (0, invocation_js_1.toolInvocation)(request, arguments.length);
122
- return this.execute(call.toolId, call.input, false, call.diagnostics, call.signal);
123
+ const callId = (0, invocation_js_1.invocationId)();
124
+ return (0, native_sub_flow_js_1.nativeSubFlowSync)({ ...call, signal: (0, cancellation_js_1.combineSignals)(this.ports.signal, call.signal), invocationId: callId }, 'tool', call.toolId, (scopedLogger) => this.execute(call.toolId, call.input, false, call.diagnostics, call.signal, scopedLogger, callId));
123
125
  }
124
126
  /**
125
127
  * Invoke a registered tool and await its result.
@@ -131,7 +133,8 @@ class ToolRegistry {
131
133
  */
132
134
  async invokeAsync(request) {
133
135
  const call = (0, invocation_js_1.toolInvocation)(request, arguments.length);
134
- return (await this.execute(call.toolId, call.input, true, call.diagnostics, call.signal));
136
+ const callId = (0, invocation_js_1.invocationId)();
137
+ return (0, native_sub_flow_js_1.nativeSubFlowAsync)({ ...call, signal: (0, cancellation_js_1.combineSignals)(this.ports.signal, call.signal), invocationId: callId }, 'tool', call.toolId, (scopedLogger) => this.execute(call.toolId, call.input, true, call.diagnostics, call.signal, scopedLogger, callId));
135
138
  }
136
139
  /**
137
140
  * Run one call: validate, parse input, execute, parse output, then record the outcome.
@@ -143,7 +146,7 @@ class ToolRegistry {
143
146
  * @param requestSignal Per-call signal, combined with the request-lifetime signal.
144
147
  * @returns The frozen result on success; every failure path throws.
145
148
  */
146
- execute(name, input, asynchronous, parentDiagnostics = this.diagnostics, requestSignal) {
149
+ execute(name, input, asynchronous, parentDiagnostics = this.diagnostics, requestSignal, logger, callId = (0, invocation_js_1.invocationId)()) {
147
150
  // A tool call stays inside the run that invoked it: mixing two diagnostic trees would
148
151
  // produce records with two parents and break run-scoped correlation.
149
152
  if (this.diagnostics?.identity?.runId &&
@@ -155,7 +158,7 @@ class ToolRegistry {
155
158
  throw this.ports.unavailable?.(name) ?? new Error(`Tool is not registered: ${name}`);
156
159
  // Either signal may cancel the call; combining them keeps both lifetimes effective.
157
160
  const signal = (0, cancellation_js_1.combineSignals)(this.ports.signal, requestSignal);
158
- const invocationId = (0, invocation_js_1.invocationId)();
161
+ const invocationId = callId;
159
162
  const diagnostics = parentDiagnostics?.child(invocationId, {
160
163
  invocationId,
161
164
  nodeRole: 'invocation',
@@ -193,24 +196,15 @@ class ToolRegistry {
193
196
  };
194
197
  const succeed = (result) => {
195
198
  signal.throwIfAborted();
196
- let debug = reports.debug();
197
199
  if (tool.debugSteps && diagnostics?.enabled('tool.result', 'content')) {
198
200
  try {
199
- debug = reports.debug({
200
- subs: (0, synchronous_js_1.synchronous)(tool.debugSteps(result, reporting), 'Tool debug reports must be synchronous'),
201
- });
201
+ (0, synchronous_js_1.synchronous)(tool.debugSteps(result, reporting), 'Tool debug reports must be synchronous');
202
202
  }
203
- catch (error) {
204
- // Debug material is optional evidence: it must not turn a successful tool call into
205
- // a failure. Defer the error until a consumer actually asks for the sub-steps.
206
- debug = {
207
- usedModel: reports.debug().usedModel,
208
- subSteps: () => {
209
- throw error;
210
- },
211
- };
203
+ catch {
204
+ diagnostics?.emit('node.progress', () => ({ reportError: 'INVALID_NODE_REPORT' }));
212
205
  }
213
206
  }
207
+ const debug = reports.debug();
214
208
  signal.throwIfAborted();
215
209
  reports.close();
216
210
  diagnostics?.emit('tool.result', () => ({
@@ -280,6 +274,7 @@ class ToolRegistry {
280
274
  signal.throwIfAborted();
281
275
  phase = 'execute';
282
276
  const value = tool.execute(parsed, {
277
+ logger,
283
278
  mode: asynchronous ? 'async' : 'sync',
284
279
  invocationId,
285
280
  signal,
@@ -35,13 +35,10 @@ function auditContextChange(original, current, mutable) {
35
35
  const changed = JSON.stringify(before.value) !== JSON.stringify(after.value);
36
36
  (0, rules_js_1.breakWhile)(changed &&
37
37
  (!mutable.has(before.id) || before.role === 'system' || before.trust === 'instruction'), fail(`Protected context changed: ${before.id}`));
38
- if (changed &&
39
- before.value !== null &&
40
- after.value !== null &&
41
- typeof before.value === 'object' &&
42
- typeof after.value === 'object')
43
- // Only the field set is compared here; field order is not meaningful for context data.
44
- (0, rules_js_1.breakWhile)(JSON.stringify(Object.keys(before.value).sort()) !==
45
- JSON.stringify(Object.keys(after.value).sort()), fail('Context fields must be preserved'));
38
+ if (changed && typeof before.value === 'object' && typeof after.value === 'object')
39
+ // A null value carries no fields. Treat it as an empty field set so turning it into an
40
+ // object, or dropping an object back to null, is still rejected as a structural change.
41
+ (0, rules_js_1.breakWhile)(JSON.stringify(Object.keys(before.value ?? {}).sort()) !==
42
+ JSON.stringify(Object.keys(after.value ?? {}).sort()), fail('Context fields must be preserved'));
46
43
  }
47
44
  }
@@ -22,15 +22,14 @@ exports.assembleContextPlan = exports.assembleFragments = void 0;
22
22
  * Core owns the guarantees here. A fragment declares its trust, lifetime and character
23
23
  * budget in one place; assembly validates those declarations and refuses to truncate;
24
24
  * auditing rejects structural change to protected fragments. Selection, ordering, compression
25
- * and model choice remain App-side nodes that run before this boundary.
25
+ * and model choice remain App-side nodes that run before this boundary. Optional Kit helpers
26
+ * such as evidence checks are imported from their own `/kits/*` entries, not from here.
26
27
  *
27
- * Exports: `assembleFragments`, `assembleContextPlan`, `ContextJournal`, the fragment helpers,
28
- * and the evidence Kit helpers consumed alongside assembled context.
28
+ * Exports: `assembleFragments`, `assembleContextPlan`, `ContextJournal` and the fragment helpers.
29
29
  */
30
30
  __exportStar(require("./fragments.js"), exports);
31
31
  var assembly_js_1 = require("./assembly.js");
32
32
  Object.defineProperty(exports, "assembleFragments", { enumerable: true, get: function () { return assembly_js_1.assembleFragments; } });
33
33
  __exportStar(require("./journal.js"), exports);
34
- __exportStar(require("../kits/evidence.js"), exports);
35
34
  var plan_js_1 = require("./plan.js");
36
35
  Object.defineProperty(exports, "assembleContextPlan", { enumerable: true, get: function () { return plan_js_1.assembleContextPlan; } });
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.reportedStepStatuses = exports.reportedStepStatusCatalog = void 0;
17
+ exports.reportedStepStatuses = exports.reportedStepStatusCatalog = exports.ScopedSubFlowLogger = exports.SubFlowLogger = void 0;
18
18
  exports.createDiagnostics = createDiagnostics;
19
19
  exports.diagnosticError = diagnosticError;
20
20
  exports.normalizeDiagnosticEvent = normalizeDiagnosticEvent;
@@ -37,6 +37,9 @@ const sub_flow_js_1 = require("./sub-flow.js");
37
37
  const rules_js_1 = require("../utils/rules.js");
38
38
  __exportStar(require("../structs/diagnostics.js"), exports);
39
39
  __exportStar(require("./catalog.js"), exports);
40
+ var sub_flow_js_2 = require("./sub-flow.js");
41
+ Object.defineProperty(exports, "SubFlowLogger", { enumerable: true, get: function () { return sub_flow_js_2.SubFlowLogger; } });
42
+ Object.defineProperty(exports, "ScopedSubFlowLogger", { enumerable: true, get: function () { return sub_flow_js_2.ScopedSubFlowLogger; } });
40
43
  var debug_js_2 = require("../structs/debug.js");
41
44
  Object.defineProperty(exports, "reportedStepStatusCatalog", { enumerable: true, get: function () { return debug_js_2.reportedStepStatusCatalog; } });
42
45
  Object.defineProperty(exports, "reportedStepStatuses", { enumerable: true, get: function () { return debug_js_2.reportedStepStatuses; } });
@@ -129,7 +132,7 @@ function normalizeDiagnosticEvent(input) {
129
132
  // The count and size bounds match what the sub-flow logger enforces, so a record produced by
130
133
  // Core can never be rejected here; only hand-edited or foreign records can.
131
134
  if (!Array.isArray(steps) ||
132
- steps.length > 256 ||
135
+ steps.length > 1024 ||
133
136
  new Set(steps.map((step) => step?.stepId)).size !== steps.length ||
134
137
  steps.some((step) => !step ||
135
138
  step.origin !== 'reported' ||
@@ -140,7 +143,15 @@ function normalizeDiagnosticEvent(input) {
140
143
  !Number.isSafeInteger(step.sequence) ||
141
144
  step.sequence < 1 ||
142
145
  (step.status !== undefined && !debug_js_1.reportedStepStatuses.includes(step.status)) ||
143
- ['parentStepId', 'relatedDefinitionId', 'caseId', 'summary'].some((key) => step[key] !== undefined && typeof step[key] !== 'string') ||
146
+ [
147
+ 'type',
148
+ 'subnodeId',
149
+ 'parentStepId',
150
+ 'relatedDefinitionId',
151
+ 'relatedInvocationId',
152
+ 'caseId',
153
+ 'summary',
154
+ ].some((key) => step[key] !== undefined && typeof step[key] !== 'string') ||
144
155
  (step.usedModel !== undefined && typeof step.usedModel !== 'boolean') ||
145
156
  (step.revision !== undefined &&
146
157
  (!Number.isSafeInteger(step.revision) ||
@@ -155,6 +166,37 @@ function normalizeDiagnosticEvent(input) {
155
166
  (!Number.isSafeInteger(raw.subStepsDropped) || Number(raw.subStepsDropped) < 0)) ||
156
167
  (raw.subStepsTruncated !== undefined && typeof raw.subStepsTruncated !== 'boolean'))
157
168
  throw new TypeError('Invalid reported diagnostic steps');
169
+ const originals = new Map();
170
+ let lastSequence = 0;
171
+ for (const step of steps) {
172
+ if (step.operation === undefined)
173
+ continue; // Historical projected snapshots remain readable.
174
+ (0, rules_js_1.breakWhile)(!['write', 'fix'].includes(step.operation) || step.sequence <= lastSequence, () => new TypeError('Invalid sub-flow record order'));
175
+ lastSequence = step.sequence;
176
+ if (step.operation === 'write') {
177
+ (0, rules_js_1.breakWhile)(step.targetStepId !== undefined || step.revision !== 1, () => new TypeError('Invalid sub-flow write record'));
178
+ originals.set(step.stepId, {
179
+ revision: 1,
180
+ subnodeId: step.subnodeId,
181
+ type: step.type,
182
+ relatedInvocationId: step.relatedInvocationId,
183
+ });
184
+ }
185
+ else {
186
+ const previous = originals.get(step.targetStepId);
187
+ (0, rules_js_1.breakWhile)(previous === undefined ||
188
+ step.revision !== previous.revision + 1 ||
189
+ step.subnodeId !== previous.subnodeId ||
190
+ step.type !== previous.type ||
191
+ step.relatedInvocationId !== previous.relatedInvocationId, () => new TypeError('Invalid sub-flow fix reference'));
192
+ originals.set(step.targetStepId, {
193
+ revision: step.revision,
194
+ subnodeId: step.subnodeId,
195
+ type: step.type,
196
+ relatedInvocationId: step.relatedInvocationId,
197
+ });
198
+ }
199
+ }
158
200
  // Structural check only: the returned snapshot is discarded because the clone below already
159
201
  // produces the detached copy kept by the normalized record.
160
202
  for (const step of steps)
@@ -167,8 +209,14 @@ function normalizeDiagnosticEvent(input) {
167
209
  (0, rules_js_1.breakWhile)(progress !== undefined &&
168
210
  (!progress ||
169
211
  !['write', 'fix'].includes(progress.operation) ||
212
+ ['type', 'subnodeId', 'relatedInvocationId'].some((key) => progress[key] !== undefined &&
213
+ typeof progress[key] !== 'string') ||
170
214
  typeof progress.stepId !== 'string' ||
171
215
  !progress.stepId ||
216
+ (progress.targetStepId !== undefined &&
217
+ (progress.operation !== 'fix' ||
218
+ typeof progress.targetStepId !== 'string' ||
219
+ !progress.targetStepId)) ||
172
220
  !Number.isSafeInteger(progress.sequence) ||
173
221
  progress.sequence < 1 ||
174
222
  !Number.isSafeInteger(progress.revision) ||
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nativeSubFlowCatalog = void 0;
4
+ exports.nativeSubFlowSync = nativeSubFlowSync;
5
+ exports.nativeSubFlowAsync = nativeSubFlowAsync;
6
+ const sub_flow_js_1 = require("./sub-flow.js");
7
+ /** Fixed metadata shared by native producers; pure getters and formatters are not producers. */
8
+ exports.nativeSubFlowCatalog = {
9
+ model: { name: 'Model call', kind: 'model', type: 'model.call' },
10
+ tool: { name: 'Tool call', kind: 'tool', type: 'tool.call' },
11
+ invocation: { name: 'Invocation', kind: 'invocation', type: 'handler.call' },
12
+ retrieval: { name: 'Retrieval', kind: 'retrieval', type: 'retrieval.run' },
13
+ task: { name: 'Read answer evidence', kind: 'retrieval', type: 'evidence.read' },
14
+ check: { name: 'Check answer', kind: 'validation', type: 'answer.check' },
15
+ output: { name: 'Compose output', kind: 'presentation', type: 'output.compose' },
16
+ answer: { name: 'Answer flow', kind: 'answering', type: 'answer.run' },
17
+ retry: { name: 'Retry model proposal', kind: 'recovery', type: 'model.retry' },
18
+ context: { name: 'Process context', kind: 'context', type: 'context.process' },
19
+ recovery: { name: 'Recovery attempt', kind: 'recovery', type: 'recovery.try' },
20
+ delivery: { name: 'Deliver result', kind: 'delivery', type: 'delivery.run' },
21
+ aggregation: { name: 'Aggregate queries', kind: 'retrieval', type: 'queries.collect' },
22
+ knowledge: { name: 'Read knowledge', kind: 'retrieval', type: 'knowledge.read' },
23
+ };
24
+ /** Start one fixed record; its revision is best-effort and never controls the operation. */
25
+ function begin(context, producer, id) {
26
+ let logger;
27
+ try {
28
+ logger =
29
+ context.logger instanceof sub_flow_js_1.SubFlowLogger
30
+ ? (0, sub_flow_js_1.bindNativeSubFlowLogger)(context.logger, producer, id)
31
+ : context.logger;
32
+ }
33
+ catch {
34
+ /* A recording limit must not turn a valid operation into a failure. */
35
+ }
36
+ let step = -1;
37
+ try {
38
+ if (logger)
39
+ step = logger.write({
40
+ ...exports.nativeSubFlowCatalog[producer],
41
+ relatedDefinitionId: id,
42
+ ...(context.invocationId === undefined
43
+ ? {}
44
+ : { relatedInvocationId: context.invocationId }),
45
+ status: 'running',
46
+ });
47
+ }
48
+ catch {
49
+ /* Optional recording must not change execution. */
50
+ }
51
+ return {
52
+ logger,
53
+ finish: (status) => {
54
+ try {
55
+ if (logger && step !== -1)
56
+ logger.fix(step, { status });
57
+ }
58
+ catch {
59
+ /* A broken or detached logger cannot replace the operation result. */
60
+ }
61
+ },
62
+ };
63
+ }
64
+ /** Signal access is diagnostic metadata and cannot replace an operation failure. */
65
+ function failureStatus(context) {
66
+ try {
67
+ return context.signal?.aborted ? 'cancelled' : 'error';
68
+ }
69
+ catch {
70
+ return 'error';
71
+ }
72
+ }
73
+ /** Preserve a synchronous boundary while pairing an optional write with one result revision. */
74
+ function nativeSubFlowSync(context, producer, id, invoke) {
75
+ if (producer === 'model' || producer === 'tool' || producer === 'invocation')
76
+ (0, sub_flow_js_1.requireSubFlowLogger)(context.logger);
77
+ if (!context.logger)
78
+ return invoke();
79
+ const { logger, finish } = begin(context, producer, id);
80
+ try {
81
+ const value = invoke(logger);
82
+ finish('success');
83
+ return value;
84
+ }
85
+ catch (error) {
86
+ finish(failureStatus(context));
87
+ throw error;
88
+ }
89
+ }
90
+ /** Await the original operation without introducing another timeout or cancellation race. */
91
+ async function nativeSubFlowAsync(context, producer, id, invoke) {
92
+ if (producer === 'model' || producer === 'tool' || producer === 'invocation')
93
+ (0, sub_flow_js_1.requireSubFlowLogger)(context.logger);
94
+ if (!context.logger)
95
+ return invoke();
96
+ const { logger, finish } = begin(context, producer, id);
97
+ try {
98
+ const value = await invoke(logger);
99
+ finish('success');
100
+ return value;
101
+ }
102
+ catch (error) {
103
+ finish(failureStatus(context));
104
+ throw error;
105
+ }
106
+ }