@jungjaehoon/mama-core 2.4.1 → 4.0.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/README.md +76 -239
- package/db/migrations/030-case-first-memory-substrate.sql +13 -98
- package/db/migrations/034-add-connector-event-scope-columns.sql +9 -13
- package/db/migrations/039-add-connector-event-operator-ingest-seq.sql +9 -95
- package/db/migrations/062-refresh-connector-event-sequences.sql +9 -113
- package/db/migrations/063-refresh-legacy-connector-event-updates.sql +9 -32
- package/db/migrations/067-add-connector-event-source-entity-id.sql +9 -13
- package/db/migrations/069-create-registry-nodes.sql +52 -0
- package/db/migrations/070-record-identity.sql +35 -0
- package/db/migrations/071-service-operation-origins.sql +187 -0
- package/db/migrations/072-observation-versions.sql +29 -0
- package/db/migrations/073-registry-corrections.sql +45 -0
- package/db/migrations/074-work-graph-ref-kinds.sql +39 -0
- package/db/migrations/075-agent-judgments.sql +58 -0
- package/db/migrations/076-scoped-checkpoint-bindings.sql +15 -0
- package/db/migrations/077-legacy-record-kind.sql +6 -0
- package/db/migrations/078-source-ingest-commands.sql +18 -0
- package/db/migrations/079-twin-edge-relations.sql +43 -0
- package/db/migrations/080-restore-duration-days.sql +7 -0
- package/db/migrations/081-mailbox.sql +61 -0
- package/db/migrations/082-commitments-row-id.sql +12 -0
- package/db/migrations/083-observation-is-the-evidence.sql +49 -0
- package/db/migrations/084-scope-kind-is-not-the-cores-to-list.sql +34 -0
- package/db/migrations/085-a-migration-has-a-source.sql +37 -0
- package/db/migrations/086-the-mailbox-is-generic.sql +110 -0
- package/db/migrations/087-mailbox-payload.sql +5 -0
- package/db/migrations/088-native-input-journal.sql +14 -0
- package/db/migrations/089-native-turn-receipt-lookup.sql +3 -0
- package/db/migrations/090-model-run-native-inputs.sql +29 -0
- package/db/migrations/091-native-turn-results.sql +11 -0
- package/db/migrations/092-restore-decision-fts.sql +34 -0
- package/db/migrations/093-native-turn-primary-kind.sql +14 -0
- package/db/migrations/094-commitment-run-provenance.sql +9 -0
- package/db/migrations/095-model-run-native-input-identity.sql +39 -0
- package/db/migrations/096-drop-connector-event-index-fts.sql +9 -0
- package/db/migrations/097-native-input-json-validity.sql +37 -0
- package/db/migrations/098-workflow-memory-kind.sql +105 -0
- package/dist/action-contracts.d.ts +212 -0
- package/dist/action-contracts.js +10 -0
- package/dist/api/catalog.d.ts +118 -0
- package/dist/api/catalog.js +1756 -0
- package/dist/api/dispatch.d.ts +76 -0
- package/dist/api/dispatch.js +372 -0
- package/dist/canonicalize.d.ts +2 -2
- package/dist/canonicalize.js +3 -3
- package/dist/client/client.d.ts +33 -0
- package/dist/client/client.js +123 -0
- package/dist/client/ipc.d.ts +81 -0
- package/dist/client/ipc.js +314 -0
- package/dist/db-adapter/base-adapter.d.ts +6 -66
- package/dist/db-adapter/base-adapter.js +6 -6
- package/dist/db-adapter/index.d.ts +5 -5
- package/dist/db-adapter/index.js +2 -5
- package/dist/db-adapter/node-sqlite-adapter.d.ts +85 -15
- package/dist/db-adapter/node-sqlite-adapter.js +1968 -570
- package/dist/db-manager.d.ts +53 -97
- package/dist/db-manager.js +121 -603
- package/dist/embedding/embedder.d.ts +132 -0
- package/dist/embedding/embedder.js +299 -0
- package/dist/identity/principal-repository.d.ts +2 -2
- package/dist/index.d.ts +43 -58
- package/dist/index.js +97 -145
- package/dist/{context-compile/channel-grant.d.ts → knowledge/access.d.ts} +12 -17
- package/dist/knowledge/access.js +663 -0
- package/dist/knowledge/case-errors.d.ts +31 -0
- package/dist/knowledge/case-errors.js +40 -0
- package/dist/{cases/search-rollup.d.ts → knowledge/case-search-rollup.d.ts} +5 -4
- package/dist/{cases/search-rollup.js → knowledge/case-search-rollup.js} +6 -8
- package/dist/{cases/store.d.ts → knowledge/case-store.d.ts} +3 -6
- package/dist/{cases/store.js → knowledge/case-store.js} +7 -42
- package/dist/{cases/timeline-range.d.ts → knowledge/case-timeline-range.d.ts} +3 -3
- package/dist/{cases/timeline-range.js → knowledge/case-timeline-range.js} +47 -25
- package/dist/{cases/types.d.ts → knowledge/case-types.d.ts} +8 -2
- package/dist/{cases/types.js → knowledge/case-types.js} +1 -1
- package/dist/knowledge/commitments.d.ts +188 -0
- package/dist/knowledge/commitments.js +370 -0
- package/dist/knowledge/decision-edges.d.ts +70 -0
- package/dist/knowledge/decision-edges.js +123 -0
- package/dist/{agent-graph/types.d.ts → knowledge/graph-query.d.ts} +80 -70
- package/dist/knowledge/graph-query.js +1585 -0
- package/dist/knowledge/identity.d.ts +16 -0
- package/dist/knowledge/identity.js +22 -0
- package/dist/knowledge/index.d.ts +47 -0
- package/dist/knowledge/index.js +90 -0
- package/dist/knowledge/judgments.d.ts +118 -0
- package/dist/knowledge/judgments.js +808 -0
- package/dist/knowledge/observations.d.ts +160 -0
- package/dist/knowledge/observations.js +449 -0
- package/dist/knowledge/question-type.d.ts +34 -0
- package/dist/knowledge/question-type.js +70 -0
- package/dist/{search → knowledge}/ranker-features.js +1 -1
- package/dist/{search → knowledge}/search-quality.d.ts +0 -1
- package/dist/knowledge/search.d.ts +38 -0
- package/dist/knowledge/search.js +91 -0
- package/dist/knowledge/source-ingest.d.ts +65 -0
- package/dist/knowledge/source-ingest.js +174 -0
- package/dist/{edges/types.d.ts → knowledge/twin-edge-types.d.ts} +31 -4
- package/dist/{edges/types.js → knowledge/twin-edge-types.js} +13 -2
- package/dist/knowledge/work-dates.d.ts +49 -0
- package/dist/knowledge/work-dates.js +120 -0
- package/dist/mama-api.d.ts +114 -778
- package/dist/mama-api.js +313 -2461
- package/dist/memory/api.d.ts +264 -24
- package/dist/memory/api.js +1633 -843
- package/dist/memory/bootstrap-builder.d.ts +2 -1
- package/dist/memory/bootstrap-builder.js +5 -5
- package/dist/memory/channel-summary-state-store.d.ts +3 -2
- package/dist/memory/channel-summary-state-store.js +53 -51
- package/dist/memory/channel-summary-store.d.ts +5 -3
- package/dist/memory/channel-summary-store.js +3 -8
- package/dist/memory/dashboard-read.d.ts +46 -0
- package/dist/memory/dashboard-read.js +94 -0
- package/dist/memory/event-store.d.ts +3 -3
- package/dist/memory/event-store.js +3 -10
- package/dist/memory/finding-store.d.ts +3 -2
- package/dist/memory/finding-store.js +2 -7
- package/dist/memory/graph-read.d.ts +52 -0
- package/dist/memory/graph-read.js +130 -0
- package/dist/memory/judgment-types.d.ts +394 -0
- package/dist/memory/judgment-types.js +16 -0
- package/dist/memory/provenance-audit.d.ts +5 -2
- package/dist/memory/provenance-audit.js +8 -14
- package/dist/memory/provenance-live.d.ts +141 -0
- package/dist/memory/provenance-live.js +409 -0
- package/dist/memory/provenance-query.d.ts +5 -4
- package/dist/memory/provenance-query.js +21 -29
- package/dist/memory/provenance-resolver.d.ts +191 -0
- package/dist/memory/provenance-resolver.js +155 -0
- package/dist/memory/provenance.d.ts +1 -11
- package/dist/memory/provenance.js +2 -33
- package/dist/memory/recall-sanitize.d.ts +55 -0
- package/dist/memory/recall-sanitize.js +144 -0
- package/dist/memory/secret-filter.d.ts +32 -0
- package/dist/memory/secret-filter.js +126 -0
- package/dist/memory/truth-store.d.ts +2 -1
- package/dist/memory/truth-store.js +1 -4
- package/dist/memory/types.d.ts +74 -24
- package/dist/memory/types.js +75 -5
- package/dist/memory/write-adapters.d.ts +98 -0
- package/dist/memory/write-adapters.js +242 -0
- package/dist/operations/owner-action-effects.d.ts +53 -0
- package/dist/operations/owner-action-effects.js +96 -0
- package/dist/provenance/source-ref.d.ts +1 -1
- package/dist/provenance/source-ref.js +0 -2
- package/dist/registry/corrections.d.ts +31 -0
- package/dist/registry/corrections.js +332 -0
- package/dist/registry/record-identity.d.ts +49 -0
- package/dist/registry/record-identity.js +133 -0
- package/dist/registry/store.d.ts +101 -0
- package/dist/registry/store.js +395 -0
- package/dist/registry/types.d.ts +28 -0
- package/dist/registry/types.js +5 -0
- package/dist/relevance-scorer.js +2 -2
- package/dist/runtime/agent-event-bus.d.ts +50 -0
- package/dist/runtime/agent-event-bus.js +101 -0
- package/dist/runtime/drivers/claude-cli-wrapper.d.ts +155 -0
- package/dist/runtime/drivers/claude-cli-wrapper.js +392 -0
- package/dist/runtime/drivers/cli-arg-redaction.d.ts +2 -0
- package/dist/runtime/drivers/cli-arg-redaction.js +18 -0
- package/dist/runtime/drivers/cli-secret-redaction.d.ts +17 -0
- package/dist/runtime/drivers/cli-secret-redaction.js +126 -0
- package/dist/runtime/drivers/codex-app-server-process.d.ts +277 -0
- package/dist/runtime/drivers/codex-app-server-process.js +2342 -0
- package/dist/runtime/drivers/codex-auxiliary-tools.d.ts +17 -0
- package/dist/runtime/drivers/codex-auxiliary-tools.js +267 -0
- package/dist/runtime/drivers/codex-home.d.ts +20 -0
- package/dist/runtime/drivers/codex-home.js +674 -0
- package/dist/runtime/drivers/codex-thread-registry.d.ts +63 -0
- package/dist/runtime/drivers/codex-thread-registry.js +433 -0
- package/dist/runtime/drivers/persistent-cli-adapter.d.ts +160 -0
- package/dist/runtime/drivers/persistent-cli-adapter.js +396 -0
- package/dist/runtime/drivers/persistent-cli-process.d.ts +424 -0
- package/dist/runtime/drivers/persistent-cli-process.js +1543 -0
- package/dist/runtime/drivers/types.d.ts +456 -0
- package/dist/runtime/drivers/types.js +110 -0
- package/dist/runtime/mailbox.d.ts +223 -0
- package/dist/runtime/mailbox.js +582 -0
- package/dist/runtime/model-run-store.d.ts +28 -0
- package/dist/{model-runs/store.js → runtime/model-run-store.js} +81 -41
- package/dist/{model-runs/types.d.ts → runtime/model-run-types.d.ts} +33 -4
- package/dist/{model-runs/types.js → runtime/model-run-types.js} +1 -1
- package/dist/runtime/native-effect-observer.d.ts +22 -0
- package/dist/runtime/native-effect-observer.js +103 -0
- package/dist/runtime/native-input-journal.d.ts +46 -0
- package/dist/runtime/native-input-journal.js +308 -0
- package/dist/runtime/native-prompt.d.ts +118 -0
- package/dist/runtime/native-prompt.js +496 -0
- package/dist/runtime/native-session.d.ts +10 -0
- package/dist/{agent-graph/index.js → runtime/native-session.js} +9 -6
- package/dist/runtime/native-tool-trace-observer.d.ts +5 -0
- package/dist/runtime/native-tool-trace-observer.js +65 -0
- package/dist/runtime/native-turn.d.ts +272 -0
- package/dist/runtime/native-turn.js +1041 -0
- package/dist/runtime/operations.d.ts +236 -0
- package/dist/runtime/operations.js +565 -0
- package/dist/runtime/post-tool-handler.d.ts +74 -0
- package/dist/runtime/post-tool-handler.js +137 -0
- package/dist/runtime/prompt-layers.d.ts +126 -0
- package/dist/runtime/prompt-layers.js +239 -0
- package/dist/runtime/runtime-process.d.ts +102 -0
- package/dist/runtime/runtime-process.js +206 -0
- package/dist/runtime/runtime.d.ts +278 -0
- package/dist/runtime/runtime.js +563 -0
- package/dist/runtime/session-pool.d.ts +176 -0
- package/dist/runtime/session-pool.js +369 -0
- package/dist/runtime/stimulus-payload.d.ts +5 -0
- package/dist/runtime/stimulus-payload.js +50 -0
- package/dist/runtime/subagent-bridge.d.ts +24 -0
- package/dist/{agent-graph/types.js → runtime/subagent-bridge.js} +1 -1
- package/dist/runtime/text-completion.d.ts +22 -0
- package/dist/{agent-situation/types.js → runtime/text-completion.js} +1 -1
- package/dist/runtime/token-estimator.d.ts +25 -0
- package/dist/runtime/token-estimator.js +75 -0
- package/dist/runtime/tool-trace-store.d.ts +22 -0
- package/dist/{model-runs → runtime}/tool-trace-store.js +46 -27
- package/dist/runtime/trace-summary.d.ts +5 -0
- package/dist/runtime/trace-summary.js +74 -0
- package/dist/runtime/turn-text.d.ts +23 -0
- package/dist/runtime/turn-text.js +41 -0
- package/dist/storage/database.d.ts +67 -0
- package/dist/storage/database.js +158 -0
- package/package.json +20 -34
- package/dist/agent-graph/alias-write.d.ts +0 -3
- package/dist/agent-graph/alias-write.js +0 -234
- package/dist/agent-graph/entity-resolve.d.ts +0 -3
- package/dist/agent-graph/entity-resolve.js +0 -271
- package/dist/agent-graph/errors.d.ts +0 -4
- package/dist/agent-graph/errors.js +0 -11
- package/dist/agent-graph/graph-query.d.ts +0 -5
- package/dist/agent-graph/graph-query.js +0 -360
- package/dist/agent-graph/index.d.ts +0 -6
- package/dist/agent-situation/builder.d.ts +0 -8
- package/dist/agent-situation/builder.js +0 -239
- package/dist/agent-situation/cache-key.d.ts +0 -4
- package/dist/agent-situation/cache-key.js +0 -64
- package/dist/agent-situation/index.d.ts +0 -7
- package/dist/agent-situation/index.js +0 -28
- package/dist/agent-situation/packet-store.d.ts +0 -27
- package/dist/agent-situation/packet-store.js +0 -228
- package/dist/agent-situation/ranking-policy.d.ts +0 -18
- package/dist/agent-situation/ranking-policy.js +0 -75
- package/dist/agent-situation/source-readers.d.ts +0 -52
- package/dist/agent-situation/source-readers.js +0 -300
- package/dist/agent-situation/types.d.ts +0 -195
- package/dist/cases/wiki-page-index.d.ts +0 -37
- package/dist/cases/wiki-page-index.js +0 -201
- package/dist/config-loader.d.ts +0 -68
- package/dist/config-loader.js +0 -239
- package/dist/connectors/event-index.d.ts +0 -24
- package/dist/connectors/event-index.js +0 -245
- package/dist/connectors/raw-query.d.ts +0 -40
- package/dist/connectors/raw-query.js +0 -412
- package/dist/connectors/types.d.ts +0 -117
- package/dist/connectors/types.js +0 -3
- package/dist/context-compile/boundary-defaults.d.ts +0 -12
- package/dist/context-compile/boundary-defaults.js +0 -105
- package/dist/context-compile/channel-grant.js +0 -66
- package/dist/context-compile/compiler-policy.d.ts +0 -39
- package/dist/context-compile/compiler-policy.js +0 -147
- package/dist/context-compile/compiler.d.ts +0 -18
- package/dist/context-compile/compiler.js +0 -404
- package/dist/context-compile/index.d.ts +0 -10
- package/dist/context-compile/index.js +0 -26
- package/dist/context-compile/packet-store.d.ts +0 -8
- package/dist/context-compile/packet-store.js +0 -239
- package/dist/context-compile/ref.d.ts +0 -7
- package/dist/context-compile/ref.js +0 -102
- package/dist/context-compile/source-readers.d.ts +0 -70
- package/dist/context-compile/source-readers.js +0 -840
- package/dist/context-compile/types.d.ts +0 -155
- package/dist/context-compile/types.js +0 -11
- package/dist/context-compile/visibility.d.ts +0 -21
- package/dist/context-compile/visibility.js +0 -224
- package/dist/decision-tracker.d.ts +0 -206
- package/dist/decision-tracker.js +0 -481
- package/dist/edges/ref-validation.d.ts +0 -7
- package/dist/edges/ref-validation.js +0 -321
- package/dist/edges/store.d.ts +0 -8
- package/dist/edges/store.js +0 -129
- package/dist/embedding-client.d.ts +0 -28
- package/dist/embedding-client.js +0 -53
- package/dist/embedding-server/index.d.ts +0 -67
- package/dist/embedding-server/index.js +0 -405
- package/dist/embedding-server/mobile/auth.d.ts +0 -44
- package/dist/embedding-server/mobile/auth.js +0 -150
- package/dist/embedding-server/mobile/daemon.d.ts +0 -129
- package/dist/embedding-server/mobile/daemon.js +0 -313
- package/dist/embedding-server/mobile/output-parser.d.ts +0 -115
- package/dist/embedding-server/mobile/output-parser.js +0 -241
- package/dist/embedding-server/mobile/session-api.d.ts +0 -57
- package/dist/embedding-server/mobile/session-api.js +0 -261
- package/dist/embedding-server/mobile/session-manager.d.ts +0 -138
- package/dist/embedding-server/mobile/session-manager.js +0 -378
- package/dist/embedding-server/mobile/websocket-handler.d.ts +0 -137
- package/dist/embedding-server/mobile/websocket-handler.js +0 -486
- package/dist/embeddings.d.ts +0 -68
- package/dist/embeddings.js +0 -244
- package/dist/entities/audit-metrics.d.ts +0 -68
- package/dist/entities/audit-metrics.js +0 -124
- package/dist/entities/candidate-generator.d.ts +0 -8
- package/dist/entities/candidate-generator.js +0 -24
- package/dist/entities/entity-linked-decision-counts.d.ts +0 -2
- package/dist/entities/entity-linked-decision-counts.js +0 -29
- package/dist/entities/entity-list.d.ts +0 -22
- package/dist/entities/entity-list.js +0 -3
- package/dist/entities/entity-orphan-list.d.ts +0 -17
- package/dist/entities/entity-orphan-list.js +0 -3
- package/dist/entities/entity-search.d.ts +0 -20
- package/dist/entities/entity-search.js +0 -3
- package/dist/entities/errors.d.ts +0 -55
- package/dist/entities/errors.js +0 -100
- package/dist/entities/lineage-store.d.ts +0 -28
- package/dist/entities/lineage-store.js +0 -204
- package/dist/entities/normalization.d.ts +0 -14
- package/dist/entities/normalization.js +0 -63
- package/dist/entities/policy-store.d.ts +0 -8
- package/dist/entities/policy-store.js +0 -75
- package/dist/entities/policy-types.d.ts +0 -72
- package/dist/entities/policy-types.js +0 -59
- package/dist/entities/projection.d.ts +0 -8
- package/dist/entities/projection.js +0 -82
- package/dist/entities/provenance-query.d.ts +0 -32
- package/dist/entities/provenance-query.js +0 -3
- package/dist/entities/read-identity.d.ts +0 -31
- package/dist/entities/read-identity.js +0 -264
- package/dist/entities/recall-bridge.d.ts +0 -5
- package/dist/entities/recall-bridge.js +0 -171
- package/dist/entities/resolution-engine.d.ts +0 -8
- package/dist/entities/resolution-engine.js +0 -3
- package/dist/entities/rollback-preview.d.ts +0 -35
- package/dist/entities/rollback-preview.js +0 -3
- package/dist/entities/source-locator.d.ts +0 -3
- package/dist/entities/source-locator.js +0 -32
- package/dist/entities/store.d.ts +0 -69
- package/dist/entities/store.js +0 -544
- package/dist/entities/types.d.ts +0 -166
- package/dist/entities/types.js +0 -30
- package/dist/memory/extraction-prompt.d.ts +0 -4
- package/dist/memory/extraction-prompt.js +0 -89
- package/dist/memory/scope-backfill.d.ts +0 -14
- package/dist/memory/scope-backfill.js +0 -3
- package/dist/memory/scope-store.d.ts +0 -4
- package/dist/memory/scope-store.js +0 -9
- package/dist/memory-store.d.ts +0 -87
- package/dist/memory-store.js +0 -78
- package/dist/model-runs/store.d.ts +0 -13
- package/dist/model-runs/tool-trace-store.d.ts +0 -8
- package/dist/notification-manager.d.ts +0 -7
- package/dist/notification-manager.js +0 -12
- package/dist/outcome-tracker.d.ts +0 -151
- package/dist/outcome-tracker.js +0 -271
- package/dist/query-intent.d.ts +0 -23
- package/dist/query-intent.js +0 -114
- package/dist/runtime/trusted-provenance.d.ts +0 -3
- package/dist/runtime/trusted-provenance.js +0 -6
- package/dist/search/question-type.d.ts +0 -5
- package/dist/search/question-type.js +0 -41
- package/dist/test-utils.d.ts +0 -80
- package/dist/test-utils.js +0 -218
- package/dist/tier-validator.d.ts +0 -43
- package/dist/tier-validator.js +0 -159
- package/dist/time-formatter.d.ts +0 -25
- package/dist/time-formatter.js +0 -93
- /package/dist/{search → knowledge}/feedback-store.d.ts +0 -0
- /package/dist/{search → knowledge}/feedback-store.js +0 -0
- /package/dist/{search → knowledge}/ranker-features.d.ts +0 -0
- /package/dist/{search → knowledge}/ranker-rescore.d.ts +0 -0
- /package/dist/{search → knowledge}/ranker-rescore.js +0 -0
- /package/dist/{search → knowledge}/ranker-trainer.d.ts +0 -0
- /package/dist/{search → knowledge}/ranker-trainer.js +0 -0
- /package/dist/{search → knowledge}/search-quality.js +0 -0
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runNativePrompt = runNativePrompt;
|
|
4
|
+
const types_js_1 = require("./drivers/types.js");
|
|
5
|
+
const debug_logger_js_1 = require("../debug-logger.js");
|
|
6
|
+
const logger = new debug_logger_js_1.DebugLogger('turn');
|
|
7
|
+
const turn_text_js_1 = require("./turn-text.js");
|
|
8
|
+
/** A model-runner failure, said in the loop's own error vocabulary. */
|
|
9
|
+
const MODEL_RUNNER_AGENT_ERROR_CODES = {
|
|
10
|
+
timeout: 'NETWORK_ERROR',
|
|
11
|
+
crash: 'CLI_ERROR',
|
|
12
|
+
context_overflow: 'MAX_TOKENS',
|
|
13
|
+
auth_failure: 'AUTH_ERROR',
|
|
14
|
+
rate_limit: 'RATE_LIMIT',
|
|
15
|
+
unknown: 'CLI_ERROR',
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Submit one native request and observe its completed exchanges and final result.
|
|
19
|
+
* `carry` is read and written: the caller reads the final state off it.
|
|
20
|
+
*/
|
|
21
|
+
async function runNativePrompt(carry, context, request, host) {
|
|
22
|
+
const { channelKey, claudeNativeTools, effectiveSessionPolicyFingerprint, restrictedReadRoots, nativeCwd, history, hostToolBridge, isCodex, isDurableRuntime, nativeEffects, ownedModelRunId, standingPolicy, systemPrompt, reanchor, resumeInstructions, runScope, toolExecutionContext, totalUsage, tracksSessionPolicy, } = context;
|
|
23
|
+
// The eight that change are taken out of `carry` and put back in a finally, so the
|
|
24
|
+
// body below is the same text it was inside the class. A throw still reports the
|
|
25
|
+
// turn it reached.
|
|
26
|
+
let { turn, stopReason, stoppedBy, budgetTokens, resolvedCliSessionId, sessionIsNew } = carry;
|
|
27
|
+
try {
|
|
28
|
+
turn++;
|
|
29
|
+
{
|
|
30
|
+
let response;
|
|
31
|
+
const ext = runScope.streamCallbacks;
|
|
32
|
+
let attemptReportedError;
|
|
33
|
+
let nativeReceipt;
|
|
34
|
+
let nativeDispatch;
|
|
35
|
+
const callbacks = {
|
|
36
|
+
onInputDispatch: (input) => {
|
|
37
|
+
ext?.onInputDispatch?.(input);
|
|
38
|
+
nativeDispatch = input;
|
|
39
|
+
},
|
|
40
|
+
onAccepted: (receipt) => {
|
|
41
|
+
nativeReceipt = receipt;
|
|
42
|
+
ext?.onAccepted?.(receipt);
|
|
43
|
+
},
|
|
44
|
+
onDelta: (text) => {
|
|
45
|
+
ext?.onDelta?.(text);
|
|
46
|
+
},
|
|
47
|
+
onToolUse: (name, input) => {
|
|
48
|
+
nativeEffects.started(name, input);
|
|
49
|
+
ext?.onToolUse?.(name, input);
|
|
50
|
+
},
|
|
51
|
+
onToolComplete: (name, toolUseId, isError, outcome) => {
|
|
52
|
+
nativeEffects.settled(name, toolUseId, isError, outcome);
|
|
53
|
+
if (outcome)
|
|
54
|
+
ext?.onToolComplete?.(name, toolUseId, isError, outcome);
|
|
55
|
+
else
|
|
56
|
+
ext?.onToolComplete?.(name, toolUseId, isError);
|
|
57
|
+
},
|
|
58
|
+
// A spawn is an admission, not an external effect: forwarded verbatim with NO
|
|
59
|
+
// nativeEffects call, so it never writes a `native_tool` ledger row and never
|
|
60
|
+
// makes the occurrence unsafe to replay.
|
|
61
|
+
onSubagentStart: (info) => {
|
|
62
|
+
ext?.onSubagentStart?.(info);
|
|
63
|
+
},
|
|
64
|
+
onFollowUp: (info) => {
|
|
65
|
+
ext?.onFollowUp?.(info);
|
|
66
|
+
},
|
|
67
|
+
onFinal: (finalResponse) => {
|
|
68
|
+
ext?.onFinal?.(finalResponse);
|
|
69
|
+
},
|
|
70
|
+
onError: (error) => {
|
|
71
|
+
// A model runner can emit onError before rejecting. Hold it until
|
|
72
|
+
// AgentLoop knows whether the attempt is terminal so a successful
|
|
73
|
+
// one-time session recovery does not leak a false failure event.
|
|
74
|
+
attemptReportedError = error;
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
let piResult;
|
|
78
|
+
// Claude: first turn uses --session-id and injects the system prompt; later turns --resume
|
|
79
|
+
// Codex: resumeSession controls durable session reset/continuation.
|
|
80
|
+
let shouldResume = isDurableRuntime
|
|
81
|
+
? turn > 1 || (request.freshSession === true ? false : (request.resumeSession ?? true))
|
|
82
|
+
: !sessionIsNew || turn > 1 || (standingPolicy && request.resumeSession === true);
|
|
83
|
+
let requestSystemPrompt = systemPrompt;
|
|
84
|
+
let provisionalDurableSessionId;
|
|
85
|
+
// All three backends preserve context and receive only the new user message.
|
|
86
|
+
const basePromptText = host.formatLastMessageOnly(history);
|
|
87
|
+
const preparePrompt = context.prepareSessionContent
|
|
88
|
+
? async (session) => {
|
|
89
|
+
const content = await context.prepareSessionContent(session);
|
|
90
|
+
const input = [...history].reverse().find((message) => message.role === 'user');
|
|
91
|
+
if (!input)
|
|
92
|
+
throw new Error('Native session content requires an input message');
|
|
93
|
+
input.content = content;
|
|
94
|
+
console.log(`[NativeTurn] [${host.backend}] ${channelKey} (${session.isNewSession ? 'NEW' : 'CONTINUE'} native session)`);
|
|
95
|
+
return host.formatLastMessageOnly(history);
|
|
96
|
+
}
|
|
97
|
+
: undefined;
|
|
98
|
+
let promptText = basePromptText;
|
|
99
|
+
const promptStart = Date.now();
|
|
100
|
+
const throwFinalCliError = (error) => {
|
|
101
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
102
|
+
const modelRunnerErrorCode = normalizedError instanceof types_js_1.ModelRunnerError
|
|
103
|
+
? MODEL_RUNNER_AGENT_ERROR_CODES[normalizedError.code]
|
|
104
|
+
: undefined;
|
|
105
|
+
const errorType = normalizedError instanceof types_js_1.ClaudeToolStreamProtocolError
|
|
106
|
+
? normalizedError.code
|
|
107
|
+
: normalizedError instanceof types_js_1.HostToolTerminalError
|
|
108
|
+
? normalizedError.terminalCode
|
|
109
|
+
: (modelRunnerErrorCode ?? 'CLI_ERROR');
|
|
110
|
+
host.onMetric?.('prompt_error', 1, {
|
|
111
|
+
backend: host.backend,
|
|
112
|
+
error_type: errorType,
|
|
113
|
+
});
|
|
114
|
+
try {
|
|
115
|
+
ext?.onError?.(attemptReportedError ?? normalizedError);
|
|
116
|
+
}
|
|
117
|
+
catch (callbackError) {
|
|
118
|
+
logger.warn(`External onError callback failed: ${callbackError instanceof Error ? callbackError.message : String(callbackError)}`);
|
|
119
|
+
}
|
|
120
|
+
if (normalizedError instanceof types_js_1.HostToolTerminalError) {
|
|
121
|
+
throw new types_js_1.AgentError(normalizedError.message, normalizedError.terminalCode, normalizedError, false);
|
|
122
|
+
}
|
|
123
|
+
if (normalizedError instanceof types_js_1.HostToolAbortError) {
|
|
124
|
+
throw new types_js_1.AgentError(normalizedError.message, 'CLI_ERROR', normalizedError, false);
|
|
125
|
+
}
|
|
126
|
+
if (normalizedError instanceof types_js_1.NativeInputUncertainError) {
|
|
127
|
+
throw new types_js_1.AgentError(normalizedError.message, 'CLI_ERROR', normalizedError, false);
|
|
128
|
+
}
|
|
129
|
+
if (normalizedError instanceof types_js_1.ClaudeToolStreamProtocolError) {
|
|
130
|
+
throw new types_js_1.AgentError(normalizedError.message, normalizedError.code, normalizedError, false);
|
|
131
|
+
}
|
|
132
|
+
throw new types_js_1.AgentError(`CLI error: ${normalizedError.message}`, modelRunnerErrorCode ?? 'CLI_ERROR', normalizedError, normalizedError instanceof types_js_1.ModelRunnerError ? normalizedError.retryable : true);
|
|
133
|
+
};
|
|
134
|
+
const appendCompletedToolExchanges = (exchanges) => {
|
|
135
|
+
for (const exchange of exchanges) {
|
|
136
|
+
history.push({ role: 'assistant', content: [exchange.toolUse] });
|
|
137
|
+
runScope.onTurn?.({
|
|
138
|
+
turn,
|
|
139
|
+
role: 'assistant',
|
|
140
|
+
content: [exchange.toolUse],
|
|
141
|
+
stopReason: 'tool_use',
|
|
142
|
+
});
|
|
143
|
+
history.push({ role: 'user', content: [exchange.toolResult] });
|
|
144
|
+
runScope.onTurn?.({
|
|
145
|
+
turn,
|
|
146
|
+
role: 'user',
|
|
147
|
+
content: [exchange.toolResult],
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
try {
|
|
152
|
+
const durablePolicyStatus = tracksSessionPolicy && turn === 1 && (shouldResume || standingPolicy)
|
|
153
|
+
? host.agent.getSessionPolicyStatus?.({
|
|
154
|
+
model: request.model,
|
|
155
|
+
resumeSession: true,
|
|
156
|
+
systemPrompt: requestSystemPrompt,
|
|
157
|
+
sessionKey: channelKey,
|
|
158
|
+
sessionPolicyFingerprint: effectiveSessionPolicyFingerprint,
|
|
159
|
+
restrictedReadRoots,
|
|
160
|
+
cwd: nativeCwd,
|
|
161
|
+
sessionId: resolvedCliSessionId ?? undefined,
|
|
162
|
+
requestTimeout: request.requestTimeoutMs,
|
|
163
|
+
// Enforced INSIDE the codex turn (usage events), see CodexAppServerProcess.
|
|
164
|
+
runTokenBudget: host.runTokenBudget,
|
|
165
|
+
hostToolBridge,
|
|
166
|
+
})
|
|
167
|
+
: undefined;
|
|
168
|
+
if (durablePolicyStatus === 'mismatch' || durablePolicyStatus === 'missing') {
|
|
169
|
+
console.log(`[turn] ${host.backend} durable session ${durablePolicyStatus}; ` +
|
|
170
|
+
'opening the full policy before model request');
|
|
171
|
+
if (host.backend === 'claude' && durablePolicyStatus === 'mismatch') {
|
|
172
|
+
if (!host.agent.resetSession) {
|
|
173
|
+
throw new Error('Claude model runner cannot retire a stale policy session');
|
|
174
|
+
}
|
|
175
|
+
await host.agent.resetSession(resolvedCliSessionId ?? undefined);
|
|
176
|
+
}
|
|
177
|
+
const newSessionId = host.sessionPool.resetSession(channelKey);
|
|
178
|
+
request.onCliSessionReset?.(newSessionId);
|
|
179
|
+
resolvedCliSessionId = newSessionId;
|
|
180
|
+
provisionalDurableSessionId = newSessionId;
|
|
181
|
+
try {
|
|
182
|
+
// Recovery is asked for only after the backend proves replacement is
|
|
183
|
+
// required, never from host pool state.
|
|
184
|
+
const reanchored = await reanchor?.();
|
|
185
|
+
if (reanchored !== undefined) {
|
|
186
|
+
requestSystemPrompt = reanchored;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch (rebuildError) {
|
|
190
|
+
host.sessionPool.invalidateSession(channelKey, newSessionId);
|
|
191
|
+
provisionalDurableSessionId = undefined;
|
|
192
|
+
attemptReportedError =
|
|
193
|
+
rebuildError instanceof Error ? rebuildError : new Error(String(rebuildError));
|
|
194
|
+
throw rebuildError;
|
|
195
|
+
}
|
|
196
|
+
shouldResume = false;
|
|
197
|
+
}
|
|
198
|
+
promptText = basePromptText;
|
|
199
|
+
piResult = await host.agent.prompt(promptText, callbacks, {
|
|
200
|
+
preparePrompt,
|
|
201
|
+
model: request.model,
|
|
202
|
+
nativeInputId: request.nativeInputId,
|
|
203
|
+
resumeSession: shouldResume,
|
|
204
|
+
systemPrompt: requestSystemPrompt,
|
|
205
|
+
resumeInstructions,
|
|
206
|
+
promptTelemetry: {
|
|
207
|
+
kind: request.promptKind ?? (request.source === 'operator' ? 'scheduled' : 'chat'),
|
|
208
|
+
brief: request.promptBrief ?? 'omitted',
|
|
209
|
+
},
|
|
210
|
+
sessionKey: channelKey,
|
|
211
|
+
sessionPolicyFingerprint: effectiveSessionPolicyFingerprint,
|
|
212
|
+
restrictedReadRoots,
|
|
213
|
+
cwd: nativeCwd,
|
|
214
|
+
sessionId: resolvedCliSessionId ?? undefined,
|
|
215
|
+
// Per-run request timeout (operator worker runs); undefined leaves
|
|
216
|
+
// the pool's construction-time default untouched (chat).
|
|
217
|
+
requestTimeout: request.requestTimeoutMs,
|
|
218
|
+
runTokenBudget: host.runTokenBudget,
|
|
219
|
+
hostToolBridge,
|
|
220
|
+
toolExecutionContext,
|
|
221
|
+
...(host.backend === 'claude' ? { tools: claudeNativeTools } : {}),
|
|
222
|
+
});
|
|
223
|
+
provisionalDurableSessionId = undefined;
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
if (provisionalDurableSessionId) {
|
|
227
|
+
host.sessionPool.invalidateSession(channelKey, provisionalDurableSessionId);
|
|
228
|
+
provisionalDurableSessionId = undefined;
|
|
229
|
+
}
|
|
230
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
231
|
+
console.error(`[turn] ${host.backend} CLI error:`, errorMessage);
|
|
232
|
+
// A codex turn interrupted by the run budget is a host decision, not a failure:
|
|
233
|
+
// stop here with what was collected and let the host record the receipt.
|
|
234
|
+
if (error?.code === 'RUN_BUDGET_STOP' ||
|
|
235
|
+
errorMessage.startsWith('run budget stop:')) {
|
|
236
|
+
stoppedBy = 'budget';
|
|
237
|
+
const stoppedUsage = error.usage;
|
|
238
|
+
if (stoppedUsage) {
|
|
239
|
+
totalUsage.input_tokens += stoppedUsage.input_tokens;
|
|
240
|
+
totalUsage.output_tokens += stoppedUsage.output_tokens;
|
|
241
|
+
budgetTokens += (0, turn_text_js_1.countBudgetTokens)(stoppedUsage, host.backend);
|
|
242
|
+
try {
|
|
243
|
+
host.onTokenUsage?.({
|
|
244
|
+
channel_key: channelKey,
|
|
245
|
+
agent_id: request.agentContext?.roleName || host.model,
|
|
246
|
+
input_tokens: stoppedUsage.input_tokens,
|
|
247
|
+
output_tokens: stoppedUsage.output_tokens,
|
|
248
|
+
cache_read_tokens: stoppedUsage.cache_read_input_tokens || 0,
|
|
249
|
+
cost_usd: 0,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
// Recording failures must never mask the stop itself.
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
budgetTokens = Math.max(budgetTokens, host.runTokenBudget);
|
|
257
|
+
try {
|
|
258
|
+
host.onBudgetStop?.({
|
|
259
|
+
channelKey,
|
|
260
|
+
modelRunId: ownedModelRunId ?? request.modelRunId ?? null,
|
|
261
|
+
agentId: request.agentContext?.roleName,
|
|
262
|
+
budgetTokens,
|
|
263
|
+
runTokenBudget: host.runTokenBudget,
|
|
264
|
+
turns: turn,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
// Receipt failures must never mask the stop itself.
|
|
269
|
+
}
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
if (error instanceof types_js_1.HostToolTerminalError && error.completedToolExchanges?.length) {
|
|
273
|
+
appendCompletedToolExchanges(error.completedToolExchanges);
|
|
274
|
+
throwFinalCliError(error);
|
|
275
|
+
}
|
|
276
|
+
if (error instanceof types_js_1.HostToolAbortError && error.completedToolExchanges.length > 0) {
|
|
277
|
+
appendCompletedToolExchanges(error.completedToolExchanges);
|
|
278
|
+
throwFinalCliError(error);
|
|
279
|
+
}
|
|
280
|
+
if (nativeReceipt || nativeDispatch) {
|
|
281
|
+
throwFinalCliError(new types_js_1.NativeInputUncertainError('Native input dispatch began; reconcile its result before replay', (nativeReceipt ?? nativeDispatch), error));
|
|
282
|
+
}
|
|
283
|
+
// Check if this is a recoverable session error
|
|
284
|
+
// 1. "No conversation found" - CLI session was lost (daemon restart, timeout)
|
|
285
|
+
// 2. "Session ID already in use" - concurrent request conflict
|
|
286
|
+
// 3. "Prompt is too long" - session context exceeded API limits
|
|
287
|
+
const isSessionNotFound = errorMessage.includes('No conversation found with session ID');
|
|
288
|
+
const isSessionInUse = errorMessage.includes('is already in use');
|
|
289
|
+
const isPromptTooLong = (error instanceof types_js_1.ModelRunnerError && error.code === 'context_overflow') ||
|
|
290
|
+
errorMessage.includes('Prompt is too long') ||
|
|
291
|
+
errorMessage.includes('prompt is too long') ||
|
|
292
|
+
errorMessage.includes('request_too_large') ||
|
|
293
|
+
errorMessage.includes('context window') ||
|
|
294
|
+
errorMessage.includes('context_length_exceeded');
|
|
295
|
+
const isCodexPolicyMismatch = errorMessage.includes('Codex app-server thread policy mismatch; reset the session explicitly');
|
|
296
|
+
// 4. API 400 on a resumed session whose stored transcript carries an
|
|
297
|
+
// empty content block (live incident 2026-07-27: sonnet emitted an
|
|
298
|
+
// empty thinking block, the CLI persisted it, and every subsequent
|
|
299
|
+
// replay of that session died with this 400). The transcript is
|
|
300
|
+
// unrecoverable - only a fresh session heals it.
|
|
301
|
+
const isCorruptTranscript = errorMessage.includes('text content blocks must be non-empty');
|
|
302
|
+
const canRecoverSession = error instanceof types_js_1.NativeSessionUnavailableError ||
|
|
303
|
+
(isCodex && isCodexPolicyMismatch) ||
|
|
304
|
+
(!isCodex &&
|
|
305
|
+
(isSessionNotFound || isSessionInUse || isPromptTooLong || isCorruptTranscript));
|
|
306
|
+
const nativeFailure = nativeEffects.failure(error, canRecoverSession);
|
|
307
|
+
if (nativeFailure !== error) {
|
|
308
|
+
throw nativeFailure;
|
|
309
|
+
}
|
|
310
|
+
if (canRecoverSession) {
|
|
311
|
+
const reason = isCodexPolicyMismatch
|
|
312
|
+
? 'policy mismatch'
|
|
313
|
+
: error instanceof types_js_1.NativeSessionUnavailableError
|
|
314
|
+
? 'native context missing'
|
|
315
|
+
: isSessionNotFound
|
|
316
|
+
? 'not found in CLI'
|
|
317
|
+
: isSessionInUse
|
|
318
|
+
? 'already in use'
|
|
319
|
+
: isCorruptTranscript
|
|
320
|
+
? 'transcript corrupt (empty content block)'
|
|
321
|
+
: 'prompt too long (context overflow)';
|
|
322
|
+
console.log(`[turn] Session ${reason}, retrying with new session`);
|
|
323
|
+
// Reset session in pool so it creates a new one
|
|
324
|
+
const newSessionId = host.sessionPool.resetSession(channelKey);
|
|
325
|
+
request.onCliSessionReset?.(newSessionId);
|
|
326
|
+
// Per-call routing: hand the new id to this prompt() and update the
|
|
327
|
+
// resolved id so later turns follow it - no shared-adapter mutation.
|
|
328
|
+
resolvedCliSessionId = newSessionId;
|
|
329
|
+
// A recoverable durable-session error can occur on a resumed
|
|
330
|
+
// native session whose per-call prompt is intentionally minimal.
|
|
331
|
+
// Rebuild the full policy before opening every replacement session.
|
|
332
|
+
let resetSystemPrompt = systemPrompt;
|
|
333
|
+
try {
|
|
334
|
+
// Discard the recoverable first-attempt error before any reset
|
|
335
|
+
// preparation. A prompt rebuild or retry failure must surface
|
|
336
|
+
// its own final error, never the mismatch that triggered it.
|
|
337
|
+
attemptReportedError = undefined;
|
|
338
|
+
const reanchoredAfterReset = await reanchor?.();
|
|
339
|
+
if (reanchoredAfterReset !== undefined) {
|
|
340
|
+
resetSystemPrompt = reanchoredAfterReset;
|
|
341
|
+
}
|
|
342
|
+
promptText = basePromptText;
|
|
343
|
+
piResult = await host.agent.prompt(promptText, callbacks, {
|
|
344
|
+
preparePrompt,
|
|
345
|
+
model: request.model,
|
|
346
|
+
nativeInputId: request.nativeInputId,
|
|
347
|
+
resumeSession: false, // Force new session
|
|
348
|
+
systemPrompt: resetSystemPrompt,
|
|
349
|
+
sessionKey: channelKey,
|
|
350
|
+
sessionPolicyFingerprint: effectiveSessionPolicyFingerprint,
|
|
351
|
+
restrictedReadRoots,
|
|
352
|
+
cwd: nativeCwd,
|
|
353
|
+
sessionId: newSessionId,
|
|
354
|
+
// Carry the per-run timeout onto the reset session too.
|
|
355
|
+
requestTimeout: request.requestTimeoutMs,
|
|
356
|
+
runTokenBudget: host.runTokenBudget,
|
|
357
|
+
hostToolBridge,
|
|
358
|
+
toolExecutionContext,
|
|
359
|
+
...(host.backend === 'claude' ? { tools: claudeNativeTools } : {}),
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
catch (retryError) {
|
|
363
|
+
console.error(`[turn] ${host.backend} reset retry failed:`, retryError instanceof Error ? retryError.message : String(retryError));
|
|
364
|
+
// resetSession() creates and locks a replacement pool entry.
|
|
365
|
+
// A failed rebuild/retry must remove it entirely; otherwise the
|
|
366
|
+
// next native turn sees isNew=false and can persist a
|
|
367
|
+
// minimal resume prompt as the replacement thread's base policy.
|
|
368
|
+
host.sessionPool.invalidateSession(channelKey, newSessionId);
|
|
369
|
+
throwFinalCliError(retryError);
|
|
370
|
+
}
|
|
371
|
+
// Prepend reset notice so user knows context was lost
|
|
372
|
+
if (isPromptTooLong && piResult?.response) {
|
|
373
|
+
piResult.response = `\u26a0\ufe0f Session reset: The previous conversation was too long, starting a new session.\n\n${piResult.response}`;
|
|
374
|
+
}
|
|
375
|
+
console.log(`[turn] Retry successful with new session: ${newSessionId}`);
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
throwFinalCliError(error);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
if (!piResult) {
|
|
382
|
+
return throwFinalCliError(new Error('Model runner returned no prompt result'));
|
|
383
|
+
}
|
|
384
|
+
// Emit one terminal metric per prompt turn, including recovered calls.
|
|
385
|
+
host.onMetric?.('prompt_latency_ms', Date.now() - promptStart, {
|
|
386
|
+
backend: host.backend,
|
|
387
|
+
turn: String(turn),
|
|
388
|
+
});
|
|
389
|
+
// After first successful call, mark session as not new for subsequent turns
|
|
390
|
+
if (turn === 1) {
|
|
391
|
+
sessionIsNew = false;
|
|
392
|
+
}
|
|
393
|
+
const contentBlocks = [];
|
|
394
|
+
if (piResult.response?.trim())
|
|
395
|
+
contentBlocks.push({ type: 'text', text: piResult.response });
|
|
396
|
+
// eslint-disable-next-line prefer-const
|
|
397
|
+
response = {
|
|
398
|
+
id: `msg_${Date.now()}`,
|
|
399
|
+
type: 'message',
|
|
400
|
+
role: 'assistant',
|
|
401
|
+
content: contentBlocks,
|
|
402
|
+
model: host.model,
|
|
403
|
+
stop_reason: 'end_turn',
|
|
404
|
+
stop_sequence: null,
|
|
405
|
+
usage: piResult.usage,
|
|
406
|
+
};
|
|
407
|
+
// Update usage
|
|
408
|
+
totalUsage.input_tokens += response.usage.input_tokens;
|
|
409
|
+
totalUsage.output_tokens += response.usage.output_tokens;
|
|
410
|
+
budgetTokens += (0, turn_text_js_1.countBudgetTokens)(response.usage, host.backend);
|
|
411
|
+
// Record token usage
|
|
412
|
+
if (host.onTokenUsage) {
|
|
413
|
+
try {
|
|
414
|
+
host.onTokenUsage({
|
|
415
|
+
channel_key: channelKey,
|
|
416
|
+
agent_id: request.agentContext?.roleName || host.model, // Use roleName if available, else model
|
|
417
|
+
input_tokens: response.usage.input_tokens,
|
|
418
|
+
output_tokens: response.usage.output_tokens,
|
|
419
|
+
cache_read_tokens: response.usage.cache_read_input_tokens || 0, // No longer needs 'as any' cast
|
|
420
|
+
cost_usd: piResult.cost_usd || 0,
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
catch {
|
|
424
|
+
// Ignore recording errors - never break the agent loop
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
// Preserve the SessionPool usage-status contract. Billing telemetry is
|
|
428
|
+
// recorded above; durable runtimes own model-aware compaction.
|
|
429
|
+
host.sessionPool.updateTokens(channelKey, response.usage.input_tokens, host.backend);
|
|
430
|
+
// Claude's MCP server may already have executed these tool calls while the
|
|
431
|
+
// prompt was streaming. Preserve the observed exchange in conversation
|
|
432
|
+
// order, but never execute the observed tool_use again.
|
|
433
|
+
// Replaying a completed mutation would turn a transport observation into a
|
|
434
|
+
// second host-side effect.
|
|
435
|
+
if (Array.isArray(piResult.completedToolExchanges)) {
|
|
436
|
+
appendCompletedToolExchanges(piResult.completedToolExchanges);
|
|
437
|
+
}
|
|
438
|
+
// The local MCP server can complete a mutation and still report an
|
|
439
|
+
// indeterminate terminal outcome. Preserve the paired exchange above
|
|
440
|
+
// for auditability, then fail this turn without sending it through the
|
|
441
|
+
// ordinary host-tool loop or retrying the prompt.
|
|
442
|
+
if (piResult.terminalError) {
|
|
443
|
+
throwFinalCliError(new types_js_1.HostToolTerminalError(piResult.terminalError.code, piResult.terminalError.message));
|
|
444
|
+
}
|
|
445
|
+
if (piResult.toolUseBlocks?.length) {
|
|
446
|
+
throwFinalCliError(new types_js_1.ClaudeToolStreamProtocolError('Unresolved native tool calls cannot be executed by a host model loop'));
|
|
447
|
+
}
|
|
448
|
+
// Add assistant response to history
|
|
449
|
+
history.push({
|
|
450
|
+
role: 'assistant',
|
|
451
|
+
content: response.content,
|
|
452
|
+
});
|
|
453
|
+
// Notify turn callback
|
|
454
|
+
runScope.onTurn?.({
|
|
455
|
+
turn,
|
|
456
|
+
role: 'assistant',
|
|
457
|
+
content: response.content,
|
|
458
|
+
stopReason: response.stop_reason,
|
|
459
|
+
usage: response.usage,
|
|
460
|
+
});
|
|
461
|
+
stopReason = response.stop_reason;
|
|
462
|
+
// Per-run budget: checked after this turn's usage and before the next dispatch, so
|
|
463
|
+
// the budget is never exceeded by more than one turn. The partial response so far is
|
|
464
|
+
// returned, and the host records the receipt.
|
|
465
|
+
if (host.runTokenBudget > 0 && budgetTokens >= host.runTokenBudget) {
|
|
466
|
+
stoppedBy = 'budget';
|
|
467
|
+
console.warn(`[turn] run budget stop: ${budgetTokens} >= ${host.runTokenBudget} tokens after turn ${turn} (${channelKey})`);
|
|
468
|
+
try {
|
|
469
|
+
host.onBudgetStop?.({
|
|
470
|
+
channelKey,
|
|
471
|
+
modelRunId: ownedModelRunId ?? request.modelRunId ?? null,
|
|
472
|
+
agentId: request.agentContext?.roleName,
|
|
473
|
+
budgetTokens,
|
|
474
|
+
runTokenBudget: host.runTokenBudget,
|
|
475
|
+
turns: turn,
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
catch {
|
|
479
|
+
// Receipt failures must never mask the stop itself.
|
|
480
|
+
}
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
finally {
|
|
486
|
+
Object.assign(carry, {
|
|
487
|
+
turn,
|
|
488
|
+
stopReason,
|
|
489
|
+
stoppedBy,
|
|
490
|
+
budgetTokens,
|
|
491
|
+
resolvedCliSessionId,
|
|
492
|
+
sessionIsNew,
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
//# sourceMappingURL=native-prompt.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Shared native protocol, session lifetime and execution observations. */
|
|
2
|
+
export * from './native-effect-observer.js';
|
|
3
|
+
export * from './post-tool-handler.js';
|
|
4
|
+
export * from './agent-event-bus.js';
|
|
5
|
+
export * from './runtime-process.js';
|
|
6
|
+
export * from './turn-text.js';
|
|
7
|
+
export * from './native-prompt.js';
|
|
8
|
+
export * from './native-turn.js';
|
|
9
|
+
export type { NativeInputReceipt } from './drivers/types.js';
|
|
10
|
+
//# sourceMappingURL=native-session.d.ts.map
|
|
@@ -14,9 +14,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
|
|
18
|
-
__exportStar(require("./
|
|
19
|
-
__exportStar(require("./
|
|
20
|
-
__exportStar(require("./
|
|
21
|
-
__exportStar(require("./
|
|
22
|
-
|
|
17
|
+
/** Shared native protocol, session lifetime and execution observations. */
|
|
18
|
+
__exportStar(require("./native-effect-observer.js"), exports);
|
|
19
|
+
__exportStar(require("./post-tool-handler.js"), exports);
|
|
20
|
+
__exportStar(require("./agent-event-bus.js"), exports);
|
|
21
|
+
__exportStar(require("./runtime-process.js"), exports);
|
|
22
|
+
__exportStar(require("./turn-text.js"), exports);
|
|
23
|
+
__exportStar(require("./native-prompt.js"), exports);
|
|
24
|
+
__exportStar(require("./native-turn.js"), exports);
|
|
25
|
+
//# sourceMappingURL=native-session.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DatabaseAdapter } from '../db-manager.js';
|
|
2
|
+
import type { NativeEffectObserver } from './native-effect-observer.js';
|
|
3
|
+
/** Native harness notifications are observations; persistence never authorizes execution. */
|
|
4
|
+
export declare function createNativeToolTraceObserver(adapter: Pick<DatabaseAdapter, 'prepare'>, modelRunId: string): NativeEffectObserver;
|
|
5
|
+
//# sourceMappingURL=native-tool-trace-observer.d.ts.map
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createNativeToolTraceObserver = createNativeToolTraceObserver;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
const tool_trace_store_js_1 = require("./tool-trace-store.js");
|
|
6
|
+
const trace_summary_js_1 = require("./trace-summary.js");
|
|
7
|
+
/** Native harness notifications are observations; persistence never authorizes execution. */
|
|
8
|
+
function createNativeToolTraceObserver(adapter, modelRunId) {
|
|
9
|
+
const calls = new Map();
|
|
10
|
+
let warned = false;
|
|
11
|
+
const failed = () => {
|
|
12
|
+
if (!warned)
|
|
13
|
+
console.warn('[NativeToolTrace] observation storage failed');
|
|
14
|
+
warned = true;
|
|
15
|
+
};
|
|
16
|
+
const settle = (callId, status) => {
|
|
17
|
+
const call = calls.get(callId);
|
|
18
|
+
if (!call || call.settled)
|
|
19
|
+
return;
|
|
20
|
+
try {
|
|
21
|
+
adapter
|
|
22
|
+
.prepare('UPDATE tool_traces SET execution_status = ?, duration_ms = ? WHERE trace_id = ?')
|
|
23
|
+
.run(status, Math.max(0, Date.now() - call.startedAt), call.traceId);
|
|
24
|
+
call.settled = status !== 'unknown';
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
failed();
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
return {
|
|
31
|
+
started(name, input) {
|
|
32
|
+
const callId = typeof input.nativeToolUseId === 'string' ? input.nativeToolUseId : (0, node_crypto_1.randomUUID)();
|
|
33
|
+
if (calls.has(callId))
|
|
34
|
+
return;
|
|
35
|
+
const call = {
|
|
36
|
+
traceId: `tr_${(0, node_crypto_1.randomUUID)().replace(/-/g, '')}`,
|
|
37
|
+
startedAt: Date.now(),
|
|
38
|
+
settled: false,
|
|
39
|
+
};
|
|
40
|
+
calls.set(callId, call);
|
|
41
|
+
void (0, tool_trace_store_js_1.appendToolTrace)(adapter, {
|
|
42
|
+
trace_id: call.traceId,
|
|
43
|
+
model_run_id: modelRunId,
|
|
44
|
+
gateway_call_id: callId,
|
|
45
|
+
tool_name: name,
|
|
46
|
+
input_summary: (0, trace_summary_js_1.traceSummary)(input),
|
|
47
|
+
execution_status: 'running',
|
|
48
|
+
duration_ms: 0,
|
|
49
|
+
created_at: call.startedAt,
|
|
50
|
+
}).catch(failed);
|
|
51
|
+
},
|
|
52
|
+
settled(_name, callId, isError, outcome) {
|
|
53
|
+
settle(callId, outcome ?? (isError ? 'failed' : 'completed'));
|
|
54
|
+
},
|
|
55
|
+
interrupted() {
|
|
56
|
+
for (const callId of calls.keys())
|
|
57
|
+
settle(callId, 'unknown');
|
|
58
|
+
},
|
|
59
|
+
finished() {
|
|
60
|
+
for (const callId of calls.keys())
|
|
61
|
+
settle(callId, 'unknown');
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=native-tool-trace-observer.js.map
|