@sema-agent/core 5.20.0 → 5.21.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 +9 -0
- package/dist/agents/agent-definition.d.ts +7 -0
- package/dist/agents/agent-transcript-tool.d.ts +30 -0
- package/dist/agents/builtin-agents.d.ts +60 -0
- package/dist/agents/cascade.d.ts +107 -0
- package/dist/agents/cumulative-stats.d.ts +56 -0
- package/dist/agents/observer.d.ts +162 -0
- package/dist/agents/peer-admission.d.ts +95 -0
- package/dist/agents/repair-loop.d.ts +226 -0
- package/dist/agents/retain-ledger.d.ts +141 -0
- package/dist/agents/roster-store.d.ts +105 -0
- package/dist/agents/send-message-tool.d.ts +92 -0
- package/dist/agents/session-util.d.ts +5 -0
- package/dist/agents/subagent-steps.d.ts +66 -0
- package/dist/agents/subagent.d.ts +600 -0
- package/dist/agents/suspend-guard.d.ts +29 -0
- package/dist/agents/teacher.d.ts +75 -0
- package/dist/agents/team.d.ts +120 -1
- package/dist/agents/tool-filter.d.ts +34 -0
- package/dist/agents/verify.d.ts +198 -0
- package/dist/bench/metrics.d.ts +455 -0
- package/dist/brain/anthropic.d.ts +30 -0
- package/dist/brain/circuit-breaker.d.ts +33 -0
- package/dist/brain/context-overflow.d.ts +60 -3
- package/dist/brain/degrading.d.ts +67 -0
- package/dist/brain/errors.d.ts +42 -0
- package/dist/brain/failover.d.ts +15 -0
- package/dist/brain/media-degrade.d.ts +39 -0
- package/dist/brain/model-presets.d.ts +31 -0
- package/dist/brain/open-responses.d.ts +19 -0
- package/dist/brain/openai.d.ts +46 -0
- package/dist/brain/reasoning.d.ts +106 -1
- package/dist/brain/repetition.d.ts +83 -0
- package/dist/brain/request-params.d.ts +56 -0
- package/dist/brain/retry.d.ts +46 -0
- package/dist/brain/routing.d.ts +12 -0
- package/dist/brain/status-sink.d.ts +30 -1
- package/dist/brain/stream-engine.d.ts +147 -0
- package/dist/brain/stream-shared.d.ts +34 -0
- package/dist/brain/terminal-cause.d.ts +31 -0
- package/dist/brain/timeout.d.ts +107 -0
- package/dist/brain/tool-call-id.d.ts +20 -0
- package/dist/brain/tool-call-repair.d.ts +13 -0
- package/dist/config/catalog.d.ts +47 -0
- package/dist/config/defaults.d.ts +33 -0
- package/dist/core/a2a-task-state.d.ts +53 -0
- package/dist/core/a2a.d.ts +51 -0
- package/dist/core/arg-summary.d.ts +62 -0
- package/dist/core/ask-question.d.ts +272 -2
- package/dist/core/auto-compaction.d.ts +467 -0
- package/dist/core/auto-compaction.js +20 -6
- package/dist/core/auto-mode-prompt-assets.d.ts +8 -0
- package/dist/core/auto-mode-prompt.d.ts +27 -0
- package/dist/core/auto-mode.d.ts +54 -3
- package/dist/core/auto-promote.d.ts +100 -0
- package/dist/core/background-agent-store.d.ts +292 -0
- package/dist/core/background-shell.d.ts +110 -0
- package/dist/core/cache-break-detector.d.ts +34 -0
- package/dist/core/canonical-json.d.ts +57 -0
- package/dist/core/checkpoint-store.d.ts +1574 -16
- package/dist/core/compliance.d.ts +30 -0
- package/dist/core/consolidate-scope.d.ts +75 -0
- package/dist/core/context-edit.d.ts +99 -0
- package/dist/core/context-guard.d.ts +46 -0
- package/dist/core/exec-gate.d.ts +44 -0
- package/dist/core/exec-output-tail.d.ts +61 -0
- package/dist/core/file-snapshot-store.d.ts +104 -0
- package/dist/core/fs-write-gate-policy.d.ts +36 -0
- package/dist/core/git-worktree-env.d.ts +31 -0
- package/dist/core/governance-codes.d.ts +19 -0
- package/dist/core/hooks.d.ts +608 -1
- package/dist/core/human-input-projection.d.ts +37 -0
- package/dist/core/human-input-projection.js +13 -0
- package/dist/core/image-downsample.d.ts +74 -0
- package/dist/core/locked-config.d.ts +37 -0
- package/dist/core/lsp-diagnostics.d.ts +77 -0
- package/dist/core/lsp-protocol.d.ts +29 -0
- package/dist/core/lsp-session.d.ts +60 -1
- package/dist/core/lsp.d.ts +150 -1
- package/dist/core/mailbox-store.d.ts +57 -0
- package/dist/core/mcp.d.ts +381 -0
- package/dist/core/media-byte-cap.d.ts +21 -0
- package/dist/core/memory-admission.d.ts +71 -0
- package/dist/core/memory-engine/content-origin.d.ts +64 -0
- package/dist/core/memory-engine/data-plane.d.ts +43 -0
- package/dist/core/memory-engine/dual-root.d.ts +24 -0
- package/dist/core/memory-engine/engine.d.ts +230 -0
- package/dist/core/memory-engine/engine.js +103 -35
- package/dist/core/memory-engine/file-backend.d.ts +155 -0
- package/dist/core/memory-engine/frontmatter.d.ts +16 -0
- package/dist/core/memory-engine/layout.d.ts +217 -0
- package/dist/core/memory-engine/memory-backend-contract.d.ts +12 -0
- package/dist/core/memory-engine/migrate.d.ts +9 -0
- package/dist/core/memory-engine/scan.d.ts +12 -0
- package/dist/core/memory-engine/scope-contract.d.ts +61 -1
- package/dist/core/memory-engine/sync-client.d.ts +87 -0
- package/dist/core/memory-engine/sync.d.ts +60 -0
- package/dist/core/memory-engine/tools.d.ts +41 -0
- package/dist/core/memory-engine/types.d.ts +188 -0
- package/dist/core/memory-recall.d.ts +141 -0
- package/dist/core/memory-vector.d.ts +20 -0
- package/dist/core/memory.d.ts +458 -0
- package/dist/core/message-utils.d.ts +6 -0
- package/dist/core/oracle-isolation.d.ts +69 -0
- package/dist/core/permission-rule-consent.d.ts +138 -0
- package/dist/core/permission-rule-model.d.ts +122 -0
- package/dist/core/permission-rule-store.d.ts +119 -3
- package/dist/core/permission-rules.d.ts +87 -1
- package/dist/core/present-plan-tool.d.ts +20 -0
- package/dist/core/pricing.d.ts +26 -0
- package/dist/core/property-harness.d.ts +86 -0
- package/dist/core/protocol-naming.d.ts +38 -0
- package/dist/core/protocol-table.d.ts +61 -0
- package/dist/core/push-queue.d.ts +1 -0
- package/dist/core/remote-env.d.ts +383 -1
- package/dist/core/retention-policy.d.ts +33 -0
- package/dist/core/retention.d.ts +51 -0
- package/dist/core/roles.d.ts +59 -0
- package/dist/core/runner/active-skill-scope.d.ts +34 -0
- package/dist/core/runner/assemble-result.d.ts +134 -0
- package/dist/core/runner/compaction-call-options.d.ts +97 -1
- package/dist/core/runner/grounding-signal.d.ts +10 -0
- package/dist/core/runner/image.d.ts +17 -0
- package/dist/core/runner/image.js +29 -15
- package/dist/core/runner/memory-consolidation.d.ts +60 -0
- package/dist/core/runner/prepare-memory.d.ts +59 -0
- package/dist/core/runner/prepare-task.d.ts +1011 -2
- package/dist/core/runner/prepare-task.js +12 -11
- package/dist/core/runner/prompt-suggestions.d.ts +7 -0
- package/dist/core/runner/runtask.d.ts +304 -3
- package/dist/core/runner/session-file-state-replay.d.ts +49 -0
- package/dist/core/runner/session-rule-policy.d.ts +58 -0
- package/dist/core/runner/strict-output-schema.d.ts +18 -3
- package/dist/core/runner/synthetic-tools.d.ts +113 -0
- package/dist/core/runner/teardown-bounded.d.ts +34 -0
- package/dist/core/runner/tool-disclosure.d.ts +227 -0
- package/dist/core/runner/tool-output-projection.d.ts +6 -0
- package/dist/core/runner/turn-attachments.d.ts +634 -0
- package/dist/core/runner/usage-accounting.d.ts +32 -0
- package/dist/core/runtime.d.ts +9 -0
- package/dist/core/safe-notify.d.ts +64 -0
- package/dist/core/safety-axis-vocab.d.ts +23 -0
- package/dist/core/safety-merge-corpus.d.ts +37 -0
- package/dist/core/scheduler.d.ts +121 -0
- package/dist/core/secret-env.d.ts +32 -0
- package/dist/core/select-model.d.ts +15 -0
- package/dist/core/sensitive-path-policy.d.ts +42 -0
- package/dist/core/session-policy-store.d.ts +94 -0
- package/dist/core/session-reconcile.d.ts +80 -0
- package/dist/core/session-store.d.ts +85 -0
- package/dist/core/session.d.ts +153 -0
- package/dist/core/shared-memory/contract.d.ts +22 -0
- package/dist/core/shared-memory/normalize.d.ts +123 -2
- package/dist/core/shared-memory/tools.d.ts +14 -0
- package/dist/core/shared-memory/types.d.ts +105 -0
- package/dist/core/shutdown-debug.d.ts +6 -0
- package/dist/core/side-query.d.ts +38 -0
- package/dist/core/side-query.js +6 -1
- package/dist/core/skill-tool-specifier.d.ts +72 -0
- package/dist/core/skills-directory.d.ts +100 -1
- package/dist/core/spec-contract.d.ts +89 -0
- package/dist/core/store-contracts/background-agent-store-contract.d.ts +31 -0
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +26 -0
- package/dist/core/store-contracts/contract-harness.d.ts +20 -0
- package/dist/core/store-contracts/contract-kit-version.d.ts +27 -0
- package/dist/core/store-contracts/file-snapshot-store-contract.d.ts +8 -0
- package/dist/core/store-contracts/mailbox-store-contract.d.ts +42 -0
- package/dist/core/store-contracts/tool-result-store-contract.d.ts +13 -0
- package/dist/core/strategy-store.d.ts +37 -0
- package/dist/core/stub-env.d.ts +7 -0
- package/dist/core/surrogate-safe-slice.d.ts +35 -0
- package/dist/core/task-notification.d.ts +202 -0
- package/dist/core/task-outcome.d.ts +53 -0
- package/dist/core/task-registry-agent.d.ts +337 -1
- package/dist/core/task-registry-monitor.d.ts +12 -0
- package/dist/core/task-registry-shared.d.ts +540 -0
- package/dist/core/task-registry.d.ts +343 -0
- package/dist/core/task-registry.js +13 -2
- package/dist/core/task-tool-shape.d.ts +44 -0
- package/dist/core/tighten-task-spec.d.ts +21 -0
- package/dist/core/tool-detach.d.ts +21 -0
- package/dist/core/tool-errors.d.ts +131 -0
- package/dist/core/tool-errors.js +4 -0
- package/dist/core/tool-name-aliases.d.ts +27 -0
- package/dist/core/tool-policy.d.ts +555 -0
- package/dist/core/tool-result-budget.d.ts +32 -0
- package/dist/core/tool-result-store.d.ts +174 -1
- package/dist/core/tools.d.ts +45 -0
- package/dist/core/trace.d.ts +323 -0
- package/dist/core/types.d.ts +3859 -2
- package/dist/core/untrusted-egress.d.ts +8 -0
- package/dist/core/untrusted-text.d.ts +156 -0
- package/dist/core/usage-window-store.d.ts +95 -0
- package/dist/core/version.d.ts +1 -0
- package/dist/core/warm-resume.d.ts +17 -0
- package/dist/core/wiring-manifest.d.ts +169 -0
- package/dist/core/with-retry.d.ts +24 -0
- package/dist/core/workflow-journal-store.d.ts +160 -0
- package/dist/core/workflow-run-store-contract.d.ts +25 -0
- package/dist/core/workflow-run-store.d.ts +119 -0
- package/dist/engine/compaction/compaction.d.ts +256 -1
- package/dist/engine/compaction/utils.d.ts +94 -0
- package/dist/engine/execution-env/kill-tree.d.ts +29 -0
- package/dist/engine/execution-env/node-execution-env.d.ts +94 -0
- package/dist/engine/harness/agent-harness.d.ts +116 -0
- package/dist/engine/harness/agent-harness.js +3 -14
- package/dist/engine/harness/messages.d.ts +15 -0
- package/dist/engine/harness/types.d.ts +464 -2
- package/dist/engine/llm/diagnostics.d.ts +4 -0
- package/dist/engine/llm/event-stream.d.ts +3 -0
- package/dist/engine/llm/index.d.ts +7 -0
- package/dist/engine/llm/types.d.ts +500 -3
- package/dist/engine/llm/validation.d.ts +3 -0
- package/dist/engine/loop/agent-loop.d.ts +87 -2
- package/dist/engine/loop/runtime-deps.d.ts +7 -0
- package/dist/engine/loop/types.d.ts +424 -0
- package/dist/engine/lsp/frame-decoder.d.ts +13 -0
- package/dist/engine/lsp/node-lsp-manager.d.ts +107 -0
- package/dist/engine/lsp/stdio-lsp-transport.d.ts +7 -0
- package/dist/engine/session/import-validate.d.ts +27 -0
- package/dist/engine/session/log-digest.d.ts +93 -0
- package/dist/engine/session/memory-repo.d.ts +6 -0
- package/dist/engine/session/memory-storage.d.ts +2 -0
- package/dist/engine/session/session.d.ts +75 -0
- package/dist/engine/session/storage-base.d.ts +8 -0
- package/dist/fixtures/index.d.ts +36 -0
- package/dist/index.d.ts +16 -1
- package/dist/index.js +0 -1
- package/dist/internal/harness-types.d.ts +6 -0
- package/dist/internal/harness.d.ts +11 -0
- package/dist/internal/llm.d.ts +6 -0
- package/dist/orchestration/builtin-workflows.d.ts +53 -0
- package/dist/orchestration/dev-vm-script-runner.d.ts +19 -0
- package/dist/orchestration/goal.d.ts +57 -0
- package/dist/orchestration/goal.js +3 -0
- package/dist/orchestration/run-spec.d.ts +42 -0
- package/dist/orchestration/run-workflow-tool.d.ts +169 -0
- package/dist/orchestration/workflow-governance.d.ts +61 -0
- package/dist/orchestration/workflow-meta.d.ts +28 -0
- package/dist/orchestration/workflow-observe.d.ts +60 -0
- package/dist/orchestration/workflow-primitives.d.ts +23 -1
- package/dist/orchestration/workflow-sandbox-conformance.d.ts +38 -0
- package/dist/orchestration/workflow-script-runner.d.ts +88 -0
- package/dist/orchestration/workflow-script-store.d.ts +98 -0
- package/dist/orchestration/workflow-size-guideline.d.ts +67 -0
- package/dist/orchestration/workflow-types.d.ts +169 -2
- package/dist/orchestration/workflow.d.ts +358 -0
- package/dist/prompt-assembly/artifact-store.d.ts +33 -0
- package/dist/prompt-assembly/artifact.d.ts +25 -0
- package/dist/prompt-assembly/assemble.d.ts +20 -0
- package/dist/prompt-assembly/composer.d.ts +29 -0
- package/dist/prompt-assembly/epoch.d.ts +55 -1
- package/dist/prompt-assembly/event-registry.d.ts +35 -0
- package/dist/prompt-assembly/explain.d.ts +12 -0
- package/dist/prompt-assembly/tool-catalog.d.ts +38 -0
- package/dist/prompt-assembly/turn-snapshot.d.ts +40 -0
- package/dist/prompt-assembly/types.d.ts +115 -0
- package/dist/prompts/coordinator.d.ts +27 -0
- package/dist/prompts/default.d.ts +539 -0
- package/dist/prompts/simple-sections.d.ts +45 -0
- package/dist/prompts/supervisor.d.ts +66 -0
- package/dist/scenarios/env.d.ts +28 -0
- package/dist/scenarios/full-body.d.ts +50 -0
- package/dist/scenarios/scenario-registry.d.ts +60 -0
- package/dist/scenarios/teacher-quickstart.d.ts +27 -0
- package/dist/server/http.d.ts +17 -0
- package/dist/stores/cc/lockfile.d.ts +6 -0
- package/dist/stores/cc/mailbox-store.d.ts +8 -0
- package/dist/stores/cc/roster-adapter.d.ts +4 -0
- package/dist/stores/cc/sidecar-transcript.d.ts +66 -0
- package/dist/stores/file/background-agent-store.d.ts +24 -0
- package/dist/stores/file/checkpoint-store.d.ts +38 -0
- package/dist/stores/file/file-snapshot-store.d.ts +25 -0
- package/dist/stores/file/fs-atomic.d.ts +155 -0
- package/dist/stores/file/index.d.ts +89 -0
- package/dist/stores/file/mailbox-store.d.ts +36 -0
- package/dist/stores/file/memory-store.d.ts +82 -0
- package/dist/stores/file/permission-rule-store.d.ts +79 -0
- package/dist/stores/file/session-policy-store.d.ts +28 -0
- package/dist/stores/file/session-store.d.ts +40 -0
- package/dist/stores/file/shared-ledger.d.ts +83 -0
- package/dist/stores/file/tool-result-store.d.ts +11 -0
- package/dist/stores/file/usage-window-store.d.ts +18 -0
- package/dist/stores/file/workflow-journal-store.d.ts +100 -0
- package/dist/stores/file/workflow-run-store.d.ts +11 -0
- package/dist/tools/fs/bash-readonly-classifier.d.ts +282 -0
- package/dist/tools/fs/encoding.d.ts +60 -0
- package/dist/tools/fs/fs-bash.d.ts +133 -0
- package/dist/tools/fs/fs-pdf.d.ts +28 -0
- package/dist/tools/fs/fs-search-tools.d.ts +5 -0
- package/dist/tools/fs/fs-shared.d.ts +360 -0
- package/dist/tools/fs/fs-write.d.ts +16 -0
- package/dist/tools/fs/gh-rate-limit.d.ts +22 -0
- package/dist/tools/fs/index.d.ts +79 -0
- package/dist/tools/fs/notebook.d.ts +56 -0
- package/dist/tools/fs/pdf.d.ts +70 -0
- package/dist/tools/fs/pdf.js +8 -2
- package/dist/tools/fs/repo-map.d.ts +10 -0
- package/dist/tools/fs/safety.d.ts +376 -0
- package/dist/tools/fs/search.d.ts +131 -0
- package/dist/tools/loop-tick.d.ts +24 -0
- package/dist/tools/monitor.d.ts +55 -0
- package/dist/tools/scheduler-tools.d.ts +51 -0
- package/dist/tools/sql-adapters.d.ts +18 -0
- package/dist/tools/sql.d.ts +25 -0
- package/dist/tools/task-list.d.ts +77 -0
- package/dist/tools/todo.d.ts +8 -0
- package/dist/tools/web.d.ts +184 -0
- package/dist/tools/worktree.d.ts +81 -0
- package/package.json +2 -2
- package/dist/tools/gitea-issue.d.ts +0 -13
- package/dist/tools/gitea-issue.js +0 -75
|
@@ -1,25 +1,106 @@
|
|
|
1
1
|
import type { AgentTool } from "../internal/harness-types.js";
|
|
2
2
|
import type { ToolPolicy } from "./tool-policy.js";
|
|
3
|
+
/** The reserved tool name for AskUserQuestion — shared so the durable-resume path (runtask) can recognize it
|
|
4
|
+
* as a content-ask whose SHOWN questions must not be rewritten by an operator `updatedInput` (design/80 D-F).
|
|
5
|
+
*
|
|
6
|
+
* RESERVED means the whole engine keys content-ask semantics on this name: a policy `ask` on it is NEVER
|
|
7
|
+
* routed to a synchronous PERMISSION approver — on the main gate, the degraded fall-through, and the
|
|
8
|
+
* inherited ancestor wrappers alike (a permission frame's allow/deny cannot carry an ANSWER; CC parity:
|
|
9
|
+
* AskUserQuestion never raises a permission card). What it DOES reach, in this order, is the run's own
|
|
10
|
+
* content-ask channel: a LIVE question face answers it in-stream (the gate routes the question, not a
|
|
11
|
+
* verdict), and only with no live face — or with the durable gate forced — does it park durably or answer
|
|
12
|
+
* the typed refusal. Permission-GATING this tool stays unsupported by design; content-ROUTING it is the
|
|
13
|
+
* supported path. A caller-supplied tool reusing this name inherits the same routing; don't. */
|
|
3
14
|
export declare const ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
|
|
15
|
+
/**
|
|
16
|
+
* AskUserQuestion (design/64 §5). A model-callable tool that lets the agent ask the USER a structured
|
|
17
|
+
* multiple-choice question (which approach? which of these?) — distinct from the design/37 permission `ask`
|
|
18
|
+
* ("may I run this tool?"). The model only EMITS the call; the harness routes it to the caller via the
|
|
19
|
+
* {@link OnQuestion} seam (deployment supplies a real human / UI / HITL). **LLM has zero IO** — it cannot
|
|
20
|
+
* collect answers itself. Headless (no `onQuestion`) returns a typed "no human available" so the model
|
|
21
|
+
* proceeds with a default instead of hanging. **design/80 D-F (answer fence):** the answer no longer assumes a
|
|
22
|
+
* trusted control plane — in the Supervisor topology it arrives over the wire (an operator `/decide`), an
|
|
23
|
+
* injection vector. So a `selected` value is echoed as a chosen option ONLY if it is one of the offered option
|
|
24
|
+
* labels (`selected ⊆ options` — the model's own text), and the operator's free-text (`note`, plus any off-list
|
|
25
|
+
* input) is wrapped in an untrusted-DATA fence so it can never be read as instructions. Abort while waiting is
|
|
26
|
+
* handled by the §9 interrupt path (the pending call is closed). Mounting ([884], CC non-interactive `isEnabled`
|
|
27
|
+
* parity): only when a delivery face exists — a live `onQuestion`, or a durable park consumer (`checkpointStore`
|
|
28
|
+
* + `durableApproval`/`forceDurableGate`), or an explicit `TaskSpec.interactiveTools: true` — see that knob.
|
|
29
|
+
*/
|
|
4
30
|
export interface AskQuestionOption {
|
|
31
|
+
/** The choice text the user picks. */
|
|
5
32
|
label: string;
|
|
33
|
+
/** What this option means / its trade-off. */
|
|
6
34
|
description: string;
|
|
35
|
+
/** design/116 W3 (CC parity): optional preview content (mockup / code snippet / comparison) shown while this
|
|
36
|
+
* option is focused. The engine only TRANSPORTS it — it rides the {@link AskQuestionRequest} to `onQuestion`
|
|
37
|
+
* untouched; rendering (markdown box, side-by-side, …) is the shell/HITL surface's job. */
|
|
7
38
|
preview?: string;
|
|
8
39
|
}
|
|
9
40
|
export interface AskQuestion {
|
|
41
|
+
/** The full question. */
|
|
10
42
|
question: string;
|
|
43
|
+
/** A short header/label (≤ ~12 chars) for UIs. */
|
|
11
44
|
header: string;
|
|
45
|
+
/** 2-4 mutually-exclusive choices (unless multiSelect). */
|
|
12
46
|
options: AskQuestionOption[];
|
|
47
|
+
/** Allow selecting more than one option. */
|
|
13
48
|
multiSelect?: boolean;
|
|
14
49
|
}
|
|
15
50
|
export interface AskQuestionRequest {
|
|
16
51
|
toolCallId: string;
|
|
52
|
+
/** 1-4 questions. */
|
|
17
53
|
questions: AskQuestion[];
|
|
54
|
+
/** Runner-filled source identity (parallel to {@link import("./tool-policy.js").AskRequest}.principal,
|
|
55
|
+
* design S1d §1): the issuing task's end-user principal (design/62), for per-user attribution by an
|
|
56
|
+
* AGGREGATING onQuestion. Worker/tool cannot set it. Undefined ⇒ none (a non-aggregating onQuestion
|
|
57
|
+
* ignores it — additive, no-op). `readonly`: Runner-populated metadata. Populated on every path that
|
|
58
|
+
* actually CALLS a question face: the in-tool synchronous call, and the gate's pre-execution content-ask
|
|
59
|
+
* routing. A durable suspend invokes no face at all, so it carries none. */
|
|
18
60
|
readonly principal?: string;
|
|
61
|
+
/** Runner-filled source-task identity (= issuing task's session id), for per-worker attribution by an
|
|
62
|
+
* aggregating onQuestion. **worker-unforgeable for Runner-created delegated subagents/team members**
|
|
63
|
+
* (those child specs do not pass TaskSpec.sessionId — the Runner mints the id); a top-level caller CAN
|
|
64
|
+
* still set `TaskSpec.sessionId`, so this is NOT a globally unforgeable run id (design S1d §1.3).
|
|
65
|
+
* `readonly` + same "only where a face is really called" caveat as `principal`. */
|
|
19
66
|
readonly sourceTaskId?: string;
|
|
67
|
+
/**
|
|
68
|
+
* The canonical hash of the tool-call arguments this question was built from, as computed by the
|
|
69
|
+
* engine's one `boundInputHashOf` (the same digest the durable park binds its checkpoint to, so the
|
|
70
|
+
* two lanes are reconcilable against each other). Present only when the engine routed the question
|
|
71
|
+
* — a directly-mounted tool calling its own face carries none.
|
|
72
|
+
*
|
|
73
|
+
* The split to keep straight, because the two words are easy to swap:
|
|
74
|
+
* - `(sourceTaskId, toolCallId, boundInputHash)` is the RECONCILIATION key — "is this the same
|
|
75
|
+
* question, on the same call, in the same run?". It is what lets an in-stream delivery be matched
|
|
76
|
+
* against a parked one, and what an audit trail joins on. It is NOT an identity: all three
|
|
77
|
+
* components repeat for two sequential deliveries of an identical question.
|
|
78
|
+
* - {@link deliveryId} is the IDENTITY — "which delivery attempt is this?" — and is the only one of
|
|
79
|
+
* the two a registry may key open requests on.
|
|
80
|
+
* Keying a registry on the reconciliation key closes the second delivery on the first one's ticket.
|
|
81
|
+
*/
|
|
20
82
|
readonly boundInputHash?: string;
|
|
83
|
+
/**
|
|
84
|
+
* The IDENTITY of this delivery attempt: engine-minted, unique per delivery, never derived from
|
|
85
|
+
* anything a model or a caller supplies. This is the key for the single-winner obligation in
|
|
86
|
+
* {@link OnQuestion} — a registry keys open requests on it (scoped by tenant), so a deadline expiry
|
|
87
|
+
* and a UI submission for the SAME delivery resolve to exactly one winner, and a late answer is
|
|
88
|
+
* refused instead of applied to a question nobody is waiting on any more.
|
|
89
|
+
*
|
|
90
|
+
* Why not the tuple you might reach for first: `toolCallId` comes from the model/provider and is not
|
|
91
|
+
* guaranteed unique within a session, `sourceTaskId` can be caller-supplied, and the argument hash
|
|
92
|
+
* is identical for two identical questions. Their combination therefore repeats for two sequential
|
|
93
|
+
* deliveries of the same question — under which a registry would close the second on the first's
|
|
94
|
+
* ticket, or hand the second the first's late answer. That tuple remains the RECONCILIATION key
|
|
95
|
+
* (see {@link boundInputHash}); this field is the identity. One names the question, the other names
|
|
96
|
+
* the attempt, and only the attempt is unique.
|
|
97
|
+
*
|
|
98
|
+
* Present on EVERY delivery the engine makes, by either route (the tool's own call and the gate's
|
|
99
|
+
* pre-execution routing). Optional on the type only because a deployment may mount the tool itself.
|
|
100
|
+
*/
|
|
21
101
|
readonly deliveryId?: string;
|
|
22
102
|
}
|
|
103
|
+
/** One question's answer: the selected option label(s) + an optional free-text note. */
|
|
23
104
|
export interface QuestionAnswerItem {
|
|
24
105
|
header: string;
|
|
25
106
|
selected: string[];
|
|
@@ -28,11 +109,35 @@ export interface QuestionAnswerItem {
|
|
|
28
109
|
export interface QuestionAnswer {
|
|
29
110
|
answers: QuestionAnswerItem[];
|
|
30
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* The "nobody could be reached for this one" arm of {@link OnQuestionOutcome}. Its contract is narrow and
|
|
114
|
+
* load-bearing: return it ONLY when the deployment made ZERO interaction on this question — no card was
|
|
115
|
+
* shown, no partial selection was collected, nothing was submitted. That is what lets the engine re-route
|
|
116
|
+
* the same question (park it durably for a later human, or answer the honest "it was NOT shown" refusal)
|
|
117
|
+
* without any risk of the same question being decided twice.
|
|
118
|
+
*
|
|
119
|
+
* A face that DID show the question and then failed (disconnect, deadline after render, adapter error)
|
|
120
|
+
* must THROW instead — the two are deliberately different values with different engine handling, and
|
|
121
|
+
* folding a failure into this arm is what would put one question in front of two deciders.
|
|
122
|
+
*/
|
|
31
123
|
export interface QuestionUnavailable {
|
|
32
124
|
readonly kind: "unavailable";
|
|
33
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* The three-valued outcome of a content-ask delivery (one value per thing that can actually happen):
|
|
128
|
+
* · a {@link QuestionAnswer} — the human answered (including "selected nothing", which IS an answer);
|
|
129
|
+
* · {@link QuestionUnavailable} — nobody was reachable and nothing was shown (see its contract);
|
|
130
|
+
* · a THROW — delivery was attempted and failed. Never collapse a throw into `unavailable`.
|
|
131
|
+
*/
|
|
34
132
|
export type OnQuestionOutcome = QuestionAnswer | QuestionUnavailable;
|
|
35
|
-
|
|
133
|
+
/** How an {@link OnQuestionOutcome} reads. `"contradictory"` covers a value claiming BOTH arms at
|
|
134
|
+
* once (the `unavailable` discriminant alongside an `answers` array — structural typing permits it, and
|
|
135
|
+
* the outcome is deployment-supplied and may cross a wire), a value claiming NEITHER arm (a failed
|
|
136
|
+
* decode must not read as "the user selected nothing"), and a value that cannot be read at all. */
|
|
137
|
+
export type QuestionOutcomeReading =
|
|
138
|
+
/** The answer, already narrowed AND captured as an inert, density-validated clone — a caller
|
|
139
|
+
* neither re-reads the caller's value to get at it nor needs a `structuredClone` of its own. */
|
|
140
|
+
{
|
|
36
141
|
readonly shape: "answered";
|
|
37
142
|
readonly answer: QuestionAnswer;
|
|
38
143
|
} | {
|
|
@@ -40,17 +145,78 @@ export type QuestionOutcomeReading = {
|
|
|
40
145
|
} | {
|
|
41
146
|
readonly shape: "contradictory";
|
|
42
147
|
};
|
|
148
|
+
/**
|
|
149
|
+
* THE reader for a question outcome, and the only place its fields are touched. Total by construction:
|
|
150
|
+
* every way the value can misbehave — a throwing getter, both arms at once — lands on
|
|
151
|
+
* `"contradictory"`, which the callers refuse rather than resolve. That refusal is the point: reading a
|
|
152
|
+
* contradictory value as unavailable would discard an answer somebody may have given AND re-route the
|
|
153
|
+
* question to a second decider, while reading it as answered would deliver an answer the face may have
|
|
154
|
+
* meant to withhold. Neither guess is safe, so neither is made.
|
|
155
|
+
*/
|
|
43
156
|
export declare function classifyQuestionOutcome(outcome: OnQuestionOutcome): QuestionOutcomeReading;
|
|
44
157
|
export declare function canonicalizeCapturedPlainData(node: unknown, seen?: WeakSet<object>): boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Narrow an {@link OnQuestionOutcome} to its no-interaction arm — the ONLY value that licenses
|
|
160
|
+
* re-routing a question to a later decider, so it is read strictly (the discriminant must be present
|
|
161
|
+
* and the value must not also carry answers).
|
|
162
|
+
*
|
|
163
|
+
* For a FORWARDING wrapper relaying this seam. The engine's own decision points do not use it: they
|
|
164
|
+
* call {@link classifyQuestionOutcome} ONCE and switch on the result, because the value is
|
|
165
|
+
* deployment-supplied and its fields may be getters — classifying twice lets an outcome read as
|
|
166
|
+
* answered on one call and unavailable on the next, which is precisely how one question would reach
|
|
167
|
+
* two deciders. A wrapper that needs more than "is this the unavailable arm" should classify once too.
|
|
168
|
+
*/
|
|
45
169
|
export declare function isQuestionUnavailable(outcome: OnQuestionOutcome): outcome is QuestionUnavailable;
|
|
170
|
+
/**
|
|
171
|
+
* The content-ask seam (design/64 §5.2): the deployment routes an AskUserQuestion to a real human/UI and
|
|
172
|
+
* returns their selection. Parallel to (and independent of) {@link import("./tool-policy.js").OnAsk} — a
|
|
173
|
+
* permission ask is allow/deny, a content ask is a choice. `signal` fires on task abort: race your wait so
|
|
174
|
+
* an unanswered question is released at the deadline (it does not hang the worker).
|
|
175
|
+
*
|
|
176
|
+
* **Single-winner obligation (the deployment's half).** A face that races a deadline against a real UI
|
|
177
|
+
* owns the atomicity: before returning {@link QuestionUnavailable} it must CLOSE the open request, so a
|
|
178
|
+
* submission arriving one tick later is refused rather than applied. A signal race alone is not enough —
|
|
179
|
+
* two independent resolutions of one question is the shape this seam exists to prevent. Key the registry
|
|
180
|
+
* on {@link AskQuestionRequest.deliveryId} (scoped by tenant) — NOT on the call id or the argument hash,
|
|
181
|
+
* neither of which is unique per delivery. The engine consumes exactly one outcome per call id
|
|
182
|
+
* and never asks the same call twice, so honoring this contract makes the whole path single-winner; core
|
|
183
|
+
* does NOT serialize question delivery ACROSS runs (a shared UI seat is the deployment's closure), only
|
|
184
|
+
* within a run — the tool executes sequentially, so one run never has two questions in flight.
|
|
185
|
+
*/
|
|
46
186
|
export type OnQuestion = (req: AskQuestionRequest, signal?: AbortSignal) => Promise<OnQuestionOutcome>;
|
|
187
|
+
/**
|
|
188
|
+
* design/173 §8.1/§8.2 — why a synthetic self-answer instruction (the NO_HUMAN text) was returned:
|
|
189
|
+
* `"seam_absent"` = no `onQuestion` face was wired at all; `"callback_failed"` = a face WAS wired
|
|
190
|
+
* and threw (shell disconnect / timeout — the more common field case, and the more deceptive one:
|
|
191
|
+
* the deployment believes it has this limb); `"declined_unavailable"` = a face was wired, it was
|
|
192
|
+
* called, and it affirmed that nobody was reachable for this question (nothing was shown). The three
|
|
193
|
+
* must never collapse — "not installed", "installed but broken" and "installed, working, and nobody
|
|
194
|
+
* home" are three different operator actions.
|
|
195
|
+
*/
|
|
47
196
|
export type SyntheticContinuationReason = "seam_absent" | "callback_failed" | "declined_unavailable";
|
|
197
|
+
/** design/173 §8.1 — who produced the answer the model continues on. The engine never fabricates an
|
|
198
|
+
* answer: the synthetic arm returns a self-answer INSTRUCTION, hence the honest name. */
|
|
48
199
|
export type AskAnswerContinuationSource = "human_response" | "synthetic_self_answer_instruction";
|
|
200
|
+
/**
|
|
201
|
+
* design/173 §8.1 — the AskUserQuestion tool card (`details.type: "ask-question"`, registered in
|
|
202
|
+
* `CC_DETAIL_TYPES` — the card set is a two-way contract: mint and registration travel in the SAME
|
|
203
|
+
* change). The in-band structured marker is the AUTHORITATIVE provenance signal (disclosure frames
|
|
204
|
+
* can drop or reorder; a consumer must never match the NO_HUMAN prose). Two shapes:
|
|
205
|
+
* - the CONTINUATION card — every answered exit, human or synthetic (`runContinues: true` is the
|
|
206
|
+
* warning-not-error semantic: the run proceeds by design, a headless deployment must not be
|
|
207
|
+
* marked failed over it);
|
|
208
|
+
* - the INTERACTIVE-FAILURE card — the run refuses the silent synthetic continuation and reports a
|
|
209
|
+
* coded tool failure instead (`isError: true`). Two codes, kept apart for the same reason the
|
|
210
|
+
* reasons above are: `"question.human_channel_failed"` = the wired channel threw;
|
|
211
|
+
* `"question.human_unavailable"` = the channel worked and said nobody was reachable.
|
|
212
|
+
*/
|
|
49
213
|
export type AskQuestionCardDetails = {
|
|
50
214
|
type: "ask-question";
|
|
215
|
+
/** The question's id (= the tool call id — the same key the park/HITL faces use). */
|
|
51
216
|
questionId: string;
|
|
52
217
|
continuationSource: AskAnswerContinuationSource;
|
|
53
218
|
runContinues: true;
|
|
219
|
+
/** Present iff `continuationSource` is synthetic. */
|
|
54
220
|
reason?: SyntheticContinuationReason;
|
|
55
221
|
} | {
|
|
56
222
|
type: "ask-question";
|
|
@@ -58,23 +224,127 @@ export type AskQuestionCardDetails = {
|
|
|
58
224
|
code: "question.human_channel_failed" | "question.human_unavailable";
|
|
59
225
|
reason: "callback_failed" | "declined_unavailable";
|
|
60
226
|
};
|
|
227
|
+
/**
|
|
228
|
+
* The ONE mint point for the continuation card. Every exit that continues the run on
|
|
229
|
+
* an answer — human or synthetic, in the tool or on the engine's routing lane — builds its card here, so
|
|
230
|
+
* a new delivery point cannot quietly reopen the silent-degrade hole by shipping without a card.
|
|
231
|
+
*/
|
|
61
232
|
export declare function askQuestionContinuationCard(questionId: string, continuationSource: AskAnswerContinuationSource, reason?: SyntheticContinuationReason): AskQuestionCardDetails;
|
|
233
|
+
/**
|
|
234
|
+
* The ONE shape validator for a question batch, shared by the tool body and by the engine's routing lane
|
|
235
|
+
* (which validates BEFORE it puts anything in front of a person — a malformed batch must be refused to
|
|
236
|
+
* the model, not rendered). Returns the model-facing error text, or `undefined` when the batch is well
|
|
237
|
+
* formed. Total: it never throws on hostile field shapes.
|
|
238
|
+
*/
|
|
62
239
|
export declare function validateAskQuestions(questions: unknown): string | undefined;
|
|
240
|
+
/** design/173 件3 — engine-side options for the mounted tool (prepare wires them; a deployment
|
|
241
|
+
* mounting the tool directly may too). All optional: absent = pre-173 behavior. */
|
|
63
242
|
export interface AskUserQuestionToolOptions {
|
|
243
|
+
/** The run's RESOLVED interaction posture — see {@link import("./types.js").TaskSpec.interactionPosture}
|
|
244
|
+
* for the three-leg resolution (spec > the spawning run's resolved posture > deps); prepare passes
|
|
245
|
+
* that one resolved value, the same one the posture door reads.
|
|
246
|
+
* Under `"interactive"` BOTH no-answer arms of a wired channel are coded tool FAILURES instead of a
|
|
247
|
+
* silent synthetic continuation — a channel that THROWS returns `question.human_channel_failed`, one
|
|
248
|
+
* that reports nobody reachable returns `question.human_unavailable` — because an interactive
|
|
249
|
+
* deployment must face both. `"headless"`/absent keep the existing degrade. */
|
|
64
250
|
posture?: "interactive" | "headless";
|
|
251
|
+
/** The EXPLICIT knob (default off) letting posture `"interactive"` continue with the synthetic
|
|
252
|
+
* self-answer instruction after all, on BOTH hardened arms (channel threw / nobody reachable);
|
|
253
|
+
* disclosure still minted. */
|
|
65
254
|
interactiveFallback?: boolean;
|
|
255
|
+
/** Engine sink for the synthetic-continuation disclosure (the onError parallel leg — phase
|
|
256
|
+
* `"degraded"`, classification `"no-human-autoanswered"`). Deduped **per ask-call** (the dedup key
|
|
257
|
+
* is the tool-call id; one call may carry 1–4 questions and still discloses ONCE — "per question"
|
|
258
|
+
* would misread against that array), not per run: a second ask-call in the same run still
|
|
259
|
+
* discloses. The suppression set lives for ONE prepare (one leg): a continuation leg re-discloses
|
|
260
|
+
* the same call id — deliberate, or the second leg's host would be blind; a host aggregating
|
|
261
|
+
* across legs dedups on (sessionId, toolCallId) itself. Swallow-guarded — an observer bug never
|
|
262
|
+
* faults the ask. */
|
|
66
263
|
onSyntheticContinuation?: (info: {
|
|
67
264
|
questionId: string;
|
|
68
265
|
reason: SyntheticContinuationReason;
|
|
69
266
|
}) => void;
|
|
267
|
+
/**
|
|
268
|
+
* The call id of the ONE pending question this leg is redeeming an operator's approval for. An
|
|
269
|
+
* approval was spent to get that question executed, so an `unavailable` outcome on THAT call must not
|
|
270
|
+
* be absorbed into the synthetic self-answer: the operator has to learn their decision bought a
|
|
271
|
+
* question nobody answered, and it becomes the coded failure `question.human_unavailable` instead.
|
|
272
|
+
* Scoped to the id rather than to the leg — a NEW question raised later on the same leg had no
|
|
273
|
+
* approval spent on it and keeps the ordinary continuation. (A THROW keeps its own posture-driven
|
|
274
|
+
* handling on every call; that arm is unchanged.)
|
|
275
|
+
*/
|
|
70
276
|
redeemedApprovalCallId?: string;
|
|
277
|
+
/** Digest of the question batch that approval was granted for, paired with
|
|
278
|
+
* {@link redeemedApprovalCallId}. Call ids are provider-supplied and can repeat, so the id alone
|
|
279
|
+
* would let a LATER question inherit the claim that an operator approved it. */
|
|
71
280
|
redeemedApprovalQuestionsHash?: string;
|
|
72
281
|
}
|
|
282
|
+
/**
|
|
283
|
+
* Durable ask (design/64 TC-5.4 — ABOVE CC, the disconnected-human case): instead of the headless
|
|
284
|
+
* "proceed with your best judgment" default, an AskUserQuestion **suspends the task durably** and the
|
|
285
|
+
* answer resumes it — built ENTIRELY from existing primitives, no new gate kind.
|
|
286
|
+
*
|
|
287
|
+
* **The park is the fallback, not the mandate.** An adjudicated question parks durably UNLESS this run
|
|
288
|
+
* has a live question face (see {@link isLiveQuestionFace}), in which case the engine routes the question
|
|
289
|
+
* to that face and the answer arrives in-stream — same turn, no checkpoint, no rebuild. The park is what
|
|
290
|
+
* happens when nobody is there: no live face, the face affirming nobody is reachable, or a control-plane
|
|
291
|
+
* `forceDurableGate` that mandates the durable breakpoint regardless. A deployment that wired a live face
|
|
292
|
+
* AND wants every question parked anyway states that with `forceDurableGate` (or by not wiring the face).
|
|
293
|
+
*
|
|
294
|
+
* 1. Run the task with `durableApproval` + a durable `CheckpointStore` (+ durable session/offload
|
|
295
|
+
* stores) and `combinePolicies(createDurableQuestionPolicy(), yourPolicy)`. The policy adjudicates
|
|
296
|
+
* the AskUserQuestion call `ask`; in durable mode that suspends BEFORE the tool executes —
|
|
297
|
+
* `onQuestion` is never called on the suspend side, so mount the tool with
|
|
298
|
+
* {@link QUESTION_AWAITS_RESUME} when no live human is connected.
|
|
299
|
+
* 2. The HITL surface reads the questions from `checkpoint.pendingAction.args.questions` and collects
|
|
300
|
+
* the human's {@link QuestionAnswer} out-of-band (hours/days later, any replica).
|
|
301
|
+
* 3. `runner.resume(token, { gate: "policy_ask", decision: "allow", boundCallId:
|
|
302
|
+
* checkpoint.pendingAction.toolCallId }, { ...taskConfig, onQuestion: async () => answer })` — the resume
|
|
303
|
+
* re-mounts the tool with the answer closure; the pending call executes against it and the model
|
|
304
|
+
* continues with "The user answered: …". `boundCallId` (design/80 D-1) must name the pending call the
|
|
305
|
+
* human answered, or the resume is rejected (`checkpoint.invalid_outcome`).
|
|
306
|
+
*
|
|
307
|
+
* A deployment that wants the CC-style threshold form ("wait N minutes for a live human, then go
|
|
308
|
+
* durable") implements it inside its own policy: return `allow` while a human is connected (the live
|
|
309
|
+
* `onQuestion` answers synchronously) and `ask` when none is — the sync-vs-durable choice is exactly
|
|
310
|
+
* one policy decision.
|
|
311
|
+
*/
|
|
73
312
|
export declare function createDurableQuestionPolicy(): ToolPolicy;
|
|
313
|
+
/**
|
|
314
|
+
* Placeholder {@link OnQuestion} that mounts the AskUserQuestion tool on a worker with NO live human
|
|
315
|
+
* (the durable-ask suspend side, TC-5.4). It must never actually run — the durable-question policy
|
|
316
|
+
* suspends the call before execution — so reaching it means the wiring is missing the policy/store;
|
|
317
|
+
* it throws a configuration error rather than silently telling the model "no human is available".
|
|
318
|
+
*/
|
|
74
319
|
export declare const QUESTION_AWAITS_RESUME: OnQuestion;
|
|
320
|
+
/**
|
|
321
|
+
* Brand a face that can answer exactly ONE pre-bound call and nothing else — the engine builds one
|
|
322
|
+
* when a resume carries an operator's answer for the checkpointed question. It is a real face for that
|
|
323
|
+
* one call id and a dead end for every other question, which is why it must not be mistaken for a run's
|
|
324
|
+
* live question channel: routing a NEW question to it would turn "ask a human" into a guaranteed
|
|
325
|
+
* failure on a leg where the honest outcome is to park the new question for its own decision.
|
|
326
|
+
* Returns the same function, so it can wrap the construction site inline.
|
|
327
|
+
*/
|
|
75
328
|
export declare function markBoundOnlyQuestionFace<F extends OnQuestion>(face: F): F;
|
|
329
|
+
/**
|
|
330
|
+
* THE named predicate for "this run has a question face that can actually answer a question put to it",
|
|
331
|
+
* shared by every reader (the gate's routing decision, the tool mount, the wiring manifest's
|
|
332
|
+
* `question.wired`, and the resume guard). One derivation, because the ways of getting it wrong point in
|
|
333
|
+
* different directions and all of them are silent:
|
|
334
|
+
* · a non-function seat value (a JS caller passing junk) is not a face at all;
|
|
335
|
+
* · {@link QUESTION_AWAITS_RESUME} IS a function, and IS the documented standard assembly of the durable
|
|
336
|
+
* topology — but its whole contract is that it must never run. Counting it as live would route real
|
|
337
|
+
* questions into a configuration error instead of the park the deployment built;
|
|
338
|
+
* · a {@link markBoundOnlyQuestionFace} face answers one already-decided call and refuses the rest.
|
|
339
|
+
* Callers resolve the seat first (`spec.onQuestion ?? deps.onQuestion`) and pass the resolved value.
|
|
340
|
+
*/
|
|
76
341
|
export declare function isLiveQuestionFace(face: unknown): face is OnQuestion;
|
|
77
|
-
|
|
342
|
+
/** Build the AskUserQuestion tool. When `onQuestion` is undefined the tool still mounts but returns the
|
|
343
|
+
* headless default (so a run started without a human in the loop never hangs). */
|
|
344
|
+
export declare function createAskUserQuestionTool(onQuestion?: OnQuestion,
|
|
345
|
+
/** design S1d §1.2: Runner-filled source identity, merged into the {@link AskQuestionRequest} so an
|
|
346
|
+
* aggregating onQuestion can attribute per worker/user. Omitted ⇒ fields stay undefined (no-op). */
|
|
347
|
+
source?: {
|
|
78
348
|
principal?: string;
|
|
79
349
|
sourceTaskId?: string;
|
|
80
350
|
}, opts?: AskUserQuestionToolOptions): AgentTool;
|