@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.
- package/CHANGELOG.md +41 -0
- package/README.md +33 -31
- 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 +6 -2
- package/development/docs/api/README.md +4 -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/observability.en.md +37 -11
- package/development/docs/api/observability.md +64 -11
- package/development/docs/api/reference.en.md +876 -657
- package/development/docs/api/reference.md +662 -508
- package/development/docs/api/support.en.md +55 -9
- package/development/docs/api/support.md +53 -7
- package/development/docs/api/types.en.md +36 -1
- package/development/docs/api/types.md +44 -0
- package/development/docs/api/workflow-views.en.md +64 -0
- package/development/docs/api/workflow-views.md +78 -0
- package/development/docs/api/workflow.en.md +6 -2
- package/development/docs/api/workflow.md +6 -2
- 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 +16 -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/invocation.js +21 -1
- package/dist/cjs/capabilities/model.js +56 -12
- package/dist/cjs/capabilities/tool-conditions.js +65 -0
- package/dist/cjs/capabilities/tool-runtime.js +18 -4
- package/dist/cjs/capabilities/tools.js +12 -17
- package/dist/cjs/context/audit.js +5 -8
- package/dist/cjs/context/index.js +3 -4
- package/dist/cjs/diagnostics/index.js +51 -3
- package/dist/cjs/diagnostics/native-sub-flow.js +106 -0
- package/dist/cjs/diagnostics/sub-flow.js +278 -32
- package/dist/cjs/execution/engine.js +3 -2
- package/dist/cjs/execution/events.js +5 -5
- package/dist/cjs/execution/reporting.js +18 -28
- package/dist/cjs/execution/workflow-chain.js +211 -0
- package/dist/cjs/execution/workflow-graph.js +72 -0
- package/dist/cjs/execution/workflow.js +34 -6
- package/dist/cjs/index.js +21 -17
- package/dist/cjs/kits/aggregation.js +17 -14
- package/dist/cjs/kits/answering/checks.js +2 -1
- package/dist/cjs/kits/answering/flow.js +24 -21
- package/dist/cjs/kits/answering/tasks.js +30 -25
- package/dist/cjs/kits/delivery.js +36 -24
- 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/knowledge/catalog.js +33 -30
- package/dist/cjs/kits/policies.js +3 -2
- package/dist/cjs/kits/presentation/formats.js +110 -0
- package/dist/cjs/kits/presentation/index.js +10 -5
- package/dist/cjs/kits/presentation/outputs.js +2 -1
- package/dist/cjs/kits/reflection.js +2 -2
- package/dist/cjs/kits/retrieval.js +7 -1
- package/dist/cjs/kits/text-blocks.js +101 -0
- package/dist/cjs/kits/tools.js +247 -158
- package/dist/cjs/model/decision-retry.js +2 -1
- 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 +34 -5
- 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/domains/scopes.js +2 -0
- 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/nodes.js +48 -45
- package/dist/cjs/support/context/processing.js +6 -3
- 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/cjs/utils/invocation.js +1 -0
- package/dist/esm/capabilities/index.d.ts +5 -10
- package/dist/esm/capabilities/index.js +5 -9
- package/dist/esm/capabilities/invocation.js +21 -1
- 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 +18 -4
- package/dist/esm/capabilities/tools.d.ts +3 -3
- package/dist/esm/capabilities/tools.js +12 -17
- 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/diagnostics/index.d.ts +1 -0
- package/dist/esm/diagnostics/index.js +48 -2
- package/dist/esm/diagnostics/native-sub-flow.d.ts +94 -0
- package/dist/esm/diagnostics/native-sub-flow.js +101 -0
- package/dist/esm/diagnostics/sub-flow.d.ts +56 -4
- package/dist/esm/diagnostics/sub-flow.js +271 -32
- package/dist/esm/execution/engine.d.ts +1 -0
- package/dist/esm/execution/engine.js +3 -2
- package/dist/esm/execution/events.js +5 -5
- package/dist/esm/execution/reporting.d.ts +6 -12
- package/dist/esm/execution/reporting.js +19 -29
- package/dist/esm/execution/workflow-chain.d.ts +3 -0
- package/dist/esm/execution/workflow-chain.js +208 -0
- package/dist/esm/execution/workflow-graph.d.ts +7 -0
- package/dist/esm/execution/workflow-graph.js +68 -0
- package/dist/esm/execution/workflow.d.ts +6 -0
- package/dist/esm/execution/workflow.js +34 -6
- package/dist/esm/index.d.ts +19 -13
- package/dist/esm/index.js +18 -15
- package/dist/esm/kits/aggregation.d.ts +1 -1
- package/dist/esm/kits/aggregation.js +17 -14
- package/dist/esm/kits/answering/checks.js +2 -1
- package/dist/esm/kits/answering/flow.js +24 -21
- package/dist/esm/kits/answering/tasks.d.ts +6 -6
- package/dist/esm/kits/answering/tasks.js +30 -25
- package/dist/esm/kits/delivery.d.ts +0 -9
- package/dist/esm/kits/delivery.js +36 -24
- 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/knowledge/catalog.js +33 -30
- package/dist/esm/kits/policies.d.ts +1 -1
- package/dist/esm/kits/policies.js +3 -2
- 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/presentation/outputs.js +2 -1
- package/dist/esm/kits/reflection.js +3 -3
- package/dist/esm/kits/retrieval.js +7 -1
- 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 +247 -158
- package/dist/esm/model/decision-retry.d.ts +2 -0
- package/dist/esm/model/decision-retry.js +2 -1
- 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.d.ts +2 -0
- package/dist/esm/model/runner.js +34 -5
- 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 +3 -1
- package/dist/esm/structs/capabilities/model.d.ts +42 -11
- package/dist/esm/structs/capabilities/tools.d.ts +16 -7
- package/dist/esm/structs/common.d.ts +3 -1
- package/dist/esm/structs/debug.d.ts +36 -20
- package/dist/esm/structs/execution/workflow-views.d.ts +123 -0
- package/dist/esm/structs/execution/workflow.d.ts +4 -3
- package/dist/esm/structs/index.d.ts +8 -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/domains/scopes.js +1 -0
- 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 +9 -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/nodes.js +48 -45
- package/dist/esm/support/context/processing.js +6 -3
- 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/dist/esm/utils/invocation.d.ts +1 -0
- package/dist/esm/utils/invocation.js +1 -0
- 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/cjs/utils/debug.js +0 -30
- 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/esm/utils/debug.d.ts +0 -27
- package/dist/esm/utils/debug.js +0 -27
- /package/dist/cjs/structs/{kits/intents/catalog.js → execution/workflow-views.js} +0 -0
- /package/dist/cjs/structs/kits/{intents/registry.js → domains/catalog.js} +0 -0
- /package/dist/cjs/structs/kits/{intents/scopes.js → domains/registry.js} +0 -0
- /package/dist/esm/structs/{kits/intents/catalog.js → execution/workflow-views.js} +0 -0
- /package/dist/esm/structs/kits/{intents/registry.js → domains/catalog.js} +0 -0
- /package/dist/esm/structs/kits/{intents/scopes.js → domains/registry.js} +0 -0
|
@@ -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.
|
|
@@ -6,7 +6,7 @@ exports.defineToolCatalog = defineToolCatalog;
|
|
|
6
6
|
* Tool support: turn typed application tool definitions into a Core-schedulable tool catalog.
|
|
7
7
|
*
|
|
8
8
|
* A tool declaration pairs an input schema with authorization, execution and output parsing. The
|
|
9
|
-
* catalog projects those tools into model
|
|
9
|
+
* catalog projects those tools into model tools and binds them to the Core tool registry
|
|
10
10
|
* when a runtime request supplies the application. Support only assembles the registration; Core
|
|
11
11
|
* still performs authorization, invocation, budgets and cancellation.
|
|
12
12
|
*
|
|
@@ -17,6 +17,7 @@ const tool_runtime_js_1 = require("./tool-runtime.js");
|
|
|
17
17
|
const schema_js_1 = require("./schema.js");
|
|
18
18
|
const catalog_js_1 = require("../utils/catalog.js");
|
|
19
19
|
const synchronous_js_1 = require("../utils/synchronous.js");
|
|
20
|
+
const tool_conditions_js_1 = require("../capabilities/tool-conditions.js");
|
|
20
21
|
/**
|
|
21
22
|
* Validate one tool declaration and freeze a detached copy of it.
|
|
22
23
|
*
|
|
@@ -39,11 +40,24 @@ function defineTool(definition) {
|
|
|
39
40
|
throw new TypeError('Missing tool handler');
|
|
40
41
|
const inputSchema = (0, schema_js_1.defineSchema)(definition.inputSchema);
|
|
41
42
|
const authorize = definition.authorize.bind(definition);
|
|
43
|
+
if (definition.active !== undefined &&
|
|
44
|
+
typeof definition.active !== 'boolean' &&
|
|
45
|
+
typeof definition.active !== 'function')
|
|
46
|
+
throw new TypeError('Invalid tool active condition');
|
|
47
|
+
const active = typeof definition.active === 'function'
|
|
48
|
+
? definition.active.bind(definition)
|
|
49
|
+
: definition.active;
|
|
50
|
+
const asIntent = (0, tool_conditions_js_1.bindIntent)((0, tool_conditions_js_1.snapshotIntent)(typeof definition.asIntent === 'function'
|
|
51
|
+
? definition.asIntent.bind(definition)
|
|
52
|
+
: definition.asIntent), definition);
|
|
42
53
|
return Object.freeze({
|
|
43
54
|
id,
|
|
44
55
|
kind,
|
|
45
56
|
description,
|
|
46
57
|
inputSchema,
|
|
58
|
+
active,
|
|
59
|
+
asIntent,
|
|
60
|
+
resolve: definition.resolve?.bind(definition) ?? ((input) => ({ toolId: id, input })),
|
|
47
61
|
authorize(input, context) {
|
|
48
62
|
return (0, synchronous_js_1.maybeAssertion)(authorize(input, context), 'Authorization must return void; rejection must throw');
|
|
49
63
|
},
|
|
@@ -52,22 +66,14 @@ function defineTool(definition) {
|
|
|
52
66
|
parseOutput: definition.parseOutput.bind(definition),
|
|
53
67
|
});
|
|
54
68
|
}
|
|
55
|
-
/**
|
|
56
|
-
* Compile tool declarations into a frozen catalog with model capabilities and runtime binding.
|
|
57
|
-
*
|
|
58
|
-
* Each tool becomes a model capability whose resolver returns `{ toolId, input }`; the model only
|
|
59
|
-
* chooses among registered tools, it never invokes them directly.
|
|
60
|
-
*
|
|
61
|
-
* @param definitions Tool declarations in catalog order.
|
|
62
|
-
* @returns A frozen catalog with `capabilities`, `select` and `bind`.
|
|
63
|
-
* @throws {TypeError} When a tool declaration is invalid or a tool ID is duplicated.
|
|
64
|
-
*/
|
|
65
69
|
function defineToolCatalog(definitions) {
|
|
66
70
|
const entries = definitions.map((definition) => defineTool(definition));
|
|
67
71
|
const view = (0, catalog_js_1.readonlyCatalog)(entries, (id) => new TypeError(`Unknown tool: ${id}`));
|
|
68
|
-
const
|
|
72
|
+
const tools = new model_js_1.ModelToolRegistry(entries.map((tool) => ({
|
|
69
73
|
id: tool.id,
|
|
70
74
|
description: tool.description,
|
|
75
|
+
active: tool.active,
|
|
76
|
+
asIntent: tool.asIntent,
|
|
71
77
|
inputSchema: (0, schema_js_1.defineSchema)({
|
|
72
78
|
jsonSchema: tool.inputSchema.jsonSchema,
|
|
73
79
|
parse: (input) => input,
|
|
@@ -76,7 +82,7 @@ function defineToolCatalog(definitions) {
|
|
|
76
82
|
}))).seal();
|
|
77
83
|
return Object.freeze({
|
|
78
84
|
...view,
|
|
79
|
-
|
|
85
|
+
tools,
|
|
80
86
|
/**
|
|
81
87
|
* Narrow the catalog to the given tool IDs, preserving their declaration order.
|
|
82
88
|
*
|
|
@@ -84,9 +90,28 @@ function defineToolCatalog(definitions) {
|
|
|
84
90
|
* @returns A new catalog containing only the selected tools.
|
|
85
91
|
* @throws {TypeError} When an ID is not registered in this catalog.
|
|
86
92
|
*/
|
|
87
|
-
select(ids) {
|
|
88
|
-
|
|
89
|
-
|
|
93
|
+
select(ids, ...context) {
|
|
94
|
+
const seen = new Set();
|
|
95
|
+
const selected = ids
|
|
96
|
+
.map((id) => {
|
|
97
|
+
if (seen.has(id))
|
|
98
|
+
throw new TypeError(`Duplicate tool selection: ${id}`);
|
|
99
|
+
seen.add(id);
|
|
100
|
+
if (!view.has(id))
|
|
101
|
+
throw new TypeError(`Tool is not registered: ${id}`);
|
|
102
|
+
return view.require(id);
|
|
103
|
+
})
|
|
104
|
+
.filter((tool) => !context.length || (0, tool_conditions_js_1.toolActive)(tool.active, context[0]));
|
|
105
|
+
return defineToolCatalog(selected);
|
|
106
|
+
},
|
|
107
|
+
/** Discover demand-facing executable tools while preserving their execution contracts. */
|
|
108
|
+
withIntent(context) {
|
|
109
|
+
return defineToolCatalog(entries.flatMap((tool) => {
|
|
110
|
+
if (!(0, tool_conditions_js_1.toolActive)(tool.active, context))
|
|
111
|
+
return [];
|
|
112
|
+
const description = (0, tool_conditions_js_1.intentDescription)(tool.asIntent, tool.description, context);
|
|
113
|
+
return description === undefined ? [] : [{ ...tool, description }];
|
|
114
|
+
}));
|
|
90
115
|
},
|
|
91
116
|
/**
|
|
92
117
|
* Bind the catalog to one application runtime request.
|
|
@@ -103,7 +128,7 @@ function defineToolCatalog(definitions) {
|
|
|
103
128
|
errors: request.errors,
|
|
104
129
|
});
|
|
105
130
|
return Object.freeze({
|
|
106
|
-
|
|
131
|
+
tools,
|
|
107
132
|
get events() {
|
|
108
133
|
return registry.events;
|
|
109
134
|
},
|
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Capability registration surface: model
|
|
2
|
+
* Capability registration surface: model tools, executable tools and host-selected
|
|
3
3
|
* invocations.
|
|
4
4
|
*
|
|
5
|
-
* These registries hold declarations only. Which
|
|
5
|
+
* These registries hold declarations only. Which tools a stage may use, whether a
|
|
6
6
|
* call is authorized, and what a payload means remain App decisions; this barrel provides
|
|
7
|
-
* the mechanisms that validate, seal and execute those declarations.
|
|
7
|
+
* the mechanisms that validate, seal and execute those declarations. Optional Kit helpers
|
|
8
|
+
* such as interaction protocols and commands are imported from their own `/kits/*` entries.
|
|
8
9
|
*
|
|
9
10
|
* Exports: the model capability registry (`model`), the executable tool registry and its
|
|
10
11
|
* sync/async invocation entry points (`tools`), host-selected invocation execution
|
|
11
|
-
* (`invocation`)
|
|
12
|
-
* shape and validate model-produced interactions.
|
|
12
|
+
* (`invocation`) and the shared protocol registry.
|
|
13
13
|
*/
|
|
14
14
|
export * from './model.js';
|
|
15
15
|
export * from './tools.js';
|
|
16
16
|
export * from './invocation.js';
|
|
17
17
|
export * from '../utils/protocol-registry.js';
|
|
18
|
-
export { defineCommand, commandSchema } from '../kits/interaction/command.js';
|
|
19
|
-
export type { Command, CommandDefinition, ProtocolCheck, ProtocolField, ProtocolReason, ProtocolPredicate, ProtocolShape, RegisteredProtocol, } from '../structs/kits/interaction.js';
|
|
20
|
-
export * from '../kits/interaction/commands.js';
|
|
21
|
-
export * from '../kits/interaction/transfer.js';
|
|
22
|
-
export * from '../kits/interaction/handlers.js';
|
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Capability registration surface: model
|
|
2
|
+
* Capability registration surface: model tools, executable tools and host-selected
|
|
3
3
|
* invocations.
|
|
4
4
|
*
|
|
5
|
-
* These registries hold declarations only. Which
|
|
5
|
+
* These registries hold declarations only. Which tools a stage may use, whether a
|
|
6
6
|
* call is authorized, and what a payload means remain App decisions; this barrel provides
|
|
7
|
-
* the mechanisms that validate, seal and execute those declarations.
|
|
7
|
+
* the mechanisms that validate, seal and execute those declarations. Optional Kit helpers
|
|
8
|
+
* such as interaction protocols and commands are imported from their own `/kits/*` entries.
|
|
8
9
|
*
|
|
9
10
|
* Exports: the model capability registry (`model`), the executable tool registry and its
|
|
10
11
|
* sync/async invocation entry points (`tools`), host-selected invocation execution
|
|
11
|
-
* (`invocation`)
|
|
12
|
-
* shape and validate model-produced interactions.
|
|
12
|
+
* (`invocation`) and the shared protocol registry.
|
|
13
13
|
*/
|
|
14
14
|
export * from './model.js';
|
|
15
15
|
export * from './tools.js';
|
|
16
16
|
export * from './invocation.js';
|
|
17
17
|
export * from '../utils/protocol-registry.js';
|
|
18
|
-
export { defineCommand, commandSchema } from '../kits/interaction/command.js';
|
|
19
|
-
export * from '../kits/interaction/commands.js';
|
|
20
|
-
export * from '../kits/interaction/transfer.js';
|
|
21
|
-
export * from '../kits/interaction/handlers.js';
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Exports: `executeInvocation` and the invocation contracts re-exported at the bottom.
|
|
10
10
|
*/
|
|
11
|
+
import { nativeSubFlowSync } from '../diagnostics/native-sub-flow.js';
|
|
11
12
|
import { invocationId } from '../utils/invocation.js';
|
|
12
13
|
import { synchronous } from '../utils/synchronous.js';
|
|
13
14
|
import { diagnosticError } from '../diagnostics/index.js';
|
|
@@ -28,12 +29,30 @@ import { NodeReports } from '../execution/reporting.js';
|
|
|
28
29
|
* signal checks.
|
|
29
30
|
*/
|
|
30
31
|
export function executeInvocation(invocation, input, context, ports = {}) {
|
|
32
|
+
let logger;
|
|
33
|
+
try {
|
|
34
|
+
logger = ports.logger?.(context);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
/* Optional recording cannot block execution. */
|
|
38
|
+
}
|
|
39
|
+
const callId = invocationId();
|
|
40
|
+
return nativeSubFlowSync({
|
|
41
|
+
logger,
|
|
42
|
+
invocationId: callId,
|
|
43
|
+
get signal() {
|
|
44
|
+
return ports.signal?.(context);
|
|
45
|
+
},
|
|
46
|
+
}, 'invocation', invocation.id, (scopedLogger) => runInvocation(invocation, input, context, ports, scopedLogger, callId));
|
|
47
|
+
}
|
|
48
|
+
/** Execute the existing synchronous lifecycle without changing journal or error precedence. */
|
|
49
|
+
function runInvocation(invocation, input, context, ports, logger, executionId = invocationId()) {
|
|
31
50
|
const toolId = invocation.id;
|
|
32
51
|
// Identify the call before touching the ports: journal and diagnostics records cannot be
|
|
33
52
|
// reconciled with an anonymous handler.
|
|
34
53
|
if (!toolId?.trim())
|
|
35
54
|
throw new TypeError('Invalid invocation handler identity');
|
|
36
|
-
const journal = ports.journal?.(context), id =
|
|
55
|
+
const journal = ports.journal?.(context), id = executionId, startedAtMs = Date.now();
|
|
37
56
|
const diagnostics = ports.diagnostics?.(context)?.child(id, {
|
|
38
57
|
invocationId: id,
|
|
39
58
|
nodeRole: 'invocation',
|
|
@@ -64,6 +83,7 @@ export function executeInvocation(invocation, input, context, ports = {}) {
|
|
|
64
83
|
// The helper rejects a promise and drains its rejection: a handler that turns async must
|
|
65
84
|
// fail here instead of escaping as an unhandled rejection.
|
|
66
85
|
synchronous(invocation.call(input, context, {
|
|
86
|
+
logger,
|
|
67
87
|
mode: 'sync',
|
|
68
88
|
invocationId: id,
|
|
69
89
|
signal: signal ?? new AbortController().signal,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ModelToolRegistration, RegisteredModelTool, ModelSelection } from '../structs/capabilities/model.js';
|
|
2
2
|
export { modelProtocolError } from '../utils/model-protocol.js';
|
|
3
3
|
/** A request/stage projection is a sealed registry. Hosts filter availability before projection. */
|
|
4
|
-
export declare class
|
|
4
|
+
export declare class ModelToolRegistry {
|
|
5
5
|
/** Insertion-ordered entries; iteration order is the declaration order of the catalog. */
|
|
6
6
|
private readonly definitionsById;
|
|
7
7
|
/** Sealing is one-way: stage-time code must never extend the catalog it is executing. */
|
|
@@ -11,7 +11,7 @@ export declare class ModelCapabilityRegistry {
|
|
|
11
11
|
* @throws TypeError when a definition is invalid or its id is duplicated (raised by
|
|
12
12
|
* `register`).
|
|
13
13
|
*/
|
|
14
|
-
constructor(definitions?: Iterable<
|
|
14
|
+
constructor(definitions?: Iterable<ModelToolRegistration>);
|
|
15
15
|
/**
|
|
16
16
|
* Register one capability.
|
|
17
17
|
*
|
|
@@ -21,28 +21,28 @@ export declare class ModelCapabilityRegistry {
|
|
|
21
21
|
* @throws Error when the registry is already sealed.
|
|
22
22
|
* @throws TypeError when the declaration is invalid or its id is already registered.
|
|
23
23
|
*/
|
|
24
|
-
register<Result>(capability:
|
|
24
|
+
register<Result>(capability: ModelToolRegistration<Result>): this;
|
|
25
25
|
/** Frozen snapshot of the registered definitions, in insertion order. */
|
|
26
|
-
get definitions(): readonly Readonly<
|
|
26
|
+
get definitions(): readonly Readonly<RegisteredModelTool>[];
|
|
27
27
|
/** Registered ids in declaration order. */
|
|
28
28
|
ids(): readonly string[];
|
|
29
29
|
/** Live iterator over `[id, definition]` pairs; it reflects only entries added before sealing. */
|
|
30
|
-
entries(): IterableIterator<readonly [string,
|
|
30
|
+
entries(): IterableIterator<readonly [string, RegisteredModelTool]>;
|
|
31
31
|
/**
|
|
32
|
-
* Register several
|
|
32
|
+
* Register several tools.
|
|
33
33
|
*
|
|
34
34
|
* @param definitions Declarations applied in iteration order.
|
|
35
35
|
* @returns This registry, for chaining.
|
|
36
36
|
* @throws Error or TypeError under the same conditions as `register`.
|
|
37
37
|
*/
|
|
38
|
-
registerAll(definitions: Iterable<
|
|
38
|
+
registerAll(definitions: Iterable<ModelToolRegistration>): this;
|
|
39
39
|
/**
|
|
40
40
|
* @param id Capability id.
|
|
41
41
|
* @returns The registered definition.
|
|
42
42
|
* @throws TypeError when the id is not registered, which usually means a stage projection
|
|
43
43
|
* omitted it.
|
|
44
44
|
*/
|
|
45
|
-
require(id: string):
|
|
45
|
+
require(id: string): RegisteredModelTool;
|
|
46
46
|
/**
|
|
47
47
|
* @param id Capability id.
|
|
48
48
|
* @returns Whether the id is registered in this registry.
|
|
@@ -52,9 +52,9 @@ export declare class ModelCapabilityRegistry {
|
|
|
52
52
|
* @param id Capability id.
|
|
53
53
|
* @returns The registered definition, or undefined when absent.
|
|
54
54
|
*/
|
|
55
|
-
get(id: string):
|
|
55
|
+
get(id: string): RegisteredModelTool | undefined;
|
|
56
56
|
/** Live iterator over the registered definitions. */
|
|
57
|
-
values(): IterableIterator<
|
|
57
|
+
values(): IterableIterator<RegisteredModelTool>;
|
|
58
58
|
/**
|
|
59
59
|
* Close the registry to further registration.
|
|
60
60
|
*
|
|
@@ -72,7 +72,11 @@ export declare class ModelCapabilityRegistry {
|
|
|
72
72
|
* @throws TypeError when the selection is empty or contains a duplicate id.
|
|
73
73
|
* @throws Error when an id was never registered.
|
|
74
74
|
*/
|
|
75
|
-
select(ids: readonly string[]):
|
|
75
|
+
select(ids: readonly string[], context?: unknown): ModelToolRegistry;
|
|
76
|
+
/** Discover active demand-facing tools without tying the projection to a workflow entry. */
|
|
77
|
+
withIntent(context: unknown): ModelToolRegistry;
|
|
78
|
+
/** Pin the host context and recheck activation before accepting a model proposal. */
|
|
79
|
+
private bound;
|
|
76
80
|
/**
|
|
77
81
|
* Parse model-supplied arguments and run the selected capability.
|
|
78
82
|
*
|
|
@@ -87,4 +91,4 @@ export declare class ModelCapabilityRegistry {
|
|
|
87
91
|
stageId: string;
|
|
88
92
|
}>): unknown;
|
|
89
93
|
}
|
|
90
|
-
export type {
|
|
94
|
+
export type { AsIntent, IntentOptions, ToolCondition, ToolContext, ToolProposal, ModelTool, ModelToolRegistration, RegisteredModelTool, ModelSelection, ModelToolSource, ModelToolCatalog, } from '../structs/capabilities/model.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Declarative catalog of model
|
|
2
|
+
* Declarative catalog of model tools for a request or one stage projection.
|
|
3
3
|
*
|
|
4
4
|
* A capability pairs an id and description with an input schema and a synchronous resolver,
|
|
5
5
|
* letting stage code parse model-supplied arguments and produce a typed value. Registration
|
|
@@ -9,14 +9,15 @@
|
|
|
9
9
|
* The registry is mutable until `seal()`. `select()` derives a sealed subset for a stage and
|
|
10
10
|
* shares the already-frozen entries rather than re-validating or re-wrapping them.
|
|
11
11
|
*
|
|
12
|
-
* Exports: `
|
|
12
|
+
* Exports: `ModelToolRegistry`, `modelProtocolError`, and the capability types.
|
|
13
13
|
*/
|
|
14
14
|
import { synchronous } from '../utils/synchronous.js';
|
|
15
15
|
import { modelProtocolError } from '../utils/model-protocol.js';
|
|
16
16
|
import { snapshotSchemaAdapter } from '../utils/schema-adapter.js';
|
|
17
|
+
import { snapshotIntent, toolActive, intentDescription, bindIntent } from './tool-conditions.js';
|
|
17
18
|
export { modelProtocolError } from '../utils/model-protocol.js';
|
|
18
19
|
/** A request/stage projection is a sealed registry. Hosts filter availability before projection. */
|
|
19
|
-
export class
|
|
20
|
+
export class ModelToolRegistry {
|
|
20
21
|
/** Insertion-ordered entries; iteration order is the declaration order of the catalog. */
|
|
21
22
|
definitionsById = new Map();
|
|
22
23
|
/** Sealing is one-way: stage-time code must never extend the catalog it is executing. */
|
|
@@ -47,13 +48,22 @@ export class ModelCapabilityRegistry {
|
|
|
47
48
|
if (!capability.id?.trim() ||
|
|
48
49
|
!capability.description?.trim() ||
|
|
49
50
|
schema?.type !== 'object' ||
|
|
50
|
-
typeof capability.resolve !== 'function' ||
|
|
51
|
+
(capability.resolve !== undefined && typeof capability.resolve !== 'function') ||
|
|
52
|
+
(capability.active !== undefined &&
|
|
53
|
+
typeof capability.active !== 'function' &&
|
|
54
|
+
typeof capability.active !== 'boolean') ||
|
|
51
55
|
this.definitionsById.has(capability.id))
|
|
52
56
|
throw new TypeError('Invalid or duplicate model capability');
|
|
53
57
|
// Clone and freeze the schema, and pin `parse`, so the stored entry is independent of
|
|
54
58
|
// the definition object the host may keep mutating.
|
|
55
59
|
const inputSchema = snapshotSchemaAdapter(capability.inputSchema, 'Model input parsers must be synchronous');
|
|
56
|
-
const resolver = capability.resolve
|
|
60
|
+
const resolver = capability.resolve?.bind(capability) ?? ((value) => value);
|
|
61
|
+
const asIntent = bindIntent(snapshotIntent(typeof capability.asIntent === 'function'
|
|
62
|
+
? capability.asIntent.bind(capability)
|
|
63
|
+
: capability.asIntent), capability);
|
|
64
|
+
const active = typeof capability.active === 'function'
|
|
65
|
+
? capability.active.bind(capability)
|
|
66
|
+
: capability.active;
|
|
57
67
|
// Bind once here: a later caller cannot substitute its own receiver for the resolver.
|
|
58
68
|
const resolve = (value, context) => synchronous(resolver(value, context), 'Model capability resolvers must be synchronous');
|
|
59
69
|
this.definitionsById.set(capability.id, Object.freeze({
|
|
@@ -61,6 +71,8 @@ export class ModelCapabilityRegistry {
|
|
|
61
71
|
description: capability.description,
|
|
62
72
|
inputSchema,
|
|
63
73
|
resolve,
|
|
74
|
+
...(asIntent !== undefined ? { asIntent } : {}),
|
|
75
|
+
...(active !== undefined ? { active } : {}),
|
|
64
76
|
}));
|
|
65
77
|
return this;
|
|
66
78
|
}
|
|
@@ -77,7 +89,7 @@ export class ModelCapabilityRegistry {
|
|
|
77
89
|
return this.definitionsById.entries();
|
|
78
90
|
}
|
|
79
91
|
/**
|
|
80
|
-
* Register several
|
|
92
|
+
* Register several tools.
|
|
81
93
|
*
|
|
82
94
|
* @param definitions Declarations applied in iteration order.
|
|
83
95
|
* @returns This registry, for chaining.
|
|
@@ -138,21 +150,53 @@ export class ModelCapabilityRegistry {
|
|
|
138
150
|
* @throws TypeError when the selection is empty or contains a duplicate id.
|
|
139
151
|
* @throws Error when an id was never registered.
|
|
140
152
|
*/
|
|
141
|
-
select(ids) {
|
|
153
|
+
select(ids, context) {
|
|
142
154
|
if (!ids.length || new Set(ids).size !== ids.length)
|
|
143
155
|
throw new TypeError('Invalid capability selection');
|
|
144
|
-
const selected = new
|
|
156
|
+
const selected = new ModelToolRegistry();
|
|
145
157
|
for (const id of ids) {
|
|
146
158
|
const capability = this.definitionsById.get(id);
|
|
147
159
|
if (!capability)
|
|
148
160
|
throw new Error(`Model capability is not registered: ${id}`);
|
|
161
|
+
if (arguments.length > 1) {
|
|
162
|
+
if (!toolActive(capability.active, context))
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
else if (capability.active === false) {
|
|
166
|
+
// Boolean activation is evaluable without a host context; predicate activation still
|
|
167
|
+
// needs an explicit context projection.
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
149
170
|
// Registration already detached/froze the schema and pinned its handlers.
|
|
150
171
|
// Stage projections share those immutable entries, not another clone and
|
|
151
172
|
// another layer of parser/resolver wrappers for every selection.
|
|
152
|
-
selected.definitionsById.set(id, capability);
|
|
173
|
+
selected.definitionsById.set(id, arguments.length > 1 ? this.bound(capability, context) : capability);
|
|
153
174
|
}
|
|
154
175
|
return selected.seal();
|
|
155
176
|
}
|
|
177
|
+
/** Discover active demand-facing tools without tying the projection to a workflow entry. */
|
|
178
|
+
withIntent(context) {
|
|
179
|
+
const selected = new ModelToolRegistry();
|
|
180
|
+
for (const tool of this.definitionsById.values()) {
|
|
181
|
+
if (!toolActive(tool.active, context))
|
|
182
|
+
continue;
|
|
183
|
+
const description = intentDescription(tool.asIntent, tool.description, context);
|
|
184
|
+
if (description !== undefined)
|
|
185
|
+
selected.definitionsById.set(tool.id, Object.freeze({ ...this.bound(tool, context), description }));
|
|
186
|
+
}
|
|
187
|
+
return selected.seal();
|
|
188
|
+
}
|
|
189
|
+
/** Pin the host context and recheck activation before accepting a model proposal. */
|
|
190
|
+
bound(tool, context) {
|
|
191
|
+
return Object.freeze({
|
|
192
|
+
...tool,
|
|
193
|
+
resolve: (input, stage) => {
|
|
194
|
+
if (!toolActive(tool.active, context))
|
|
195
|
+
modelProtocolError('Tool is inactive');
|
|
196
|
+
return tool.resolve(input, stage);
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
}
|
|
156
200
|
/**
|
|
157
201
|
* Parse model-supplied arguments and run the selected capability.
|
|
158
202
|
*
|
|
@@ -167,7 +211,7 @@ export class ModelCapabilityRegistry {
|
|
|
167
211
|
const { stageId } = context;
|
|
168
212
|
// Model output is untrusted: unknown ids and non-object arguments are protocol failures,
|
|
169
213
|
// not ordinary `undefined` results.
|
|
170
|
-
const capability = this.definitionsById.get(selection.
|
|
214
|
+
const capability = this.definitionsById.get(selection.toolId) ??
|
|
171
215
|
modelProtocolError('Model capability is unavailable in this stage');
|
|
172
216
|
if (!selection.input || typeof selection.input !== 'object' || Array.isArray(selection.input))
|
|
173
217
|
modelProtocolError('Model capability input must be an object');
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AsIntent, ToolCondition } from '../structs/capabilities/model.js';
|
|
2
|
+
/** Validate and snapshot discovery metadata without evaluating host predicates. */
|
|
3
|
+
export declare function snapshotIntent<Context>(value: AsIntent<Context> | undefined): AsIntent<Context> | undefined;
|
|
4
|
+
/** Bind an optional object-form predicate to its owning Tool, without touching other forms. */
|
|
5
|
+
export declare function bindIntent<Context>(value: AsIntent<Context> | undefined, owner: unknown): AsIntent<Context> | undefined;
|
|
6
|
+
/** Check activation and reject asynchronous or nonboolean predicate results. */
|
|
7
|
+
export declare function toolActive<Context>(condition: ToolCondition<Context> | undefined, context: Context): boolean;
|
|
8
|
+
/** Resolve the demand-facing description only when discovery is enabled. */
|
|
9
|
+
export declare function intentDescription<Context>(metadata: AsIntent<Context> | undefined, fallback: string, context: Context): string | undefined;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Tool metadata validation and synchronous activation shared by registration and execution. */
|
|
2
|
+
import { booleanResult } from '../utils/synchronous.js';
|
|
3
|
+
/** Validate and snapshot discovery metadata without evaluating host predicates. */
|
|
4
|
+
export function snapshotIntent(value) {
|
|
5
|
+
if (value === undefined || value === true || typeof value === 'function')
|
|
6
|
+
return value;
|
|
7
|
+
if (typeof value === 'string') {
|
|
8
|
+
if (!value.trim())
|
|
9
|
+
throw new TypeError('Intent description must not be blank');
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
13
|
+
throw new TypeError('Invalid asIntent metadata');
|
|
14
|
+
if (value.description !== undefined &&
|
|
15
|
+
(typeof value.description !== 'string' || !value.description.trim()))
|
|
16
|
+
throw new TypeError('Invalid intent description');
|
|
17
|
+
if (value.when !== undefined && typeof value.when !== 'function')
|
|
18
|
+
throw new TypeError('Invalid intent predicate');
|
|
19
|
+
const delegates = value.delegates;
|
|
20
|
+
if (delegates !== undefined &&
|
|
21
|
+
(!Array.isArray(delegates) ||
|
|
22
|
+
!delegates.length ||
|
|
23
|
+
delegates.some((id) => typeof id !== 'string' || !id.trim()) ||
|
|
24
|
+
new Set(delegates).size !== delegates.length))
|
|
25
|
+
throw new TypeError('Invalid intent delegates');
|
|
26
|
+
return Object.freeze({
|
|
27
|
+
description: value.description,
|
|
28
|
+
...(value.when !== undefined ? { when: value.when } : {}),
|
|
29
|
+
...(delegates ? { delegates: Object.freeze([...delegates]) } : {}),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/** Bind an optional object-form predicate to its owning Tool, without touching other forms. */
|
|
33
|
+
export function bindIntent(value, owner) {
|
|
34
|
+
if (!value || typeof value !== 'object' || typeof value.when !== 'function')
|
|
35
|
+
return value;
|
|
36
|
+
return Object.freeze({ ...value, when: value.when.bind(owner) });
|
|
37
|
+
}
|
|
38
|
+
/** Check activation and reject asynchronous or nonboolean predicate results. */
|
|
39
|
+
export function toolActive(condition, context) {
|
|
40
|
+
if (condition === undefined)
|
|
41
|
+
return true;
|
|
42
|
+
if (typeof condition === 'boolean')
|
|
43
|
+
return condition;
|
|
44
|
+
if (typeof condition !== 'function')
|
|
45
|
+
throw new TypeError('Invalid tool active condition');
|
|
46
|
+
return booleanResult(condition(context), 'Tool predicates must be synchronous', 'Tool predicates must return boolean');
|
|
47
|
+
}
|
|
48
|
+
/** Resolve the demand-facing description only when discovery is enabled. */
|
|
49
|
+
export function intentDescription(metadata, fallback, context) {
|
|
50
|
+
if (metadata === undefined)
|
|
51
|
+
return undefined;
|
|
52
|
+
if (typeof metadata === 'string')
|
|
53
|
+
return metadata;
|
|
54
|
+
if (metadata === true)
|
|
55
|
+
return fallback;
|
|
56
|
+
if (typeof metadata === 'function')
|
|
57
|
+
return toolActive(metadata, context) ? fallback : undefined;
|
|
58
|
+
return toolActive(metadata.when, context) ? (metadata.description ?? fallback) : undefined;
|
|
59
|
+
}
|