@jangts/agent-core 0.3.6 → 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 (214) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +5 -5
  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 +4 -2
  7. package/development/docs/api/README.md +2 -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/reference.en.md +508 -410
  23. package/development/docs/api/reference.md +508 -410
  24. package/development/docs/api/support.en.md +55 -9
  25. package/development/docs/api/support.md +53 -7
  26. package/development/docs/api/types.en.md +35 -1
  27. package/development/docs/api/types.md +43 -0
  28. package/development/docs/basic-usage.en.md +1 -1
  29. package/development/docs/basic-usage.md +1 -1
  30. package/development/docs/create-app.en.md +1 -1
  31. package/development/docs/examples/registration/associated.mjs +8 -0
  32. package/development/docs/examples/registration/independent.mjs +20 -0
  33. package/development/docs/examples/registration/protocol.mjs +48 -0
  34. package/development/docs/examples/registration/run.mjs +47 -0
  35. package/development/docs/examples/registration/tools.mjs +75 -0
  36. package/development/docs/examples/registration/workflow.mjs +109 -0
  37. package/development/docs/flows/knowledge-maintenance.en.md +1 -1
  38. package/development/docs/materials.en.md +1 -1
  39. package/development/docs/mechanisms.en.md +2 -2
  40. package/development/docs/mechanisms.md +1 -1
  41. package/development/docs/operations.en.md +1 -1
  42. package/development/docs/records.en.md +1 -1
  43. package/development/docs/registration.en.md +4 -4
  44. package/development/docs/registration.md +2 -2
  45. package/development/skills/agent-core-app/SKILL.md +4 -4
  46. package/development/skills/agent-core-app/templates/node-ts/README.md.tpl +1 -1
  47. package/development/skills/agent-core-app/templates/node-ts/src/catalog.ts.tpl +2 -2
  48. package/development/skills/agent-core-app/templates/node-ts/test/app.test.mjs.tpl +1 -1
  49. package/dist/cjs/capabilities/index.js +5 -12
  50. package/dist/cjs/capabilities/model.js +56 -12
  51. package/dist/cjs/capabilities/tool-conditions.js +65 -0
  52. package/dist/cjs/capabilities/tool-runtime.js +10 -3
  53. package/dist/cjs/context/audit.js +5 -8
  54. package/dist/cjs/context/index.js +3 -4
  55. package/dist/cjs/index.js +21 -17
  56. package/dist/cjs/kits/answering/tasks.js +5 -5
  57. package/dist/cjs/kits/domains/catalog.js +113 -0
  58. package/dist/cjs/kits/domains/index.js +20 -0
  59. package/dist/cjs/kits/{intents → domains}/registry.js +77 -31
  60. package/dist/cjs/kits/{intents → domains}/scopes.js +21 -21
  61. package/dist/cjs/kits/index.js +14 -13
  62. package/dist/cjs/kits/presentation/formats.js +110 -0
  63. package/dist/cjs/kits/presentation/index.js +10 -5
  64. package/dist/cjs/kits/reflection.js +2 -2
  65. package/dist/cjs/kits/text-blocks.js +101 -0
  66. package/dist/cjs/kits/tools.js +246 -158
  67. package/dist/cjs/model/index.js +2 -6
  68. package/dist/cjs/model/interactions/calls.js +61 -0
  69. package/dist/cjs/model/interactions/json-object.js +11 -11
  70. package/dist/cjs/model/interactions/native-functions.js +17 -23
  71. package/dist/cjs/model/message-diagnostics.js +13 -3
  72. package/dist/cjs/model/options.js +2 -0
  73. package/dist/cjs/model/preparation.js +39 -6
  74. package/dist/cjs/model/runner.js +14 -0
  75. package/dist/cjs/model/selection-transport.js +4 -4
  76. package/dist/cjs/model/token-budget.js +3 -0
  77. package/dist/cjs/model/transports.js +3 -2
  78. package/dist/cjs/structs/index.js +7 -6
  79. package/dist/cjs/structs/kits/presentation/formats.js +2 -0
  80. package/dist/cjs/structs/kits/text-blocks.js +11 -0
  81. package/dist/cjs/structs/model/session.js +11 -0
  82. package/dist/cjs/structs/support/associations.js +2 -0
  83. package/dist/cjs/support/associations.js +79 -0
  84. package/dist/cjs/support/context/snapshot.js +11 -1
  85. package/dist/cjs/support/decorators/index.js +45 -3
  86. package/dist/cjs/support/index.js +1 -0
  87. package/dist/cjs/support/model/capabilities.js +35 -5
  88. package/dist/cjs/support/model/chat-completions.js +11 -2
  89. package/dist/cjs/support/model/completion/calls.js +10 -56
  90. package/dist/cjs/support/model/preview-rules.js +11 -11
  91. package/dist/cjs/support/model/reply-preview.js +3 -3
  92. package/dist/cjs/support/model/session.js +152 -0
  93. package/dist/cjs/support/model/stage-transport.js +8 -8
  94. package/dist/cjs/support/model/transports.js +5 -2
  95. package/dist/cjs/support/tools.js +42 -17
  96. package/dist/esm/capabilities/index.d.ts +5 -10
  97. package/dist/esm/capabilities/index.js +5 -9
  98. package/dist/esm/capabilities/model.d.ts +17 -13
  99. package/dist/esm/capabilities/model.js +54 -10
  100. package/dist/esm/capabilities/tool-conditions.d.ts +9 -0
  101. package/dist/esm/capabilities/tool-conditions.js +59 -0
  102. package/dist/esm/capabilities/tool-runtime.js +10 -3
  103. package/dist/esm/capabilities/tools.d.ts +3 -3
  104. package/dist/esm/context/audit.js +5 -8
  105. package/dist/esm/context/index.d.ts +3 -4
  106. package/dist/esm/context/index.js +3 -4
  107. package/dist/esm/index.d.ts +19 -13
  108. package/dist/esm/index.js +18 -15
  109. package/dist/esm/kits/answering/tasks.d.ts +6 -6
  110. package/dist/esm/kits/answering/tasks.js +5 -5
  111. package/dist/esm/kits/domains/catalog.d.ts +42 -0
  112. package/dist/esm/kits/domains/catalog.js +110 -0
  113. package/dist/esm/kits/domains/index.d.ts +4 -0
  114. package/dist/esm/kits/domains/index.js +4 -0
  115. package/dist/esm/kits/domains/registry.d.ts +100 -0
  116. package/dist/esm/kits/{intents → domains}/registry.js +77 -31
  117. package/dist/esm/kits/{intents → domains}/scopes.d.ts +18 -18
  118. package/dist/esm/kits/{intents → domains}/scopes.js +21 -21
  119. package/dist/esm/kits/index.d.ts +6 -5
  120. package/dist/esm/kits/index.js +6 -5
  121. package/dist/esm/kits/presentation/formats.d.ts +42 -0
  122. package/dist/esm/kits/presentation/formats.js +105 -0
  123. package/dist/esm/kits/presentation/index.d.ts +14 -5
  124. package/dist/esm/kits/presentation/index.js +10 -5
  125. package/dist/esm/kits/reflection.js +3 -3
  126. package/dist/esm/kits/text-blocks.d.ts +24 -0
  127. package/dist/esm/kits/text-blocks.js +97 -0
  128. package/dist/esm/kits/tools.d.ts +69 -52
  129. package/dist/esm/kits/tools.js +246 -158
  130. package/dist/esm/model/index.d.ts +2 -6
  131. package/dist/esm/model/index.js +2 -6
  132. package/dist/esm/model/interactions/calls.d.ts +40 -0
  133. package/dist/esm/model/interactions/calls.js +58 -0
  134. package/dist/esm/model/interactions/json-object.js +11 -11
  135. package/dist/esm/model/interactions/native-functions.js +17 -23
  136. package/dist/esm/model/message-diagnostics.d.ts +6 -5
  137. package/dist/esm/model/message-diagnostics.js +13 -3
  138. package/dist/esm/model/options.js +2 -0
  139. package/dist/esm/model/preparation.js +39 -6
  140. package/dist/esm/model/runner.js +14 -0
  141. package/dist/esm/model/selection-transport.js +4 -4
  142. package/dist/esm/model/token-budget.js +3 -0
  143. package/dist/esm/model/transports.d.ts +2 -1
  144. package/dist/esm/model/transports.js +3 -2
  145. package/dist/esm/structs/capabilities/invocation.d.ts +1 -1
  146. package/dist/esm/structs/capabilities/model.d.ts +42 -11
  147. package/dist/esm/structs/capabilities/tools.d.ts +9 -4
  148. package/dist/esm/structs/common.d.ts +1 -1
  149. package/dist/esm/structs/index.d.ts +7 -6
  150. package/dist/esm/structs/index.js +7 -6
  151. package/dist/esm/structs/kits/answering/tasks.d.ts +2 -2
  152. package/dist/esm/structs/kits/{intents → domains}/catalog.d.ts +20 -20
  153. package/dist/esm/structs/kits/{intents → domains}/registry.d.ts +24 -21
  154. package/dist/esm/structs/kits/{intents → domains}/scopes.d.ts +9 -9
  155. package/dist/esm/structs/kits/presentation/formats.d.ts +42 -0
  156. package/dist/esm/structs/kits/presentation/formats.js +1 -0
  157. package/dist/esm/structs/kits/text-blocks.d.ts +25 -0
  158. package/dist/esm/structs/kits/text-blocks.js +10 -0
  159. package/dist/esm/structs/kits/tools.d.ts +82 -83
  160. package/dist/esm/structs/model/interactions.d.ts +18 -11
  161. package/dist/esm/structs/model/messages.d.ts +34 -2
  162. package/dist/esm/structs/model/runtime.d.ts +7 -0
  163. package/dist/esm/structs/model/session.d.ts +29 -0
  164. package/dist/esm/structs/model/session.js +10 -0
  165. package/dist/esm/structs/support/associations.d.ts +22 -0
  166. package/dist/esm/structs/support/associations.js +1 -0
  167. package/dist/esm/structs/support/model/interactions.d.ts +2 -2
  168. package/dist/esm/structs/support/model/messages.d.ts +6 -13
  169. package/dist/esm/structs/support/tools.d.ts +23 -23
  170. package/dist/esm/support/associations.d.ts +26 -0
  171. package/dist/esm/support/associations.js +76 -0
  172. package/dist/esm/support/context/snapshot.js +11 -1
  173. package/dist/esm/support/decorators/index.d.ts +13 -2
  174. package/dist/esm/support/decorators/index.js +40 -3
  175. package/dist/esm/support/decorators/pool.d.ts +6 -5
  176. package/dist/esm/support/decorators/types.d.ts +3 -1
  177. package/dist/esm/support/index.d.ts +1 -0
  178. package/dist/esm/support/index.js +1 -0
  179. package/dist/esm/support/model/capabilities.d.ts +8 -3
  180. package/dist/esm/support/model/capabilities.js +35 -5
  181. package/dist/esm/support/model/chat-completions.js +11 -2
  182. package/dist/esm/support/model/completion/calls.d.ts +6 -34
  183. package/dist/esm/support/model/completion/calls.js +8 -55
  184. package/dist/esm/support/model/index.d.ts +1 -1
  185. package/dist/esm/support/model/preview-rules.d.ts +13 -8
  186. package/dist/esm/support/model/preview-rules.js +11 -11
  187. package/dist/esm/support/model/reply-preview.d.ts +2 -2
  188. package/dist/esm/support/model/reply-preview.js +3 -3
  189. package/dist/esm/support/model/session.d.ts +61 -0
  190. package/dist/esm/support/model/session.js +148 -0
  191. package/dist/esm/support/model/stage-transport.d.ts +1 -1
  192. package/dist/esm/support/model/stage-transport.js +9 -9
  193. package/dist/esm/support/model/transports.d.ts +2 -0
  194. package/dist/esm/support/model/transports.js +2 -1
  195. package/dist/esm/support/tools.d.ts +11 -3
  196. package/dist/esm/support/tools.js +43 -18
  197. package/dist/esm/utils/catalog.d.ts +1 -1
  198. package/package.json +20 -6
  199. package/dist/cjs/execution/index.js +0 -30
  200. package/dist/cjs/kits/intents/catalog.js +0 -82
  201. package/dist/cjs/kits/intents/index.js +0 -35
  202. package/dist/esm/execution/index.d.ts +0 -11
  203. package/dist/esm/execution/index.js +0 -11
  204. package/dist/esm/kits/intents/catalog.d.ts +0 -39
  205. package/dist/esm/kits/intents/catalog.js +0 -79
  206. package/dist/esm/kits/intents/index.d.ts +0 -22
  207. package/dist/esm/kits/intents/index.js +0 -18
  208. package/dist/esm/kits/intents/registry.d.ts +0 -88
  209. /package/dist/cjs/structs/kits/{intents → domains}/catalog.js +0 -0
  210. /package/dist/cjs/structs/kits/{intents → domains}/registry.js +0 -0
  211. /package/dist/cjs/structs/kits/{intents → domains}/scopes.js +0 -0
  212. /package/dist/esm/structs/kits/{intents → domains}/catalog.js +0 -0
  213. /package/dist/esm/structs/kits/{intents → domains}/registry.js +0 -0
  214. /package/dist/esm/structs/kits/{intents → domains}/scopes.js +0 -0
@@ -1,13 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.modelPool = exports.agentPool = exports.workflowPool = exports.fragmentPool = exports.toolPool = exports.nodePool = void 0;
4
+ exports.Intent = Intent;
4
5
  exports.node = node;
6
+ exports.WorkflowNode = node;
5
7
  exports.tool = tool;
8
+ exports.WorkflowTool = tool;
9
+ exports.tool = tool;
10
+ exports.WorkflowTool = tool;
11
+ exports.node = node;
12
+ exports.WorkflowNode = node;
6
13
  exports.fragment = fragment;
7
14
  exports.workflow = workflow;
8
15
  exports.agent = agent;
9
16
  exports.model = model;
10
17
  const tools_js_1 = require("../tools.js");
18
+ const capabilities_js_1 = require("../model/capabilities.js");
19
+ const tool_conditions_js_1 = require("../../capabilities/tool-conditions.js");
11
20
  const workflow_js_1 = require("../../execution/workflow.js");
12
21
  const assembly_js_1 = require("../context/assembly.js");
13
22
  const binding_js_1 = require("../../model/binding.js");
@@ -19,15 +28,43 @@ Object.defineProperty(exports, "fragmentPool", { enumerable: true, get: function
19
28
  Object.defineProperty(exports, "workflowPool", { enumerable: true, get: function () { return pool_js_1.workflowPool; } });
20
29
  Object.defineProperty(exports, "agentPool", { enumerable: true, get: function () { return pool_js_1.agentPool; } });
21
30
  Object.defineProperty(exports, "modelPool", { enumerable: true, get: function () { return pool_js_1.modelPool; } });
31
+ /** Metadata follows the actual decorated target, independently of decorator order. */
32
+ const intentKey = Symbol.for('@jangts/agent-core/tool-intent-metadata/v1');
33
+ const realm = globalThis;
34
+ const intentMetadata = realm[intentKey] ?? new WeakMap();
35
+ if (!realm[intentKey])
36
+ Object.defineProperty(globalThis, intentKey, { value: intentMetadata });
37
+ /** Mark a WorkflowTool for demand discovery; alone this decorator registers nothing. */
38
+ function Intent(metadata = true) {
39
+ const normalized = (0, tool_conditions_js_1.snapshotIntent)(metadata);
40
+ return (value, context) => {
41
+ if (context.kind !== 'class' && context.kind !== 'method')
42
+ throw new TypeError('Intent requires a class or method');
43
+ if (intentMetadata.has(value))
44
+ throw new TypeError('Duplicate Intent decoration');
45
+ intentMetadata.set(value, normalized);
46
+ };
47
+ }
22
48
  /** Internal conversion shared by node/tool/fragment; never a public free-function adapter. */
23
49
  function decorate(kind, id, options, key, compile) {
24
50
  return (value, context) => {
51
+ const convert = (definition) => {
52
+ if (kind !== 'tool')
53
+ return compile(definition);
54
+ if ('asIntent' in definition)
55
+ throw new TypeError('Use @Intent instead of asIntent in @WorkflowTool');
56
+ const metadata = intentMetadata.get(value);
57
+ // Intent metadata is collected before class/method initializers compile definitions.
58
+ if (metadata !== undefined)
59
+ Object.defineProperty(definition, 'asIntent', { value: metadata, enumerable: true });
60
+ return compile(definition);
61
+ };
25
62
  if (context?.kind === 'class') {
26
- (0, definition_js_1.classDecoration)(kind, id, options, compile)(value, context);
63
+ (0, definition_js_1.classDecoration)(kind, id, options, convert)(value, context);
27
64
  }
28
65
  else {
29
66
  const { ns, ...metadata } = options;
30
- (0, definition_js_1.methodDecoration)(kind, id, metadata, key, { ns }, compile)(value, context);
67
+ (0, definition_js_1.methodDecoration)(kind, id, metadata, key, { ns }, convert)(value, context);
31
68
  }
32
69
  };
33
70
  }
@@ -35,7 +72,12 @@ function node(id, options = {}) {
35
72
  return decorate('node', id, options, 'run', (value) => value);
36
73
  }
37
74
  function tool(id, options = {}) {
38
- return decorate('tool', id, options, 'execute', (value) => (0, tools_js_1.defineTool)(value));
75
+ if ('asIntent' in options)
76
+ throw new TypeError('Use @Intent instead of asIntent in @WorkflowTool');
77
+ const handlerKey = 'inputSchema' in options && !('authorize' in options) ? 'resolve' : 'execute';
78
+ return decorate('tool', id, options, handlerKey, (value) => 'kind' in value || 'authorize' in value || 'execute' in value
79
+ ? (0, tools_js_1.defineTool)(value)
80
+ : (0, capabilities_js_1.defineModelTools)([value]).require(value.id));
39
81
  }
40
82
  function fragment(id, options = {}) {
41
83
  return decorate('fragment', id, options, 'format', (value) => {
@@ -42,3 +42,4 @@ Object.defineProperty(exports, "createReplyPreview", { enumerable: true, get: fu
42
42
  __exportStar(require("./capabilities.js"), exports);
43
43
  var decision_retry_js_1 = require("../model/decision-retry.js");
44
44
  Object.defineProperty(exports, "retryMultipleModelCalls", { enumerable: true, get: function () { return decision_retry_js_1.retryMultipleModelCalls; } });
45
+ __exportStar(require("./associations.js"), exports);
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defineModelCapabilities = defineModelCapabilities;
3
+ exports.defineModelTools = defineModelTools;
4
4
  /**
5
5
  * Model capability catalog: seal a typed declaration list into a reusable catalog.
6
6
  *
7
7
  * The catalog is a frozen snapshot, so mutating the original declaration list cannot widen the
8
- * result type or add capabilities at runtime. Resolution stays inside Core's registry; Support only
8
+ * result type or add tools at runtime. Resolution stays inside Core's registry; Support only
9
9
  * projects the declarations and their output type.
10
10
  *
11
- * Main export: `defineModelCapabilities`.
11
+ * Main export: `defineModelTools`.
12
12
  */
13
13
  const catalog_js_1 = require("../../utils/catalog.js");
14
14
  const model_js_1 = require("../../capabilities/model.js");
@@ -22,10 +22,40 @@ const model_js_1 = require("../../capabilities/model.js");
22
22
  * unknown ID.
23
23
  * @throws {Error} When a resolver is asynchronous.
24
24
  */
25
- function defineModelCapabilities(definitions) {
26
- const registry = new model_js_1.ModelCapabilityRegistry(definitions).seal();
25
+ function defineModelTools(definitions) {
26
+ const registry = new model_js_1.ModelToolRegistry(definitions.map(modelDefinition)).seal();
27
+ return project(registry);
28
+ }
29
+ /** Executable tools propose raw arguments; business parsing occurs once at execution. */
30
+ function modelDefinition(definition) {
31
+ const executable = definition;
32
+ if (typeof executable.execute !== 'function')
33
+ return definition;
34
+ if (typeof executable.authorize !== 'function' || typeof executable.parseOutput !== 'function')
35
+ throw new TypeError('Missing executable tool handler');
36
+ const id = definition.id;
37
+ return {
38
+ id,
39
+ description: definition.description,
40
+ active: typeof definition.active === 'function'
41
+ ? definition.active.bind(definition)
42
+ : definition.active,
43
+ asIntent: typeof definition.asIntent === 'function'
44
+ ? definition.asIntent.bind(definition)
45
+ : definition.asIntent,
46
+ inputSchema: {
47
+ jsonSchema: definition.inputSchema.jsonSchema,
48
+ parse: (input) => input,
49
+ },
50
+ resolve: (input) => ({ toolId: id, input }),
51
+ };
52
+ }
53
+ /** Project existing immutable entries without re-registering schemas or rebinding handlers. */
54
+ function project(registry) {
27
55
  return Object.freeze({
28
56
  ...(0, catalog_js_1.readonlyCatalog)(registry.definitions, (id) => new TypeError(`Unknown model capability: ${id}`)),
29
57
  resolve: (selection, stage) => registry.resolve(selection, stage),
58
+ select: (ids, ...context) => project(context.length ? registry.select(ids, context[0]) : registry.select(ids)),
59
+ withIntent: (context) => project(registry.withIntent(context)),
30
60
  });
31
61
  }
@@ -19,10 +19,19 @@ function chatCompletionFunctionOptions(options) {
19
19
  return {};
20
20
  if (!options.functions.length)
21
21
  throw new TypeError('Empty model function catalog');
22
+ if (options.toolChoice !== undefined &&
23
+ !['auto', 'required', 'none'].includes(options.toolChoice))
24
+ throw new TypeError('Invalid toolChoice');
25
+ if (options.parallelToolCalls !== undefined &&
26
+ options.parallelToolCalls !== 'omit' &&
27
+ typeof options.parallelToolCalls !== 'boolean')
28
+ throw new TypeError('Invalid parallelToolCalls');
22
29
  return {
23
30
  tools: options.functions.map((fn) => ({ type: 'function', function: fn })),
24
- tool_choice: 'required',
25
- parallel_tool_calls: false,
31
+ tool_choice: options.toolChoice ?? 'required',
32
+ ...(options.parallelToolCalls === 'omit'
33
+ ? {}
34
+ : { parallel_tool_calls: options.parallelToolCalls ?? false }),
26
35
  };
27
36
  }
28
37
  /**
@@ -1,61 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createToolCallCollector = createToolCallCollector;
4
- const model_protocol_js_1 = require("../../../utils/model-protocol.js");
3
+ exports.createToolCallCollector = void 0;
5
4
  /**
6
- * Create a collector for one response.
5
+ * Tool-call delta aggregation, re-exported from Core.
7
6
  *
8
- * @param fail - Protocol failure factory; defaults to the Core model protocol error.
9
- * @returns A collector that keeps its own state and never shares it with another response.
7
+ * The algorithm lives in `model/interactions/calls.ts` so session transports and
8
+ * completion policies share one implementation. This module keeps the existing
9
+ * Support import path stable.
10
+ *
11
+ * Exports: `AggregatedToolCall`, `ToolCallCollector`, `ToolCallFailure` and
12
+ * `createToolCallCollector`.
10
13
  */
11
- function createToolCallCollector(fail = model_protocol_js_1.modelProtocolError) {
12
- const pending = new Map();
13
- const ids = new Set();
14
- const calls = () => [...pending.entries()]
15
- .sort(([left], [right]) => left - right)
16
- .map(([index, call]) => ({ index, ...call }));
17
- return {
18
- push(part) {
19
- if (typeof part === 'string')
20
- return;
21
- if (!part || typeof part !== 'object' || Array.isArray(part))
22
- fail('Expected a native model call');
23
- const { type, index, id, name, arguments: args } = part;
24
- if (type !== 'function-call-delta')
25
- fail('Expected a native model call');
26
- if (!Number.isInteger(index) || index < 0)
27
- fail('Invalid model call index');
28
- if ((id !== undefined && (typeof id !== 'string' || !id)) ||
29
- (name !== undefined && typeof name !== 'string') ||
30
- (args !== undefined && typeof args !== 'string'))
31
- fail('Invalid model call fields');
32
- let call = pending.get(index);
33
- if (!call) {
34
- call = { id: '', name: '', arguments: '' };
35
- pending.set(index, call);
36
- }
37
- if (id !== undefined) {
38
- if (call.id && call.id !== id)
39
- fail('Conflicting model call IDs');
40
- if (!call.id) {
41
- if (ids.has(id))
42
- fail('Duplicate model call ID');
43
- ids.add(id);
44
- call.id = id;
45
- }
46
- }
47
- call.name += name ?? '';
48
- call.arguments += args ?? '';
49
- },
50
- get calls() {
51
- return calls();
52
- },
53
- complete() {
54
- const completed = calls();
55
- for (const call of completed)
56
- if (!call.id || !call.name)
57
- fail('Incomplete model call');
58
- return completed;
59
- },
60
- };
61
- }
14
+ var calls_js_1 = require("../../../model/interactions/calls.js");
15
+ Object.defineProperty(exports, "createToolCallCollector", { enumerable: true, get: function () { return calls_js_1.createToolCallCollector; } });
@@ -83,29 +83,29 @@ function previewSnapshot(preview) {
83
83
  * Capabilities without preview metadata are skipped even when their stage opts in. Default paths
84
84
  * are `text` and `bubbles[*]`, each kept only when the capability schema declares it.
85
85
  *
86
- * @param options Stage declarations and the capabilities they may reference.
86
+ * @param options Stage declarations and the tools they may reference.
87
87
  * @returns Frozen rules in stage order, each with deep-frozen paths and eligibility.
88
88
  * @throws {Error} When a capability or stage ID repeats, a stage references an unknown capability,
89
89
  * a preview mode is unknown, or a preview path or eligibility field is absent from the schema.
90
90
  */
91
91
  function createReplyPreviewRules(options) {
92
- const capabilities = new Map();
93
- for (const capability of options.capabilities) {
92
+ const tools = new Map();
93
+ for (const capability of options.tools) {
94
94
  const id = capability.id;
95
- (0, rules_js_1.breakWhile)(!id || capabilities.has(id), 'Duplicate preview capability declaration');
95
+ (0, rules_js_1.breakWhile)(!id || tools.has(id), 'Duplicate preview capability declaration');
96
96
  const preview = previewSnapshot(capability.preview);
97
97
  // Validate and emit the same canonical snapshot, never reread App getters.
98
98
  const jsonSchema = preview ? structuredClone(capability.jsonSchema) : {};
99
- capabilities.set(id, { id, preview, jsonSchema });
99
+ tools.set(id, { id, preview, jsonSchema });
100
100
  }
101
101
  const stages = new Set(), rules = [];
102
102
  for (const stage of options.stages) {
103
- const { id: stageId, preview, capabilityIds } = stage;
103
+ const { id: stageId, preview, toolIds } = stage;
104
104
  (0, rules_js_1.breakWhile)(!stageId || stages.has(stageId), 'Duplicate preview stage declaration');
105
105
  stages.add(stageId);
106
- const ids = capabilityIds === undefined ? [] : stringList(capabilityIds, 'capability IDs');
107
- (0, rules_js_1.breakWhile)(new Set(ids).size !== ids.length || ids.some((id) => !capabilities.has(id)), 'Preview stage references an unknown capability');
108
- (0, rules_js_1.breakWhile)(preview !== undefined && !['text', 'capabilities'].includes(preview), 'Unknown preview stage mode');
106
+ const ids = toolIds === undefined ? [] : stringList(toolIds, 'capability IDs');
107
+ (0, rules_js_1.breakWhile)(new Set(ids).size !== ids.length || ids.some((id) => !tools.has(id)), 'Preview stage references an unknown capability');
108
+ (0, rules_js_1.breakWhile)(preview !== undefined && !['text', 'tools'].includes(preview), 'Unknown preview stage mode');
109
109
  if (!preview)
110
110
  continue;
111
111
  if (preview === 'text') {
@@ -114,7 +114,7 @@ function createReplyPreviewRules(options) {
114
114
  continue;
115
115
  }
116
116
  for (const id of ids) {
117
- const capability = capabilities.get(id);
117
+ const capability = tools.get(id);
118
118
  if (!capability.preview)
119
119
  continue;
120
120
  const source = capability.preview === true ? {} : capability.preview;
@@ -130,7 +130,7 @@ function createReplyPreviewRules(options) {
130
130
  Object.freeze({ path: Object.freeze(when.path), values: Object.freeze(when.values) });
131
131
  rules.push(Object.freeze({
132
132
  stageId,
133
- capabilityId: (0, arguments_js_1.wireName)(id),
133
+ toolId: (0, arguments_js_1.wireName)(id),
134
134
  paths: emittedPaths,
135
135
  ...(emittedWhen ? { when: emittedWhen } : {}),
136
136
  }));
@@ -199,7 +199,7 @@ function createReplyPreview(options) {
199
199
  if (!Number.isSafeInteger(maxChars) || maxChars < 1)
200
200
  throw new TypeError('Invalid reply preview budget');
201
201
  const rules = options.rules.map((rule) => Object.freeze({
202
- capabilityId: rule.capabilityId,
202
+ toolId: rule.toolId,
203
203
  stageId: rule.stageId,
204
204
  paths: rule.paths === undefined ? undefined : structuredClone(rule.paths),
205
205
  when: rule.when === undefined ? undefined : structuredClone(rule.when),
@@ -261,7 +261,7 @@ function createReplyPreview(options) {
261
261
  return;
262
262
  }
263
263
  if (typeof part === 'string') {
264
- const rule = rules.find((rule) => !rule.capabilityId && rule.stageId === event.payload.stageId);
264
+ const rule = rules.find((rule) => !rule.toolId && rule.stageId === event.payload.stageId);
265
265
  if (!rule) {
266
266
  if (part.trim()) {
267
267
  disabled = true;
@@ -279,7 +279,7 @@ function createReplyPreview(options) {
279
279
  return;
280
280
  }
281
281
  name += part.name ?? '';
282
- const rule = rules.find((rule) => rule.capabilityId === name && (!rule.stageId || rule.stageId === event.payload.stageId));
282
+ const rule = rules.find((rule) => rule.toolId === name && (!rule.stageId || rule.stageId === event.payload.stageId));
283
283
  if (!rule) {
284
284
  if (selected) {
285
285
  disabled = true;
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.prepareSessionFunctions = prepareSessionFunctions;
4
+ exports.createSessionModelTransport = createSessionModelTransport;
5
+ /**
6
+ * Session transport policy: one response may contain prose and several tool calls.
7
+ *
8
+ * Core owns the raw `ModelSessionResult`; this Support module adds the host-facing
9
+ * resolution fields (`toolId`, parsed `input`, non-fatal `problem`) and the transport
10
+ * that advertises the stage's tools. Keeping the resolution policy here prevents Core
11
+ * from depending on tool catalogs or business error categories.
12
+ *
13
+ * Exports: `ResolvedSessionCall`, `ResolvedSessionResult`, `PreparedSessionTransport`,
14
+ * `SessionFunctionOptions`, `SessionModelTransportRegistration`, `prepareSessionFunctions`
15
+ * and `createSessionModelTransport`.
16
+ */
17
+ const arguments_js_1 = require("../../model/interactions/arguments.js");
18
+ const calls_js_1 = require("../../model/interactions/calls.js");
19
+ const options_js_1 = require("../../model/options.js");
20
+ const model_protocol_js_1 = require("../../utils/model-protocol.js");
21
+ /**
22
+ * Parse one call's raw arguments without failing the whole response.
23
+ *
24
+ * @param raw - Raw JSON text; an empty string means an empty argument object.
25
+ * @returns The parsed object, or undefined when the text is not a JSON object.
26
+ */
27
+ function parseArguments(raw) {
28
+ try {
29
+ const value = JSON.parse(raw === '' ? '{}' : raw);
30
+ return value && typeof value === 'object' && !Array.isArray(value)
31
+ ? value
32
+ : undefined;
33
+ }
34
+ catch {
35
+ return undefined;
36
+ }
37
+ }
38
+ /**
39
+ * Build the session policy for one stage.
40
+ *
41
+ * @param tools - Registered tools available in this stage; must be non-empty.
42
+ * @param options - Sampling and tool-selection settings.
43
+ * @returns A prepared transport whose collector returns text and every completed call.
44
+ * @throws TypeError When the tool list is empty or two ids collide on the wire name.
45
+ */
46
+ function prepareSessionFunctions(tools, options = {}) {
47
+ if (!tools.length)
48
+ throw new TypeError('Session transport requires registered tools');
49
+ const names = new Map(tools.map((tool) => [(0, arguments_js_1.wireName)(tool.id), tool.id]));
50
+ if (names.size !== tools.length)
51
+ throw new TypeError('Model wire name collision');
52
+ const functions = tools.map((tool) => ({
53
+ name: (0, arguments_js_1.wireName)(tool.id),
54
+ description: tool.description,
55
+ parameters: tool.inputSchema.jsonSchema,
56
+ strict: false,
57
+ }));
58
+ const instruction = 'You may answer directly or call one or more registered tools. Prose and calls may appear together. A call is a proposal, not proof of execution.';
59
+ return {
60
+ options: {
61
+ json: false,
62
+ functions,
63
+ toolChoice: options.toolChoice ?? 'auto',
64
+ ...(options.parallelToolCalls === undefined
65
+ ? {}
66
+ : { parallelToolCalls: options.parallelToolCalls }),
67
+ ...(options.temperature === undefined ? {} : { temperature: options.temperature }),
68
+ },
69
+ schemaChars: JSON.stringify(functions).length + instruction.length,
70
+ instruction,
71
+ createResponse() {
72
+ const collector = (0, calls_js_1.createToolCallCollector)();
73
+ let text = '';
74
+ return {
75
+ get outputChars() {
76
+ return (text.length +
77
+ collector.calls.reduce((sum, call) => sum + call.id.length + call.name.length + call.arguments.length, 0));
78
+ },
79
+ get calls() {
80
+ try {
81
+ return collector.complete().map((call) => ({
82
+ id: call.id,
83
+ name: call.name,
84
+ argumentChars: call.arguments.length,
85
+ toolId: names.get(call.name),
86
+ }));
87
+ }
88
+ catch {
89
+ return undefined;
90
+ }
91
+ },
92
+ push(part) {
93
+ if (typeof part === 'string') {
94
+ text += part;
95
+ return;
96
+ }
97
+ collector.push(part);
98
+ },
99
+ finish() {
100
+ const completed = collector.complete();
101
+ if (text.trim() === '' && completed.length === 0)
102
+ (0, model_protocol_js_1.modelProtocolError)('Model response is empty', 'MODEL_INCOMPLETE');
103
+ const calls = completed.map((call) => {
104
+ const toolId = names.get(call.name);
105
+ const input = parseArguments(call.arguments);
106
+ return {
107
+ index: call.index,
108
+ id: call.id,
109
+ name: call.name,
110
+ arguments: call.arguments,
111
+ argumentChars: call.arguments.length,
112
+ ...(toolId === undefined ? {} : { toolId }),
113
+ ...(input === undefined ? {} : { input }),
114
+ ...(toolId === undefined
115
+ ? { problem: 'unknown-tool' }
116
+ : input === undefined
117
+ ? { problem: 'invalid-arguments' }
118
+ : {}),
119
+ };
120
+ });
121
+ return { text, calls };
122
+ },
123
+ };
124
+ },
125
+ };
126
+ }
127
+ /**
128
+ * Create a session transport.
129
+ *
130
+ * @param registration - Transport id, tool source and optional settings.
131
+ * @returns A frozen transport definition whose result contains text and every completed call.
132
+ * @throws TypeError When the id is blank.
133
+ */
134
+ function createSessionModelTransport(registration) {
135
+ const id = registration.id;
136
+ if (typeof id !== 'string' || !id.trim())
137
+ throw new TypeError('Session transport requires an ID');
138
+ const source = registration.tools;
139
+ const options = (0, options_js_1.snapshotModelOptions)(registration.options ?? {});
140
+ return Object.freeze({
141
+ id,
142
+ prepare() {
143
+ return prepareSessionFunctions([...source.values()], {
144
+ ...(options.temperature === undefined ? {} : { temperature: options.temperature }),
145
+ ...(options.toolChoice === undefined ? {} : { toolChoice: options.toolChoice }),
146
+ ...(options.parallelToolCalls === undefined
147
+ ? {}
148
+ : { parallelToolCalls: options.parallelToolCalls }),
149
+ });
150
+ },
151
+ });
152
+ }
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createStageModelTransport = createStageModelTransport;
4
4
  /**
5
- * Stage-scoped model transport: expose only the capabilities declared for each stage.
5
+ * Stage-scoped model transport: expose only the tools declared for each stage.
6
6
  *
7
7
  * Static capability sources are projected once at construction; dynamic sources are re-projected
8
8
  * at the model boundary. Either way, an undeclared stage or capability is rejected rather than
@@ -19,14 +19,14 @@ const transports_js_1 = require("./transports.js");
19
19
  *
20
20
  * @param registration Transport declaration: unique ID, stage-to-capability references, interaction
21
21
  * adapter, options and a static or per-stage capability source.
22
- * @returns A Core model transport with `capabilities(stage)`.
22
+ * @returns A Core model transport with `tools(stage)`.
23
23
  * @throws {Error} When a stage ID repeats, has no capability IDs, the declaration has no stages, a
24
24
  * stage or capability is not registered, or a dynamic capability source is asynchronous.
25
25
  */
26
26
  function createStageModelTransport(registration) {
27
27
  const stages = new Map();
28
28
  for (const stage of registration.stages) {
29
- const ids = stage.capabilityIds;
29
+ const ids = stage.toolIds;
30
30
  (0, rules_js_1.breakWhile)(!stage.id?.trim() ||
31
31
  stages.has(stage.id) ||
32
32
  !Array.isArray(ids) ||
@@ -35,15 +35,15 @@ function createStageModelTransport(registration) {
35
35
  stages.set(stage.id, Object.freeze([...ids]));
36
36
  }
37
37
  (0, rules_js_1.breakWhile)(!stages.size, 'Model transport requires declared stages');
38
- const { id, adapter, options, requireStrictArguments, capabilities: source } = registration;
39
- const project = (stage, capabilities) => {
38
+ const { id, adapter, options, requireStrictArguments, tools: source } = registration;
39
+ const project = (stage, tools) => {
40
40
  const ids = stages.get(stage);
41
41
  (0, rules_js_1.breakWhile)(!ids, `Unregistered model stage: ${id} -> ${stage}`);
42
- const catalog = new model_js_1.ModelCapabilityRegistry(capabilities.values());
42
+ const catalog = new model_js_1.ModelToolRegistry(tools.values());
43
43
  for (const id of ids)
44
44
  (0, rules_js_1.breakWhile)(!catalog.has(id), `Unregistered model capability: ${stage} -> ${id}`);
45
45
  const selected = catalog.select(ids);
46
- const resolve = capabilities.resolve.bind(capabilities);
46
+ const resolve = tools.resolve.bind(tools);
47
47
  return Object.freeze({
48
48
  values: () => selected.values(),
49
49
  resolve(selection, context) {
@@ -61,7 +61,7 @@ function createStageModelTransport(registration) {
61
61
  adapter,
62
62
  options,
63
63
  requireStrictArguments,
64
- capabilities(stage) {
64
+ tools(stage) {
65
65
  (0, rules_js_1.breakWhile)(!stages.has(stage), `Unregistered model stage: ${id} -> ${stage}`);
66
66
  return fixed
67
67
  ? fixed.get(stage)
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createModelTransport = void 0;
3
+ exports.prepareSessionFunctions = exports.createSessionModelTransport = exports.createModelTransport = void 0;
4
4
  exports.createTextTransport = createTextTransport;
5
5
  exports.createJsonTransport = createJsonTransport;
6
6
  /**
@@ -18,6 +18,9 @@ const model_protocol_js_1 = require("../../utils/model-protocol.js");
18
18
  const transports_js_1 = require("../../model/transports.js");
19
19
  var selection_transport_js_1 = require("../../model/selection-transport.js");
20
20
  Object.defineProperty(exports, "createModelTransport", { enumerable: true, get: function () { return selection_transport_js_1.createModelTransport; } });
21
+ var session_js_1 = require("./session.js");
22
+ Object.defineProperty(exports, "createSessionModelTransport", { enumerable: true, get: function () { return session_js_1.createSessionModelTransport; } });
23
+ Object.defineProperty(exports, "prepareSessionFunctions", { enumerable: true, get: function () { return session_js_1.prepareSessionFunctions; } });
21
24
  /**
22
25
  * Create a plain-text transport that trims the assembled response.
23
26
  *
@@ -25,7 +28,7 @@ Object.defineProperty(exports, "createModelTransport", { enumerable: true, get:
25
28
  * @returns A frozen Core transport definition typed as string output.
26
29
  */
27
30
  function createTextTransport(definition) {
28
- return (0, transports_js_1.createPlainTextTransport)(definition.id, definition.options);
31
+ return (0, transports_js_1.createPlainTextTransport)(definition.id, definition.options, definition.trim);
29
32
  }
30
33
  /**
31
34
  * Create a typed JSON transport without a capability-selection envelope.