@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
|
@@ -97,6 +97,13 @@ export interface ModelCallTrace extends InvocationMetadata {
|
|
|
97
97
|
name: string;
|
|
98
98
|
argumentChars: number;
|
|
99
99
|
};
|
|
100
|
+
/** All calls produced by a session response; omitted for single-selection transports. */
|
|
101
|
+
calls?: readonly {
|
|
102
|
+
id: string;
|
|
103
|
+
name: string;
|
|
104
|
+
argumentChars: number;
|
|
105
|
+
toolId?: string;
|
|
106
|
+
}[];
|
|
100
107
|
/** Context accounting: per-fragment usage and characters shared with the previous call. */
|
|
101
108
|
context?: {
|
|
102
109
|
fragmentUsage: ContextFragmentUsage[];
|
|
@@ -175,6 +182,8 @@ export type ModelRunnerOptions<Transports extends readonly ModelTransportDefinit
|
|
|
175
182
|
} & ModelRunnerSettings;
|
|
176
183
|
/** One model call request. The input shape selects prompt mode or message mode. */
|
|
177
184
|
export type ModelCallRequest<Transport = string> = {
|
|
185
|
+
/** Record this call in the supplied logger; omission adds no sub-flow record. */
|
|
186
|
+
readonly logger?: import('../debug.js').SubFlowLogger;
|
|
178
187
|
/** Additional cancellation can shorten, never replace, the Runner lifetime. */
|
|
179
188
|
readonly signal?: AbortSignal;
|
|
180
189
|
/** Parent observation scope for this invocation; never changes execution budget or signal. */
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw session response contracts: one response may carry text and several tool calls.
|
|
3
|
+
*
|
|
4
|
+
* These shapes are Core-only and deliberately contain no host tool resolution. Support's
|
|
5
|
+
* session transport adds `toolId`, parsed `input` and non-fatal `problem` fields in its own
|
|
6
|
+
* `ResolvedSessionResult` type.
|
|
7
|
+
*
|
|
8
|
+
* Exports: `ModelSessionCall`, `ModelSessionResult`.
|
|
9
|
+
*/
|
|
10
|
+
/** One completed tool call in a session response. */
|
|
11
|
+
export interface ModelSessionCall {
|
|
12
|
+
/** Provider index used to join streamed fragments. */
|
|
13
|
+
readonly index: number;
|
|
14
|
+
/** Provider call id, echoed by the matching tool result. */
|
|
15
|
+
readonly id: string;
|
|
16
|
+
/** Declared function name exactly as returned by the model. */
|
|
17
|
+
readonly name: string;
|
|
18
|
+
/** Raw JSON argument text exactly as returned by the model. */
|
|
19
|
+
readonly arguments: string;
|
|
20
|
+
/** Characters counted for the output budget. */
|
|
21
|
+
readonly argumentChars: number;
|
|
22
|
+
}
|
|
23
|
+
/** Complete result of one session response. */
|
|
24
|
+
export interface ModelSessionResult {
|
|
25
|
+
/** Streamed assistant prose; may be empty when the response only declares calls. */
|
|
26
|
+
readonly text: string;
|
|
27
|
+
/** Completed calls in provider index order. */
|
|
28
|
+
readonly calls: readonly ModelSessionCall[];
|
|
29
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw session response contracts: one response may carry text and several tool calls.
|
|
3
|
+
*
|
|
4
|
+
* These shapes are Core-only and deliberately contain no host tool resolution. Support's
|
|
5
|
+
* session transport adds `toolId`, parsed `input` and non-fatal `problem` fields in its own
|
|
6
|
+
* `ResolvedSessionResult` type.
|
|
7
|
+
*
|
|
8
|
+
* Exports: `ModelSessionCall`, `ModelSessionResult`.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** App-side associations between registered owners and model tools; no separate intent entity. */
|
|
2
|
+
import type { ModelToolRegistration } from '../capabilities/model.js';
|
|
3
|
+
/** Explicit tool references or inline overrides of the owner's default model interface. */
|
|
4
|
+
export type ToolAssociation = string | Partial<ModelToolRegistration>;
|
|
5
|
+
/** Owners retain their business fields; Support only reads model interface associations. */
|
|
6
|
+
export interface AssociatedRegistration {
|
|
7
|
+
readonly id: string;
|
|
8
|
+
readonly description: string;
|
|
9
|
+
readonly modelTools?: readonly ToolAssociation[];
|
|
10
|
+
}
|
|
11
|
+
/** Shared independent tools and a default projection from existing contracts. */
|
|
12
|
+
export interface AssociationOptions<Entry extends AssociatedRegistration> {
|
|
13
|
+
readonly tools?: readonly ModelToolRegistration[];
|
|
14
|
+
readonly toolDefaults?: (entry: Readonly<Entry>) => ModelToolRegistration | undefined;
|
|
15
|
+
}
|
|
16
|
+
/** Local provenance, never an extra model input requirement. */
|
|
17
|
+
export interface AssociationSource {
|
|
18
|
+
readonly kind: 'standalone' | 'registration';
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly description: string;
|
|
21
|
+
readonly toolIds: readonly string[];
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Stage-scoped model transport contract.
|
|
3
3
|
*
|
|
4
|
-
* Place in the package: Support-side registration for transports that expose only the
|
|
4
|
+
* Place in the package: Support-side registration for transports that expose only the tools
|
|
5
5
|
* declared for each stage. Static sources are projected once; dynamic sources are re-projected at
|
|
6
6
|
* the model boundary. Either way, an undeclared stage or capability is rejected rather than
|
|
7
7
|
* silently omitted.
|
|
@@ -16,6 +16,6 @@ export interface ModelStageTransportRegistration<Result = unknown> extends Model
|
|
|
16
16
|
/** Declared stages; each id is unique and lists non-empty, unique capability ids. */
|
|
17
17
|
readonly stages: readonly {
|
|
18
18
|
readonly id: string;
|
|
19
|
-
readonly
|
|
19
|
+
readonly toolIds: readonly string[];
|
|
20
20
|
}[];
|
|
21
21
|
}
|
|
@@ -1,23 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Provider-level message shapes for direct compatible-provider use.
|
|
3
3
|
*
|
|
4
|
-
* Place in the package: Support-side input for hosts that keep their own tool thread.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Place in the package: Support-side input for hosts that keep their own tool thread. Core
|
|
5
|
+
* `ModelMessage` also supports the tool thread; these stricter shapes remain for hosts that want
|
|
6
|
+
* role and field association enforced by the union and re-checked at runtime.
|
|
7
7
|
*
|
|
8
8
|
* Exports: `ProviderToolCall`, `ProviderSystemMessage`, `ProviderUserMessage`,
|
|
9
9
|
* `ProviderAssistantMessage`, `ProviderToolMessage`, `ProviderMessage`.
|
|
10
10
|
*/
|
|
11
|
-
import type { ModelImage } from '../../model/messages.js';
|
|
12
|
-
/** One tool call the assistant declared, in wire order. */
|
|
13
|
-
export
|
|
14
|
-
/** Provider call ID, echoed by the matching tool result. */
|
|
15
|
-
readonly id: string;
|
|
16
|
-
/** Declared function name. */
|
|
17
|
-
readonly name: string;
|
|
18
|
-
/** Raw JSON arguments exactly as the provider produced them. */
|
|
19
|
-
readonly arguments: string;
|
|
20
|
-
}
|
|
11
|
+
import type { ModelImage, ModelToolCall } from '../../model/messages.js';
|
|
12
|
+
/** One tool call the assistant declared, in wire order; aliases the Core shape. */
|
|
13
|
+
export type ProviderToolCall = ModelToolCall;
|
|
21
14
|
/** System instruction turn; text only, so the union rejects images and tool fields here. */
|
|
22
15
|
export interface ProviderSystemMessage {
|
|
23
16
|
readonly role: 'system';
|
|
@@ -1,35 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool catalog contract used by Support's tool assembly.
|
|
3
3
|
*
|
|
4
|
-
* Place in the package: an App-side projection of typed tool definitions into model
|
|
4
|
+
* Place in the package: an App-side projection of typed tool definitions into model tools.
|
|
5
5
|
* The model may only propose `{ toolId, input }`; authorization, invocation, budgets and
|
|
6
6
|
* cancellation still happen in Core's tool registry.
|
|
7
7
|
*
|
|
8
|
-
* Exports: `ToolDefinition` (type re-export), `ToolProposal`, `
|
|
8
|
+
* Exports: `ToolDefinition` (type re-export), `ToolProposal`, `ToolModelView`, `SelectedTools`,
|
|
9
9
|
* `ToolOutput`, `CompiledTool`, `ToolRuntime`, `ToolCatalogEntry`, `ToolCatalog`.
|
|
10
10
|
*/
|
|
11
11
|
import type { ToolResult } from '../invocation.js';
|
|
12
12
|
import type { SchemaAdapter, ExecutionOptions, ReadonlyCatalog } from '../common.js';
|
|
13
|
-
import type {
|
|
14
|
-
import type {
|
|
15
|
-
import type { ToolDefinition, ToolExecutionEvent, ToolRegistryPorts, ToolInvocationRequest } from '../capabilities/tools.js';
|
|
13
|
+
import type { RegisteredModelTool, ModelSelection } from '../capabilities/model.js';
|
|
14
|
+
import type { ModelToolRegistry } from '../../capabilities/model.js';
|
|
15
|
+
import type { ToolDefinition, ExecutableTool, ToolExecutionEvent, ToolRegistryPorts, ToolInvocationRequest } from '../capabilities/tools.js';
|
|
16
16
|
export type { ToolDefinition } from '../capabilities/tools.js';
|
|
17
17
|
/** A model's proposal to call one tool; nothing has been authorized or executed yet. */
|
|
18
|
-
export
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
/** Model capability view of a tool catalog. */
|
|
25
|
-
export interface ToolCapabilities extends ModelCapabilityRegistry {
|
|
26
|
-
values(): IterableIterator<RegisteredModelCapability<ToolProposal>>;
|
|
18
|
+
export type { ToolProposal } from '../capabilities/model.js';
|
|
19
|
+
import type { ToolProposal } from '../capabilities/model.js';
|
|
20
|
+
/** Model capability view of a tool catalog, retaining the host context type. */
|
|
21
|
+
export interface ToolModelView<App = unknown> extends ModelToolRegistry {
|
|
22
|
+
values(): IterableIterator<RegisteredModelTool<ToolProposal>>;
|
|
27
23
|
/** Resolves a model selection into a proposal; throws for unknown or invalid selections. */
|
|
28
24
|
resolve(selection: ModelSelection, context: Readonly<{
|
|
29
25
|
stageId: string;
|
|
30
26
|
}>): ToolProposal;
|
|
31
27
|
/** Narrows the capability set to `ids`; throws for unregistered ids. */
|
|
32
|
-
select(ids: readonly string[]):
|
|
28
|
+
select(ids: readonly string[], context?: App): ToolModelView<App>;
|
|
29
|
+
/** Discovery retains this projection's ToolProposal result contract. */
|
|
30
|
+
withIntent(context: App): ToolModelView<App>;
|
|
33
31
|
}
|
|
34
32
|
type ResultDefinition = {
|
|
35
33
|
readonly id: string;
|
|
@@ -46,13 +44,13 @@ export type CompiledTool<App, Definition> = Definition extends {
|
|
|
46
44
|
parseOutput(value: unknown): infer Output;
|
|
47
45
|
} ? Definition extends {
|
|
48
46
|
readonly id: infer Id extends string;
|
|
49
|
-
} ?
|
|
47
|
+
} ? ExecutableTool<Definition extends {
|
|
50
48
|
inputSchema: SchemaAdapter<infer Input>;
|
|
51
49
|
} ? Input : unknown, Output, App, Id> : never : never;
|
|
52
50
|
/** Catalog bound to one App request. */
|
|
53
|
-
export interface ToolRuntime<Tool extends ResultDefinition = ResultDefinition> {
|
|
54
|
-
/** The catalog's model
|
|
55
|
-
readonly
|
|
51
|
+
export interface ToolRuntime<Tool extends ResultDefinition = ResultDefinition, App = unknown> {
|
|
52
|
+
/** The catalog's model tools, shared with the catalog instance. */
|
|
53
|
+
readonly tools: ToolModelView<App>;
|
|
56
54
|
/** Execution events recorded by this runtime so far, in occurrence order. */
|
|
57
55
|
readonly events: readonly ToolExecutionEvent[];
|
|
58
56
|
/** Synchronous invocation; rejects tools declared as asynchronous. */
|
|
@@ -64,15 +62,17 @@ export interface ToolRuntime<Tool extends ResultDefinition = ResultDefinition> {
|
|
|
64
62
|
}
|
|
65
63
|
/** Public declaration surface of one tool, without registry internals. */
|
|
66
64
|
export type ToolCatalogEntry<App, Tool extends ToolDefinition<unknown, unknown, App>> = Tool extends ToolDefinition<unknown, unknown, App> ? Pick<Tool, keyof ToolDefinition<unknown, unknown, App>> : never;
|
|
67
|
-
/** Frozen tool catalog with model
|
|
65
|
+
/** Frozen tool catalog with model tools and per-request binding. */
|
|
68
66
|
export interface ToolCatalog<App, Tool extends ToolDefinition<unknown, unknown, App> = ToolDefinition<unknown, unknown, App>> extends ReadonlyCatalog<ToolCatalogEntry<App, Tool>> {
|
|
69
|
-
readonly
|
|
67
|
+
readonly tools: ToolModelView<App>;
|
|
70
68
|
/** Narrows the catalog while preserving declaration order; throws for unknown ids. */
|
|
71
|
-
select<const Ids extends readonly string[]>(ids: Ids): ToolCatalog<App, SelectedTools<Tool, Ids[number]>>;
|
|
69
|
+
select<const Ids extends readonly string[]>(ids: Ids, context?: App): ToolCatalog<App, SelectedTools<Tool, Ids[number]>>;
|
|
70
|
+
/** Active tools advertising demand-discovery use; descriptions are view-local. */
|
|
71
|
+
withIntent(context: App): ToolCatalog<App, Tool>;
|
|
72
72
|
/** Binds the catalog to one App request and returns an invocable runtime. */
|
|
73
73
|
bind(request: {
|
|
74
74
|
app: App;
|
|
75
75
|
execution?: ExecutionOptions;
|
|
76
76
|
errors?: Pick<ToolRegistryPorts, 'unavailable' | 'errorCode'>;
|
|
77
|
-
}): ToolRuntime<Tool>;
|
|
77
|
+
}): ToolRuntime<Tool, App>;
|
|
78
78
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AssociatedRegistration, AssociationOptions } from '../structs/support/associations.js';
|
|
2
|
+
/** Compile independent and owner-derived Tool declarations, validating all references eagerly. */
|
|
3
|
+
export declare function defineAssociatedCatalog<Entry extends AssociatedRegistration>(entries: readonly Entry[], options?: AssociationOptions<Entry>): Readonly<{
|
|
4
|
+
tools: import("../index.js").ModelToolCatalog<any>;
|
|
5
|
+
bindings: import("../index.js").ReadonlyCatalog<{
|
|
6
|
+
id: Entry["id"];
|
|
7
|
+
toolIds: readonly string[];
|
|
8
|
+
}>;
|
|
9
|
+
sources: import("../index.js").ReadonlyCatalog<{
|
|
10
|
+
id: string;
|
|
11
|
+
sources: readonly Readonly<{
|
|
12
|
+
toolIds: readonly string[];
|
|
13
|
+
kind: "standalone" | "registration";
|
|
14
|
+
id: string;
|
|
15
|
+
description: string;
|
|
16
|
+
}>[];
|
|
17
|
+
}>;
|
|
18
|
+
definitions: readonly Readonly<Entry>[];
|
|
19
|
+
ids(): readonly string[];
|
|
20
|
+
values(): IterableIterator<Readonly<Entry>>;
|
|
21
|
+
entries(): IterableIterator<readonly [string, Readonly<Entry>]>;
|
|
22
|
+
has(id: string): boolean;
|
|
23
|
+
get(id: string): Readonly<Entry> | undefined;
|
|
24
|
+
require(id: string): Readonly<Entry>;
|
|
25
|
+
}>;
|
|
26
|
+
export type * from '../structs/support/associations.js';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/** Compile owner-to-tool relations without parallel intent identities or execution side effects. */
|
|
2
|
+
import { readonlyCatalog } from '../utils/catalog.js';
|
|
3
|
+
import { synchronous } from '../utils/synchronous.js';
|
|
4
|
+
import { defineModelTools } from './model/capabilities.js';
|
|
5
|
+
/** Compile independent and owner-derived Tool declarations, validating all references eagerly. */
|
|
6
|
+
export function defineAssociatedCatalog(entries, options = {}) {
|
|
7
|
+
const owners = readonlyCatalog(entries, (id) => new TypeError(`Unknown tool owner: ${id}`));
|
|
8
|
+
const definitions = new Map();
|
|
9
|
+
const sources = new Map();
|
|
10
|
+
const declare = (tool, source) => {
|
|
11
|
+
if (definitions.has(tool.id))
|
|
12
|
+
throw new TypeError(`Duplicate model tool: ${tool.id}`);
|
|
13
|
+
definitions.set(tool.id, tool);
|
|
14
|
+
sources.set(tool.id, [source]);
|
|
15
|
+
};
|
|
16
|
+
const independent = new Set();
|
|
17
|
+
for (const tool of options.tools ?? []) {
|
|
18
|
+
independent.add(tool.id);
|
|
19
|
+
declare(tool, {
|
|
20
|
+
kind: 'standalone',
|
|
21
|
+
id: tool.id,
|
|
22
|
+
description: tool.description,
|
|
23
|
+
toolIds: [tool.id],
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const bindings = owners.definitions.map((owner) => {
|
|
27
|
+
const fallback = options.toolDefaults
|
|
28
|
+
? synchronous(options.toolDefaults(owner), 'Tool defaults must be synchronous')
|
|
29
|
+
: undefined;
|
|
30
|
+
const declarations = owner.modelTools ?? (fallback ? [{}] : []);
|
|
31
|
+
const toolIds = [];
|
|
32
|
+
for (const declaration of declarations) {
|
|
33
|
+
if (typeof declaration === 'string') {
|
|
34
|
+
if (!independent.has(declaration))
|
|
35
|
+
throw new TypeError(`Tool reference must name an independent tool: ${owner.id} -> ${declaration}`);
|
|
36
|
+
sources.get(declaration).push({
|
|
37
|
+
kind: 'registration',
|
|
38
|
+
id: owner.id,
|
|
39
|
+
description: owner.description,
|
|
40
|
+
toolIds: [declaration],
|
|
41
|
+
});
|
|
42
|
+
toolIds.push(declaration);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
if (!declaration || typeof declaration !== 'object' || Array.isArray(declaration))
|
|
46
|
+
throw new TypeError('Invalid tool association');
|
|
47
|
+
const tool = {
|
|
48
|
+
...fallback,
|
|
49
|
+
...declaration,
|
|
50
|
+
id: declaration.id ?? fallback?.id ?? owner.id,
|
|
51
|
+
description: declaration.description ?? fallback?.description ?? owner.description,
|
|
52
|
+
resolve: declaration.resolve?.bind(declaration) ?? fallback?.resolve?.bind(fallback),
|
|
53
|
+
};
|
|
54
|
+
declare(tool, {
|
|
55
|
+
kind: 'registration',
|
|
56
|
+
id: owner.id,
|
|
57
|
+
description: owner.description,
|
|
58
|
+
toolIds: [tool.id],
|
|
59
|
+
});
|
|
60
|
+
toolIds.push(tool.id);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (new Set(toolIds).size !== toolIds.length)
|
|
64
|
+
throw new TypeError(`Duplicate tool reference: ${owner.id}`);
|
|
65
|
+
return Object.freeze({ id: owner.id, toolIds: Object.freeze(toolIds) });
|
|
66
|
+
});
|
|
67
|
+
return Object.freeze({
|
|
68
|
+
...owners,
|
|
69
|
+
tools: defineModelTools([...definitions.values()]),
|
|
70
|
+
bindings: readonlyCatalog(bindings, (id) => new TypeError(`Unknown tool binding: ${id}`)),
|
|
71
|
+
sources: readonlyCatalog([...sources].map(([id, values]) => Object.freeze({
|
|
72
|
+
id,
|
|
73
|
+
sources: Object.freeze(values.map((source) => Object.freeze({ ...source, toolIds: Object.freeze([...source.toolIds]) }))),
|
|
74
|
+
})), (id) => new TypeError(`Unknown tool source: ${id}`)),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* Main exports: `createContextProcessingNode`, `createContextSelectionNode`,
|
|
10
10
|
* `createContextReductionNode` and their result/definition types.
|
|
11
11
|
*/
|
|
12
|
+
import { nativeSubFlowAsync } from '../../diagnostics/native-sub-flow.js';
|
|
12
13
|
import { beginContextProcessing, finishContextProcessing, chooseSteps, applyReduction, needsReduction, watermarks, validateReductionTargets, contextPolicyCatalog, validateContextPolicy, } from './processing.js';
|
|
13
14
|
import { modelRunnerDefaults } from '../../model/defaults.js';
|
|
14
15
|
import { synchronous } from '../../utils/synchronous.js';
|
|
@@ -124,53 +125,55 @@ function contextNode(definition, execute) {
|
|
|
124
125
|
onErrorRouteId: definition.onErrorRouteId,
|
|
125
126
|
routes: definition.routes,
|
|
126
127
|
async run(state, context) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
diagnostics: context.diagnostics,
|
|
149
|
-
compressors,
|
|
150
|
-
selectors,
|
|
151
|
-
// Read lazily so handlers see the live budget rather than the value at preparation.
|
|
152
|
-
remainingCalls: () => prepared.remainingCalls,
|
|
153
|
-
callModel: (options) => context.model.invoke({
|
|
154
|
-
...options,
|
|
155
|
-
modelId: options.modelId ?? prepared.modelId,
|
|
128
|
+
return nativeSubFlowAsync(context, 'context', definition.id, async () => {
|
|
129
|
+
// The node timeout is an additional bound; parent cancellation still wins.
|
|
130
|
+
const signal = combineSignals(context.signal, AbortSignal.timeout(timeoutMs));
|
|
131
|
+
const prepared = selectPrepared
|
|
132
|
+
? selectPrepared(state, context)
|
|
133
|
+
: context.model.prepare(typeof request === 'function' ? request(state, context) : request);
|
|
134
|
+
const input = synchronous(plan(state, context), 'Context plans must be synchronous');
|
|
135
|
+
// An empty measurement reports the allowance left after transport, instruction and schema
|
|
136
|
+
// overhead, so processing must fit inside whichever limit is tighter.
|
|
137
|
+
const overhead = prepared.measure([]);
|
|
138
|
+
const fullLimit = Math.min(input.maxInputChars, overhead.maxInputChars);
|
|
139
|
+
const bodyLimit = fullLimit;
|
|
140
|
+
breakWhile(bodyLimit < 1, 'No input capacity for context');
|
|
141
|
+
const work = beginContextProcessing({
|
|
142
|
+
fragments: input.fragments,
|
|
143
|
+
additionalMessages: input.additionalMessages,
|
|
144
|
+
originalFragments: input.originalFragments,
|
|
145
|
+
mutableFragmentIds: input.mutableFragmentIds,
|
|
146
|
+
maxInputChars: bodyLimit,
|
|
147
|
+
}, policy, {
|
|
148
|
+
stageId: prepared.stageId,
|
|
156
149
|
signal,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
150
|
+
diagnostics: context.diagnostics,
|
|
151
|
+
compressors,
|
|
152
|
+
selectors,
|
|
153
|
+
// Read lazily so handlers see the live budget rather than the value at preparation.
|
|
154
|
+
remainingCalls: () => prepared.remainingCalls,
|
|
155
|
+
callModel: (options) => context.model.invoke({
|
|
156
|
+
...options,
|
|
157
|
+
modelId: options.modelId ?? prepared.modelId,
|
|
158
|
+
signal,
|
|
159
|
+
}),
|
|
160
|
+
...(overhead.counterId
|
|
161
|
+
? {
|
|
162
|
+
tokenBudget: {
|
|
163
|
+
counterId: overhead.counterId,
|
|
164
|
+
inputLimit: overhead.inputTokenLimit,
|
|
165
|
+
measure: (messages) => prepared.measure(messages).inputTokens,
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
: {}),
|
|
169
|
+
});
|
|
170
|
+
context.report({ payload: { phase: 'processing', fragmentCount: input.fragments.length } });
|
|
171
|
+
const result = await execute(work, prepared, fullLimit, state, context);
|
|
172
|
+
// Never report or commit a result produced after cancellation.
|
|
173
|
+
signal.throwIfAborted();
|
|
174
|
+
context.report({ payload: { phase: 'processed', report: work.report } });
|
|
175
|
+
return synchronous(update(result, state), 'Context node updates must be synchronous');
|
|
167
176
|
});
|
|
168
|
-
context.report({ payload: { phase: 'processing', fragmentCount: input.fragments.length } });
|
|
169
|
-
const result = await execute(work, prepared, fullLimit, state, context);
|
|
170
|
-
// Never report or commit a result produced after cancellation.
|
|
171
|
-
signal.throwIfAborted();
|
|
172
|
-
context.report({ payload: { phase: 'processed', report: work.report } });
|
|
173
|
-
return synchronous(update(result, state), 'Context node updates must be synchronous');
|
|
174
177
|
},
|
|
175
178
|
};
|
|
176
179
|
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* `finishContextProcessing` (staged runs), the policy/reduction catalogs and the individual
|
|
12
12
|
* validation, measurement and reduction helpers used by workflow nodes.
|
|
13
13
|
*/
|
|
14
|
+
import { nativeSubFlowAsync } from '../../diagnostics/native-sub-flow.js';
|
|
14
15
|
import { snapshotFragment, snapshotMessage } from './snapshot.js';
|
|
15
16
|
import { auditContextChange as audit } from '../../context/audit.js';
|
|
16
17
|
import { historyGroups, validateRecentHistory } from './history.js';
|
|
@@ -595,7 +596,9 @@ export function finishContextProcessing(state) {
|
|
|
595
596
|
* @throws {BudgetError} When a handler exhausts its call allowance.
|
|
596
597
|
*/
|
|
597
598
|
export async function processContext(plan, policy, ports) {
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
599
|
+
return nativeSubFlowAsync(ports, 'context', policy.mode, async () => {
|
|
600
|
+
const state = beginContextProcessing(plan, policy, ports);
|
|
601
|
+
await contextPolicyCatalog[policy.mode].run(state);
|
|
602
|
+
return finishContextProcessing(state);
|
|
603
|
+
});
|
|
601
604
|
}
|
|
@@ -17,7 +17,7 @@ export function snapshotFragment(fragment) {
|
|
|
17
17
|
* unsupported `detail` value.
|
|
18
18
|
*/
|
|
19
19
|
export function snapshotMessage(message) {
|
|
20
|
-
const { role, content, images } = message;
|
|
20
|
+
const { role, content, images, toolCalls, toolCallId } = message;
|
|
21
21
|
if (images !== undefined && !Array.isArray(images))
|
|
22
22
|
throw new TypeError('Context images must be an array');
|
|
23
23
|
return {
|
|
@@ -34,5 +34,15 @@ export function snapshotMessage(message) {
|
|
|
34
34
|
return { url, ...(detail === undefined ? {} : { detail }) };
|
|
35
35
|
}),
|
|
36
36
|
}),
|
|
37
|
+
...(toolCalls === undefined
|
|
38
|
+
? {}
|
|
39
|
+
: {
|
|
40
|
+
toolCalls: toolCalls.map((call) => ({
|
|
41
|
+
id: call.id,
|
|
42
|
+
name: call.name,
|
|
43
|
+
arguments: call.arguments,
|
|
44
|
+
})),
|
|
45
|
+
}),
|
|
46
|
+
...(toolCallId === undefined ? {} : { toolCallId }),
|
|
37
47
|
};
|
|
38
48
|
}
|
|
@@ -7,6 +7,7 @@ import type { AgentCoreEngineSetup } from '../../execution/engine.js';
|
|
|
7
7
|
import type { ToolDefinition } from '../../structs/capabilities/tools.js';
|
|
8
8
|
import type { ContextFragmentConfig } from '../../structs/support/context.js';
|
|
9
9
|
import type { ModelRunnerOptions } from '../../structs/model/runtime.js';
|
|
10
|
+
import type { AsIntent, ModelTool } from '../../structs/capabilities/model.js';
|
|
10
11
|
import { type ClassDecoration, type MethodDecoration, type DecorationOptions } from './definition.js';
|
|
11
12
|
import type { IdentifiedDefinition } from './pool.js';
|
|
12
13
|
export { nodePool, toolPool, fragmentPool, workflowPool, agentPool, modelPool } from './pool.js';
|
|
@@ -15,14 +16,24 @@ export type { ClassDecoration, MethodDecoration, DecorationOptions } from './def
|
|
|
15
16
|
export type { Node, Tool, Fragment, Workflow, Agent, Model } from './types.js';
|
|
16
17
|
/** Method metadata describes the adapted handler, with optional external namespaces. */
|
|
17
18
|
type MethodOptions<Definition extends IdentifiedDefinition, Key extends keyof Definition> = Omit<Definition, 'id' | Key> & DecorationOptions;
|
|
19
|
+
/** Intent composition belongs to its own decorator, including on definition classes. */
|
|
20
|
+
type WithoutIntent<Definition> = Definition extends unknown ? Omit<Definition, 'asIntent'> & {
|
|
21
|
+
readonly asIntent?: never;
|
|
22
|
+
} : never;
|
|
23
|
+
/** Mark a WorkflowTool for demand discovery; alone this decorator registers nothing. */
|
|
24
|
+
export declare function Intent<Context = any>(metadata?: AsIntent<Context>): (value: object, context: ClassDecoratorContext | ClassMethodDecoratorContext) => void;
|
|
18
25
|
/** Instantiate a node definition class once, injecting its id; graph validation stays in Workflow. */
|
|
19
26
|
export declare function node<State = any, Result = unknown, App = any>(id: string, options?: DecorationOptions): ClassDecoration<WorkflowNode<State, Result, App>>;
|
|
20
27
|
/** Bind a named host method as run without renaming or manually binding the original object. */
|
|
21
28
|
export declare function node<State = any, Result = unknown, App = any>(id: string, options: MethodOptions<WorkflowNode<State, Result, App>, 'run'>): MethodDecoration<NonNullable<WorkflowNode<State, Result, App>['run']>>;
|
|
22
29
|
/** Instantiate a tool definition class; schema and authorization stay with existing defineTool. */
|
|
23
|
-
export declare function tool<Input =
|
|
30
|
+
export declare function tool<Input = any, Output = any, App = any>(id: string, options?: DecorationOptions): ClassDecoration<WithoutIntent<ToolDefinition<Input, Output, App> | ModelTool<Input, Output, App>>>;
|
|
24
31
|
/** Bind an existing host method as the tool's execute callback. */
|
|
25
|
-
export declare function tool<Input = unknown, Output = unknown, App = any>(id: string, options: MethodOptions<ToolDefinition<Input, Output, App>, 'execute'>): MethodDecoration<ToolDefinition<Input, Output, App>['execute']>;
|
|
32
|
+
export declare function tool<Input = unknown, Output = unknown, App = any>(id: string, options: MethodOptions<Omit<ToolDefinition<Input, Output, App>, 'asIntent'>, 'execute'>): MethodDecoration<ToolDefinition<Input, Output, App>['execute']>;
|
|
33
|
+
/** A model-only tool method provides its synchronous resolver. */
|
|
34
|
+
export declare function tool<Input = unknown, Output = Input, App = any>(id: string, options: MethodOptions<Omit<ModelTool<Input, Output, App>, 'asIntent'>, 'resolve'>): MethodDecoration<ModelTool<Input, Output, App>['resolve']>;
|
|
35
|
+
/** Explicit workflow names share the same implementation and pools. */
|
|
36
|
+
export { tool as WorkflowTool, node as WorkflowNode };
|
|
26
37
|
/** Instantiate a self-describing fragment class; the original builder owns formatting checks. */
|
|
27
38
|
export declare function fragment<Input = unknown>(id: string, options?: DecorationOptions): ClassDecoration<ContextFragmentConfig<Input>>;
|
|
28
39
|
/** Bind a host's formatter method into an original fragment configuration. */
|
|
@@ -1,18 +1,48 @@
|
|
|
1
1
|
import { defineTool } from '../tools.js';
|
|
2
|
+
import { defineModelTools } from '../model/capabilities.js';
|
|
3
|
+
import { snapshotIntent } from '../../capabilities/tool-conditions.js';
|
|
2
4
|
import { defineWorkflow } from '../../execution/workflow.js';
|
|
3
5
|
import { defineContextFragments } from '../context/assembly.js';
|
|
4
6
|
import { snapshotModelBinding } from '../../model/binding.js';
|
|
5
7
|
import { classDecoration, methodDecoration, } from './definition.js';
|
|
6
8
|
export { nodePool, toolPool, fragmentPool, workflowPool, agentPool, modelPool } from './pool.js';
|
|
9
|
+
/** Metadata follows the actual decorated target, independently of decorator order. */
|
|
10
|
+
const intentKey = Symbol.for('@jangts/agent-core/tool-intent-metadata/v1');
|
|
11
|
+
const realm = globalThis;
|
|
12
|
+
const intentMetadata = realm[intentKey] ?? new WeakMap();
|
|
13
|
+
if (!realm[intentKey])
|
|
14
|
+
Object.defineProperty(globalThis, intentKey, { value: intentMetadata });
|
|
15
|
+
/** Mark a WorkflowTool for demand discovery; alone this decorator registers nothing. */
|
|
16
|
+
export function Intent(metadata = true) {
|
|
17
|
+
const normalized = snapshotIntent(metadata);
|
|
18
|
+
return (value, context) => {
|
|
19
|
+
if (context.kind !== 'class' && context.kind !== 'method')
|
|
20
|
+
throw new TypeError('Intent requires a class or method');
|
|
21
|
+
if (intentMetadata.has(value))
|
|
22
|
+
throw new TypeError('Duplicate Intent decoration');
|
|
23
|
+
intentMetadata.set(value, normalized);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
7
26
|
/** Internal conversion shared by node/tool/fragment; never a public free-function adapter. */
|
|
8
27
|
function decorate(kind, id, options, key, compile) {
|
|
9
28
|
return (value, context) => {
|
|
29
|
+
const convert = (definition) => {
|
|
30
|
+
if (kind !== 'tool')
|
|
31
|
+
return compile(definition);
|
|
32
|
+
if ('asIntent' in definition)
|
|
33
|
+
throw new TypeError('Use @Intent instead of asIntent in @WorkflowTool');
|
|
34
|
+
const metadata = intentMetadata.get(value);
|
|
35
|
+
// Intent metadata is collected before class/method initializers compile definitions.
|
|
36
|
+
if (metadata !== undefined)
|
|
37
|
+
Object.defineProperty(definition, 'asIntent', { value: metadata, enumerable: true });
|
|
38
|
+
return compile(definition);
|
|
39
|
+
};
|
|
10
40
|
if (context?.kind === 'class') {
|
|
11
|
-
classDecoration(kind, id, options,
|
|
41
|
+
classDecoration(kind, id, options, convert)(value, context);
|
|
12
42
|
}
|
|
13
43
|
else {
|
|
14
44
|
const { ns, ...metadata } = options;
|
|
15
|
-
methodDecoration(kind, id, metadata, key, { ns },
|
|
45
|
+
methodDecoration(kind, id, metadata, key, { ns }, convert)(value, context);
|
|
16
46
|
}
|
|
17
47
|
};
|
|
18
48
|
}
|
|
@@ -20,8 +50,15 @@ export function node(id, options = {}) {
|
|
|
20
50
|
return decorate('node', id, options, 'run', (value) => value);
|
|
21
51
|
}
|
|
22
52
|
export function tool(id, options = {}) {
|
|
23
|
-
|
|
53
|
+
if ('asIntent' in options)
|
|
54
|
+
throw new TypeError('Use @Intent instead of asIntent in @WorkflowTool');
|
|
55
|
+
const handlerKey = 'inputSchema' in options && !('authorize' in options) ? 'resolve' : 'execute';
|
|
56
|
+
return decorate('tool', id, options, handlerKey, (value) => 'kind' in value || 'authorize' in value || 'execute' in value
|
|
57
|
+
? defineTool(value)
|
|
58
|
+
: defineModelTools([value]).require(value.id));
|
|
24
59
|
}
|
|
60
|
+
/** Explicit workflow names share the same implementation and pools. */
|
|
61
|
+
export { tool as WorkflowTool, node as WorkflowNode };
|
|
25
62
|
export function fragment(id, options = {}) {
|
|
26
63
|
return decorate('fragment', id, options, 'format', (value) => {
|
|
27
64
|
defineContextFragments([value]);
|