@jangts/agent-core 0.1.0 → 0.2.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 +18 -0
- package/README.md +59 -0
- package/development/docs/api/reference.md +1907 -1874
- package/development/docs/api/support.md +27 -0
- package/development/docs/assets/agent-core-icon.png +0 -0
- package/development/docs/assets/agent-core-logo.png +0 -0
- package/development/docs/assets/character-agent-core.png +0 -0
- package/development/skills/agent-core-app/scripts/create-app.mjs +267 -70
- package/development/skills/agent-core-app/scripts/lib/knowledge.mjs +40 -15
- package/development/skills/agent-core-app/scripts/lib/source.mjs +30 -2
- package/development/skills/agent-core-app/scripts/plan.mjs +37 -12
- package/development/skills/agent-core-app/scripts/prepare-source.mjs +61 -10
- package/development/skills/agent-core-app/scripts/resources.mjs +45 -17
- package/development/skills/agent-core-app/scripts/validate-knowledge.mjs +18 -1
- package/development/skills/agent-core-app/templates/catalog.json +36 -22
- package/dist/cjs/capabilities/index.js +13 -0
- package/dist/cjs/capabilities/invocation.js +80 -10
- package/dist/cjs/capabilities/model.js +126 -13
- package/dist/cjs/capabilities/tool-runtime.js +64 -12
- package/dist/cjs/capabilities/tools.js +266 -31
- package/dist/cjs/context/assembly.js +46 -5
- package/dist/cjs/context/audit.js +31 -6
- package/dist/cjs/context/fragments.js +54 -11
- package/dist/cjs/context/index.js +12 -0
- package/dist/cjs/context/journal.js +84 -7
- package/dist/cjs/context/plan.js +30 -2
- package/dist/cjs/diagnostics/catalog.js +11 -3
- package/dist/cjs/diagnostics/index.js +149 -29
- package/dist/cjs/diagnostics/sub-flow.js +240 -40
- package/dist/cjs/errors.js +99 -17
- package/dist/cjs/execution/branch.js +20 -4
- package/dist/cjs/execution/engine.js +470 -56
- package/dist/cjs/execution/events.js +136 -18
- package/dist/cjs/execution/index.js +7 -0
- package/dist/cjs/execution/reporting.js +75 -6
- package/dist/cjs/execution/state.js +161 -22
- package/dist/cjs/execution/workflow.js +224 -32
- package/dist/cjs/index.js +18 -0
- package/dist/cjs/kits/aggregation.js +45 -3
- package/dist/cjs/kits/answering/batch.js +23 -4
- package/dist/cjs/kits/answering/check-result.js +31 -8
- package/dist/cjs/kits/answering/checks.js +24 -3
- package/dist/cjs/kits/answering/flow.js +192 -36
- package/dist/cjs/kits/answering/index.js +19 -1
- package/dist/cjs/kits/answering/tasks.js +88 -13
- package/dist/cjs/kits/artifacts.js +36 -4
- package/dist/cjs/kits/candidates.js +47 -5
- package/dist/cjs/kits/delivery.js +40 -5
- package/dist/cjs/kits/durable.js +155 -31
- package/dist/cjs/kits/evidence.js +66 -15
- package/dist/cjs/kits/family.js +152 -22
- package/dist/cjs/kits/index.js +12 -1
- package/dist/cjs/kits/inference.js +104 -16
- package/dist/cjs/kits/intents/catalog.js +67 -16
- package/dist/cjs/kits/intents/index.js +11 -0
- package/dist/cjs/kits/intents/registry.js +188 -43
- package/dist/cjs/kits/intents/scopes.js +215 -46
- package/dist/cjs/kits/interaction/command.js +140 -36
- package/dist/cjs/kits/interaction/commands.js +86 -11
- package/dist/cjs/kits/interaction/handlers.js +27 -10
- package/dist/cjs/kits/interaction/index.js +10 -0
- package/dist/cjs/kits/interaction/transfer.js +80 -14
- package/dist/cjs/kits/knowledge/catalog.js +62 -11
- package/dist/cjs/kits/knowledge/index.js +16 -1
- package/dist/cjs/kits/knowledge/publication.js +99 -23
- package/dist/cjs/kits/knowledge/sections.js +33 -4
- package/dist/cjs/kits/normalization.js +51 -7
- package/dist/cjs/kits/policies.js +79 -15
- package/dist/cjs/kits/presentation/events.js +54 -10
- package/dist/cjs/kits/presentation/index.js +24 -1
- package/dist/cjs/kits/presentation/outputs.js +176 -38
- package/dist/cjs/kits/presentation/templates.js +33 -5
- package/dist/cjs/kits/presentation/variants.js +31 -2
- package/dist/cjs/kits/projection.js +63 -8
- package/dist/cjs/kits/rank-fusion.js +27 -4
- package/dist/cjs/kits/reflection-log-source.js +89 -16
- package/dist/cjs/kits/reflection.js +234 -60
- package/dist/cjs/kits/retrieval.js +98 -18
- package/dist/cjs/kits/search.js +180 -27
- package/dist/cjs/kits/text-skills.js +104 -19
- package/dist/cjs/kits/tools.js +415 -74
- package/dist/cjs/kits/vector-search.js +50 -16
- package/dist/cjs/mock/node.js +7 -1
- package/dist/cjs/mock/web.js +7 -1
- package/dist/cjs/mock.js +7 -1
- package/dist/cjs/model/binding.js +68 -17
- package/dist/cjs/model/call-budget.js +45 -4
- package/dist/cjs/model/decision-retry.js +19 -1
- package/dist/cjs/model/defaults.js +27 -4
- package/dist/cjs/model/index.js +7 -0
- package/dist/cjs/model/interactions/arguments.js +36 -1
- package/dist/cjs/model/interactions/json-object.js +48 -12
- package/dist/cjs/model/interactions/native-functions.js +52 -10
- package/dist/cjs/model/message-diagnostics.js +17 -4
- package/dist/cjs/model/options.js +9 -1
- package/dist/cjs/model/preparation.js +86 -12
- package/dist/cjs/model/runner.js +413 -79
- package/dist/cjs/model/selection-transport.js +48 -8
- package/dist/cjs/model/settings.js +67 -13
- package/dist/cjs/model/token-budget.js +69 -11
- package/dist/cjs/model/transports.js +59 -6
- package/dist/cjs/structs/common.js +11 -0
- package/dist/cjs/structs/debug.js +34 -5
- package/dist/cjs/structs/errors.js +26 -1
- package/dist/cjs/structs/index.js +11 -1
- package/dist/cjs/structs/kits/durable.js +7 -0
- package/dist/cjs/structs/kits/family.js +1 -0
- package/dist/cjs/structs/kits/interaction.js +8 -1
- package/dist/cjs/structs/kits/knowledge-publication.js +1 -0
- package/dist/cjs/structs/kits/reflection.js +18 -3
- package/dist/cjs/structs/model/chat-provider.js +6 -0
- package/dist/cjs/structs/support/model/completion.js +2 -0
- package/dist/cjs/structs/support/model/messages.js +2 -0
- package/dist/cjs/support/capabilities.js +43 -6
- package/dist/cjs/support/context/assembly.js +88 -16
- package/dist/cjs/support/context/compression.js +48 -6
- package/dist/cjs/support/context/fragments.js +6 -0
- package/dist/cjs/support/context/history.js +36 -1
- package/dist/cjs/support/context/index.js +11 -0
- package/dist/cjs/support/context/nodes.js +164 -35
- package/dist/cjs/support/context/processing.js +319 -61
- package/dist/cjs/support/context/selection-policy.js +98 -21
- package/dist/cjs/support/context/selection.js +61 -10
- package/dist/cjs/support/context/snapshot.js +29 -7
- package/dist/cjs/support/context/strategies.js +120 -28
- package/dist/cjs/support/index.js +9 -1
- package/dist/cjs/support/model/capabilities.js +20 -1
- package/dist/cjs/support/model/chat-completions.js +92 -20
- package/dist/cjs/support/model/children.js +34 -6
- package/dist/cjs/support/model/compatible-provider.js +189 -59
- package/dist/cjs/support/model/completion/calls.js +61 -0
- package/dist/cjs/support/model/completion/default.js +32 -0
- package/dist/cjs/support/model/completion/index.js +28 -0
- package/dist/cjs/support/model/completion/session.js +102 -0
- package/dist/cjs/support/model/index.js +12 -0
- package/dist/cjs/support/model/interactions/index.js +12 -1
- package/dist/cjs/support/model/interactions/json-object.js +6 -0
- package/dist/cjs/support/model/interactions/native-functions.js +6 -0
- package/dist/cjs/support/model/observer.js +32 -6
- package/dist/cjs/support/model/preview-rules.js +66 -16
- package/dist/cjs/support/model/reply-preview.js +77 -17
- package/dist/cjs/support/model/stage-transport.js +33 -7
- package/dist/cjs/support/model/strategies.js +75 -14
- package/dist/cjs/support/model/transports.js +53 -11
- package/dist/cjs/support/registration.js +49 -7
- package/dist/cjs/support/schema.js +46 -4
- package/dist/cjs/support/stream-events.js +60 -8
- package/dist/cjs/support/tool-runtime.js +6 -0
- package/dist/cjs/support/tools.js +79 -10
- package/dist/cjs/support/transport/index.js +7 -0
- package/dist/cjs/support/transport/json.js +28 -4
- package/dist/cjs/support/transport/sse.js +25 -2
- package/dist/cjs/utils/break-observer.js +20 -2
- package/dist/cjs/utils/cancellation.js +77 -9
- package/dist/cjs/utils/catalog.js +19 -4
- package/dist/cjs/utils/debug.js +14 -2
- package/dist/cjs/utils/index.js +8 -0
- package/dist/cjs/utils/interaction-definition.js +26 -6
- package/dist/cjs/utils/invocation.js +42 -4
- package/dist/cjs/utils/model-protocol.js +20 -1
- package/dist/cjs/utils/object.js +16 -0
- package/dist/cjs/utils/observer.js +22 -2
- package/dist/cjs/utils/protocol-registry.js +47 -4
- package/dist/cjs/utils/query-key.js +21 -2
- package/dist/cjs/utils/registration.js +18 -2
- package/dist/cjs/utils/rules.js +39 -11
- package/dist/cjs/utils/schema-adapter.js +25 -2
- package/dist/cjs/utils/synchronous.js +64 -7
- package/dist/cjs/utils/text.js +15 -1
- package/dist/esm/capabilities/index.d.ts +13 -0
- package/dist/esm/capabilities/index.js +13 -0
- package/dist/esm/capabilities/invocation.d.ts +16 -2
- package/dist/esm/capabilities/invocation.js +80 -10
- package/dist/esm/capabilities/model.d.ts +68 -1
- package/dist/esm/capabilities/model.js +126 -13
- package/dist/esm/capabilities/tool-runtime.d.ts +11 -0
- package/dist/esm/capabilities/tool-runtime.js +64 -12
- package/dist/esm/capabilities/tools.d.ts +96 -3
- package/dist/esm/capabilities/tools.js +267 -32
- package/dist/esm/context/assembly.d.ts +13 -2
- package/dist/esm/context/assembly.js +46 -5
- package/dist/esm/context/audit.d.ts +23 -1
- package/dist/esm/context/audit.js +31 -6
- package/dist/esm/context/fragments.d.ts +37 -3
- package/dist/esm/context/fragments.js +54 -11
- package/dist/esm/context/index.d.ts +12 -0
- package/dist/esm/context/index.js +12 -0
- package/dist/esm/context/journal.d.ts +32 -1
- package/dist/esm/context/journal.js +84 -7
- package/dist/esm/context/plan.d.ts +11 -1
- package/dist/esm/context/plan.js +30 -2
- package/dist/esm/diagnostics/catalog.js +11 -3
- package/dist/esm/diagnostics/index.d.ts +30 -2
- package/dist/esm/diagnostics/index.js +149 -29
- package/dist/esm/diagnostics/sub-flow.d.ts +41 -3
- package/dist/esm/diagnostics/sub-flow.js +240 -40
- package/dist/esm/errors.d.ts +22 -2
- package/dist/esm/errors.js +99 -17
- package/dist/esm/execution/branch.d.ts +19 -1
- package/dist/esm/execution/branch.js +20 -4
- package/dist/esm/execution/engine.d.ts +291 -5
- package/dist/esm/execution/engine.js +471 -57
- package/dist/esm/execution/events.d.ts +16 -2
- package/dist/esm/execution/events.js +136 -18
- package/dist/esm/execution/index.d.ts +7 -0
- package/dist/esm/execution/index.js +7 -0
- package/dist/esm/execution/reporting.d.ts +49 -1
- package/dist/esm/execution/reporting.js +75 -6
- package/dist/esm/execution/state.d.ts +126 -10
- package/dist/esm/execution/state.js +161 -22
- package/dist/esm/execution/workflow.d.ts +121 -3
- package/dist/esm/execution/workflow.js +224 -32
- package/dist/esm/index.d.ts +17 -1
- package/dist/esm/index.js +18 -0
- package/dist/esm/kits/aggregation.d.ts +34 -2
- package/dist/esm/kits/aggregation.js +45 -3
- package/dist/esm/kits/answering/batch.d.ts +17 -0
- package/dist/esm/kits/answering/batch.js +23 -4
- package/dist/esm/kits/answering/check-result.d.ts +18 -1
- package/dist/esm/kits/answering/check-result.js +31 -8
- package/dist/esm/kits/answering/checks.d.ts +11 -0
- package/dist/esm/kits/answering/checks.js +24 -3
- package/dist/esm/kits/answering/flow.d.ts +25 -2
- package/dist/esm/kits/answering/flow.js +192 -36
- package/dist/esm/kits/answering/index.d.ts +12 -0
- package/dist/esm/kits/answering/index.js +19 -1
- package/dist/esm/kits/answering/tasks.d.ts +32 -1
- package/dist/esm/kits/answering/tasks.js +88 -13
- package/dist/esm/kits/artifacts.d.ts +11 -0
- package/dist/esm/kits/artifacts.js +36 -4
- package/dist/esm/kits/candidates.d.ts +23 -1
- package/dist/esm/kits/candidates.js +47 -5
- package/dist/esm/kits/delivery.d.ts +34 -0
- package/dist/esm/kits/delivery.js +40 -5
- package/dist/esm/kits/durable.d.ts +19 -0
- package/dist/esm/kits/durable.js +155 -31
- package/dist/esm/kits/evidence.d.ts +28 -5
- package/dist/esm/kits/evidence.js +66 -15
- package/dist/esm/kits/family.d.ts +17 -1
- package/dist/esm/kits/family.js +152 -22
- package/dist/esm/kits/index.d.ts +12 -1
- package/dist/esm/kits/index.js +12 -1
- package/dist/esm/kits/inference.d.ts +64 -0
- package/dist/esm/kits/inference.js +104 -16
- package/dist/esm/kits/intents/catalog.d.ts +13 -1
- package/dist/esm/kits/intents/catalog.js +67 -16
- package/dist/esm/kits/intents/index.d.ts +11 -0
- package/dist/esm/kits/intents/index.js +11 -0
- package/dist/esm/kits/intents/registry.d.ts +61 -3
- package/dist/esm/kits/intents/registry.js +188 -43
- package/dist/esm/kits/intents/scopes.d.ts +73 -3
- package/dist/esm/kits/intents/scopes.js +215 -46
- package/dist/esm/kits/interaction/command.d.ts +38 -4
- package/dist/esm/kits/interaction/command.js +140 -36
- package/dist/esm/kits/interaction/commands.d.ts +66 -2
- package/dist/esm/kits/interaction/commands.js +86 -11
- package/dist/esm/kits/interaction/handlers.d.ts +19 -2
- package/dist/esm/kits/interaction/handlers.js +27 -10
- package/dist/esm/kits/interaction/index.d.ts +10 -0
- package/dist/esm/kits/interaction/index.js +10 -0
- package/dist/esm/kits/interaction/transfer.d.ts +39 -2
- package/dist/esm/kits/interaction/transfer.js +80 -14
- package/dist/esm/kits/knowledge/catalog.d.ts +13 -0
- package/dist/esm/kits/knowledge/catalog.js +62 -11
- package/dist/esm/kits/knowledge/index.d.ts +11 -0
- package/dist/esm/kits/knowledge/index.js +16 -1
- package/dist/esm/kits/knowledge/publication.d.ts +15 -1
- package/dist/esm/kits/knowledge/publication.js +99 -23
- package/dist/esm/kits/knowledge/sections.d.ts +31 -1
- package/dist/esm/kits/knowledge/sections.js +33 -4
- package/dist/esm/kits/normalization.d.ts +25 -2
- package/dist/esm/kits/normalization.js +51 -7
- package/dist/esm/kits/policies.d.ts +26 -3
- package/dist/esm/kits/policies.js +79 -15
- package/dist/esm/kits/presentation/events.d.ts +51 -4
- package/dist/esm/kits/presentation/events.js +54 -10
- package/dist/esm/kits/presentation/index.d.ts +12 -0
- package/dist/esm/kits/presentation/index.js +25 -2
- package/dist/esm/kits/presentation/outputs.d.ts +30 -1
- package/dist/esm/kits/presentation/outputs.js +176 -38
- package/dist/esm/kits/presentation/templates.d.ts +32 -3
- package/dist/esm/kits/presentation/templates.js +33 -5
- package/dist/esm/kits/presentation/variants.d.ts +29 -0
- package/dist/esm/kits/presentation/variants.js +31 -2
- package/dist/esm/kits/projection.d.ts +42 -5
- package/dist/esm/kits/projection.js +63 -8
- package/dist/esm/kits/rank-fusion.d.ts +21 -1
- package/dist/esm/kits/rank-fusion.js +28 -5
- package/dist/esm/kits/reflection-log-source.d.ts +28 -1
- package/dist/esm/kits/reflection-log-source.js +89 -16
- package/dist/esm/kits/reflection.d.ts +17 -1
- package/dist/esm/kits/reflection.js +235 -61
- package/dist/esm/kits/retrieval.d.ts +18 -2
- package/dist/esm/kits/retrieval.js +98 -18
- package/dist/esm/kits/search.d.ts +56 -3
- package/dist/esm/kits/search.js +180 -27
- package/dist/esm/kits/text-skills.d.ts +16 -2
- package/dist/esm/kits/text-skills.js +104 -19
- package/dist/esm/kits/tools.d.ts +122 -2
- package/dist/esm/kits/tools.js +416 -74
- package/dist/esm/kits/vector-search.d.ts +47 -1
- package/dist/esm/kits/vector-search.js +51 -17
- package/dist/esm/mock/node.d.ts +7 -0
- package/dist/esm/mock/node.js +7 -1
- package/dist/esm/mock/web.d.ts +7 -0
- package/dist/esm/mock/web.js +7 -1
- package/dist/esm/mock.d.ts +7 -0
- package/dist/esm/mock.js +7 -1
- package/dist/esm/model/binding.d.ts +32 -3
- package/dist/esm/model/binding.js +68 -17
- package/dist/esm/model/call-budget.d.ts +30 -2
- package/dist/esm/model/call-budget.js +45 -4
- package/dist/esm/model/decision-retry.d.ts +10 -1
- package/dist/esm/model/decision-retry.js +19 -1
- package/dist/esm/model/defaults.d.ts +13 -2
- package/dist/esm/model/defaults.js +27 -4
- package/dist/esm/model/index.d.ts +7 -0
- package/dist/esm/model/index.js +7 -0
- package/dist/esm/model/interactions/arguments.d.ts +27 -0
- package/dist/esm/model/interactions/arguments.js +36 -1
- package/dist/esm/model/interactions/json-object.d.ts +7 -1
- package/dist/esm/model/interactions/json-object.js +48 -12
- package/dist/esm/model/interactions/native-functions.d.ts +6 -0
- package/dist/esm/model/interactions/native-functions.js +52 -10
- package/dist/esm/model/message-diagnostics.d.ts +17 -1
- package/dist/esm/model/message-diagnostics.js +17 -4
- package/dist/esm/model/options.d.ts +18 -1
- package/dist/esm/model/options.js +9 -1
- package/dist/esm/model/preparation.d.ts +30 -2
- package/dist/esm/model/preparation.js +86 -12
- package/dist/esm/model/runner.d.ts +129 -5
- package/dist/esm/model/runner.js +414 -80
- package/dist/esm/model/selection-transport.d.ts +14 -1
- package/dist/esm/model/selection-transport.js +48 -8
- package/dist/esm/model/settings.d.ts +11 -0
- package/dist/esm/model/settings.js +67 -13
- package/dist/esm/model/token-budget.d.ts +59 -1
- package/dist/esm/model/token-budget.js +69 -11
- package/dist/esm/model/transports.d.ts +20 -2
- package/dist/esm/model/transports.js +59 -6
- package/dist/esm/structs/capabilities/invocation.d.ts +36 -0
- package/dist/esm/structs/capabilities/model.d.ts +27 -0
- package/dist/esm/structs/capabilities/tools.d.ts +38 -0
- package/dist/esm/structs/common.d.ts +62 -2
- package/dist/esm/structs/common.js +11 -0
- package/dist/esm/structs/context/fragments.d.ts +28 -0
- package/dist/esm/structs/context/journal.d.ts +28 -3
- package/dist/esm/structs/context/processing.d.ts +11 -0
- package/dist/esm/structs/debug.d.ts +58 -1
- package/dist/esm/structs/debug.js +34 -5
- package/dist/esm/structs/diagnostics.d.ts +119 -1
- package/dist/esm/structs/errors.d.ts +42 -1
- package/dist/esm/structs/errors.js +26 -1
- package/dist/esm/structs/execution/engine.d.ts +24 -1
- package/dist/esm/structs/execution/events.d.ts +12 -0
- package/dist/esm/structs/execution/workflow.d.ts +71 -0
- package/dist/esm/structs/index.d.ts +11 -1
- package/dist/esm/structs/index.js +11 -1
- package/dist/esm/structs/invocation.d.ts +30 -0
- package/dist/esm/structs/kits/aggregation.d.ts +12 -0
- package/dist/esm/structs/kits/answering/checks.d.ts +11 -0
- package/dist/esm/structs/kits/answering/flow.d.ts +35 -1
- package/dist/esm/structs/kits/answering/state.d.ts +21 -0
- package/dist/esm/structs/kits/answering/tasks.d.ts +21 -0
- package/dist/esm/structs/kits/artifacts.d.ts +14 -0
- package/dist/esm/structs/kits/candidates.d.ts +19 -0
- package/dist/esm/structs/kits/delivery.d.ts +22 -0
- package/dist/esm/structs/kits/durable.d.ts +56 -3
- package/dist/esm/structs/kits/durable.js +7 -0
- package/dist/esm/structs/kits/evidence.d.ts +23 -0
- package/dist/esm/structs/kits/family.d.ts +49 -1
- package/dist/esm/structs/kits/family.js +1 -0
- package/dist/esm/structs/kits/intents/catalog.d.ts +26 -0
- package/dist/esm/structs/kits/intents/registry.d.ts +34 -0
- package/dist/esm/structs/kits/intents/scopes.d.ts +36 -1
- package/dist/esm/structs/kits/interaction.d.ts +64 -0
- package/dist/esm/structs/kits/interaction.js +8 -1
- package/dist/esm/structs/kits/knowledge-publication.d.ts +43 -1
- package/dist/esm/structs/kits/knowledge-publication.js +1 -0
- package/dist/esm/structs/kits/knowledge.d.ts +39 -2
- package/dist/esm/structs/kits/normalization.d.ts +15 -0
- package/dist/esm/structs/kits/policies.d.ts +25 -1
- package/dist/esm/structs/kits/presentation/events.d.ts +28 -4
- package/dist/esm/structs/kits/presentation/outputs.d.ts +38 -1
- package/dist/esm/structs/kits/presentation/templates.d.ts +15 -0
- package/dist/esm/structs/kits/projection.d.ts +21 -0
- package/dist/esm/structs/kits/reflection.d.ts +61 -2
- package/dist/esm/structs/kits/reflection.js +18 -3
- package/dist/esm/structs/kits/retrieval.d.ts +38 -0
- package/dist/esm/structs/kits/search.d.ts +22 -0
- package/dist/esm/structs/kits/text-skills.d.ts +36 -0
- package/dist/esm/structs/kits/tools.d.ts +87 -0
- package/dist/esm/structs/model/chat-provider.d.ts +24 -1
- package/dist/esm/structs/model/chat-provider.js +6 -0
- package/dist/esm/structs/model/interactions.d.ts +38 -0
- package/dist/esm/structs/model/messages.d.ts +30 -0
- package/dist/esm/structs/model/runtime.d.ts +104 -6
- package/dist/esm/structs/support/capabilities.d.ts +19 -2
- package/dist/esm/structs/support/context-processing.d.ts +88 -9
- package/dist/esm/structs/support/context.d.ts +29 -1
- package/dist/esm/structs/support/model/completion.d.ts +50 -0
- package/dist/esm/structs/support/model/completion.js +1 -0
- package/dist/esm/structs/support/model/interactions.d.ts +13 -1
- package/dist/esm/structs/support/model/messages.d.ts +52 -0
- package/dist/esm/structs/support/model/messages.js +1 -0
- package/dist/esm/structs/support/model/provider-observer.d.ts +22 -1
- package/dist/esm/structs/support/model/provider.d.ts +71 -6
- package/dist/esm/structs/support/registration.d.ts +13 -0
- package/dist/esm/structs/support/schema.d.ts +14 -0
- package/dist/esm/structs/support/tools.d.ts +28 -0
- package/dist/esm/structs/support/transport/json.d.ts +16 -0
- package/dist/esm/structs/support/transport/sse.d.ts +15 -0
- package/dist/esm/structs/utils/rules.d.ts +19 -0
- package/dist/esm/support/capabilities.d.ts +25 -2
- package/dist/esm/support/capabilities.js +43 -6
- package/dist/esm/support/context/assembly.d.ts +35 -4
- package/dist/esm/support/context/assembly.js +88 -16
- package/dist/esm/support/context/compression.d.ts +17 -1
- package/dist/esm/support/context/compression.js +48 -6
- package/dist/esm/support/context/fragments.d.ts +6 -0
- package/dist/esm/support/context/fragments.js +6 -0
- package/dist/esm/support/context/history.d.ts +43 -0
- package/dist/esm/support/context/history.js +36 -1
- package/dist/esm/support/context/index.d.ts +13 -2
- package/dist/esm/support/context/index.js +12 -1
- package/dist/esm/support/context/nodes.d.ts +49 -3
- package/dist/esm/support/context/nodes.js +165 -36
- package/dist/esm/support/context/processing.d.ts +145 -1
- package/dist/esm/support/context/processing.js +320 -62
- package/dist/esm/support/context/selection-policy.d.ts +42 -2
- package/dist/esm/support/context/selection-policy.js +98 -21
- package/dist/esm/support/context/selection.d.ts +14 -1
- package/dist/esm/support/context/selection.js +61 -10
- package/dist/esm/support/context/snapshot.d.ts +23 -1
- package/dist/esm/support/context/snapshot.js +29 -7
- package/dist/esm/support/context/strategies.d.ts +35 -2
- package/dist/esm/support/context/strategies.js +120 -28
- package/dist/esm/support/index.d.ts +9 -1
- package/dist/esm/support/index.js +9 -1
- package/dist/esm/support/model/capabilities.d.ts +10 -0
- package/dist/esm/support/model/capabilities.js +20 -1
- package/dist/esm/support/model/chat-completions.d.ts +44 -15
- package/dist/esm/support/model/chat-completions.js +92 -20
- package/dist/esm/support/model/children.d.ts +32 -2
- package/dist/esm/support/model/children.js +34 -6
- package/dist/esm/support/model/compatible-provider.d.ts +29 -3
- package/dist/esm/support/model/compatible-provider.js +190 -60
- package/dist/esm/support/model/completion/calls.d.ts +40 -0
- package/dist/esm/support/model/completion/calls.js +58 -0
- package/dist/esm/support/model/completion/default.d.ts +10 -0
- package/dist/esm/support/model/completion/default.js +29 -0
- package/dist/esm/support/model/completion/index.d.ts +10 -0
- package/dist/esm/support/model/completion/index.js +22 -0
- package/dist/esm/support/model/completion/session.d.ts +11 -0
- package/dist/esm/support/model/completion/session.js +99 -0
- package/dist/esm/support/model/index.d.ts +14 -0
- package/dist/esm/support/model/index.js +12 -0
- package/dist/esm/support/model/interactions/index.d.ts +1 -1
- package/dist/esm/support/model/interactions/index.js +12 -1
- package/dist/esm/support/model/interactions/json-object.d.ts +6 -0
- package/dist/esm/support/model/interactions/json-object.js +6 -0
- package/dist/esm/support/model/interactions/native-functions.d.ts +6 -0
- package/dist/esm/support/model/interactions/native-functions.js +6 -0
- package/dist/esm/support/model/observer.d.ts +25 -2
- package/dist/esm/support/model/observer.js +32 -6
- package/dist/esm/support/model/preview-rules.d.ts +20 -2
- package/dist/esm/support/model/preview-rules.js +66 -16
- package/dist/esm/support/model/reply-preview.d.ts +15 -1
- package/dist/esm/support/model/reply-preview.js +77 -17
- package/dist/esm/support/model/stage-transport.d.ts +9 -1
- package/dist/esm/support/model/stage-transport.js +33 -7
- package/dist/esm/support/model/strategies.d.ts +24 -2
- package/dist/esm/support/model/strategies.js +75 -14
- package/dist/esm/support/model/transports.d.ts +17 -1
- package/dist/esm/support/model/transports.js +53 -11
- package/dist/esm/support/registration.d.ts +20 -1
- package/dist/esm/support/registration.js +49 -7
- package/dist/esm/support/schema.d.ts +31 -1
- package/dist/esm/support/schema.js +46 -4
- package/dist/esm/support/stream-events.d.ts +22 -1
- package/dist/esm/support/stream-events.js +60 -8
- package/dist/esm/support/tool-runtime.d.ts +6 -0
- package/dist/esm/support/tool-runtime.js +6 -0
- package/dist/esm/support/tools.d.ts +22 -0
- package/dist/esm/support/tools.js +79 -10
- package/dist/esm/support/transport/index.d.ts +7 -0
- package/dist/esm/support/transport/index.js +7 -0
- package/dist/esm/support/transport/json.d.ts +29 -2
- package/dist/esm/support/transport/json.js +28 -4
- package/dist/esm/support/transport/sse.d.ts +31 -1
- package/dist/esm/support/transport/sse.js +25 -2
- package/dist/esm/types.d.ts +9 -1
- package/dist/esm/utils/break-observer.d.ts +27 -2
- package/dist/esm/utils/break-observer.js +20 -2
- package/dist/esm/utils/cancellation.d.ts +56 -5
- package/dist/esm/utils/cancellation.js +77 -9
- package/dist/esm/utils/catalog.d.ts +20 -1
- package/dist/esm/utils/catalog.js +19 -4
- package/dist/esm/utils/debug.d.ts +20 -1
- package/dist/esm/utils/debug.js +14 -2
- package/dist/esm/utils/index.d.ts +8 -0
- package/dist/esm/utils/index.js +8 -0
- package/dist/esm/utils/interaction-definition.d.ts +18 -1
- package/dist/esm/utils/interaction-definition.js +26 -6
- package/dist/esm/utils/invocation.d.ts +36 -1
- package/dist/esm/utils/invocation.js +42 -4
- package/dist/esm/utils/model-protocol.d.ts +8 -0
- package/dist/esm/utils/model-protocol.js +20 -1
- package/dist/esm/utils/object.d.ts +16 -0
- package/dist/esm/utils/object.js +16 -0
- package/dist/esm/utils/observer.d.ts +19 -1
- package/dist/esm/utils/observer.js +22 -2
- package/dist/esm/utils/protocol-registry.d.ts +38 -1
- package/dist/esm/utils/protocol-registry.js +47 -4
- package/dist/esm/utils/query-key.d.ts +11 -1
- package/dist/esm/utils/query-key.js +21 -2
- package/dist/esm/utils/registration.d.ts +34 -2
- package/dist/esm/utils/registration.js +18 -2
- package/dist/esm/utils/rules.d.ts +81 -4
- package/dist/esm/utils/rules.js +39 -11
- package/dist/esm/utils/schema-adapter.d.ts +12 -1
- package/dist/esm/utils/schema-adapter.js +25 -2
- package/dist/esm/utils/synchronous.d.ts +60 -4
- package/dist/esm/utils/synchronous.js +64 -7
- package/dist/esm/utils/text.d.ts +15 -1
- package/dist/esm/utils/text.js +15 -1
- package/package.json +23 -3
|
@@ -1,6 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded execution: the generic agent run loop and workflow driver.
|
|
3
|
+
*
|
|
4
|
+
* Two execution shapes share the round budget, cancellation and one diagnostic scope. A
|
|
5
|
+
* `CoreStep` loop owns its own round counter and returns an explicit continue/complete
|
|
6
|
+
* outcome; a bound workflow is traversed node by node, with routes selected after each
|
|
7
|
+
* commit. Business rules, tools and models are injected by the host — this module only
|
|
8
|
+
* enforces ordering, cancellation, budgets and reporting.
|
|
9
|
+
*
|
|
10
|
+
* Exports: `AgentCoreEngine` and the engine option/identity types.
|
|
11
|
+
*/
|
|
1
12
|
import { ModelCallBudget, parentModelBudget } from '../model/call-budget.js';
|
|
2
13
|
import { ModelRunner } from '../model/runner.js';
|
|
3
|
-
import { compiledModelBinding, modelBindingId, snapshotModelBinding } from '../model/binding.js';
|
|
14
|
+
import { compiledModelBinding, modelBindingId, snapshotModelBinding, } from '../model/binding.js';
|
|
4
15
|
import { getErrorInfo } from '../errors.js';
|
|
5
16
|
import { invocationId } from '../utils/invocation.js';
|
|
6
17
|
import { synchronous } from '../utils/synchronous.js';
|
|
@@ -13,10 +24,20 @@ import { breakWhile } from '../utils/rules.js';
|
|
|
13
24
|
import { NodeReports } from './reporting.js';
|
|
14
25
|
import { snapshotBranch } from './branch.js';
|
|
15
26
|
export * from './workflow.js';
|
|
16
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Bounded execution shared by applications; business rules are registered by each host.
|
|
29
|
+
*
|
|
30
|
+
* Configuration is bound before a run and may be bound only once per model, tool runtime
|
|
31
|
+
* and workflow. A run resolves its signal from the engine, the request runtime and the
|
|
32
|
+
* caller, then executes either the bound workflow or a supplied step function until the
|
|
33
|
+
* round budget, cancellation or a completion stops it.
|
|
34
|
+
*/
|
|
17
35
|
export class AgentCoreEngine {
|
|
36
|
+
/** Workflow catalog constructor, exposed so hosts do not import two modules. */
|
|
18
37
|
static Workflow = AgentWorkflow;
|
|
38
|
+
/** Attempt budget, exposed for hosts that gate their own sub-steps. */
|
|
19
39
|
static AttemptBudget = AttemptBudget;
|
|
40
|
+
/** Factory for a validated workflow definition. */
|
|
20
41
|
static createWorkflow = defineWorkflow;
|
|
21
42
|
maxRounds;
|
|
22
43
|
exhausted;
|
|
@@ -27,26 +48,70 @@ export class AgentCoreEngine {
|
|
|
27
48
|
models;
|
|
28
49
|
selectedModelId;
|
|
29
50
|
maxModelCalls;
|
|
51
|
+
/**
|
|
52
|
+
* Compile model options and reject engine-owned settings.
|
|
53
|
+
*
|
|
54
|
+
* @param options - Model binding supplied to the engine.
|
|
55
|
+
* @returns The compiled binding.
|
|
56
|
+
* @throws TypeError When the binding carries its own execution scope.
|
|
57
|
+
*/
|
|
30
58
|
snapshotModel(options) {
|
|
31
59
|
if (options.execution || options.signal)
|
|
32
60
|
throw new TypeError('Configure model execution on the Engine');
|
|
33
61
|
return snapshotModelBinding(options);
|
|
34
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Bind the single model this engine will use.
|
|
65
|
+
*
|
|
66
|
+
* @param options - App model settings.
|
|
67
|
+
* @returns This engine, for chaining.
|
|
68
|
+
* @throws TypeError When a model is already bound or the settings are invalid.
|
|
69
|
+
*/
|
|
35
70
|
bindModel(options) {
|
|
36
71
|
if (this.modelOptions || this.models || this.modelRuntime)
|
|
37
72
|
throw new TypeError('Engine already has a bound model');
|
|
38
73
|
return this.setModel(options);
|
|
39
74
|
}
|
|
40
|
-
/**
|
|
75
|
+
/**
|
|
76
|
+
* Bind an existing request lifetime once, for App services sharing this Runner's budget.
|
|
77
|
+
*
|
|
78
|
+
* Callbacks are bound to the source runtime and the counters stay live getters, so the
|
|
79
|
+
* engine and the App observe exactly the same budget and signal.
|
|
80
|
+
*
|
|
81
|
+
* @param source - Request model runtime owned by the App.
|
|
82
|
+
* @returns This engine, for chaining.
|
|
83
|
+
* @throws Error When another model is already bound or the runtime lacks a usable signal.
|
|
84
|
+
*/
|
|
41
85
|
bindModelRuntime(source) {
|
|
42
86
|
breakWhile(!!this.modelOptions || !!this.models || !!this.modelRuntime, 'Engine already has a bound model');
|
|
43
87
|
const execution = source.execution, invoke = source.invoke, prepare = source.prepare;
|
|
44
|
-
breakWhile(typeof invoke !== 'function' ||
|
|
45
|
-
|
|
88
|
+
breakWhile(typeof invoke !== 'function' ||
|
|
89
|
+
typeof prepare !== 'function' ||
|
|
90
|
+
typeof execution?.signal?.throwIfAborted !== 'function', 'Invalid request model runtime');
|
|
91
|
+
this.modelRuntime = Object.freeze({
|
|
92
|
+
invoke: invoke.bind(source),
|
|
93
|
+
prepare: prepare.bind(source),
|
|
46
94
|
execution: Object.freeze({ signal: execution.signal, diagnostics: execution.diagnostics }),
|
|
47
|
-
get remainingCalls() {
|
|
95
|
+
get remainingCalls() {
|
|
96
|
+
return source.remainingCalls;
|
|
97
|
+
},
|
|
98
|
+
get callCount() {
|
|
99
|
+
return source.callCount;
|
|
100
|
+
},
|
|
101
|
+
get totalCallCount() {
|
|
102
|
+
return source.totalCallCount;
|
|
103
|
+
},
|
|
104
|
+
});
|
|
48
105
|
return this;
|
|
49
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Select a configured model, or replace the single bound model's configuration.
|
|
109
|
+
*
|
|
110
|
+
* @param options - A configured model id, or new settings for the single bound model.
|
|
111
|
+
* @returns This engine, for chaining.
|
|
112
|
+
* @throws WorkflowContractError When the id is not configured.
|
|
113
|
+
* @throws TypeError When no single model is bound to switch.
|
|
114
|
+
*/
|
|
50
115
|
switchModel(options) {
|
|
51
116
|
if (typeof options === 'string') {
|
|
52
117
|
this.requireModel(options, this.models);
|
|
@@ -57,17 +122,38 @@ export class AgentCoreEngine {
|
|
|
57
122
|
throw new TypeError('Bind a single model before switching its configuration');
|
|
58
123
|
return this.setModel(options);
|
|
59
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Look up a configured model by id.
|
|
127
|
+
*
|
|
128
|
+
* @param id - Configured model id.
|
|
129
|
+
* @param models - Configured model map, when the engine uses a catalog.
|
|
130
|
+
* @returns The compiled binding.
|
|
131
|
+
* @throws WorkflowContractError When the id is not configured.
|
|
132
|
+
*/
|
|
60
133
|
requireModel(id, models) {
|
|
61
134
|
const options = models?.get(id);
|
|
62
135
|
if (!options)
|
|
63
136
|
throw new WorkflowContractError(`Unknown configured model: ${id}`);
|
|
64
137
|
return options;
|
|
65
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Compile and store the single bound model.
|
|
141
|
+
*
|
|
142
|
+
* @param options - App model settings.
|
|
143
|
+
* @returns This engine, for chaining.
|
|
144
|
+
*/
|
|
66
145
|
setModel(options) {
|
|
67
146
|
this.modelOptions = this.snapshotModel(options);
|
|
68
147
|
return this;
|
|
69
148
|
}
|
|
70
149
|
invokeTool;
|
|
150
|
+
/**
|
|
151
|
+
* Bind the tool runtime used by workflow context.
|
|
152
|
+
*
|
|
153
|
+
* @param tools - Registry exposing `invokeAsync`, or an object exposing `invoke`.
|
|
154
|
+
* @returns This engine, for chaining.
|
|
155
|
+
* @throws TypeError When tools are already bound or expose no invoke method.
|
|
156
|
+
*/
|
|
71
157
|
bindToolRuntime(tools) {
|
|
72
158
|
if (this.invokeTool)
|
|
73
159
|
throw new TypeError('Engine already has a bound tool runtime');
|
|
@@ -85,41 +171,109 @@ export class AgentCoreEngine {
|
|
|
85
171
|
engine.bind(workflow, app);
|
|
86
172
|
return engine;
|
|
87
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Store the workflow and its dependencies.
|
|
176
|
+
*
|
|
177
|
+
* @param workflow - Workflow to execute.
|
|
178
|
+
* @param app - App dependencies handed to every node and route.
|
|
179
|
+
* @throws TypeError When a workflow is already bound.
|
|
180
|
+
*/
|
|
88
181
|
bind(workflow, app) {
|
|
89
182
|
if (this.boundWorkflow)
|
|
90
183
|
throw new TypeError('Engine already has a bound workflow');
|
|
91
184
|
this.boundWorkflow = { workflow, app };
|
|
92
185
|
}
|
|
186
|
+
/** The bound workflow. */
|
|
93
187
|
get workflow() {
|
|
94
188
|
if (!this.boundWorkflow)
|
|
95
189
|
throw new TypeError('Engine has no bound workflow');
|
|
96
190
|
return this.boundWorkflow.workflow;
|
|
97
191
|
}
|
|
192
|
+
// A default identity is generated eagerly so checkpoints taken before a run still carry
|
|
193
|
+
// a stable branch, and a forked engine can point at the parent's ids.
|
|
98
194
|
branchIdentity = Object.freeze({
|
|
99
|
-
agentId: invocationId(),
|
|
195
|
+
agentId: invocationId(),
|
|
196
|
+
branchId: invocationId(),
|
|
197
|
+
agentVersionId: invocationId(),
|
|
100
198
|
});
|
|
199
|
+
// Membership test for checkpoints: a checkpoint object from another engine (or a
|
|
200
|
+
// hand-built lookalike) must not be accepted as if it proved branch ownership.
|
|
101
201
|
checkpoints = new WeakSet();
|
|
102
|
-
|
|
202
|
+
/** Identity of this engine's branch. */
|
|
203
|
+
get branch() {
|
|
204
|
+
return this.branchIdentity;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Take an in-memory checkpoint of host-owned data.
|
|
208
|
+
*
|
|
209
|
+
* The data is cloned on write and on every read, so neither side can mutate the other.
|
|
210
|
+
*
|
|
211
|
+
* @param data - Serializable data to capture.
|
|
212
|
+
* @returns A checkpoint bound to this branch.
|
|
213
|
+
*/
|
|
103
214
|
checkpoint(data) {
|
|
104
215
|
const snapshot = structuredClone(data);
|
|
105
|
-
const checkpoint = Object.freeze({
|
|
216
|
+
const checkpoint = Object.freeze({
|
|
217
|
+
id: invocationId(),
|
|
218
|
+
source: this.branch,
|
|
219
|
+
read: () => structuredClone(snapshot),
|
|
220
|
+
});
|
|
106
221
|
this.checkpoints.add(checkpoint);
|
|
107
222
|
return checkpoint;
|
|
108
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Export a checkpoint for host-owned persistence.
|
|
226
|
+
*
|
|
227
|
+
* @param checkpoint - Checkpoint taken by this engine.
|
|
228
|
+
* @returns A serializable record with a validated branch identity.
|
|
229
|
+
* @throws Error When the checkpoint belongs to another engine.
|
|
230
|
+
*/
|
|
109
231
|
exportCheckpoint(checkpoint) {
|
|
110
232
|
breakWhile(!this.checkpoints.has(checkpoint), 'Checkpoint belongs to another branch');
|
|
111
|
-
return {
|
|
233
|
+
return {
|
|
234
|
+
id: checkpoint.id,
|
|
235
|
+
source: snapshotBranch(checkpoint.source),
|
|
236
|
+
data: checkpoint.read(),
|
|
237
|
+
};
|
|
112
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Recreate a checkpoint from a persisted record.
|
|
241
|
+
*
|
|
242
|
+
* The record's branch must match this engine's branch exactly; otherwise persisted data
|
|
243
|
+
* from another branch would be adopted silently.
|
|
244
|
+
*
|
|
245
|
+
* @param record - Record produced by `exportCheckpoint`.
|
|
246
|
+
* @returns A checkpoint bound to this engine.
|
|
247
|
+
* @throws Error When the id is invalid or the branch identity differs.
|
|
248
|
+
*/
|
|
113
249
|
restoreCheckpoint(record) {
|
|
114
250
|
const source = snapshotBranch(record.source);
|
|
115
|
-
breakWhile(typeof record.id !== 'string' ||
|
|
116
|
-
|
|
251
|
+
breakWhile(typeof record.id !== 'string' ||
|
|
252
|
+
!record.id.trim() ||
|
|
253
|
+
record.id.length > 200 ||
|
|
254
|
+
JSON.stringify(source) !== JSON.stringify(snapshotBranch(this.branch)), 'Checkpoint identity does not match the restored branch');
|
|
117
255
|
const data = structuredClone(record.data);
|
|
118
256
|
const checkpoint = Object.freeze({ id: record.id, source, read: () => structuredClone(data) });
|
|
119
257
|
this.checkpoints.add(checkpoint);
|
|
120
258
|
return checkpoint;
|
|
121
259
|
}
|
|
122
|
-
|
|
260
|
+
/**
|
|
261
|
+
* Create an engine on a new branch forked at a checkpoint.
|
|
262
|
+
*
|
|
263
|
+
* The forked engine keeps the round budget, observation and configuration, receives an
|
|
264
|
+
* optional workflow extension, and gets a new branch identity whose parent ids point at
|
|
265
|
+
* this engine. Live handles are not copied: an App dependency, request runtime or tool
|
|
266
|
+
* runtime must be restored by the `resume` callback, because they cannot be serialized.
|
|
267
|
+
*
|
|
268
|
+
* @param request.at - Checkpoint taken by this engine to fork from.
|
|
269
|
+
* @param request.workflow - Optional extension or replacement workflow.
|
|
270
|
+
* @param request.routes - Route overrides; only valid with a workflow instance.
|
|
271
|
+
* @param request.resume - Receives the checkpoint data and returns restored dependencies.
|
|
272
|
+
* @returns A new engine on the forked branch.
|
|
273
|
+
* @throws TypeError When the checkpoint is foreign or the App dependency is missing.
|
|
274
|
+
* @throws Error When a bound request runtime or tool runtime was not restored.
|
|
275
|
+
*/
|
|
276
|
+
fork({ at, workflow, routes, resume, }) {
|
|
123
277
|
if (!this.boundWorkflow)
|
|
124
278
|
throw new TypeError('Engine has no bound workflow');
|
|
125
279
|
if (!this.checkpoints.has(at))
|
|
@@ -134,8 +288,12 @@ export class AgentCoreEngine {
|
|
|
134
288
|
breakWhile(!!this.modelRuntime && !dependencies?.model, 'Fork requires a restored request model runtime');
|
|
135
289
|
breakWhile(!!this.invokeTool && !dependencies?.tools, 'Fork requires a restored tool runtime');
|
|
136
290
|
const engine = new AgentCoreEngine({
|
|
137
|
-
maxRounds: this.maxRounds,
|
|
138
|
-
|
|
291
|
+
maxRounds: this.maxRounds,
|
|
292
|
+
errors: { exhausted: this.exhausted },
|
|
293
|
+
execution: {
|
|
294
|
+
diagnostics: this.options.execution?.diagnostics,
|
|
295
|
+
observe: this.options.execution?.observe,
|
|
296
|
+
},
|
|
139
297
|
});
|
|
140
298
|
engine.bind(definition, dependencies?.app);
|
|
141
299
|
if (dependencies?.tools)
|
|
@@ -149,13 +307,30 @@ export class AgentCoreEngine {
|
|
|
149
307
|
engine.maxModelCalls = this.maxModelCalls;
|
|
150
308
|
}
|
|
151
309
|
engine.branchIdentity = Object.freeze({
|
|
152
|
-
agentId: this.branch.agentId,
|
|
153
|
-
|
|
310
|
+
agentId: this.branch.agentId,
|
|
311
|
+
branchId: engine.branch.branchId,
|
|
312
|
+
agentVersionId: engine.branch.agentVersionId,
|
|
313
|
+
parentBranchId: this.branch.branchId,
|
|
314
|
+
parentAgentVersionId: this.branch.agentVersionId,
|
|
315
|
+
forkPointId: at.id,
|
|
154
316
|
});
|
|
155
317
|
return engine;
|
|
156
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* Build an engine and validate its wiring.
|
|
321
|
+
*
|
|
322
|
+
* Legacy top-level names (`maxSteps`, `exhausted`, `signal`, `diagnostics`,
|
|
323
|
+
* `onWorkflowEvent`, `observe`) are rejected rather than ignored, because silently
|
|
324
|
+
* dropping them would change budgets or observation.
|
|
325
|
+
*
|
|
326
|
+
* @param settings - Round budget, errors, execution scope, model, tools, workflow and branch.
|
|
327
|
+
* @throws TypeError When settings are invalid, removed names are used, or model wiring is
|
|
328
|
+
* inconsistent.
|
|
329
|
+
*/
|
|
157
330
|
constructor(settings = {}) {
|
|
158
|
-
if (!settings ||
|
|
331
|
+
if (!settings ||
|
|
332
|
+
typeof settings !== 'object' ||
|
|
333
|
+
['maxSteps', 'exhausted', 'signal', 'diagnostics', 'onWorkflowEvent', 'observe'].some((key) => key in settings)) {
|
|
159
334
|
throw new TypeError('Use maxRounds, execution (including observe) and errors');
|
|
160
335
|
}
|
|
161
336
|
const execution = settings.execution;
|
|
@@ -163,10 +338,18 @@ export class AgentCoreEngine {
|
|
|
163
338
|
this.branchIdentity = snapshotBranch(settings.branch);
|
|
164
339
|
const observer = execution?.observe;
|
|
165
340
|
this.maxRounds = settings.maxRounds ?? 8;
|
|
166
|
-
this.exhausted =
|
|
341
|
+
this.exhausted =
|
|
342
|
+
settings.errors?.exhausted?.bind(settings.errors) ??
|
|
343
|
+
(() => new BudgetError('Agent round budget exhausted'));
|
|
167
344
|
this.options = {
|
|
168
|
-
execution: {
|
|
169
|
-
|
|
345
|
+
execution: {
|
|
346
|
+
signal: execution?.signal,
|
|
347
|
+
diagnostics: execution?.diagnostics,
|
|
348
|
+
observe: observer && {
|
|
349
|
+
accepts: observer.accepts?.bind(observer),
|
|
350
|
+
event: observer.event.bind(observer),
|
|
351
|
+
},
|
|
352
|
+
},
|
|
170
353
|
};
|
|
171
354
|
breakWhile(!Number.isSafeInteger(this.maxRounds) || this.maxRounds < 1, () => new TypeError('maxRounds must be a positive safe integer'));
|
|
172
355
|
if (settings.workflow)
|
|
@@ -216,12 +399,45 @@ export class AgentCoreEngine {
|
|
|
216
399
|
this.runtimeActive = false;
|
|
217
400
|
}
|
|
218
401
|
}
|
|
402
|
+
/**
|
|
403
|
+
* Resolve the lifetime of one run.
|
|
404
|
+
*
|
|
405
|
+
* All three sources are lifetime bounds only, so the strictest wins and no source can
|
|
406
|
+
* extend another.
|
|
407
|
+
*
|
|
408
|
+
* @param requestSignal - Caller-supplied signal for this run.
|
|
409
|
+
* @returns The combined signal.
|
|
410
|
+
*/
|
|
219
411
|
executionSignal(requestSignal) {
|
|
220
412
|
return combineSignals(this.options.execution?.signal, this.modelRuntime?.execution.signal, requestSignal);
|
|
221
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Resolve the observation scope for one run.
|
|
416
|
+
*
|
|
417
|
+
* A bound request runtime contributes its scope only when the engine has none, so one
|
|
418
|
+
* fact source serves both the App and the engine.
|
|
419
|
+
*
|
|
420
|
+
* @returns Execution options with the effective diagnostic scope.
|
|
421
|
+
*/
|
|
222
422
|
executionOptions() {
|
|
223
|
-
return {
|
|
423
|
+
return {
|
|
424
|
+
...this.options.execution,
|
|
425
|
+
diagnostics: this.options.execution?.diagnostics ?? this.modelRuntime?.execution.diagnostics,
|
|
426
|
+
};
|
|
224
427
|
}
|
|
428
|
+
/**
|
|
429
|
+
* Drive a caller-supplied step function until it completes or the budget ends.
|
|
430
|
+
*
|
|
431
|
+
* Each iteration is a round: the step must return an explicit continue/complete outcome,
|
|
432
|
+
* the continue path owns the round limit, and a report scope always closes before the
|
|
433
|
+
* next round starts. Failures leave the loop and are rethrown after the scope closes.
|
|
434
|
+
*
|
|
435
|
+
* @param step - Step implementation receiving the round index and context.
|
|
436
|
+
* @param requestSignal - Caller signal for this run.
|
|
437
|
+
* @returns The value of the completing step.
|
|
438
|
+
* @throws WorkflowContractError When the step returns something other than continue/complete.
|
|
439
|
+
* @throws The configured exhausted error, the step's failure, or the signal reason.
|
|
440
|
+
*/
|
|
225
441
|
async runLoop(step, requestSignal) {
|
|
226
442
|
const signal = this.executionSignal(requestSignal);
|
|
227
443
|
const events = executionEvents(this.executionOptions());
|
|
@@ -229,7 +445,14 @@ export class AgentCoreEngine {
|
|
|
229
445
|
// failures leave the loop and propagate after the report scope closes.
|
|
230
446
|
let failure;
|
|
231
447
|
for (let index = 0;; index++) {
|
|
232
|
-
const diagnostics = events?.child(invocationId(), {
|
|
448
|
+
const diagnostics = events?.child(invocationId(), {
|
|
449
|
+
nodeRole: 'loop-step',
|
|
450
|
+
definitionKind: 'loop',
|
|
451
|
+
definitionId: 'loop',
|
|
452
|
+
nodeId: 'step',
|
|
453
|
+
nodeName: 'step',
|
|
454
|
+
nodeKind: 'loop-step',
|
|
455
|
+
});
|
|
233
456
|
const reports = new NodeReports(diagnostics, signal, 'loop.event');
|
|
234
457
|
let phase = 'boundary';
|
|
235
458
|
try {
|
|
@@ -237,10 +460,17 @@ export class AgentCoreEngine {
|
|
|
237
460
|
this.emitLoop({ type: 'enter', roundIndex: index }, diagnostics);
|
|
238
461
|
phase = 'run';
|
|
239
462
|
signal.throwIfAborted();
|
|
240
|
-
const result = await awaitWithSignal(step(index, {
|
|
463
|
+
const result = await awaitWithSignal(step(index, {
|
|
464
|
+
signal,
|
|
465
|
+
diagnostics,
|
|
466
|
+
report: reports.report.bind(reports),
|
|
467
|
+
createSubFlowLogger: reports.createSubFlowLogger.bind(reports),
|
|
468
|
+
}), signal);
|
|
241
469
|
signal.throwIfAborted();
|
|
242
|
-
if (!result ||
|
|
243
|
-
|
|
470
|
+
if (!result ||
|
|
471
|
+
(typeof result !== 'object' && typeof result !== 'function') ||
|
|
472
|
+
(result.type !== 'continue' && result.type !== 'complete') ||
|
|
473
|
+
(result.type === 'complete' && !('value' in result)))
|
|
244
474
|
throw new WorkflowContractError('Loop steps must return explicit continue/complete outcomes');
|
|
245
475
|
if (result.type === 'complete') {
|
|
246
476
|
const value = result.value;
|
|
@@ -265,13 +495,36 @@ export class AgentCoreEngine {
|
|
|
265
495
|
}
|
|
266
496
|
throw failure;
|
|
267
497
|
}
|
|
498
|
+
/**
|
|
499
|
+
* Traverse a workflow node by node.
|
|
500
|
+
*
|
|
501
|
+
* Per visit the order is fixed: cancellation and round-budget checks, `requires`
|
|
502
|
+
* validation, the node handler, commit of `provides`, route selection, then either
|
|
503
|
+
* completion or transition. Failures are reported before any recovery decision, and only
|
|
504
|
+
* non-aborted, non-contract failures may follow `onErrorNodeId`; anything else propagates.
|
|
505
|
+
*
|
|
506
|
+
* @param workflow - Validated workflow catalog.
|
|
507
|
+
* @param state - Initial state; mutated in place by commits.
|
|
508
|
+
* @param app - Host dependencies exposed as `context.app`.
|
|
509
|
+
* @param requestSignal - Caller signal for this run.
|
|
510
|
+
* @param requestModelId - Per-run configured model override.
|
|
511
|
+
* @returns The workflow result.
|
|
512
|
+
* @throws WorkflowContractError for contract violations, or the node failure otherwise.
|
|
513
|
+
*/
|
|
268
514
|
async executeWorkflow(workflow, state, app, requestSignal, requestModelId) {
|
|
269
515
|
const signal = this.executionSignal(requestSignal);
|
|
270
516
|
const invokeTool = this.invokeTool;
|
|
271
517
|
const workflowInvocationId = invocationId();
|
|
272
518
|
// The execution scope also correlates content delivery when no observer or log is installed.
|
|
273
|
-
const workflowDiagnostics = (executionEvents(this.executionOptions()) ?? createEventScope()).child(workflowInvocationId, {
|
|
274
|
-
|
|
519
|
+
const workflowDiagnostics = (executionEvents(this.executionOptions()) ?? createEventScope()).child(workflowInvocationId, {
|
|
520
|
+
...this.branch,
|
|
521
|
+
invocationId: workflowInvocationId,
|
|
522
|
+
workflowInvocationId,
|
|
523
|
+
nodeRole: 'invocation',
|
|
524
|
+
definitionKind: 'workflow',
|
|
525
|
+
definitionId: workflow.id,
|
|
526
|
+
definitionRevision: workflow.revision,
|
|
527
|
+
});
|
|
275
528
|
const modelOptions = this.modelOptions;
|
|
276
529
|
const models = this.models;
|
|
277
530
|
const selectedModelId = requestModelId ?? this.selectedModelId;
|
|
@@ -291,8 +544,13 @@ export class AgentCoreEngine {
|
|
|
291
544
|
throw new WorkflowContractError('Select a configured modelId');
|
|
292
545
|
let runner = runners.get(modelId);
|
|
293
546
|
if (!runner) {
|
|
294
|
-
const setup = {
|
|
295
|
-
|
|
547
|
+
const setup = {
|
|
548
|
+
provider: options.provider,
|
|
549
|
+
[compiledModelBinding]: options,
|
|
550
|
+
[modelBindingId]: modelId,
|
|
551
|
+
[parentModelBudget]: budget,
|
|
552
|
+
execution: { signal, diagnostics: workflowDiagnostics },
|
|
553
|
+
};
|
|
296
554
|
runner = new ModelRunner(setup);
|
|
297
555
|
runners.set(modelId, runner);
|
|
298
556
|
}
|
|
@@ -311,41 +569,114 @@ export class AgentCoreEngine {
|
|
|
311
569
|
throw this.exhausted();
|
|
312
570
|
}
|
|
313
571
|
catch (error) {
|
|
314
|
-
const diagnostics = workflowDiagnostics?.child(nextVisitId, {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
572
|
+
const diagnostics = workflowDiagnostics?.child(nextVisitId, {
|
|
573
|
+
nodeRole: 'workflow-boundary',
|
|
574
|
+
definitionKind: 'workflow',
|
|
575
|
+
definitionId: workflow.id,
|
|
576
|
+
definitionRevision: workflow.revision,
|
|
577
|
+
nodeId: node.id,
|
|
578
|
+
workflowNodeId: node.id,
|
|
579
|
+
nodeName: node.name ?? node.id,
|
|
580
|
+
nodeKind: 'workflow-node',
|
|
581
|
+
nodeDescription: node.description.slice(0, 1024),
|
|
582
|
+
});
|
|
583
|
+
this.emit({
|
|
584
|
+
...this.branch,
|
|
585
|
+
workflowId: workflow.id,
|
|
586
|
+
workflowInvocationId,
|
|
587
|
+
nodeId: node.id,
|
|
588
|
+
roundIndex: round,
|
|
589
|
+
...diagnostics?.identity,
|
|
590
|
+
type: 'error',
|
|
591
|
+
phase: 'boundary',
|
|
592
|
+
errorCode: this.errorCode(error, signal),
|
|
593
|
+
}, diagnostics);
|
|
318
594
|
throw error;
|
|
319
595
|
}
|
|
320
596
|
if (node.startsRound)
|
|
321
597
|
round = rounds++;
|
|
322
598
|
const started = Date.now();
|
|
323
|
-
const nodeDiagnostics = workflowDiagnostics?.child(nextVisitId, {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
599
|
+
const nodeDiagnostics = workflowDiagnostics?.child(nextVisitId, {
|
|
600
|
+
nodeRole: 'workflow-node',
|
|
601
|
+
definitionKind: 'workflow',
|
|
602
|
+
definitionId: workflow.id,
|
|
603
|
+
definitionRevision: workflow.revision,
|
|
604
|
+
nodeId: node.id,
|
|
605
|
+
workflowNodeId: node.id,
|
|
606
|
+
nodeName: node.name ?? node.id,
|
|
607
|
+
nodeKind: 'workflow-node',
|
|
608
|
+
nodeDescription: node.description.slice(0, 1024),
|
|
609
|
+
invocationId: undefined,
|
|
610
|
+
stageId: undefined,
|
|
611
|
+
});
|
|
612
|
+
const event = {
|
|
613
|
+
...this.branch,
|
|
614
|
+
workflowId: workflow.id,
|
|
615
|
+
workflowInvocationId,
|
|
616
|
+
errorEventId: failure?.errorEventId,
|
|
617
|
+
nodeId: node.id,
|
|
618
|
+
roundIndex: round,
|
|
619
|
+
...(nodeDiagnostics?.identity
|
|
620
|
+
? {
|
|
621
|
+
runId: nodeDiagnostics.identity.runId,
|
|
622
|
+
spanId: nodeDiagnostics.identity.spanId,
|
|
623
|
+
parentSpanId: nodeDiagnostics.identity.parentSpanId,
|
|
624
|
+
}
|
|
625
|
+
: {}),
|
|
626
|
+
};
|
|
327
627
|
function invokeModel(request) {
|
|
328
628
|
signal.throwIfAborted();
|
|
329
629
|
const owner = request.prepared && preparedOwners.get(request.prepared);
|
|
330
|
-
if (request.prepared &&
|
|
630
|
+
if (request.prepared &&
|
|
631
|
+
(!owner || (request.modelId !== undefined && request.modelId !== owner.modelId)))
|
|
331
632
|
throw new WorkflowContractError('Prepared model call belongs to another execution or model');
|
|
332
633
|
const runner = owner?.runner ?? runnerFor(request.modelId);
|
|
333
|
-
return runner.invoke({
|
|
334
|
-
|
|
335
|
-
|
|
634
|
+
return runner.invoke({
|
|
635
|
+
stageId: request.stageId,
|
|
636
|
+
maxOutputTokens: request.maxOutputTokens,
|
|
637
|
+
transport: request.transport,
|
|
638
|
+
prepared: request.prepared,
|
|
639
|
+
signal: combineSignals(signal, request.signal),
|
|
640
|
+
diagnostics: nodeDiagnostics,
|
|
641
|
+
...(typeof request.input === 'string'
|
|
642
|
+
? { input: request.input, instructions: request.instructions }
|
|
643
|
+
: { input: request.input }),
|
|
644
|
+
});
|
|
336
645
|
}
|
|
337
646
|
const prepareModel = ((request = {}) => {
|
|
338
647
|
signal.throwIfAborted();
|
|
339
648
|
const runner = runnerFor(request.modelId);
|
|
340
|
-
const snapshot = runner.prepare({
|
|
649
|
+
const snapshot = runner.prepare({
|
|
650
|
+
stageId: request.stageId,
|
|
651
|
+
maxOutputTokens: request.maxOutputTokens,
|
|
652
|
+
transport: request.transport,
|
|
653
|
+
});
|
|
341
654
|
preparedOwners.set(snapshot, { runner, modelId: request.modelId ?? selectedModelId });
|
|
342
655
|
return snapshot;
|
|
343
656
|
});
|
|
344
657
|
const reports = new NodeReports(nodeDiagnostics, signal);
|
|
345
|
-
const context = {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
658
|
+
const context = {
|
|
659
|
+
report: reports.report.bind(reports),
|
|
660
|
+
createSubFlowLogger: reports.createSubFlowLogger.bind(reports),
|
|
661
|
+
roundIndex: round,
|
|
662
|
+
app: app,
|
|
663
|
+
signal,
|
|
664
|
+
diagnostics: nodeDiagnostics,
|
|
665
|
+
model: {
|
|
666
|
+
invoke: invokeModel,
|
|
667
|
+
prepare: prepareModel,
|
|
668
|
+
get remainingCalls() {
|
|
669
|
+
return runnerFor().remainingCalls;
|
|
670
|
+
},
|
|
671
|
+
get callCount() {
|
|
672
|
+
return runnerFor().callCount;
|
|
673
|
+
},
|
|
674
|
+
get totalCallCount() {
|
|
675
|
+
return runnerFor().totalCallCount;
|
|
676
|
+
},
|
|
677
|
+
},
|
|
678
|
+
tools: {
|
|
679
|
+
async invoke(request) {
|
|
349
680
|
const toolSignal = combineSignals(signal, request.signal);
|
|
350
681
|
toolSignal.throwIfAborted();
|
|
351
682
|
if (!invokeTool)
|
|
@@ -353,7 +684,10 @@ export class AgentCoreEngine {
|
|
|
353
684
|
const result = await awaitWithSignal(invokeTool({ ...request, signal: toolSignal, diagnostics: nodeDiagnostics }), toolSignal);
|
|
354
685
|
toolSignal.throwIfAborted();
|
|
355
686
|
return result;
|
|
356
|
-
}
|
|
687
|
+
},
|
|
688
|
+
},
|
|
689
|
+
...(failure ?? {}),
|
|
690
|
+
};
|
|
357
691
|
this.emit({ ...event, type: 'enter' }, nodeDiagnostics);
|
|
358
692
|
let phase = 'requires';
|
|
359
693
|
let selectedRoute;
|
|
@@ -369,7 +703,7 @@ export class AgentCoreEngine {
|
|
|
369
703
|
phase = 'provides';
|
|
370
704
|
this.commit(state, update, node.provides ?? [], signal);
|
|
371
705
|
phase = 'route';
|
|
372
|
-
const routeIndex = node.routes.findIndex(route => {
|
|
706
|
+
const routeIndex = node.routes.findIndex((route) => {
|
|
373
707
|
selectedRoute = route;
|
|
374
708
|
if (!route.when)
|
|
375
709
|
return true;
|
|
@@ -410,11 +744,29 @@ export class AgentCoreEngine {
|
|
|
410
744
|
if (valid !== true)
|
|
411
745
|
throw new WorkflowContractError(`Invalid workflow result: ${workflow.id}`);
|
|
412
746
|
signal.throwIfAborted();
|
|
413
|
-
this.emit({
|
|
747
|
+
this.emit({
|
|
748
|
+
...event,
|
|
749
|
+
type: 'complete',
|
|
750
|
+
route: routeIndex,
|
|
751
|
+
routeId: route.id,
|
|
752
|
+
conditionId: route.conditionId,
|
|
753
|
+
durationMs: Date.now() - started,
|
|
754
|
+
}, nodeDiagnostics, node.report ? () => node.report(structuredClone(update), context) : undefined, reports);
|
|
414
755
|
return result;
|
|
415
756
|
}
|
|
416
757
|
nextVisitId = invocationId();
|
|
417
|
-
this.emit({
|
|
758
|
+
this.emit({
|
|
759
|
+
...event,
|
|
760
|
+
targetSpanId: workflowDiagnostics?.identity
|
|
761
|
+
? `${workflowDiagnostics.identity.spanId}/${nextVisitId}`
|
|
762
|
+
: undefined,
|
|
763
|
+
type: 'transition',
|
|
764
|
+
targetNodeId: route.targetNodeId,
|
|
765
|
+
route: routeIndex,
|
|
766
|
+
routeId: route.id,
|
|
767
|
+
conditionId: route.conditionId,
|
|
768
|
+
durationMs: Date.now() - started,
|
|
769
|
+
}, nodeDiagnostics, node.report ? () => node.report(structuredClone(update), context) : undefined, reports);
|
|
418
770
|
target = route.targetNodeId;
|
|
419
771
|
failure = undefined;
|
|
420
772
|
}
|
|
@@ -422,10 +774,22 @@ export class AgentCoreEngine {
|
|
|
422
774
|
const recoverable = !signal.aborted && !(error instanceof WorkflowContractError);
|
|
423
775
|
if (recoverable && node.onErrorNodeId !== undefined)
|
|
424
776
|
nextVisitId = invocationId();
|
|
425
|
-
const errorEvent = this.emit({
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
777
|
+
const errorEvent = this.emit({
|
|
778
|
+
...event,
|
|
779
|
+
targetSpanId: recoverable && node.onErrorNodeId !== undefined && workflowDiagnostics?.identity
|
|
780
|
+
? `${workflowDiagnostics.identity.spanId}/${nextVisitId}`
|
|
781
|
+
: undefined,
|
|
782
|
+
type: 'error',
|
|
783
|
+
targetNodeId: recoverable ? node.onErrorNodeId : undefined,
|
|
784
|
+
routeId: recoverable ? node.onErrorRouteId : undefined,
|
|
785
|
+
phase,
|
|
786
|
+
failedRouteId: ['route', 'complete', 'result'].includes(phase)
|
|
787
|
+
? selectedRoute?.id
|
|
788
|
+
: undefined,
|
|
789
|
+
conditionId: phase === 'route' ? selectedRoute?.conditionId : undefined,
|
|
790
|
+
durationMs: Date.now() - started,
|
|
791
|
+
errorCode: this.errorCode(error, signal),
|
|
792
|
+
}, nodeDiagnostics, undefined, reports);
|
|
429
793
|
signal.throwIfAborted();
|
|
430
794
|
if (node.onErrorNodeId === undefined || error instanceof WorkflowContractError)
|
|
431
795
|
throw error;
|
|
@@ -437,6 +801,20 @@ export class AgentCoreEngine {
|
|
|
437
801
|
}
|
|
438
802
|
}
|
|
439
803
|
}
|
|
804
|
+
/**
|
|
805
|
+
* Merge a node's state update and assert its declared outputs.
|
|
806
|
+
*
|
|
807
|
+
* The update is read once, checked against `provides` on the merged view, and only then
|
|
808
|
+
* written into the state, so a missing output never leaves a half-applied update.
|
|
809
|
+
* Cancellation is checked between the check and the write.
|
|
810
|
+
*
|
|
811
|
+
* @param state - State mutated in place.
|
|
812
|
+
* @param update - Object returned by the node handler, or undefined for no change.
|
|
813
|
+
* @param provides - Fields the node promises to leave defined.
|
|
814
|
+
* @param signal - Signal checked immediately before writing.
|
|
815
|
+
* @throws WorkflowContractError When the update is not an object or a provided field is
|
|
816
|
+
* undefined.
|
|
817
|
+
*/
|
|
440
818
|
commit(state, update, provides, signal) {
|
|
441
819
|
if (update !== undefined && (!update || typeof update !== 'object' || Array.isArray(update))) {
|
|
442
820
|
throw new WorkflowContractError('Workflow handlers must return a state update object or undefined');
|
|
@@ -456,26 +834,62 @@ export class AgentCoreEngine {
|
|
|
456
834
|
state[key] = fields[key];
|
|
457
835
|
}
|
|
458
836
|
}
|
|
837
|
+
/**
|
|
838
|
+
* Publish one loop event.
|
|
839
|
+
*
|
|
840
|
+
* The report scope is closed before emission for every event type, including `enter`,
|
|
841
|
+
* so a step cannot report progress against a round that has already ended.
|
|
842
|
+
*
|
|
843
|
+
* @param event - Loop event without its id.
|
|
844
|
+
* @param diagnostics - Scope of the current round.
|
|
845
|
+
* @param reports - Report scope for the current round.
|
|
846
|
+
*/
|
|
459
847
|
emitLoop(event, diagnostics, reports) {
|
|
460
848
|
const record = Object.freeze({ ...event, eventId: invocationId() });
|
|
461
849
|
reports?.close();
|
|
462
850
|
diagnostics?.emit('loop.event', () => record, reports?.debug());
|
|
463
851
|
}
|
|
852
|
+
/**
|
|
853
|
+
* Publish one workflow event and attach the node's report when content is enabled.
|
|
854
|
+
*
|
|
855
|
+
* The event is always emitted, even if the report throws or is malformed; a report is
|
|
856
|
+
* optional evidence, while the event is the authoritative transition record.
|
|
857
|
+
*
|
|
858
|
+
* @param input - Event fields without its id.
|
|
859
|
+
* @param diagnostics - Scope of the current node visit.
|
|
860
|
+
* @param report - Optional report builder evaluated only when content is enabled.
|
|
861
|
+
* @param reports - Report scope closed after emission.
|
|
862
|
+
* @returns The frozen event, so callers can reference its id.
|
|
863
|
+
*/
|
|
464
864
|
emit(input, diagnostics, report, reports) {
|
|
465
865
|
const event = Object.freeze({ ...input, eventId: invocationId() });
|
|
466
866
|
let detail;
|
|
467
|
-
if (report &&
|
|
867
|
+
if (report &&
|
|
868
|
+
diagnostics?.enabled('workflow.event') &&
|
|
869
|
+
diagnostics.enabled('workflow.event', 'content')) {
|
|
468
870
|
try {
|
|
469
871
|
const result = synchronous(report(), 'Workflow reports must be synchronous');
|
|
470
872
|
reports?.receive(result);
|
|
471
873
|
detail = { payload: structuredClone(result.payload), subs: result.subs };
|
|
472
874
|
}
|
|
473
|
-
catch {
|
|
875
|
+
catch {
|
|
876
|
+
/* A report cannot suppress the workflow event. */
|
|
877
|
+
}
|
|
474
878
|
}
|
|
475
879
|
reports?.close();
|
|
476
880
|
diagnostics?.emit('workflow.event', () => ({ event, ...(detail?.payload === undefined ? {} : { payload: detail.payload }) }), reports?.debug(detail));
|
|
477
881
|
return event;
|
|
478
882
|
}
|
|
883
|
+
/**
|
|
884
|
+
* Classify a failure for reporting.
|
|
885
|
+
*
|
|
886
|
+
* Cancellation takes precedence over the error itself: once the signal is aborted, the
|
|
887
|
+
* reason matters more than whatever the interrupted code threw.
|
|
888
|
+
*
|
|
889
|
+
* @param error - Failure to classify.
|
|
890
|
+
* @param signal - Execution signal at the time of failure.
|
|
891
|
+
* @returns `TIMEOUT`, `CANCELLED`, or the error's own code.
|
|
892
|
+
*/
|
|
479
893
|
errorCode(error, signal) {
|
|
480
894
|
if (signal?.aborted)
|
|
481
895
|
return isTimeoutReason(signal.reason) ? 'TIMEOUT' : 'CANCELLED';
|