@sema-agent/core 7.54.1 → 7.55.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 +437 -0
- package/dist/agents/agent-transcript-tool.js +2 -1
- package/dist/agents/builtin-agents.d.ts +12 -14
- package/dist/agents/cc-peer-directory.d.ts +36 -0
- package/dist/agents/cc-peer-directory.js +138 -0
- package/dist/agents/cc-peer-wire.d.ts +105 -0
- package/dist/agents/cc-peer-wire.js +98 -0
- package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
- package/dist/agents/cc-uds-peer-channel.js +457 -0
- package/dist/agents/cross-session-envelope.d.ts +4 -1
- package/dist/agents/cross-session-envelope.js +8 -1
- package/dist/agents/cross-session-judge.d.ts +2 -2
- package/dist/agents/list-agents-tool.js +2 -1
- package/dist/agents/observer.d.ts +4 -5
- package/dist/agents/observer.js +2 -1
- package/dist/agents/peer-admission.d.ts +6 -0
- package/dist/agents/peer-admission.js +4 -1
- package/dist/agents/peer-directory.d.ts +43 -9
- package/dist/agents/peer-directory.js +66 -23
- package/dist/agents/peer-notices.d.ts +1 -1
- package/dist/agents/peer-session-drain.d.ts +3 -1
- package/dist/agents/peer-session-drain.js +1 -0
- package/dist/agents/read-inbox-tool.js +2 -1
- package/dist/agents/retain-ledger.d.ts +1 -1
- package/dist/agents/roster-store.d.ts +1 -1
- package/dist/agents/send-message-tool.d.ts +10 -0
- package/dist/agents/send-message-tool.js +34 -5
- package/dist/agents/subagent.d.ts +34 -79
- package/dist/agents/subagent.js +45 -46
- package/dist/agents/tool-filter.d.ts +29 -46
- package/dist/agents/tool-filter.js +8 -31
- package/dist/agents/verify.d.ts +3 -3
- package/dist/brain/anthropic.js +14 -9
- package/dist/brain/errors.d.ts +15 -0
- package/dist/brain/errors.js +10 -0
- package/dist/brain/model-presets.d.ts +4 -4
- package/dist/brain/open-responses.js +15 -10
- package/dist/brain/openai.js +17 -12
- package/dist/brain/provider-dialect.d.ts +39 -3
- package/dist/brain/provider-dialect.js +28 -0
- package/dist/brain/reasoning.d.ts +1 -1
- package/dist/brain/request-params.d.ts +55 -5
- package/dist/brain/request-params.js +35 -3
- package/dist/brain/retry.d.ts +1 -1
- package/dist/brain/route-adjudicator.d.ts +15 -0
- package/dist/brain/route-adjudicator.js +15 -0
- package/dist/brain/stream-engine.js +6 -5
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/core/advisor-verdict.d.ts +120 -0
- package/dist/core/advisor-verdict.js +92 -0
- package/dist/core/agent-definition.d.ts +7 -8
- package/dist/core/allow-entry.d.ts +49 -23
- package/dist/core/allow-entry.js +57 -32
- package/dist/core/allow-rule-shadow.d.ts +7 -0
- package/dist/core/approval-object.d.ts +2 -1
- package/dist/core/approval-object.js +6 -6
- package/dist/core/ask-origin.d.ts +63 -11
- package/dist/core/ask-origin.js +27 -5
- package/dist/core/ask-question.js +10 -4
- package/dist/core/auto-compaction.d.ts +11 -8
- package/dist/core/auto-compaction.js +4 -2
- package/dist/core/auto-mode-arming.d.ts +2 -2
- package/dist/core/auto-mode-defaults.d.ts +8 -8
- package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
- package/dist/core/auto-mode-prompt.d.ts +1 -1
- package/dist/core/auto-mode.d.ts +17 -9
- package/dist/core/auto-mode.js +9 -6
- package/dist/core/background-agent-store.d.ts +3 -3
- package/dist/core/canonical-json.d.ts +1 -1
- package/dist/core/canonical-json.js +2 -2
- package/dist/core/checkpoint-requirements.d.ts +6 -3
- package/dist/core/checkpoint-requirements.js +4 -14
- package/dist/core/checkpoint-store.d.ts +80 -51
- package/dist/core/checkpoint-store.js +56 -74
- package/dist/core/child-clamp-seats.d.ts +6 -0
- package/dist/core/child-clamp-seats.js +3 -16
- package/dist/core/compliance.d.ts +2 -2
- package/dist/core/context-edit.d.ts +6 -7
- package/dist/core/cross-boundary-taint.d.ts +9 -3
- package/dist/core/cross-boundary-taint.js +5 -3
- package/dist/core/decision-receipt.js +2 -2
- package/dist/core/effective-path-target.d.ts +1 -1
- package/dist/core/engine-notice.d.ts +19 -5
- package/dist/core/exec-output-tail.d.ts +1 -1
- package/dist/core/file-history-retention.d.ts +1 -1
- package/dist/core/file-history-store.d.ts +59 -9
- package/dist/core/file-history-store.js +35 -17
- package/dist/core/gate-fold.js +3 -2
- package/dist/core/gate-lanes.js +12 -8
- package/dist/core/gate-outcome.d.ts +17 -4
- package/dist/core/gate-outcome.js +30 -0
- package/dist/core/governance-codes.d.ts +13 -3
- package/dist/core/governance-codes.js +10 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +4 -4
- package/dist/core/host-target.d.ts +49 -0
- package/dist/core/host-target.js +59 -0
- package/dist/core/image-downsample.d.ts +1 -1
- package/dist/core/lsp-diagnostics.d.ts +4 -4
- package/dist/core/lsp.d.ts +3 -3
- package/dist/core/mailbox-store.d.ts +4 -0
- package/dist/core/mcp-connection-pool.d.ts +18 -2
- package/dist/core/mcp-connection-pool.js +53 -6
- package/dist/core/mcp-failure.d.ts +23 -4
- package/dist/core/mcp-failure.js +26 -11
- package/dist/core/mcp-listing-drift.d.ts +10 -0
- package/dist/core/mcp-listing-drift.js +6 -0
- package/dist/core/mcp-server-link.d.ts +173 -0
- package/dist/core/mcp-server-link.js +127 -0
- package/dist/core/mcp-server-spec.d.ts +4 -2
- package/dist/core/mcp-session-end.d.ts +26 -0
- package/dist/core/mcp-session-end.js +29 -0
- package/dist/core/mcp-startup-request.d.ts +17 -0
- package/dist/core/mcp-startup-request.js +17 -0
- package/dist/core/mcp.d.ts +13 -13
- package/dist/core/mcp.js +187 -162
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-engine/engine.d.ts +9 -9
- package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
- package/dist/core/memory-engine/tools.js +4 -1
- package/dist/core/mode-policy.d.ts +1 -1
- package/dist/core/namespaced-rule-name.d.ts +33 -7
- package/dist/core/namespaced-rule-name.js +39 -25
- package/dist/core/output-style.d.ts +1 -1
- package/dist/core/param-rule-reach.d.ts +15 -0
- package/dist/core/param-rule-reach.js +30 -0
- package/dist/core/parent-spec-seat.d.ts +8 -1
- package/dist/core/parent-spec-seat.js +4 -0
- package/dist/core/pause-registry.d.ts +16 -5
- package/dist/core/pause-registry.js +6 -2
- package/dist/core/peer-channel.d.ts +70 -0
- package/dist/core/peer-channel.js +1 -0
- package/dist/core/permission-rule-consent.d.ts +11 -5
- package/dist/core/permission-rule-consent.js +37 -30
- package/dist/core/permission-rule-model.d.ts +233 -64
- package/dist/core/permission-rule-model.js +384 -85
- package/dist/core/permission-rule-provider.d.ts +2 -1
- package/dist/core/permission-rule-store.d.ts +20 -25
- package/dist/core/permission-rule-store.js +1 -4
- package/dist/core/permission-rule-sync.d.ts +11 -2
- package/dist/core/permission-rule-sync.js +8 -1
- package/dist/core/permission-rules.d.ts +49 -11
- package/dist/core/permission-rules.js +123 -89
- package/dist/core/persisted-rule-arms.d.ts +4 -2
- package/dist/core/present-plan-tool.js +3 -1
- package/dist/core/protocol-naming.d.ts +2 -2
- package/dist/core/read-only-shell-table.d.ts +1 -1
- package/dist/core/read-only-shell.d.ts +1 -1
- package/dist/core/roles.d.ts +6 -2
- package/dist/core/roles.js +45 -44
- package/dist/core/rule-offer-read.d.ts +53 -0
- package/dist/core/rule-offer-read.js +146 -0
- package/dist/core/rule-owner.d.ts +46 -0
- package/dist/core/rule-owner.js +28 -0
- package/dist/core/runner/advisor-instructions.d.ts +70 -0
- package/dist/core/runner/advisor-instructions.js +61 -0
- package/dist/core/runner/advisor-tool.d.ts +33 -0
- package/dist/core/runner/advisor-tool.js +112 -0
- package/dist/core/runner/announce-once-ledger.d.ts +4 -26
- package/dist/core/runner/announce-once-ledger.js +14 -46
- package/dist/core/runner/approval-feedback.js +6 -3
- package/dist/core/runner/assemble-result.d.ts +1 -1
- package/dist/core/runner/caller-roster.d.ts +7 -0
- package/dist/core/runner/caller-roster.js +11 -0
- package/dist/core/runner/classifier-ladder.d.ts +27 -5
- package/dist/core/runner/classifier-ladder.js +12 -11
- package/dist/core/runner/compaction-restate.d.ts +10 -6
- package/dist/core/runner/compaction-restate.js +9 -3
- package/dist/core/runner/contracts.d.ts +13 -9
- package/dist/core/runner/conversation-segment.d.ts +28 -0
- package/dist/core/runner/conversation-segment.js +42 -0
- package/dist/core/runner/cross-boundary-lane.d.ts +6 -5
- package/dist/core/runner/cross-boundary-lane.js +26 -15
- package/dist/core/runner/decide-continuation.d.ts +7 -4
- package/dist/core/runner/decide-continuation.js +2 -2
- package/dist/core/runner/denial-limit-arms.d.ts +2 -2
- package/dist/core/runner/derived-route-fallback.d.ts +24 -24
- package/dist/core/runner/derived-route-fallback.js +9 -7
- package/dist/core/runner/gate-exit.d.ts +6 -0
- package/dist/core/runner/gate-exit.js +7 -2
- package/dist/core/runner/initial-run-state.js +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +2 -2
- package/dist/core/runner/permission-rule-lanes.js +14 -7
- package/dist/core/runner/person-path-rows.js +1 -1
- package/dist/core/runner/prepare-advisor.d.ts +63 -0
- package/dist/core/runner/prepare-advisor.js +77 -0
- package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
- package/dist/core/runner/prepare-config-doors.d.ts +6 -4
- package/dist/core/runner/prepare-config-doors.js +18 -12
- package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.js +1 -1
- package/dist/core/runner/prepare-file-history.js +39 -39
- package/dist/core/runner/prepare-gate-stations.d.ts +1 -4
- package/dist/core/runner/prepare-gate-stations.js +2 -7
- package/dist/core/runner/prepare-inherited-gate.d.ts +5 -4
- package/dist/core/runner/prepare-inherited-gate.js +3 -3
- package/dist/core/runner/prepare-park-ask.js +7 -7
- package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
- package/dist/core/runner/prepare-policy-chain.js +4 -10
- package/dist/core/runner/prepare-project-context.d.ts +5 -2
- package/dist/core/runner/prepare-project-context.js +6 -3
- package/dist/core/runner/prepare-prompt-inputs.js +1 -1
- package/dist/core/runner/prepare-protocol-tools.d.ts +2 -2
- package/dist/core/runner/prepare-protocol-tools.js +3 -2
- package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
- package/dist/core/runner/prepare-safety-scan.js +8 -6
- package/dist/core/runner/prepare-task.js +15 -18
- package/dist/core/runner/prepare-tool-disclosure-mount.js +6 -4
- package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -3
- package/dist/core/runner/prepare-wiring-manifest.js +2 -2
- package/dist/core/runner/resume-policy-outcome.js +1 -1
- package/dist/core/runner/retired-runner-deps.js +1 -1
- package/dist/core/runner/run-attachment-seats.js +0 -1
- package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
- package/dist/core/runner/run-compaction-machinery.js +2 -12
- package/dist/core/runner/run-git-lane.d.ts +1 -0
- package/dist/core/runner/run-harness-handlers.js +2 -3
- package/dist/core/runner/run-leg.js +13 -0
- package/dist/core/runner/run-settle-and-teardown.js +1 -1
- package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
- package/dist/core/runner/run-turn-boundary.d.ts +1 -0
- package/dist/core/runner/run-turn-boundary.js +14 -12
- package/dist/core/runner/session-rule-policy.d.ts +22 -21
- package/dist/core/runner/session-rule-policy.js +13 -28
- package/dist/core/runner/side-call-account.d.ts +32 -8
- package/dist/core/runner/side-call-account.js +23 -1
- package/dist/core/runner/strict-output-schema.d.ts +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -3
- package/dist/core/runner/synthetic-tools.d.ts +10 -13
- package/dist/core/runner/synthetic-tools.js +4 -2
- package/dist/core/runner/tool-disclosure.js +2 -1
- package/dist/core/runner/tool-face-overlay.d.ts +2 -1
- package/dist/core/runner/tool-face-overlay.js +17 -1
- package/dist/core/runner/tool-progress-lane.d.ts +2 -2
- package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
- package/dist/core/runner/turn-attachments.d.ts +60 -67
- package/dist/core/runner-deps.d.ts +37 -37
- package/dist/core/runtime-caps.d.ts +4 -4
- package/dist/core/safety-merge-corpus.js +17 -1
- package/dist/core/same-plain-value.d.ts +40 -0
- package/dist/core/same-plain-value.js +49 -0
- package/dist/core/scheduler.d.ts +1 -1
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +1 -1
- package/dist/core/session-policy-store.d.ts +77 -22
- package/dist/core/session-policy-store.js +56 -14
- package/dist/core/session-reconcile.d.ts +2 -2
- package/dist/core/session-store.d.ts +80 -30
- package/dist/core/session-store.js +118 -76
- package/dist/core/session.d.ts +24 -46
- package/dist/core/shared-memory/tools.js +3 -1
- package/dist/core/shared-memory/types.d.ts +1 -1
- package/dist/core/side-query.d.ts +10 -0
- package/dist/core/side-query.js +5 -0
- package/dist/core/store-contracts/checkpoint-store-contract.js +29 -2
- package/dist/core/store-contracts/file-history-store-contract.js +43 -3
- package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
- package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
- package/dist/core/store-contracts/session-repo-contract.js +125 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +4 -7
- package/dist/core/store-contracts/session-store-contract.js +215 -41
- package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
- package/dist/core/surrogate-safe-slice.d.ts +3 -3
- package/dist/core/task-event.d.ts +10 -4
- package/dist/core/task-notification.d.ts +3 -3
- package/dist/core/task-registry-agent.d.ts +4 -4
- package/dist/core/task-registry-shared.d.ts +4 -4
- package/dist/core/task-registry-shared.js +1 -0
- package/dist/core/task-registry.d.ts +4 -4
- package/dist/core/task-registry.js +3 -1
- package/dist/core/task-result.d.ts +3 -3
- package/dist/core/task-spec.d.ts +52 -52
- package/dist/core/task-stream.d.ts +6 -6
- package/dist/core/task-tool-shape.d.ts +4 -4
- package/dist/core/tighten-task-spec.d.ts +1 -1
- package/dist/core/tool-catalog-entries.d.ts +19 -2
- package/dist/core/tool-catalog-entries.js +57 -42
- package/dist/core/tool-conformance.js +1 -0
- package/dist/core/tool-errors.d.ts +2 -2
- package/dist/core/tool-face-reader.js +5 -3
- package/dist/core/tool-face.d.ts +21 -2
- package/dist/core/tool-face.js +1 -1
- package/dist/core/tool-model-gate.d.ts +3 -3
- package/dist/core/tool-name-aliases.d.ts +29 -8
- package/dist/core/tool-name-aliases.js +27 -3
- package/dist/core/tool-name-readings.d.ts +5 -8
- package/dist/core/tool-name-readings.js +1 -2
- package/dist/core/tool-policy.d.ts +24 -5
- package/dist/core/tool-policy.js +34 -10
- package/dist/core/tool-registry.d.ts +14 -7
- package/dist/core/tool-registry.js +17 -7
- package/dist/core/tool-result-store.js +2 -1
- package/dist/core/tool-roster.d.ts +47 -18
- package/dist/core/tool-roster.js +53 -32
- package/dist/core/tool-spec-members.js +1 -1
- package/dist/core/tool-spec.d.ts +35 -21
- package/dist/core/tools.js +3 -2
- package/dist/core/trace.d.ts +4 -0
- package/dist/core/untrusted-egress.d.ts +1 -1
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/warm-resume.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +49 -0
- package/dist/core/wiring-manifest.js +13 -5
- package/dist/core/workflow-journal-store.d.ts +62 -0
- package/dist/core/workflow-journal-store.js +77 -1
- package/dist/core/workflow-run-store.d.ts +6 -0
- package/dist/core/workflow-run-store.js +2 -0
- package/dist/engine/compaction/compaction.d.ts +9 -9
- package/dist/engine/execution-env/node-execution-env.d.ts +19 -5
- package/dist/engine/execution-env/node-execution-env.js +43 -22
- package/dist/engine/harness/agent-harness.d.ts +14 -8
- package/dist/engine/harness/agent-harness.js +33 -26
- package/dist/engine/harness/types.d.ts +29 -7
- package/dist/engine/harness/types.js +12 -1
- package/dist/engine/llm/types.d.ts +9 -9
- package/dist/engine/llm/validation.d.ts +4 -1
- package/dist/engine/llm/validation.js +13 -1
- package/dist/engine/loop/agent-loop.d.ts +1 -1
- package/dist/engine/loop/agent-loop.js +10 -8
- package/dist/engine/loop/types.d.ts +15 -13
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/memory-repo.d.ts +10 -11
- package/dist/engine/session/memory-repo.js +13 -8
- package/dist/engine/session/parent-chain-guard.d.ts +3 -2
- package/dist/engine/session/parent-chain-guard.js +1 -1
- package/dist/engine/session/repo-utils.d.ts +31 -3
- package/dist/engine/session/repo-utils.js +42 -5
- package/dist/index.d.ts +27 -15
- package/dist/index.js +21 -11
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/harness.d.ts +3 -3
- package/dist/internal/harness.js +2 -2
- package/dist/internal/llm.d.ts +1 -1
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +2 -2
- package/dist/orchestration/run-workflow-tool.js +5 -3
- package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
- package/dist/orchestration/workflow-types.d.ts +18 -0
- package/dist/orchestration/workflow-types.js +6 -0
- package/dist/orchestration/workflow.d.ts +2 -13
- package/dist/orchestration/workflow.js +21 -31
- package/dist/prompt-assembly/event-registry.js +1 -0
- package/dist/prompt-assembly/tool-catalog.d.ts +3 -0
- package/dist/prompt-assembly/tool-catalog.js +3 -0
- package/dist/prompts/default.d.ts +14 -14
- package/dist/scenarios/full-body.d.ts +4 -4
- package/dist/stores/file/adoption/adopt.d.ts +4 -3
- package/dist/stores/file/adoption/adopt.js +24 -31
- package/dist/stores/file/adoption/marker.d.ts +6 -13
- package/dist/stores/file/adoption/marker.js +6 -15
- package/dist/stores/file/checkpoint-store.d.ts +3 -0
- package/dist/stores/file/checkpoint-store.js +9 -3
- package/dist/stores/file/file-history-store.d.ts +20 -19
- package/dist/stores/file/file-history-store.js +152 -135
- package/dist/stores/file/fs-atomic.d.ts +15 -0
- package/dist/stores/file/fs-atomic.js +89 -14
- package/dist/stores/file/index.d.ts +1 -1
- package/dist/stores/file/mailbox-store.d.ts +3 -0
- package/dist/stores/file/mailbox-store.js +3 -1
- package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
- package/dist/stores/file/permission-rule-adopt.js +15 -16
- package/dist/stores/file/permission-rule-store.d.ts +18 -2
- package/dist/stores/file/permission-rule-store.js +21 -14
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/dist/stores/file/session-store.d.ts +26 -11
- package/dist/stores/file/session-store.js +77 -40
- package/dist/stores/file/workflow-journal-store.d.ts +10 -4
- package/dist/stores/file/workflow-journal-store.js +28 -13
- package/dist/tools/artifact/artifact-text.d.ts +1 -1
- package/dist/tools/artifact/artifact-tool.js +2 -1
- package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
- package/dist/tools/fs/fs-bash.d.ts +2 -2
- package/dist/tools/fs/fs-bash.js +3 -1
- package/dist/tools/fs/fs-shared.d.ts +8 -8
- package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
- package/dist/tools/fs/notebook.d.ts +2 -2
- package/dist/tools/fs/read-deny.d.ts +29 -7
- package/dist/tools/fs/read-deny.js +63 -22
- package/dist/tools/fs/removal-targets.d.ts +1 -1
- package/dist/tools/fs/safety.d.ts +9 -9
- package/dist/tools/fs/search.d.ts +6 -6
- package/dist/tools/fs/shell-read-check.js +6 -1
- package/dist/tools/fs/shell-read-judge.d.ts +4 -0
- package/dist/tools/fs/shell-read-judge.js +5 -2
- package/dist/tools/loop-tick.d.ts +2 -2
- package/dist/tools/scheduler-tools.js +5 -1
- package/dist/tools/task-list.d.ts +7 -7
- package/dist/tools/task-list.js +5 -1
- package/dist/tools/todo.js +2 -1
- package/dist/tools/web.d.ts +1 -1
- package/dist/tools/web.js +40 -37
- package/dist/tools/worktree.d.ts +3 -3
- package/dist/tools/worktree.js +3 -1
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +5756 -5638
- package/wire-changes/core@7.55.0.json +3318 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
- package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
import { stripErrorCodePrefix, thrownBrainFailure } from "../../brain/errors.js";
|
|
3
|
+
import { ADVISOR_TOOL_NAME, advisorFailureHolds, advisorHoldOf } from "../advisor-verdict.js";
|
|
4
|
+
import { runSideQuery } from "../side-query.js";
|
|
5
|
+
import { thrownText } from "../thrown-value.js";
|
|
6
|
+
import { defineTool } from "../tools.js";
|
|
7
|
+
import { mountRuleFace, toolFace } from "../tool-catalog-entries.js";
|
|
8
|
+
import { egressText } from "../untrusted-egress.js";
|
|
9
|
+
const ADVISOR_MESSAGE_MAX_CHARS = 2_000;
|
|
10
|
+
export const ADVISOR_SYSTEM_PROMPT = `You are the advisor: a stronger reviewer model consulted by an agent in the middle of its task. Above is the agent's conversation as it stood in the agent's last request — its task, every tool call it made and every result it saw — ending at the point where it asked for advice.
|
|
11
|
+
|
|
12
|
+
Reply in plain text only. Do not call tools: any tool call you make is discarded and counts as no answer. Be concrete and short: name the decision the agent is facing, say what you would do and why, point at the specific evidence in the conversation that supports it, and flag anything the agent has assumed without checking. If the agent asked before declaring the task done, review the deliverable against the task as stated and list what is missing or wrong. If something you need is not in the conversation, say what is missing and what the agent should check first — that is still guidance.`;
|
|
13
|
+
export const ADVISOR_HANDOFF = "You are the advisor now. Review everything above and reply with your guidance.";
|
|
14
|
+
const AGENT_INSTRUCTIONS_HEADER = "# The agent's instructions (context for you; they bind the agent, not you)";
|
|
15
|
+
const HOLD_SENTENCE = "The advisor is off for this conversation until it is compacted; do not call it again before then.";
|
|
16
|
+
function unavailable(model, failure, message, hold, extra = {}) {
|
|
17
|
+
const cause = failure.errorKind ?? failure.code ?? failure.stopReason;
|
|
18
|
+
const bounded = message !== undefined && message.trim() !== "" ? egressText("same-principal", message).slice(0, ADVISOR_MESSAGE_MAX_CHARS) : undefined;
|
|
19
|
+
const text = [`Advisor unavailable${cause !== undefined ? ` (${cause})` : ""}.`, ...(bounded !== undefined ? [bounded] : []), ...(hold ? [HOLD_SENTENCE] : [])].join(" ");
|
|
20
|
+
const card = {
|
|
21
|
+
type: "advisor",
|
|
22
|
+
outcome: "unavailable",
|
|
23
|
+
model: model.id,
|
|
24
|
+
...extra,
|
|
25
|
+
...(failure.stopReason !== undefined ? { stopReason: failure.stopReason } : {}),
|
|
26
|
+
...(failure.code !== undefined ? { code: failure.code } : {}),
|
|
27
|
+
...(failure.errorKind !== undefined ? { errorKind: failure.errorKind } : {}),
|
|
28
|
+
...(hold ? { hold: true } : {}),
|
|
29
|
+
};
|
|
30
|
+
return { text, card };
|
|
31
|
+
}
|
|
32
|
+
function askingTurn(branch, toolCallId) {
|
|
33
|
+
for (let i = branch.length - 1; i >= 0; i--) {
|
|
34
|
+
const e = branch[i];
|
|
35
|
+
if (e.type !== "message" || e.message.role !== "assistant")
|
|
36
|
+
continue;
|
|
37
|
+
const m = e.message;
|
|
38
|
+
if (!m.content.some((c) => c.type === "toolCall" && c.id === toolCallId))
|
|
39
|
+
continue;
|
|
40
|
+
return { ...m, content: m.content.filter((c) => c.type !== "toolCall" || c.id === toolCallId) };
|
|
41
|
+
}
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
function projection(sent, turn, toolCallId) {
|
|
45
|
+
const close = { role: "toolResult", toolCallId, toolName: ADVISOR_TOOL_NAME, content: [{ type: "text", text: ADVISOR_HANDOFF }], isError: false };
|
|
46
|
+
return [...sent.messages, turn, close];
|
|
47
|
+
}
|
|
48
|
+
function systemPromptOf(sent) {
|
|
49
|
+
const sentSystemText = sent.systemPrompt ?? sent.systemBlocks?.map((b) => b.text).join("") ?? "";
|
|
50
|
+
return sentSystemText === "" ? ADVISOR_SYSTEM_PROMPT : `${ADVISOR_SYSTEM_PROMPT}\n\n${AGENT_INSTRUCTIONS_HEADER}\n${sentSystemText}`;
|
|
51
|
+
}
|
|
52
|
+
function outcomeOf(model, r) {
|
|
53
|
+
const served = r.servedModel !== model.id ? { servedModel: r.servedModel } : {};
|
|
54
|
+
const base = { type: "advisor", model: model.id, ...served, stopReason: r.stopReason, usage: r.usage };
|
|
55
|
+
if ((r.stopReason === "stop" || r.stopReason === "length") && r.text.trim() !== "")
|
|
56
|
+
return { text: r.text, card: { ...base, outcome: "reviewed" } };
|
|
57
|
+
if (r.stopReason === "error" && r.errorCode === "refusal") {
|
|
58
|
+
const reason = r.errorMessage !== undefined ? stripErrorCodePrefix(r.errorMessage).trim() : "";
|
|
59
|
+
const bounded = reason !== "" ? egressText("same-principal", reason).slice(0, ADVISOR_MESSAGE_MAX_CHARS) : "";
|
|
60
|
+
return { text: `Advisor declined to advise on this request.${bounded !== "" ? ` Reason: ${bounded}` : ""}`, card: { ...base, outcome: "declined" } };
|
|
61
|
+
}
|
|
62
|
+
const failure = { ...(r.errorCode !== undefined ? { code: r.errorCode } : {}), ...(r.errorKind !== undefined ? { errorKind: r.errorKind } : {}), ...(r.inputTooLongRuledOut === true ? { inputTooLongRuledOut: true } : {}) };
|
|
63
|
+
const message = r.stopReason === "toolUse" ? "the advisor model answered with a tool call instead of guidance" : r.stopReason === "error" || r.stopReason === "aborted" ? (r.errorMessage !== undefined ? stripErrorCodePrefix(r.errorMessage) : undefined) : "the advisor model returned no guidance";
|
|
64
|
+
return unavailable(model, { ...failure, stopReason: r.stopReason }, message, advisorFailureHolds(failure), { ...served, usage: r.usage });
|
|
65
|
+
}
|
|
66
|
+
async function consult(seat, toolCallId, signal) {
|
|
67
|
+
const model = seat.model;
|
|
68
|
+
let branch;
|
|
69
|
+
try {
|
|
70
|
+
branch = await seat.readBranch();
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return unavailable(model, {}, "the advisor's availability for this conversation could not be read; try again later", false);
|
|
74
|
+
}
|
|
75
|
+
const held = advisorHoldOf(branch);
|
|
76
|
+
if (held !== undefined)
|
|
77
|
+
return unavailable(model, held, undefined, true);
|
|
78
|
+
const sent = seat.lastSentRequest();
|
|
79
|
+
if (sent === undefined)
|
|
80
|
+
return unavailable(model, {}, "no request has been sent to the model on this resumed run yet; call advisor again", false);
|
|
81
|
+
const turn = askingTurn(branch, toolCallId) ?? { role: "assistant", content: [{ type: "toolCall", id: toolCallId, name: ADVISOR_TOOL_NAME, arguments: {} }] };
|
|
82
|
+
try {
|
|
83
|
+
const r = await runSideQuery({
|
|
84
|
+
model,
|
|
85
|
+
systemPrompt: systemPromptOf(sent),
|
|
86
|
+
messages: projection(sent, turn, toolCallId),
|
|
87
|
+
...(sent.tools !== undefined && sent.tools.length > 0 ? { tools: sent.tools.map((t) => ({ name: t.name, description: t.description, parameters: t.parameters })) } : {}),
|
|
88
|
+
...(signal !== undefined ? { signal } : {}),
|
|
89
|
+
...(seat.getApiKeyAndHeaders !== undefined ? { getApiKeyAndHeaders: seat.getApiKeyAndHeaders } : {}),
|
|
90
|
+
}, { brain: seat.brain });
|
|
91
|
+
return outcomeOf(model, r);
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
seat.markUsageUnknown();
|
|
95
|
+
const failure = thrownBrainFailure(e);
|
|
96
|
+
return unavailable(model, { ...failure, stopReason: "error" }, stripErrorCodePrefix(thrownText(e)), advisorFailureHolds(failure));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export function createAdvisorTool(seat) {
|
|
100
|
+
return defineTool({
|
|
101
|
+
name: ADVISOR_TOOL_NAME,
|
|
102
|
+
...toolFace("advisor"),
|
|
103
|
+
ruleFace: mountRuleFace("advisor"),
|
|
104
|
+
label: seat.model.id,
|
|
105
|
+
description: "Consult the advisor: a stronger reviewer model reads this conversation and returns guidance. Takes no parameters.",
|
|
106
|
+
parameters: Type.Object({}),
|
|
107
|
+
execute: async (_args, ctx) => {
|
|
108
|
+
const { text, card } = await consult(seat, ctx.toolCallId, ctx.signal);
|
|
109
|
+
return { content: text, details: card, isError: card.outcome === "unavailable" };
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { AnnouncedListingSnapshot, AnnouncedListingSnapshotInput, AnnouncedMcpFailure } from "../../internal/harness.js";
|
|
2
|
-
import type {
|
|
3
|
-
import type { AnnounceOnceSink, DateAnchorRead } from "./contracts.js";
|
|
2
|
+
import type { AnnounceOnceSink } from "./contracts.js";
|
|
4
3
|
import type { McpDroppedTool, McpServerStatus } from "../mcp.js";
|
|
5
4
|
import type { RunnerDeps } from "../types.js";
|
|
6
5
|
/** Upper bound on the advisory-digest arm kept in the record (oldest dropped past it). A digest is
|
|
@@ -85,6 +84,9 @@ export interface AnnounceOnceLedger {
|
|
|
85
84
|
* the record is dropped; a new one is forwarded to `deps.onError` and recorded. With no sink wired
|
|
86
85
|
* nothing is recorded either — "announced" means delivered. Same signature as `RunnerDeps.onError`. */
|
|
87
86
|
onError: NonNullable<RunnerDeps["onError"]>;
|
|
87
|
+
/** The record's one dedupe verb, for any announcement of a session fact: `deliver` runs unless `digest` is already in the
|
|
88
|
+
* record, and the digest is recorded once it ran ({@link onError} is this verb over the operator sink). */
|
|
89
|
+
oncePerSession(digest: string, deliver: () => void): void;
|
|
88
90
|
/** The operator-lane sink for a DEPLOYMENT fact (see {@link AnnounceOnceSink.onErrorOncePerRunner}): the same
|
|
89
91
|
* `(code, message)` digest, judged against what THIS RUNNER's sink has already been told rather than against
|
|
90
92
|
* the session's record. Writes no digest into the record and owes the transcript nothing. */
|
|
@@ -127,28 +129,4 @@ export declare function loadAnnounceOnceLedger(session: AnnounceOnceSession, che
|
|
|
127
129
|
* present-only arms, copied; `undefined` when nothing was announced on any face (the resume seed
|
|
128
130
|
* then falls to the lower rungs — unchanged contract). */
|
|
129
131
|
export declare function serializeAnnouncedListings(ref: AnnouncedListingSnapshotInput): AnnouncedListingSnapshot | undefined;
|
|
130
|
-
/** The custom-entry kind that carries the session's date anchor (engine-owned; never model-visible). */
|
|
131
|
-
export declare const DATE_ANCHOR_CUSTOM_TYPE = "engine:date-anchor";
|
|
132
|
-
/**
|
|
133
|
-
* Read the session's date anchor off the active branch: the nearest anchor entry NEWER than the nearest
|
|
134
|
-
* compaction, honored only when it was written for that same segment. An anchor written by a leg whose
|
|
135
|
-
* prefix predates a compaction that landed in between therefore reads as absent — the one rule that makes a
|
|
136
|
-
* compaction re-anchor the date. An unreadable branch returns undefined (the leg renders today, writes nothing).
|
|
137
|
-
*/
|
|
138
|
-
export declare function readDateAnchor(session: {
|
|
139
|
-
getBranch(): Promise<ReadonlyArray<SessionTreeEntry>>;
|
|
140
|
-
}): Promise<DateAnchorRead | undefined>;
|
|
141
|
-
/**
|
|
142
|
-
* The anchor write a leg owes when it settles, or undefined: owed when prepare found no anchor for the segment
|
|
143
|
-
* (the leg rendered today) or the model has since been told a newer date; never after an unreadable branch.
|
|
144
|
-
* Best-effort — a lost write costs one re-rendered prefix or one repeated reminder next leg, never a wrong date.
|
|
145
|
-
*/
|
|
146
|
-
export declare function owedDateAnchor(session: {
|
|
147
|
-
appendCustomEntry(customType: string, data?: unknown): Promise<string>;
|
|
148
|
-
}, seat: {
|
|
149
|
-
legDate: string;
|
|
150
|
-
anchor: DateAnchorRead | undefined;
|
|
151
|
-
} | undefined, state: {
|
|
152
|
-
announcedDate: string;
|
|
153
|
-
} | undefined): (() => Promise<void>) | undefined;
|
|
154
132
|
export {};
|
|
@@ -53,24 +53,26 @@ export async function loadAnnounceOnceLedger(session, checkpointMirror, onError)
|
|
|
53
53
|
recovered = false;
|
|
54
54
|
return undefined;
|
|
55
55
|
});
|
|
56
|
-
const seed = checkpointMirror?.mcpFailed !== undefined || checkpointMirror?.advisories !== undefined ? checkpointMirror : entry;
|
|
56
|
+
const seed = checkpointMirror?.mcpFailed !== undefined || checkpointMirror?.advisories !== undefined || checkpointMirror?.advisor !== undefined ? checkpointMirror : entry;
|
|
57
57
|
const listingSrc = checkpointMirror?.agents !== undefined || checkpointMirror?.skills !== undefined || checkpointMirror?.models !== undefined ? checkpointMirror : entry;
|
|
58
58
|
let mcpFailed = (seed?.mcpFailed ?? []).map((f) => ({ ...f }));
|
|
59
59
|
const advisories = new Set(seed?.advisories ?? []);
|
|
60
60
|
let dirty = false;
|
|
61
|
+
const oncePerSession = (digest, deliver) => {
|
|
62
|
+
if (advisories.has(digest))
|
|
63
|
+
return;
|
|
64
|
+
deliver();
|
|
65
|
+
advisories.add(digest);
|
|
66
|
+
dirty = true;
|
|
67
|
+
};
|
|
61
68
|
return {
|
|
62
69
|
entry,
|
|
63
70
|
recovered,
|
|
64
71
|
onError: (err, ctx) => {
|
|
65
|
-
if (onError
|
|
66
|
-
|
|
67
|
-
const digest = warningDigest(err);
|
|
68
|
-
if (advisories.has(digest))
|
|
69
|
-
return;
|
|
70
|
-
onError(err, ctx);
|
|
71
|
-
advisories.add(digest);
|
|
72
|
-
dirty = true;
|
|
72
|
+
if (onError !== undefined)
|
|
73
|
+
oncePerSession(warningDigest(err), () => onError(err, ctx));
|
|
73
74
|
},
|
|
75
|
+
oncePerSession,
|
|
74
76
|
onErrorOncePerRunner: (err, ctx) => {
|
|
75
77
|
if (onError === undefined)
|
|
76
78
|
return;
|
|
@@ -106,6 +108,7 @@ export async function loadAnnounceOnceLedger(session, checkpointMirror, onError)
|
|
|
106
108
|
...(listingSrc?.models !== undefined ? { models: [...listingSrc.models] } : {}),
|
|
107
109
|
...(mcpFailed.length > 0 ? { mcpFailed: mcpFailed.map((f) => ({ ...f })) } : {}),
|
|
108
110
|
...(advisories.size > 0 ? { advisories: withAnnounceDigests(undefined, [...advisories]) } : {}),
|
|
111
|
+
...(seed?.advisor !== undefined ? { advisor: { ...seed.advisor } } : {}),
|
|
109
112
|
}),
|
|
110
113
|
settle: async (s, ref) => {
|
|
111
114
|
if (advisories.size > 0)
|
|
@@ -119,6 +122,7 @@ export async function loadAnnounceOnceLedger(session, checkpointMirror, onError)
|
|
|
119
122
|
...(ref.models !== undefined ? { models: ref.models } : {}),
|
|
120
123
|
...(ref.mcpFailed !== undefined && ref.mcpFailed.length > 0 ? { mcpFailed: ref.mcpFailed } : {}),
|
|
121
124
|
...(ref.advisories !== undefined && ref.advisories.length > 0 ? { advisories: ref.advisories } : {}),
|
|
125
|
+
...(ref.advisor !== undefined ? { advisor: ref.advisor } : {}),
|
|
122
126
|
})
|
|
123
127
|
.catch(() => undefined);
|
|
124
128
|
},
|
|
@@ -131,43 +135,7 @@ export function serializeAnnouncedListings(ref) {
|
|
|
131
135
|
...(ref.models !== undefined ? { models: [...ref.models] } : {}),
|
|
132
136
|
...(ref.mcpFailed !== undefined ? { mcpFailed: ref.mcpFailed.map((f) => ({ ...f })) } : {}),
|
|
133
137
|
...(ref.advisories !== undefined ? { advisories: [...ref.advisories] } : {}),
|
|
138
|
+
...(ref.advisor !== undefined ? { advisor: { ...ref.advisor } } : {}),
|
|
134
139
|
};
|
|
135
140
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
136
141
|
}
|
|
137
|
-
export const DATE_ANCHOR_CUSTOM_TYPE = "engine:date-anchor";
|
|
138
|
-
const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
139
|
-
function normalizeDateAnchor(v) {
|
|
140
|
-
if (typeof v !== "object" || v === null)
|
|
141
|
-
return undefined;
|
|
142
|
-
const { prefixDate, announcedDate, segment } = v;
|
|
143
|
-
if (typeof prefixDate !== "string" || !ISO_DATE.test(prefixDate) || typeof announcedDate !== "string" || !ISO_DATE.test(announcedDate))
|
|
144
|
-
return undefined;
|
|
145
|
-
if (segment !== null && (typeof segment !== "string" || segment.length > 200))
|
|
146
|
-
return undefined;
|
|
147
|
-
return { prefixDate, announcedDate, segment };
|
|
148
|
-
}
|
|
149
|
-
export async function readDateAnchor(session) {
|
|
150
|
-
let branch;
|
|
151
|
-
try {
|
|
152
|
-
branch = await session.getBranch();
|
|
153
|
-
}
|
|
154
|
-
catch {
|
|
155
|
-
return undefined;
|
|
156
|
-
}
|
|
157
|
-
let found;
|
|
158
|
-
let i = branch.length - 1;
|
|
159
|
-
for (; i >= 0 && branch[i].type !== "compaction"; i--) {
|
|
160
|
-
const e = branch[i];
|
|
161
|
-
if (found === undefined && e.type === "custom" && e.customType === DATE_ANCHOR_CUSTOM_TYPE)
|
|
162
|
-
found = normalizeDateAnchor(e.data);
|
|
163
|
-
}
|
|
164
|
-
const segment = i >= 0 ? branch[i].id : null;
|
|
165
|
-
return { current: found !== undefined && found.segment === segment ? { prefixDate: found.prefixDate, announcedDate: found.announcedDate } : undefined, segment };
|
|
166
|
-
}
|
|
167
|
-
export function owedDateAnchor(session, seat, state) {
|
|
168
|
-
const read = seat?.anchor;
|
|
169
|
-
if (read === undefined || state === undefined || read.current?.announcedDate === state.announcedDate)
|
|
170
|
-
return undefined;
|
|
171
|
-
const data = { prefixDate: seat.legDate, announcedDate: state.announcedDate, segment: read.segment };
|
|
172
|
-
return () => session.appendCustomEntry(DATE_ANCHOR_CUSTOM_TYPE, data).then(() => undefined, () => undefined);
|
|
173
|
-
}
|
|
@@ -9,16 +9,19 @@ export function refuseUnfitFeedback(twin) {
|
|
|
9
9
|
if (words === undefined)
|
|
10
10
|
return;
|
|
11
11
|
if (twin.decision !== "allow") {
|
|
12
|
-
throw
|
|
12
|
+
throw feedbackRefusal("resume carried `feedback` on a `deny` — feedback is the approving person's words on an `allow` (a denial's words are `reason`); refusing rather than dropping it silently, the checkpoint stays pending");
|
|
13
13
|
}
|
|
14
14
|
const byPerson = twin.hostDecision.decidedBy === "person";
|
|
15
15
|
if (!byPerson) {
|
|
16
|
-
throw
|
|
16
|
+
throw feedbackRefusal(`resume carried \`feedback\` on a decide made by "${twin.hostDecision.decidedBy}" — feedback is delivered to the model as the user's own words, which only a person's decide can be; refusing rather than attributing a machine's text to the user, the checkpoint stays pending`);
|
|
17
17
|
}
|
|
18
18
|
if (sanitizeUntrustedText(words) !== words) {
|
|
19
|
-
throw
|
|
19
|
+
throw feedbackRefusal(sentinelTagRefusal("resume allow feedback"));
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
+
function feedbackRefusal(message) {
|
|
23
|
+
return new CheckpointError("checkpoint.invalid_outcome", message, { field: "feedback" });
|
|
24
|
+
}
|
|
22
25
|
export function approvalWordsOf(outcome) {
|
|
23
26
|
return outcome.gate === "policy_ask" && outcome.decision === "allow" ? writtenFeedback(outcome.feedback) : undefined;
|
|
24
27
|
}
|
|
@@ -67,7 +67,7 @@ export interface Stats {
|
|
|
67
67
|
* (so it can't be re-derived from `costMicroUsd` alone). The {@link costBreakdown.compactionMicroUsd}
|
|
68
68
|
* source. Run-loop internal — not a public `TaskResult.stats` field. */
|
|
69
69
|
compactionMicroUsd?: number;
|
|
70
|
-
/** The permission classifier's
|
|
70
|
+
/** The permission classifier's, a mod's and the advisor tool's model-call cost (micro-USD), accumulated by `recordSideCallUsage`. Folded
|
|
71
71
|
* into `costMicroUsd` like compaction, but it STAYS inside {@link costBreakdown.llmRootMicroUsd} (an "of which" line,
|
|
72
72
|
* not a partition member). Absent until a call is booked. Run-loop internal — the public figure is
|
|
73
73
|
* `costBreakdown.sideCallMicroUsd`. */
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
import type { AgentTool } from "../../internal/harness.js";
|
|
33
33
|
import type { TaskSpec } from "../types.js";
|
|
34
34
|
import type { ToolSpec } from "../tool-spec.js";
|
|
35
|
+
import type { ToolDeclarationCode } from "../governance-codes.js";
|
|
35
36
|
import { type ToolCtxEnricher } from "../tools.js";
|
|
36
37
|
declare const ROSTER_FACE: unique symbol;
|
|
37
38
|
/** A roster entry as the snapshot minted it. The brand is private to this module and {@link rosterFaceOf} is the only
|
|
@@ -56,6 +57,12 @@ export declare function callerEntryOrigin(entry: object): object;
|
|
|
56
57
|
/** Can the mount's ToolSpec arm build this roster entry? Only the verdict recorded at the snapshot answers: an object that
|
|
57
58
|
* is no face of this snapshot, a primitive, a product's face, is not built from. */
|
|
58
59
|
export declare function specArmCanBuild(entry: RosterFace): boolean;
|
|
60
|
+
/** A `TaskSpec.tools` spec declaring an engine contract (a `core.` id) its catalog did not mint for it — the id written by hand — refused where the
|
|
61
|
+
* declaration enters. An engine definition under any declared name carries the minted object; a host can forge the string, never the object. */
|
|
62
|
+
export declare function callerEngineContractProblem(face: RosterFace): {
|
|
63
|
+
code: ToolDeclarationCode;
|
|
64
|
+
message: string;
|
|
65
|
+
} | undefined;
|
|
59
66
|
/** One entry of the roster, and the ONLY place a {@link RosterFace} is minted. Every object entry (a function included) becomes a frozen face, so no entry the snapshot holds is a
|
|
60
67
|
* live object: a primitive is immutable and stays as read; a `defineTool` product's face names the product for its sealed
|
|
61
68
|
* rebind; an entry the ToolSpec arm cannot build gets a face too, and the mount refuses it from the verdict recorded here —
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { TOOL_SPEC_MEMBERS, frozenExtra, frozenMember, newCopyState } from "../tool-spec-members.js";
|
|
2
2
|
import { isDefineToolProduct, rebindDefineToolCtx } from "../tools.js";
|
|
3
|
+
import { isCatalogContract } from "../tool-catalog-entries.js";
|
|
4
|
+
import { contractOriginOf } from "../../prompt-assembly/tool-catalog.js";
|
|
3
5
|
function specArmCanConstruct(t) {
|
|
4
6
|
if (typeof t !== "object" || t === null)
|
|
5
7
|
return false;
|
|
@@ -43,6 +45,13 @@ function refuseUnreadableEntry(index, entry, cause) {
|
|
|
43
45
|
e.code = "config.tool_mount_denied";
|
|
44
46
|
throw e;
|
|
45
47
|
}
|
|
48
|
+
const CATALOG_CONTRACT_FACES = new WeakSet();
|
|
49
|
+
export function callerEngineContractProblem(face) {
|
|
50
|
+
const id = face.contract?.contractId;
|
|
51
|
+
if (typeof id !== "string" || contractOriginOf(id) !== "core" || CATALOG_CONTRACT_FACES.has(face))
|
|
52
|
+
return undefined;
|
|
53
|
+
return { code: "config.tool_face_invalid", message: `tool ${JSON.stringify(String(face.name).slice(0, 40))} declares the engine contract ${JSON.stringify(id.slice(0, 64))}, which no engine definition minted for it — a contract id under \`core.\` belongs to the engine's own definitions; declare an id of your own, or none` };
|
|
54
|
+
}
|
|
46
55
|
export function rosterFaceOf(t, index) {
|
|
47
56
|
if ((typeof t !== "object" && typeof t !== "function") || t === null)
|
|
48
57
|
return t;
|
|
@@ -58,6 +67,8 @@ export function rosterFaceOf(t, index) {
|
|
|
58
67
|
if (value === undefined && !own)
|
|
59
68
|
continue;
|
|
60
69
|
let kept;
|
|
70
|
+
if (key === "contract" && isCatalogContract(value))
|
|
71
|
+
CATALOG_CONTRACT_FACES.add(face);
|
|
61
72
|
if (typeof key === "string" && IS_MEMBER.has(key))
|
|
62
73
|
kept = frozenMember(key, value, ledger);
|
|
63
74
|
else {
|
|
@@ -99,6 +99,28 @@ export declare function classifierSeatModel(args: {
|
|
|
99
99
|
deps: Pick<RunnerDeps, "models" | "roles" | "tiers">;
|
|
100
100
|
main: Model;
|
|
101
101
|
}): ClassifierSeat;
|
|
102
|
+
/**
|
|
103
|
+
* The catalog the seat is read off. The Runner expands tier bindings into the catalog at construction and
|
|
104
|
+
* keeps that expansion PRIVATE, so the engine reaches this seat with tier words already catalog keys — a host
|
|
105
|
+
* holding its own deps does not, and the tier-relative leg (which addresses the catalog BY tier word) would
|
|
106
|
+
* find nothing and answer `main_only`. Expanding here is idempotent: an existing catalog key SHADOWS the tier
|
|
107
|
+
* binding, so a second expansion over an expanded catalog changes no key.
|
|
108
|
+
*
|
|
109
|
+
* A binding naming a model the catalog no longer carries throws in the expansion — that is the BOOT error a
|
|
110
|
+
* deployment gets from the Runner's constructor, and a seat READ must not re-raise it: this function's whole
|
|
111
|
+
* posture is that a stale reference never fails the caller ({@link classifierSeatModel}'s two `catch` arms). Such a deployment
|
|
112
|
+
* cannot construct a Runner at all, so there is no engine answer to disagree with; the raw catalog is handed
|
|
113
|
+
* on and the ordinary fallbacks name the seat.
|
|
114
|
+
*/
|
|
115
|
+
export declare function normalizeSeatDeps<T extends Pick<RunnerDeps, "models" | "tiers">>(deps: T): T;
|
|
116
|
+
/**
|
|
117
|
+
* The tier a model SITS on, as an index into `DEFAULT_TIER_ORDER` (0 = strongest): the LOWEST known tier whose
|
|
118
|
+
* expanded catalog key resolves to the same route as `model`. Read off a catalog {@link normalizeSeatDeps} expanded.
|
|
119
|
+
* The lowest, because a key synthesised for an unbound tier falls DOWN to the next bound one, so a model's lowest
|
|
120
|
+
* tier is the tier it was bound to. `undefined` when the deployment declares no tiers, or the model is on none.
|
|
121
|
+
* The one tier reading: the classifier seat and the advisor pairing both read it.
|
|
122
|
+
*/
|
|
123
|
+
export declare function tierIndexOf(deps: Pick<RunnerDeps, "models" | "tiers">, model: Model): number | undefined;
|
|
102
124
|
/**
|
|
103
125
|
* The `classifier.role_defaulted` line — minted ONCE per run by the arming, AFTER the route pre-flight, so it
|
|
104
126
|
* names the seat actually asked (a pre-flight swap to the main model is its own line,
|
|
@@ -160,7 +182,7 @@ export interface ClassifierUnavailableStation {
|
|
|
160
182
|
* The classifier's REASONING SEAT, read off the model a classification is actually asked on — ONE predicate:
|
|
161
183
|
* does the wire SPELL off ({@link thinkingOffSpelled})? Yes ⇒ `off` + the verdict-sized cap (the request pays
|
|
162
184
|
* for the answer alone); no ⇒ `low` + the verdict cap + the low allowance (a model whose thinking the wire
|
|
163
|
-
* cannot turn off is asked for the least it can grade, in the room that costs —
|
|
185
|
+
* cannot turn off is asked for the least it can grade, in the room that costs — spell off,
|
|
164
186
|
* or leave thinking to the provider and pay 2048). A model that declares no reasoning at all is on the `low`
|
|
165
187
|
* seat too: its wire carries nothing either way, so the request is the gateway's default, and a default-on
|
|
166
188
|
* gateway thinks — the arm that used to read it as "never thinks" is the one the field report was about.
|
|
@@ -194,9 +216,9 @@ export type ClassifierSeatRequest = typeof CLASSIFIER_OFF_SEAT | typeof CLASSIFI
|
|
|
194
216
|
*/
|
|
195
217
|
export declare function classifierRungSeat(model: Model): typeof CLASSIFIER_OFF_SEAT | typeof CLASSIFIER_LOW_SEAT;
|
|
196
218
|
/**
|
|
197
|
-
* The user-message TAIL of each attempt —
|
|
219
|
+
* The user-message TAIL of each attempt — the reference's classifier suffixes: the FIRST attempt
|
|
198
220
|
* carries the fast-mode suffix (`$ns`: the answer must begin with `<block>`, no preamble), the RE-ASK carries
|
|
199
|
-
* the thinking-stage suffix (`Uns`: think in `<thinking>` first, then answer). The base prompt
|
|
221
|
+
* the thinking-stage suffix (`Uns`: think in `<thinking>` first, then answer). The base prompt
|
|
200
222
|
* already says "no preamble" once; upstream repeats it at the END of the user message, and it is the repeat
|
|
201
223
|
* that lands — live 2026-09-15, a Qwen 3.8 with thinking off went from 70% tagged replies (1.2–3.9k chars of
|
|
202
224
|
* "Looking at this action…" prose) to 90% at 8 output tokens with the first suffix, and the re-ask suffix
|
|
@@ -209,7 +231,7 @@ export declare const CLASSIFIER_ATTEMPT_SUFFIX: {
|
|
|
209
231
|
/** The classifier reply's answer text — every text block joined; thinking blocks are not the verdict. */
|
|
210
232
|
export declare function classifierReplyText(reply: AssistantMessage): string;
|
|
211
233
|
/**
|
|
212
|
-
*
|
|
234
|
+
* An EMPTY reply that stopped at the output cap is "unparseable" — a reply to ask for again,
|
|
213
235
|
* not a refusal and not a verdict. The engine's brains report that cut two ways: `stopReason:"length"` (an
|
|
214
236
|
* engine-shrunk cap) or `stopReason:"error"` with `errorKind:"length_empty"` (a static cap — the classifier's
|
|
215
237
|
* own). An empty reply with any OTHER stop is CC's `policy_refusal` arm: not re-asked.
|
|
@@ -243,7 +265,7 @@ export declare function classifierReplyVerdictText(reply: AssistantMessage): str
|
|
|
243
265
|
* ({@link classifierReplyTagOnly}), or text in which the reader finds no answer at all (`parse_error` of form
|
|
244
266
|
* `missing`: prose, a thinking-only reply). Not a CONFLICT (two `<block>` answers — it carries a `yes`, and a second attempt that answered `no`
|
|
245
267
|
* would erase it: the fail-closed `parse_error` it is stands) and not an empty reply with a non-cap stop
|
|
246
|
-
* (CC's refusal arm).
|
|
268
|
+
* (CC's refusal arm). The reference re-asks an unparseable reply up to `maxRetries` times; sema re-asks
|
|
247
269
|
* ONCE, on the stage-2 room, so a rung costs at most two calls. A failed reply ({@link classifierReplyFailure})
|
|
248
270
|
* is judged before this and never reaches it.
|
|
249
271
|
*/
|
|
@@ -44,7 +44,7 @@ export function classifierSeatModel(args) {
|
|
|
44
44
|
return { model: main, defaulted: "main_only" };
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
function normalizeSeatDeps(deps) {
|
|
47
|
+
export function normalizeSeatDeps(deps) {
|
|
48
48
|
if (deps.tiers === undefined)
|
|
49
49
|
return deps;
|
|
50
50
|
try {
|
|
@@ -54,20 +54,21 @@ function normalizeSeatDeps(deps) {
|
|
|
54
54
|
return deps;
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
function
|
|
57
|
+
export function tierIndexOf(deps, model) {
|
|
58
58
|
if (deps.tiers === undefined || Object.keys(deps.tiers).length === 0 || deps.models === undefined)
|
|
59
59
|
return undefined;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (m !== undefined && sameRouteQuietly(m, main)) {
|
|
65
|
-
mainTier = i;
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
60
|
+
for (let i = DEFAULT_TIER_ORDER.length - 1; i >= 0; i--) {
|
|
61
|
+
const m = deps.models[DEFAULT_TIER_ORDER[i]];
|
|
62
|
+
if (m !== undefined && sameRouteQuietly(m, model))
|
|
63
|
+
return i;
|
|
68
64
|
}
|
|
69
|
-
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
function tierBelowMain(deps, main) {
|
|
68
|
+
const mainTier = tierIndexOf(deps, main);
|
|
69
|
+
if (mainTier === undefined)
|
|
70
70
|
return undefined;
|
|
71
|
+
const bound = DEFAULT_TIER_ORDER.map((tier) => deps.models?.[tier]);
|
|
71
72
|
for (let i = mainTier + 1; i < bound.length; i++) {
|
|
72
73
|
const m = bound[i];
|
|
73
74
|
if (m !== undefined && !sameRouteQuietly(m, main))
|
|
@@ -35,16 +35,20 @@ export declare function postureRestateOption(prepared: Prepared): Pick<MaybeComp
|
|
|
35
35
|
* of every engine frame written at a boundary, the git frame's re-assert and the compaction itself: the run continues
|
|
36
36
|
* and the failure is reported, `onError` phase `degraded`). Never throws.
|
|
37
37
|
*/
|
|
38
|
-
export declare function appendOwedPosture(prepared: Pick<Prepared, "approvalPosture" | "toolRoster" | "hookIdentity" | "session" | "reminderMark" | "postureFrameRef" | "batchHaltRef">, ask: "always" | "on_change"): Promise<void>;
|
|
38
|
+
export declare function appendOwedPosture(prepared: Pick<Prepared, "approvalPosture" | "toolRoster" | "hookIdentity" | "session" | "reminderMark" | "postureFrameRef" | "batchHaltRef" | "frameReceipts">, ask: "always" | "on_change"): Promise<void>;
|
|
39
39
|
/** The declared output style's frame as one engine-marked reminder — the one spelling every site that states it directly
|
|
40
40
|
* (a resumed leg's continuation, a boundary a queued input continues) mints. */
|
|
41
41
|
export declare function mintOutputStyleReminder(prepared: Pick<Prepared, "outputStyleFrame" | "reminderMark">): string | undefined;
|
|
42
|
+
/** Is a frame of this source already on its way to the next request (a pending receipt)? The one reading, for every
|
|
43
|
+
* collector that could state it again: the boundary bundle, the direct-write style lane and the posture writer. */
|
|
44
|
+
export declare function frameCarried(ledger: Prepared["frameReceipts"], source: Prepared["frameReceipts"]["pending"][number]["source"]): boolean;
|
|
42
45
|
/**
|
|
43
46
|
* The turn boundary's direct writes, for a boundary a request can follow: the owed posture, and the output style when
|
|
44
|
-
* the turn
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
+
* the turn's tool results do not go back as the next request (`turnOwesRequest` false) and queued input already
|
|
48
|
+
* guarantees the next one (`pendingInjectionCount`, both lanes: what can continue a run), unless that request already
|
|
49
|
+
* carries it ({@link frameCarried}). Both frames keep the posture's halt rule. The guarantee is read synchronously, at
|
|
50
|
+
* the call, before any await — a boundary with nothing queued returns the posture's own promise.
|
|
47
51
|
*/
|
|
48
|
-
export declare function appendBoundaryFrames(prepared: Pick<Prepared, "approvalPosture" | "toolRoster" | "hookIdentity" | "session" | "reminderMark" | "postureFrameRef" | "batchHaltRef" | "outputStyleFrame" | "harness">,
|
|
52
|
+
export declare function appendBoundaryFrames(prepared: Pick<Prepared, "approvalPosture" | "toolRoster" | "hookIdentity" | "session" | "reminderMark" | "postureFrameRef" | "batchHaltRef" | "outputStyleFrame" | "harness" | "frameReceipts">, turnOwesRequest: boolean): Promise<void>;
|
|
49
53
|
/** Every post-compaction restatement the turn boundary registers, at one spread site. */
|
|
50
|
-
export declare function compactionRestateOptions(prepared: Prepared): Pick<MaybeCompactOptions, "gitRestate" | "postureRestate">;
|
|
54
|
+
export declare function compactionRestateOptions(prepared: Prepared): Pick<MaybeCompactOptions, "gitRestate" | "postureRestate" | "advisorRestate">;
|
|
@@ -4,6 +4,7 @@ import { mintSystemReminder } from "../reminder-mint.js";
|
|
|
4
4
|
import { thrownText } from "../thrown-value.js";
|
|
5
5
|
import { rosterEntryNamed } from "../tool-roster.js";
|
|
6
6
|
import { sanitizeUntrustedText } from "../untrusted-text.js";
|
|
7
|
+
import { appendAdvisorRestate } from "./advisor-instructions.js";
|
|
7
8
|
import { gitRestateOption } from "./git-leg-delivery.js";
|
|
8
9
|
import { attachmentEnvelopeTags } from "./turn-attachments.js";
|
|
9
10
|
export function postureFactsOf(prepared) {
|
|
@@ -44,6 +45,8 @@ export function postureRestateOption(prepared) {
|
|
|
44
45
|
};
|
|
45
46
|
}
|
|
46
47
|
export async function appendOwedPosture(prepared, ask) {
|
|
48
|
+
if (frameCarried(prepared.frameReceipts, "posture"))
|
|
49
|
+
return;
|
|
47
50
|
const ref = prepared.postureFrameRef;
|
|
48
51
|
const text = await owedPostureText(prepared, ask);
|
|
49
52
|
if (text === undefined) {
|
|
@@ -88,11 +91,14 @@ async function appendOutputStyleRestate(prepared) {
|
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
93
|
}
|
|
91
|
-
export function
|
|
92
|
-
|
|
94
|
+
export function frameCarried(ledger, source) {
|
|
95
|
+
return ledger.pending.some((r) => r.source === source);
|
|
96
|
+
}
|
|
97
|
+
export function appendBoundaryFrames(prepared, turnOwesRequest) {
|
|
98
|
+
const styleOwed = prepared.outputStyleFrame !== undefined && !turnOwesRequest && prepared.batchHaltRef.current === undefined && !frameCarried(prepared.frameReceipts, "output_style") && prepared.harness.pendingInjectionCount() > 0;
|
|
93
99
|
const posture = appendOwedPosture(prepared, "on_change");
|
|
94
100
|
return styleOwed ? posture.then(() => appendOutputStyleRestate(prepared)) : posture;
|
|
95
101
|
}
|
|
96
102
|
export function compactionRestateOptions(prepared) {
|
|
97
|
-
return { ...gitRestateOption(prepared), ...postureRestateOption(prepared) };
|
|
103
|
+
return { ...gitRestateOption(prepared), ...postureRestateOption(prepared), ...(prepared.advisorInstruction?.mounted === true ? { advisorRestate: () => appendAdvisorRestate(prepared) } : {}) };
|
|
98
104
|
}
|
|
@@ -232,9 +232,9 @@ export interface DateAnchorRead {
|
|
|
232
232
|
export interface FrameReceipt {
|
|
233
233
|
/** The carrying message's exact text (its first text block) — the receipt's match key. */
|
|
234
234
|
text: string;
|
|
235
|
-
/** Which frame this receipt settles.
|
|
236
|
-
*
|
|
237
|
-
source: "git_status" | "agent_listing" | "skills_listing" | "date_change" | "output_style" | "approval_feedback";
|
|
235
|
+
/** Which frame this receipt settles. No collector renders a frame whose receipt is still pending (the frame is on
|
|
236
|
+
* its way, not yet in the transcript) — the one reading is `frameCarried` (compaction-restate.ts). */
|
|
237
|
+
source: "git_status" | "agent_listing" | "skills_listing" | "date_change" | "output_style" | "posture" | "approval_feedback" | "advisor_tool";
|
|
238
238
|
/** Runs inside the `message_end` walk (synchronous, never awaited): advances the run-local record
|
|
239
239
|
* and parks any session write for the next serialization point. */
|
|
240
240
|
commit: (entryId: string) => void;
|
|
@@ -1007,6 +1007,11 @@ export interface Prepared {
|
|
|
1007
1007
|
* calls themselves never pass through the recorded seam (they ride the separate compaction-brain
|
|
1008
1008
|
* wrapper), so the snapshot is never polluted by a summary request. */
|
|
1009
1009
|
lastBrainContext: () => CompactionForkContext | undefined;
|
|
1010
|
+
/** The same recorded request, unconditionally — the one write {@link lastBrainContext} also reads, minus its lossy-projection
|
|
1011
|
+
* exclusion: what the main lane last actually sent (the advisor's projection reads it). `undefined` until the first call. */
|
|
1012
|
+
lastSentRequest: () => CompactionForkContext | undefined;
|
|
1013
|
+
/** The leg's advisor-instructions seat (advisor-instructions.ts); absent when the leg neither mounts the advisor nor has told the model of it. */
|
|
1014
|
+
advisorInstruction?: import("./advisor-instructions.js").AdvisorInstructionSeat;
|
|
1010
1015
|
/** The post-compaction restore (`MaybeCompactOptions.workingFileAttachments.restore`): re-reads the candidates through
|
|
1011
1016
|
* the leg's one file reader under the run's synthetic-Read judge — the user attachment's own path read — deduplicated
|
|
1012
1017
|
* against the read state the summary leaves, and mints their attachment frames (`readCompactionRestore`); a file it
|
|
@@ -1030,7 +1035,7 @@ export interface Prepared {
|
|
|
1030
1035
|
* result from a stub hit whose original full transmission may already be summarized away. Present
|
|
1031
1036
|
* only with hands. */
|
|
1032
1037
|
isDedupStubResult?: (resultText: string) => boolean;
|
|
1033
|
-
/** Wired to `MaybeCompactOptions.onApplied` by every compaction lane (
|
|
1038
|
+
/** Wired to `MaybeCompactOptions.onApplied` by every compaction lane (the reference clears readFileState at its
|
|
1034
1039
|
* compaction landing site, @388663). Drops every read-state entry the summary took out of view
|
|
1035
1040
|
* (`readFileStateAfterSummary`); the restored files then re-register through their frames' own commits. Present
|
|
1036
1041
|
* only with hands. `preserveReadState` carries the files the context the summary leaves still shows — their
|
|
@@ -1159,7 +1164,7 @@ export interface Prepared {
|
|
|
1159
1164
|
};
|
|
1160
1165
|
/** G1 通告层续批 (CC `agent_listing_delta` parity) — the mounted delegation tool's agent-type roster
|
|
1161
1166
|
* (read off `ToolSpec.agentListing`, filled by createSubagentTool), plus the tool's mounted name for
|
|
1162
|
-
* the
|
|
1167
|
+
* the roster headers. [c209-C]: this seam is now the roster's ONLY model-facing carrier —
|
|
1163
1168
|
* the run loop delivers the initial full frame ON THE FIRST USER TURN (prompt-adjacent) and
|
|
1164
1169
|
* boundary drift deltas after. `models` (Q4, read off `ToolSpec.agentModels`) rides the initial
|
|
1165
1170
|
* frame's tail line. `seedAnnounced` = a durable-resume leg: the run loop seeds the producer's
|
|
@@ -1839,8 +1844,8 @@ export interface RunInternals {
|
|
|
1839
1844
|
* `spec.systemPrompt ?? resolvedRole.systemPrompt ?? internals.defaultSystemPrompt` — so a deployment's
|
|
1840
1845
|
* `roles.subagent.systemPrompt` / `roles.default.systemPrompt` preset still wins (pre-G1 semantics: an
|
|
1841
1846
|
* unset child systemPrompt let the role preset apply; G1's first cut put SUBAGENT_PROMPT at spec level
|
|
1842
|
-
* and silently shadowed the preset). Only when NO preset resolves does the lean SUBAGENT_PROMPT (
|
|
1843
|
-
*
|
|
1847
|
+
* and silently shadowed the preset). Only when NO preset resolves does the lean SUBAGENT_PROMPT (general-purpose
|
|
1848
|
+
* persona) replace the full DEFAULT_SYSTEM_PROMPT constitution base.
|
|
1844
1849
|
* TRUSTED run-scoped channel (NOT a {@link TaskSpec} field), mirroring `insideFork`.
|
|
1845
1850
|
*/
|
|
1846
1851
|
defaultSystemPrompt?: string;
|
|
@@ -2149,7 +2154,7 @@ export interface RunInternals {
|
|
|
2149
2154
|
* Hands THIS run's notification injector back to the SPAWNER once the lane is
|
|
2150
2155
|
* live (runtask calls it with its wrapped `injectTaskNotification`). The spawner stores it on the
|
|
2151
2156
|
* child's registry handle so a parent/sibling SendMessage can deliver TO the RUNNING child at its
|
|
2152
|
-
* next turn boundary (
|
|
2157
|
+
* next turn boundary (the in-memory `pendingMessages` pedestal,
|
|
2153
2158
|
* messaging-runtime.md §2.5). The injector outlives its run safely: once this lane is over the frame
|
|
2154
2159
|
* is routed to whatever run the SESSION has live, and only a session with no live run parks it
|
|
2155
2160
|
* (PendingSessionNotifications) — exactly CC's durable-mailbox posture for an idle teammate (§2.4).
|
|
@@ -2529,7 +2534,6 @@ export interface RunState {
|
|
|
2529
2534
|
* requested id — surfaced on `turn_end.responseModel`, reset with the rest of the per-turn
|
|
2530
2535
|
* bookkeeping. Same shape as `turnStopReason`: last-message-wins, absent by default. */
|
|
2531
2536
|
turnResponseModel: string | undefined;
|
|
2532
|
-
lastTurnHadToolCalls: boolean;
|
|
2533
2537
|
/** B15 三期使能:postToolBatch 的本回合聚集批(每回合边界消费并重置 — 回合语义,故归 turn)。 */
|
|
2534
2538
|
toolBatch: PostToolBatchCall[];
|
|
2535
2539
|
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { SessionTreeEntry } from "../../internal/harness-types.js";
|
|
2
|
+
import type { DateAnchorRead } from "./contracts.js";
|
|
3
|
+
/** The id of the active branch's latest compaction entry — the segment a fact is recorded for — or `null` before any. */
|
|
4
|
+
export declare function conversationSegmentOf(branch: ReadonlyArray<SessionTreeEntry>): string | null;
|
|
5
|
+
/** The custom-entry kind that carries the session's date anchor (engine-owned; never model-visible). */
|
|
6
|
+
export declare const DATE_ANCHOR_CUSTOM_TYPE = "engine:date-anchor";
|
|
7
|
+
/**
|
|
8
|
+
* Read the session's date anchor off the active branch: the nearest anchor entry NEWER than the nearest
|
|
9
|
+
* compaction, honored only when it was written for that same segment. An anchor written by a leg whose
|
|
10
|
+
* prefix predates a compaction that landed in between therefore reads as absent — the one rule that makes a
|
|
11
|
+
* compaction re-anchor the date. An unreadable branch returns undefined (the leg renders today, writes nothing).
|
|
12
|
+
*/
|
|
13
|
+
export declare function readDateAnchor(session: {
|
|
14
|
+
getBranch(): Promise<ReadonlyArray<SessionTreeEntry>>;
|
|
15
|
+
}): Promise<DateAnchorRead | undefined>;
|
|
16
|
+
/**
|
|
17
|
+
* The anchor write a leg owes when it settles, or undefined: owed when prepare found no anchor for the segment
|
|
18
|
+
* (the leg rendered today) or the model has since been told a newer date; never after an unreadable branch.
|
|
19
|
+
* Best-effort — a lost write costs one re-rendered prefix or one repeated reminder next leg, never a wrong date.
|
|
20
|
+
*/
|
|
21
|
+
export declare function owedDateAnchor(session: {
|
|
22
|
+
appendCustomEntry(customType: string, data?: unknown): Promise<string>;
|
|
23
|
+
}, seat: {
|
|
24
|
+
legDate: string;
|
|
25
|
+
anchor: DateAnchorRead | undefined;
|
|
26
|
+
} | undefined, state: {
|
|
27
|
+
announcedDate: string;
|
|
28
|
+
} | undefined): (() => Promise<void>) | undefined;
|