@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.
- package/CHANGELOG.md +20 -0
- package/README.md +5 -5
- package/development/docs/README.en.md +2 -2
- package/development/docs/acceptance.en.md +2 -2
- package/development/docs/agent-development.en.md +1 -1
- package/development/docs/api/README.en.md +4 -2
- package/development/docs/api/README.md +2 -0
- package/development/docs/api/configuration-in-workflow.en.md +403 -0
- package/development/docs/api/configuration-in-workflow.md +403 -0
- package/development/docs/api/core.en.md +7 -7
- package/development/docs/api/core.md +6 -6
- package/development/docs/api/decorators.en.md +20 -0
- package/development/docs/api/decorators.md +20 -0
- package/development/docs/api/examples.en.md +1 -1
- package/development/docs/api/examples.md +1 -1
- package/development/docs/api/kits.en.md +22 -4
- package/development/docs/api/kits.md +22 -4
- package/development/docs/api/knowledge-answering.en.md +4 -1
- package/development/docs/api/knowledge-answering.md +4 -1
- package/development/docs/api/mock.en.md +2 -0
- package/development/docs/api/mock.md +2 -0
- package/development/docs/api/reference.en.md +508 -410
- package/development/docs/api/reference.md +508 -410
- package/development/docs/api/support.en.md +55 -9
- package/development/docs/api/support.md +53 -7
- package/development/docs/api/types.en.md +35 -1
- package/development/docs/api/types.md +43 -0
- package/development/docs/basic-usage.en.md +1 -1
- package/development/docs/basic-usage.md +1 -1
- package/development/docs/create-app.en.md +1 -1
- package/development/docs/examples/registration/associated.mjs +8 -0
- package/development/docs/examples/registration/independent.mjs +20 -0
- package/development/docs/examples/registration/protocol.mjs +48 -0
- package/development/docs/examples/registration/run.mjs +47 -0
- package/development/docs/examples/registration/tools.mjs +75 -0
- package/development/docs/examples/registration/workflow.mjs +109 -0
- package/development/docs/flows/knowledge-maintenance.en.md +1 -1
- package/development/docs/materials.en.md +1 -1
- package/development/docs/mechanisms.en.md +2 -2
- package/development/docs/mechanisms.md +1 -1
- package/development/docs/operations.en.md +1 -1
- package/development/docs/records.en.md +1 -1
- package/development/docs/registration.en.md +4 -4
- package/development/docs/registration.md +2 -2
- package/development/skills/agent-core-app/SKILL.md +4 -4
- package/development/skills/agent-core-app/templates/node-ts/README.md.tpl +1 -1
- package/development/skills/agent-core-app/templates/node-ts/src/catalog.ts.tpl +2 -2
- package/development/skills/agent-core-app/templates/node-ts/test/app.test.mjs.tpl +1 -1
- package/dist/cjs/capabilities/index.js +5 -12
- package/dist/cjs/capabilities/model.js +56 -12
- package/dist/cjs/capabilities/tool-conditions.js +65 -0
- package/dist/cjs/capabilities/tool-runtime.js +10 -3
- package/dist/cjs/context/audit.js +5 -8
- package/dist/cjs/context/index.js +3 -4
- package/dist/cjs/index.js +21 -17
- package/dist/cjs/kits/answering/tasks.js +5 -5
- package/dist/cjs/kits/domains/catalog.js +113 -0
- package/dist/cjs/kits/domains/index.js +20 -0
- package/dist/cjs/kits/{intents → domains}/registry.js +77 -31
- package/dist/cjs/kits/{intents → domains}/scopes.js +21 -21
- package/dist/cjs/kits/index.js +14 -13
- package/dist/cjs/kits/presentation/formats.js +110 -0
- package/dist/cjs/kits/presentation/index.js +10 -5
- package/dist/cjs/kits/reflection.js +2 -2
- package/dist/cjs/kits/text-blocks.js +101 -0
- package/dist/cjs/kits/tools.js +246 -158
- package/dist/cjs/model/index.js +2 -6
- package/dist/cjs/model/interactions/calls.js +61 -0
- package/dist/cjs/model/interactions/json-object.js +11 -11
- package/dist/cjs/model/interactions/native-functions.js +17 -23
- package/dist/cjs/model/message-diagnostics.js +13 -3
- package/dist/cjs/model/options.js +2 -0
- package/dist/cjs/model/preparation.js +39 -6
- package/dist/cjs/model/runner.js +14 -0
- package/dist/cjs/model/selection-transport.js +4 -4
- package/dist/cjs/model/token-budget.js +3 -0
- package/dist/cjs/model/transports.js +3 -2
- package/dist/cjs/structs/index.js +7 -6
- package/dist/cjs/structs/kits/presentation/formats.js +2 -0
- package/dist/cjs/structs/kits/text-blocks.js +11 -0
- package/dist/cjs/structs/model/session.js +11 -0
- package/dist/cjs/structs/support/associations.js +2 -0
- package/dist/cjs/support/associations.js +79 -0
- package/dist/cjs/support/context/snapshot.js +11 -1
- package/dist/cjs/support/decorators/index.js +45 -3
- package/dist/cjs/support/index.js +1 -0
- package/dist/cjs/support/model/capabilities.js +35 -5
- package/dist/cjs/support/model/chat-completions.js +11 -2
- package/dist/cjs/support/model/completion/calls.js +10 -56
- package/dist/cjs/support/model/preview-rules.js +11 -11
- package/dist/cjs/support/model/reply-preview.js +3 -3
- package/dist/cjs/support/model/session.js +152 -0
- package/dist/cjs/support/model/stage-transport.js +8 -8
- package/dist/cjs/support/model/transports.js +5 -2
- package/dist/cjs/support/tools.js +42 -17
- package/dist/esm/capabilities/index.d.ts +5 -10
- package/dist/esm/capabilities/index.js +5 -9
- package/dist/esm/capabilities/model.d.ts +17 -13
- package/dist/esm/capabilities/model.js +54 -10
- package/dist/esm/capabilities/tool-conditions.d.ts +9 -0
- package/dist/esm/capabilities/tool-conditions.js +59 -0
- package/dist/esm/capabilities/tool-runtime.js +10 -3
- package/dist/esm/capabilities/tools.d.ts +3 -3
- package/dist/esm/context/audit.js +5 -8
- package/dist/esm/context/index.d.ts +3 -4
- package/dist/esm/context/index.js +3 -4
- package/dist/esm/index.d.ts +19 -13
- package/dist/esm/index.js +18 -15
- package/dist/esm/kits/answering/tasks.d.ts +6 -6
- package/dist/esm/kits/answering/tasks.js +5 -5
- package/dist/esm/kits/domains/catalog.d.ts +42 -0
- package/dist/esm/kits/domains/catalog.js +110 -0
- package/dist/esm/kits/domains/index.d.ts +4 -0
- package/dist/esm/kits/domains/index.js +4 -0
- package/dist/esm/kits/domains/registry.d.ts +100 -0
- package/dist/esm/kits/{intents → domains}/registry.js +77 -31
- package/dist/esm/kits/{intents → domains}/scopes.d.ts +18 -18
- package/dist/esm/kits/{intents → domains}/scopes.js +21 -21
- package/dist/esm/kits/index.d.ts +6 -5
- package/dist/esm/kits/index.js +6 -5
- package/dist/esm/kits/presentation/formats.d.ts +42 -0
- package/dist/esm/kits/presentation/formats.js +105 -0
- package/dist/esm/kits/presentation/index.d.ts +14 -5
- package/dist/esm/kits/presentation/index.js +10 -5
- package/dist/esm/kits/reflection.js +3 -3
- package/dist/esm/kits/text-blocks.d.ts +24 -0
- package/dist/esm/kits/text-blocks.js +97 -0
- package/dist/esm/kits/tools.d.ts +69 -52
- package/dist/esm/kits/tools.js +246 -158
- package/dist/esm/model/index.d.ts +2 -6
- package/dist/esm/model/index.js +2 -6
- package/dist/esm/model/interactions/calls.d.ts +40 -0
- package/dist/esm/model/interactions/calls.js +58 -0
- package/dist/esm/model/interactions/json-object.js +11 -11
- package/dist/esm/model/interactions/native-functions.js +17 -23
- package/dist/esm/model/message-diagnostics.d.ts +6 -5
- package/dist/esm/model/message-diagnostics.js +13 -3
- package/dist/esm/model/options.js +2 -0
- package/dist/esm/model/preparation.js +39 -6
- package/dist/esm/model/runner.js +14 -0
- package/dist/esm/model/selection-transport.js +4 -4
- package/dist/esm/model/token-budget.js +3 -0
- package/dist/esm/model/transports.d.ts +2 -1
- package/dist/esm/model/transports.js +3 -2
- package/dist/esm/structs/capabilities/invocation.d.ts +1 -1
- package/dist/esm/structs/capabilities/model.d.ts +42 -11
- package/dist/esm/structs/capabilities/tools.d.ts +9 -4
- package/dist/esm/structs/common.d.ts +1 -1
- package/dist/esm/structs/index.d.ts +7 -6
- package/dist/esm/structs/index.js +7 -6
- package/dist/esm/structs/kits/answering/tasks.d.ts +2 -2
- package/dist/esm/structs/kits/{intents → domains}/catalog.d.ts +20 -20
- package/dist/esm/structs/kits/{intents → domains}/registry.d.ts +24 -21
- package/dist/esm/structs/kits/{intents → domains}/scopes.d.ts +9 -9
- package/dist/esm/structs/kits/presentation/formats.d.ts +42 -0
- package/dist/esm/structs/kits/presentation/formats.js +1 -0
- package/dist/esm/structs/kits/text-blocks.d.ts +25 -0
- package/dist/esm/structs/kits/text-blocks.js +10 -0
- package/dist/esm/structs/kits/tools.d.ts +82 -83
- package/dist/esm/structs/model/interactions.d.ts +18 -11
- package/dist/esm/structs/model/messages.d.ts +34 -2
- package/dist/esm/structs/model/runtime.d.ts +7 -0
- package/dist/esm/structs/model/session.d.ts +29 -0
- package/dist/esm/structs/model/session.js +10 -0
- package/dist/esm/structs/support/associations.d.ts +22 -0
- package/dist/esm/structs/support/associations.js +1 -0
- package/dist/esm/structs/support/model/interactions.d.ts +2 -2
- package/dist/esm/structs/support/model/messages.d.ts +6 -13
- package/dist/esm/structs/support/tools.d.ts +23 -23
- package/dist/esm/support/associations.d.ts +26 -0
- package/dist/esm/support/associations.js +76 -0
- package/dist/esm/support/context/snapshot.js +11 -1
- package/dist/esm/support/decorators/index.d.ts +13 -2
- package/dist/esm/support/decorators/index.js +40 -3
- package/dist/esm/support/decorators/pool.d.ts +6 -5
- package/dist/esm/support/decorators/types.d.ts +3 -1
- package/dist/esm/support/index.d.ts +1 -0
- package/dist/esm/support/index.js +1 -0
- package/dist/esm/support/model/capabilities.d.ts +8 -3
- package/dist/esm/support/model/capabilities.js +35 -5
- package/dist/esm/support/model/chat-completions.js +11 -2
- package/dist/esm/support/model/completion/calls.d.ts +6 -34
- package/dist/esm/support/model/completion/calls.js +8 -55
- package/dist/esm/support/model/index.d.ts +1 -1
- package/dist/esm/support/model/preview-rules.d.ts +13 -8
- package/dist/esm/support/model/preview-rules.js +11 -11
- package/dist/esm/support/model/reply-preview.d.ts +2 -2
- package/dist/esm/support/model/reply-preview.js +3 -3
- package/dist/esm/support/model/session.d.ts +61 -0
- package/dist/esm/support/model/session.js +148 -0
- package/dist/esm/support/model/stage-transport.d.ts +1 -1
- package/dist/esm/support/model/stage-transport.js +9 -9
- package/dist/esm/support/model/transports.d.ts +2 -0
- package/dist/esm/support/model/transports.js +2 -1
- package/dist/esm/support/tools.d.ts +11 -3
- package/dist/esm/support/tools.js +43 -18
- package/dist/esm/utils/catalog.d.ts +1 -1
- package/package.json +20 -6
- package/dist/cjs/execution/index.js +0 -30
- package/dist/cjs/kits/intents/catalog.js +0 -82
- package/dist/cjs/kits/intents/index.js +0 -35
- package/dist/esm/execution/index.d.ts +0 -11
- package/dist/esm/execution/index.js +0 -11
- package/dist/esm/kits/intents/catalog.d.ts +0 -39
- package/dist/esm/kits/intents/catalog.js +0 -79
- package/dist/esm/kits/intents/index.d.ts +0 -22
- package/dist/esm/kits/intents/index.js +0 -18
- package/dist/esm/kits/intents/registry.d.ts +0 -88
- /package/dist/cjs/structs/kits/{intents → domains}/catalog.js +0 -0
- /package/dist/cjs/structs/kits/{intents → domains}/registry.js +0 -0
- /package/dist/cjs/structs/kits/{intents → domains}/scopes.js +0 -0
- /package/dist/esm/structs/kits/{intents → domains}/catalog.js +0 -0
- /package/dist/esm/structs/kits/{intents → domains}/registry.js +0 -0
- /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,
|
|
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 },
|
|
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
|
-
|
|
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.
|
|
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
|
|
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: `
|
|
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
|
|
26
|
-
const registry = new model_js_1.
|
|
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
|
-
|
|
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 =
|
|
4
|
-
const model_protocol_js_1 = require("../../../utils/model-protocol.js");
|
|
3
|
+
exports.createToolCallCollector = void 0;
|
|
5
4
|
/**
|
|
6
|
-
*
|
|
5
|
+
* Tool-call delta aggregation, re-exported from Core.
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
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
|
-
|
|
12
|
-
|
|
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
|
|
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
|
|
93
|
-
for (const capability of options.
|
|
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 ||
|
|
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
|
-
|
|
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,
|
|
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 =
|
|
107
|
-
(0, rules_js_1.breakWhile)(new Set(ids).size !== ids.length || ids.some((id) => !
|
|
108
|
-
(0, rules_js_1.breakWhile)(preview !== undefined && !['text', '
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
|
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 `
|
|
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.
|
|
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,
|
|
39
|
-
const project = (stage,
|
|
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.
|
|
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 =
|
|
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
|
-
|
|
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.
|