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