@sema-agent/core 5.20.0 → 5.21.1
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 +19 -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-search-tools.js +0 -1
- 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,12 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/171 §5.2/§6.4 — THE single projection point for human-input speaker envelopes.
|
|
3
|
+
*
|
|
4
|
+
* One renderer covers every human-input carrier: the core-side five (objective / live steer /
|
|
5
|
+
* nextTurn / the resume tail's parked-steer frames / the wake message) and a serving layer's own
|
|
6
|
+
* carriers through the same contract. The division of labor is fixed (ruled 2026-08-05): the INGRESS
|
|
7
|
+
* sanitizes text and mints the {@link ActorAssertion}; this module only PROJECTS — it renders the
|
|
8
|
+
* speaker label ahead of the text, and it never sanitizes, truncates, or rewrites the text itself.
|
|
9
|
+
*
|
|
10
|
+
* Envelope contract:
|
|
11
|
+
* - no `actor` ⇒ BYTE-IDENTICAL passthrough. Every pre-171 caller and every single-user host
|
|
12
|
+
* supplies no actor, so the model-facing bytes of their runs are pinned unchanged.
|
|
13
|
+
* - `source: "system"` ⇒ passthrough regardless of actor: machine text (hook wake buses, engine
|
|
14
|
+
* notes) is never rendered as human speech.
|
|
15
|
+
* - otherwise ⇒ `[from "<id>"]` (plus an explicit `(unverified)` mark when the host did not derive
|
|
16
|
+
* the identity from ingress credentials) on its own line ahead of the text. The label is DISPLAY
|
|
17
|
+
* ONLY — an attribution, never authority (the normative clause on {@link ActorAssertion}).
|
|
18
|
+
*
|
|
19
|
+
* The label goes through the same two neutralizers as the external notification's `from="…"` header
|
|
20
|
+
* (`inlineUntrusted` + `attrEscape` — one-line, capped, break-out-defused, quote-escaped), so a
|
|
21
|
+
* hostile id can never close the `[from "…"]` frame, escape an enclosing `<system-reminder>`, or
|
|
22
|
+
* smuggle a fake `(unverified)`-free identity. The projection runs BEFORE trust framing at every
|
|
23
|
+
* call site, so the annotation always sits INSIDE the frame it attributes (a trusted frame's
|
|
24
|
+
* reminder wrapper, an untrusted frame's fence) and can never be separated from its text.
|
|
25
|
+
*/
|
|
1
26
|
import { type ActorAssertion } from "../internal/llm.js";
|
|
2
27
|
import type { HumanInputEvent, HumanInputSource, TaskEventIdentity } from "./types.js";
|
|
3
28
|
export type { HumanInputSource, HumanInputDelivery, HumanInputEvent } from "./types.js";
|
|
29
|
+
/** One human-input frame as the projection point receives it: ingress-sanitized text + the
|
|
30
|
+
* ingress-minted assertion (absent = anonymous). */
|
|
4
31
|
export interface HumanInputFrame {
|
|
32
|
+
/** The input text, ALREADY sanitized by the ingress that accepted it. Returned untouched. */
|
|
5
33
|
text: string;
|
|
34
|
+
/** Who spoke — absent means the caller supplied no attribution (every pre-171 caller). */
|
|
6
35
|
actor?: ActorAssertion;
|
|
7
36
|
source: HumanInputSource;
|
|
8
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Render the speaker envelope for one human-input frame. Pure; see the module contract above.
|
|
40
|
+
* Call BEFORE any trust framing (`formatHookFeedback` / `delimitUntrusted`) so the label stays
|
|
41
|
+
* inside the frame it attributes.
|
|
42
|
+
*/
|
|
9
43
|
export declare function projectHumanInput(frame: HumanInputFrame): string;
|
|
44
|
+
/** design/171 §6.2 — the one constructor for the `human_input` TaskEvent arm: mints the `inputId`
|
|
45
|
+
* when the caller has none and materializes NO absent optional keys (absence is the semantic —
|
|
46
|
+
* see the three-valued attribution note on the arm in core/types.ts). */
|
|
10
47
|
export declare function buildHumanInputEvent(input: Omit<HumanInputEvent, "type" | "inputId" | keyof TaskEventIdentity> & {
|
|
11
48
|
inputId?: string;
|
|
12
49
|
}): HumanInputEvent;
|
|
@@ -11,7 +11,20 @@ export function projectHumanInput(frame) {
|
|
|
11
11
|
const mark = frame.actor.hostAsserted ? "" : " (unverified)";
|
|
12
12
|
return `[from "${label}"${mark}]\n${frame.text}`;
|
|
13
13
|
}
|
|
14
|
+
const HANDLED_HUMAN_INPUT_KEYS = {
|
|
15
|
+
type: "minted-here",
|
|
16
|
+
inputId: "minted-here",
|
|
17
|
+
sessionSeq: "forwarded",
|
|
18
|
+
carrier: "forwarded",
|
|
19
|
+
source: "forwarded",
|
|
20
|
+
issuer: "forwarded",
|
|
21
|
+
actor: "forwarded",
|
|
22
|
+
delivery: "forwarded",
|
|
23
|
+
principal: "forwarded",
|
|
24
|
+
entryId: "forwarded",
|
|
25
|
+
};
|
|
14
26
|
export function buildHumanInputEvent(input) {
|
|
27
|
+
void HANDLED_HUMAN_INPUT_KEYS;
|
|
15
28
|
return {
|
|
16
29
|
type: "human_input",
|
|
17
30
|
inputId: input.inputId ?? uuidv7(),
|
|
@@ -1,23 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic image downsample/resize pipeline (design/157 S3 — split out of `core/mcp.ts`, which historically
|
|
3
|
+
* carried this alongside MCP-protocol plumbing even though the pipeline itself has no MCP dependency).
|
|
4
|
+
* Two consumers share this ONE pipeline + ONE size yardstick: the MCP inline-image bound (`core/mcp.ts`
|
|
5
|
+
* `boundedImageBlock`) and the Read tool's image branch (`tools/fs/index.ts`). `core/mcp.ts` re-exports
|
|
6
|
+
* everything below (`export * from "./image-downsample.js"`) so existing importers (`tools/fs/index.ts`,
|
|
7
|
+
* `core/types.ts`) needed no changes on this car.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* design/116 W5-1 — the max base64 size of ONE inline image (5MB). Value = CC 2.1.187
|
|
11
|
+
* `API_IMAGE_MAX_BASE64_SIZE` (constants/apiLimits.ts:22, "5 * 1024 * 1024 // 5 MB" — the hard Anthropic API
|
|
12
|
+
* limit on a base64 image block; CC resizes/compresses down to fit UNDER it, imageResizer.ts). An MCP server
|
|
13
|
+
* returning a bigger image previously passed straight through = a context/API bomb.
|
|
14
|
+
*/
|
|
1
15
|
export declare const MCP_IMAGE_MAX_BASE64: number;
|
|
16
|
+
/**
|
|
17
|
+
* 批③ image-pipeline — CC 2.1.x `constants/apiLimits.ts` values, shared by the MCP inline-image bound
|
|
18
|
+
* AND the Read tool's image branch (tools/fs — internal consistency: ONE yardstick per limit). See also
|
|
19
|
+
* `tools/fs/index.ts:40-41` ("one limit, two consumers, no drift") — the other consumer of this same
|
|
20
|
+
* yardstick, which is where this invariant was originally called out.
|
|
21
|
+
* - `IMAGE_TARGET_RAW_SIZE` (apiLimits.ts:29): raw-byte target that guarantees the base64 encoding stays
|
|
22
|
+
* under {@link MCP_IMAGE_MAX_BASE64} (raw × 4/3 = base64 → 3.75MB raw = 5MB base64).
|
|
23
|
+
* - `IMAGE_MAX_WIDTH/HEIGHT` (apiLimits.ts:42-43): client-side resize box. The API internally resizes
|
|
24
|
+
* above 1568px anyway; 2000px preserves a little extra quality while bounding token burn (~3x for a
|
|
25
|
+
* full-resolution screenshot vs the box).
|
|
26
|
+
*/
|
|
2
27
|
export declare const IMAGE_TARGET_RAW_SIZE: number;
|
|
3
28
|
export declare const IMAGE_MAX_WIDTH = 2000;
|
|
4
29
|
export declare const IMAGE_MAX_HEIGHT = 2000;
|
|
30
|
+
/**
|
|
31
|
+
* design/116 W5-1 — bound an inline MCP image. HONEST DELTA vs CC: CC really resizes/downsamples an
|
|
32
|
+
* oversized image with sharp (utils/imageResizer.ts `maybeResizeAndDownsampleImageBuffer`: ≤2000x2000px,
|
|
33
|
+
* ≤3.75MB raw = 5MB base64, progressive JPEG/PNG quality ladder). Core deliberately takes NO image-processing
|
|
34
|
+
* dependency (arch decision — sharp is a native module we won't force on every consumer), so instead of
|
|
35
|
+
* resizing we BOUND: an image whose base64 exceeds {@link MCP_IMAGE_MAX_BASE64} is spilled to disk and
|
|
36
|
+
* replaced by an explanatory text block with the size + path; a within-limit image passes through unchanged.
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* Optional image-resize seam (design/116 review CONFIRM-1, clay 拍 2026-07-02 加 seam 保体验): given an
|
|
40
|
+
* over-limit image, return a smaller re-encoded one — or undefined when it can't. CC resizes with sharp
|
|
41
|
+
* (imageResizer.ts: fit within 2000x2000, JPEG quality ladder) so the model still SEES a degraded image;
|
|
42
|
+
* core must not hard-depend on a native image library, so the capability is injected (or auto-detected).
|
|
43
|
+
*/
|
|
5
44
|
export type McpImageResizer = (base64: string, mimeType: string) => Promise<{
|
|
6
45
|
base64: string;
|
|
7
46
|
mimeType: string;
|
|
8
47
|
} | undefined>;
|
|
48
|
+
/**
|
|
49
|
+
* 批③ image-pipeline — original vs displayed size of a processed image (CC `imageResizer.ts`
|
|
50
|
+
* `ImageDimensions`). `display*` = what the model actually sees; the Read tool renders the CC coordinate-
|
|
51
|
+
* mapping meta text from the ratio, so vision coordinate reasoning survives a downsample.
|
|
52
|
+
*/
|
|
9
53
|
export interface ImageDimensions {
|
|
10
54
|
originalWidth: number;
|
|
11
55
|
originalHeight: number;
|
|
12
56
|
displayWidth: number;
|
|
13
57
|
displayHeight: number;
|
|
14
58
|
}
|
|
59
|
+
/** Result of {@link ImageDownsampler}: re-encoded (or passed-through) image + dimensions when known. */
|
|
15
60
|
export interface DownsampledImage {
|
|
16
61
|
base64: string;
|
|
62
|
+
/** Full mime form (`image/jpeg`), ready for an ImageContent block. */
|
|
17
63
|
mimeType: string;
|
|
18
64
|
dimensions?: ImageDimensions;
|
|
19
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* 批③ — buffer-level image downsampler shared by the MCP inline-image bound AND the Read tool's image
|
|
68
|
+
* branch. Returns undefined when the input can't be processed (corrupt/unsupported) — the caller keeps
|
|
69
|
+
* its non-sharp path (spill for MCP, original-bytes for Read). A within-limits image passes through
|
|
70
|
+
* UNCHANGED (with dimensions when known) — pass-through is not a failure.
|
|
71
|
+
*/
|
|
20
72
|
export type ImageDownsampler = (input: Buffer, mimeType: string) => Promise<DownsampledImage | undefined>;
|
|
73
|
+
/** Minimal structural slice of the sharp API the pipeline uses (fresh instance per operation — CC note:
|
|
74
|
+
* reusing an instance after toBuffer() silently skips format conversions on some native builds). */
|
|
21
75
|
type SharpFactory = (input: Buffer) => SharpOps;
|
|
22
76
|
interface SharpOps {
|
|
23
77
|
metadata: () => Promise<{
|
|
@@ -38,7 +92,27 @@ interface SharpOps {
|
|
|
38
92
|
}) => SharpOps;
|
|
39
93
|
toBuffer: () => Promise<Buffer>;
|
|
40
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* The CC downsample pipeline (imageResizer.ts `maybeResizeAndDownsampleImageBuffer`, called by
|
|
97
|
+
* FileReadTool.ts:1097 `readImageWithTokenBudget`), ported over an injected sharp factory so the ladder
|
|
98
|
+
* is unit-testable without the native dependency:
|
|
99
|
+
* 1. fits already (raw ≤ 3.75MB AND ≤ 2000×2000) → pass through, dimensions attached;
|
|
100
|
+
* 2. dims fit but bytes over → full-resolution compression first (PNG lossless/palette for PNGs, then
|
|
101
|
+
* JPEG quality ladder 80/60/40/20) — preserves resolution when possible;
|
|
102
|
+
* 3. dims over → constrain to the 2000×2000 box (aspect kept), then the same ladder on the resized
|
|
103
|
+
* image if still over; last rung = ≤1000px wide JPEG q20 (returned without a further size check —
|
|
104
|
+
* the caller's base64 gate stays the final arbiter, CC-identical shape);
|
|
105
|
+
* 4. metadata without dimensions → JPEG q80 when over target, else pass through (CC branch).
|
|
106
|
+
* Exported for tests (fake sharp factory); production entry = {@link sharpImageDownsampler}.
|
|
107
|
+
*/
|
|
41
108
|
export declare function createImageDownsampler(sharp: SharpFactory): ImageDownsampler;
|
|
42
109
|
export declare function sharpImageDownsampler(): Promise<ImageDownsampler | undefined>;
|
|
110
|
+
/**
|
|
111
|
+
* Default resizer factory: dynamic `import("sharp")` — a turnkey deployment with sharp installed gets the
|
|
112
|
+
* CC experience automatically; without it this resolves to undefined and the spill path applies. Since
|
|
113
|
+
* 批③ this is a thin base64 adapter over {@link sharpImageDownsampler} (single pipeline, CC ladder);
|
|
114
|
+
* the contract is unchanged: undefined when sharp is missing, the input is corrupt, or even the lowest
|
|
115
|
+
* ladder rung stays over the API limit.
|
|
116
|
+
*/
|
|
43
117
|
export declare function sharpImageResizer(): Promise<McpImageResizer | undefined>;
|
|
44
118
|
export {};
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import type { RunnerDeps, TaskSpec } from "./types.js";
|
|
2
2
|
import type { ToolPolicy } from "./tool-policy.js";
|
|
3
|
+
/** The closed set of administratively lockable configuration keys. Adding a member is a deliberate
|
|
4
|
+
* edit HERE (tsc forces the registry row), never a free-form string. */
|
|
3
5
|
export type LockedKey = "mcp" | "toolPolicy" | "compliancePosture" | "retentionPolicy";
|
|
6
|
+
/**
|
|
7
|
+
* The closed locked-key registry: each key names the exact `TaskSpec` fields it guards. Keys whose
|
|
8
|
+
* field set is EMPTY guard deployment-only surfaces (`compliancePosture` rides
|
|
9
|
+
* `RunnerDeps.compliancePostureResolver`, `retentionPolicy` rides `RunnerDeps.retentionPolicy`) —
|
|
10
|
+
* there is structurally no untrusted spec field to refuse, so for those the lock is a declaration
|
|
11
|
+
* consumed elsewhere (the retention startup validation keys off `retentionPolicy` being locked; the
|
|
12
|
+
* server control plane reads the declaration for its own sync gate). `satisfies` keeps the row set
|
|
13
|
+
* and the {@link LockedKey} union in lockstep — tsc refuses a key without a row and a row without a
|
|
14
|
+
* key.
|
|
15
|
+
*/
|
|
4
16
|
export declare const LOCKED_KEY_REGISTRY: {
|
|
5
17
|
readonly mcp: {
|
|
6
18
|
readonly specFields: readonly ["mcp"];
|
|
@@ -15,13 +27,38 @@ export declare const LOCKED_KEY_REGISTRY: {
|
|
|
15
27
|
readonly specFields: readonly [];
|
|
16
28
|
};
|
|
17
29
|
};
|
|
30
|
+
/** A deployment's lock declaration ({@link RunnerDeps.lockedConfig}). Config-time, trusted. */
|
|
18
31
|
export interface LockedConfig {
|
|
32
|
+
/** The keys this deployment locks. Wire-validated against {@link LOCKED_KEY_REGISTRY} at the
|
|
33
|
+
* preflight door — an unknown member is a loud `config.locked_registry` refusal, never a no-op. */
|
|
19
34
|
keys: readonly LockedKey[];
|
|
20
35
|
}
|
|
36
|
+
/** The preflight's resolved snapshot — the ONLY thing downstream task assembly reads for the
|
|
37
|
+
* guarded slots (never the raw `spec.mcp` / `spec.toolPolicy` fields). */
|
|
21
38
|
export interface LockedPreflight {
|
|
39
|
+
/** The validated lock set (empty when the deployment declares none). */
|
|
22
40
|
lockedKeys: ReadonlySet<LockedKey>;
|
|
41
|
+
/** Effective MCP server list for this task: `spec.mcp` when the key is unlocked; with `mcp`
|
|
42
|
+
* locked a spec-supplied value has already been refused, so this is always `undefined` (core has
|
|
43
|
+
* no deployment-level MCP seat — a locked deployment mounts no task-supplied servers). */
|
|
23
44
|
mcp: TaskSpec["mcp"];
|
|
45
|
+
/** Effective caller tool policy: the same `spec.toolPolicy ?? deps.toolPolicy` slot the gate has
|
|
46
|
+
* always enforced, resolved ONCE here. With `toolPolicy` locked, the deployment's own
|
|
47
|
+
* `deps.toolPolicy` is the whole answer (a spec-supplied policy has already been refused). */
|
|
24
48
|
toolPolicy: ToolPolicy | undefined;
|
|
25
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Validate a deployment's lock declaration against the closed registry. Fail-loud on any unknown
|
|
52
|
+
* key (`config.locked_registry`): a security control that doesn't parse must refuse to arm, not
|
|
53
|
+
* degrade to "that key silently unlocked". Exported for deployments that want the check at their
|
|
54
|
+
* own startup; the task-preparation preflight runs it on every leg regardless (a mis-declared lock
|
|
55
|
+
* then fails the first prepare instead of silently guarding nothing).
|
|
56
|
+
*/
|
|
26
57
|
export declare function resolveLockedKeys(config: LockedConfig | undefined): ReadonlySet<LockedKey>;
|
|
58
|
+
/**
|
|
59
|
+
* The single preflight resolver: validate the lock declaration, refuse a spec that tries to occupy
|
|
60
|
+
* a locked slot (`config.locked_key`, two-state — the whole prepare is rejected, nothing is
|
|
61
|
+
* silently dropped or merged), and produce the resolved snapshot downstream assembly consumes.
|
|
62
|
+
* Runs BEFORE any side effect of task preparation.
|
|
63
|
+
*/
|
|
27
64
|
export declare function preflightLockedConfig(spec: TaskSpec, deps: RunnerDeps): LockedPreflight;
|
|
@@ -1,5 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/121 — LSP diagnostics registry + model-facing formatting (CC 2.1.198 parity).
|
|
3
|
+
*
|
|
4
|
+
* CC's two diagnostics sources (IDE MCP baseline/diff + passive LSP publishDiagnostics) collapse to
|
|
5
|
+
* ONE in sema: the passive registry. The "only NEW diagnostics" semantics CC gets from per-file
|
|
6
|
+
* baselines falls out of the delivered-set here — a diagnostic is injected at most once PER RUN, and a
|
|
7
|
+
* run editing a file clears its delivered set so a persisting problem can resurface (CC `Fjn` same
|
|
8
|
+
* behavior). The registry object itself is deployment-scoped, so "per run" is a keyed fact, not an
|
|
9
|
+
* object lifetime; see {@link LspDiagnosticsRegistry}.
|
|
10
|
+
*
|
|
11
|
+
* Volumes and wire format are CC-exact (198:320661 `Njn=10, nqa=30`; 198:320480-320505 summary +
|
|
12
|
+
* 4000-char cap; severity symbols ✖/⚠/ℹ/★).
|
|
13
|
+
*
|
|
14
|
+
* NOT durable: diagnostics regenerate from the language server on the next edit; a suspend/resume
|
|
15
|
+
* simply starts empty (recorded in design/121 §2).
|
|
16
|
+
*/
|
|
17
|
+
/** One LSP diagnostic, the subset the model/shell needs (LSP `Diagnostic` narrowed). */
|
|
1
18
|
export interface LspDiagnostic {
|
|
2
19
|
message: string;
|
|
20
|
+
/** LSP severity: 1=Error 2=Warning 3=Information 4=Hint. Absent = unknown (sorted last). */
|
|
3
21
|
severity?: number;
|
|
4
22
|
range?: {
|
|
5
23
|
start: {
|
|
@@ -14,18 +32,77 @@ export interface LspDiagnostic {
|
|
|
14
32
|
code?: string | number;
|
|
15
33
|
source?: string;
|
|
16
34
|
}
|
|
35
|
+
/** One file's new diagnostics, as drained for injection + the wire frame. */
|
|
17
36
|
export interface LspFileDiagnostics {
|
|
18
37
|
uri: string;
|
|
19
38
|
diagnostics: LspDiagnostic[];
|
|
20
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* The pending/delivered diagnostics registry.
|
|
42
|
+
*
|
|
43
|
+
* **Lifetime, stated honestly:** ONE registry is constructed per `NodeLspManager`, i.e. per DEPLOYMENT —
|
|
44
|
+
* every task served through `RunnerDeps.lspManager` shares this object. Its two halves scope differently,
|
|
45
|
+
* and deliberately:
|
|
46
|
+
* - `pending` is the language server's own view of the workspace (whole-file replacement per the LSP
|
|
47
|
+
* spec) and is therefore deployment-wide, like the servers that feed it;
|
|
48
|
+
* - `delivered` — "this was already injected into the transcript" — is a per-RUN fact, so it is keyed by
|
|
49
|
+
* the caller's `runIdent`. Without that scope a diagnostic delivered to one run was filtered out of
|
|
50
|
+
* every later run's drain for the lifetime of the process, including runs that had never seen it and
|
|
51
|
+
* (never having edited that file) had no way to make it resurface. Growth is bounded by the ACTIVE
|
|
52
|
+
* runs, because {@link releaseRun} drops a finished run's keys.
|
|
53
|
+
*
|
|
54
|
+
* `publish` is called by an LSP session's publishDiagnostics subscription; `drain` is called at the turn
|
|
55
|
+
* boundary and returns only diagnostics THAT RUN has not been shown, sorted and volume-capped.
|
|
56
|
+
*
|
|
57
|
+
* NOT durable: diagnostics regenerate from the language server on the next edit, and a resumed run is a
|
|
58
|
+
* new run (fresh delivered scope), so a suspend/resume re-delivers rather than losing anything.
|
|
59
|
+
*/
|
|
21
60
|
export declare class LspDiagnosticsRegistry {
|
|
61
|
+
/** uri → the LAST published full diagnostic set for that file (LSP replace semantics). */
|
|
22
62
|
private readonly pending;
|
|
63
|
+
/** runIdent → the diagnostic keys already injected into THAT run. Cleared per file when that run edits
|
|
64
|
+
* it (the problem may resurface against the new text), and wholesale when the run ends
|
|
65
|
+
* ({@link releaseRun}). A Map of Sets rather than one flat prefixed set so that releasing/clearing a
|
|
66
|
+
* run can never touch a run whose ident merely starts with the same characters. */
|
|
23
67
|
private readonly delivered;
|
|
68
|
+
/** Record a `textDocument/publishDiagnostics` payload (already version-checked by the session). */
|
|
24
69
|
publish(uri: string, diagnostics: LspDiagnostic[]): void;
|
|
70
|
+
/** The run `runIdent` edited `uri` — that run's delivered keys for the file reset, so a still-present
|
|
71
|
+
* problem can resurface against the NEW text (CC clears per-file delivered on edit, 198 `Fjn`). Only
|
|
72
|
+
* the editing run's view is cleared: another run never saw this edit, and re-showing it a diagnostic
|
|
73
|
+
* it is already carrying in its transcript would be duplication, not news. */
|
|
25
74
|
fileEdited(runIdent: string, uri: string): void;
|
|
75
|
+
/** The run ended — drop its delivered keys. This is what bounds the registry: without it the set grows
|
|
76
|
+
* monotonically for the lifetime of the (deployment-scoped) manager. Idempotent; unknown idents are a
|
|
77
|
+
* no-op, so a caller may release a run that never drained. */
|
|
26
78
|
releaseRun(runIdent: string): void;
|
|
79
|
+
/** True when a drain would produce nothing (cheap pre-check for the turn-boundary hook). */
|
|
27
80
|
isEmpty(): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Take the diagnostics `runIdent` has NOT been shown: sorted Error>Warning>Info>Hint within each file,
|
|
83
|
+
* capped at {@link MAX_PER_FILE}/{@link MAX_TOTAL}, marked delivered FOR THAT RUN. A file whose
|
|
84
|
+
* diagnostics this run has all seen drops out (until its server publishes again or that run edits it).
|
|
85
|
+
* "Delivered" is scoped to the run because it means "already in this transcript" — another run's
|
|
86
|
+
* transcript does not have it, and must be able to see it (see the class note on lifetime).
|
|
87
|
+
*
|
|
88
|
+
* HRD-LSP-3: what the caps hold back is REQUEUED, not dropped. The old body capped the take and then
|
|
89
|
+
* `pending.clear()`-ed unconditionally, so diagnostic #11 of a file — and every file after the 30-item
|
|
90
|
+
* total ceiling — was neither returned nor marked delivered: it vanished, and no later drain could
|
|
91
|
+
* recover it unless the server happened to re-publish. Errors ranked first inside a file made that worse,
|
|
92
|
+
* not better: the highest-severity items were delivered and the REST were the ones destroyed. The
|
|
93
|
+
* remainder now survives into the next drain (the next turn boundary), which is also what makes the
|
|
94
|
+
* per-turn volume cap a PACING rule instead of a silent data cap.
|
|
95
|
+
*/
|
|
28
96
|
drain(runIdent: string): LspFileDiagnostics[];
|
|
29
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* CC 198 `formatDiagnosticsSummary` (198:320480-320499), verbatim shape:
|
|
100
|
+
* ```
|
|
101
|
+
* {basename}:
|
|
102
|
+
* {symbol} [Line {line+1}:{col+1}] {message}[ [{code}]][ ({source})]
|
|
103
|
+
* ```
|
|
104
|
+
* capped at 4000 chars with an honest `…[truncated]` tail.
|
|
105
|
+
*/
|
|
30
106
|
export declare function formatDiagnosticsSummary(files: LspFileDiagnostics[]): string;
|
|
107
|
+
/** CC 198 model-facing injection block (198:320500-320503), verbatim framing. */
|
|
31
108
|
export declare function formatDiagnosticsBlock(files: LspFileDiagnostics[]): string;
|
|
@@ -1,9 +1,38 @@
|
|
|
1
1
|
import type { LspOperation, LspRequestParams, LspResult } from "./lsp.js";
|
|
2
|
+
/**
|
|
3
|
+
* file:// URI for an absolute path (verified on a Windows host): this serves TWO lanes —
|
|
4
|
+
* TOC host files (NodeLspManager, host semantics correct) AND remote WS-lane container paths
|
|
5
|
+
* (E2B/kata sidecar, Linux form). `pathToFileURL` is HOST-platform-semantic: on a win32 host it
|
|
6
|
+
* parses a remote `/home/user/x.ts` as drive-relative → `file:///C:/home/user/x.ts` → the remote
|
|
7
|
+
* LSP server gets a nonexistent URI (breaking the remote lane on a win32 host entirely). Structural
|
|
8
|
+
* form detection instead (same philosophy as the fs-safety dual-family fix — paths come from the
|
|
9
|
+
* ExecutionEnv and may be of the OTHER family than the host, so never key on process.platform):
|
|
10
|
+
* POSIX-form absolutes are hand-assembled (percent-encoded per segment, no host path module);
|
|
11
|
+
* drive-letter form keeps `pathToFileURL` (CC parity for Windows files). On a POSIX host the
|
|
12
|
+
* hand-assembled branch matches `pathToFileURL(p).href` for typical paths (common characters like
|
|
13
|
+
* spaces encode identically; exotic characters follow the stricter encodeURIComponent form, and LSP
|
|
14
|
+
* servers accept both).
|
|
15
|
+
*/
|
|
2
16
|
export declare function pathToUri(p: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* [K-PLATFORM-SWEEP] MINOR#5: structural inverse of {@link pathToUri} — the naive `file://` prefix strip
|
|
19
|
+
* left win-form URIs as `/C:/x` (never matching the didOpen keys) and never percent-decoded (a space in a
|
|
20
|
+
* filename broke the staleness map). Form-detected, never host `fileURLToPath` (cross-family lanes).
|
|
21
|
+
*/
|
|
3
22
|
export declare function uriToPath(uri: string): string;
|
|
23
|
+
/** The follow-up method for the 2-step call ops (issued by the session after prepareCallHierarchy). */
|
|
4
24
|
export declare function callHierarchyMethod(op: "incomingCalls" | "outgoingCalls"): string;
|
|
25
|
+
/** The LSP method + params for an op (incoming/outgoing FIRST issue prepareCallHierarchy — the session 2-steps). */
|
|
5
26
|
export declare function buildRequest(op: LspOperation, params: LspRequestParams): {
|
|
6
27
|
method: string;
|
|
7
28
|
params: unknown;
|
|
8
29
|
} | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* @param fallbackUri the QUERIED document's URI — required for `documentSymbol`, whose standard reply shape
|
|
32
|
+
* (`DocumentSymbol[]`: name/range/selectionRange/children, NO uri and NO location) carries no location of its
|
|
33
|
+
* own. Without it every symbol of that shape was dropped and a perfectly good reply rendered as "No results."
|
|
34
|
+
* (HRD-LSP-6 — gopls/rust-analyzer/pyright all answer in that shape). Deliberately NOT applied to
|
|
35
|
+
* `workspaceSymbol`/call-hierarchy: those shapes always carry their own uri, and substituting the queried
|
|
36
|
+
* file's would attribute a symbol to the wrong file.
|
|
37
|
+
*/
|
|
9
38
|
export declare function parseResult(op: LspOperation, raw: unknown, fallbackUri?: string): LspResult;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { LspSession, LspOperation, LspRequestParams, LspResult, LspTransport, LspReadText } from "./lsp.js";
|
|
2
2
|
import type { LspDiagnosticsRegistry } from "./lsp-diagnostics.js";
|
|
3
3
|
export interface SessionWarmup {
|
|
4
|
+
/** Empty results within this window after session creation are retried (a freshly-spawned server answers
|
|
5
|
+
* non-blocking ops with EMPTY results while its project is still loading — the model may call
|
|
6
|
+
* hover/documentSymbol FIRST and get non-null-but-empty answers; goToDefinition happens to block on load,
|
|
7
|
+
* which is why op-order made it look random). 0 disables. */
|
|
4
8
|
windowMs: number;
|
|
5
9
|
retryMs: number;
|
|
6
10
|
}
|
|
@@ -8,30 +12,85 @@ export declare class TransportLspSession implements LspSession {
|
|
|
8
12
|
private readonly transport;
|
|
9
13
|
private readonly languageId;
|
|
10
14
|
private readonly readText;
|
|
15
|
+
/** Observability hook for swallowed degrades (graceful "none" hides real transport faults otherwise). */
|
|
11
16
|
private readonly log;
|
|
12
17
|
private readonly warmup;
|
|
18
|
+
/** filePath → the last text SENT to the server (didOpen/didChange) + its document version. */
|
|
13
19
|
private readonly opened;
|
|
20
|
+
/** HRD-LSP-19: the URI we actually SENT for each opened file → that file's `opened` key. The diagnostics
|
|
21
|
+
* staleness guard used to re-derive the key with `uriToPath(publishedUri)`, which normalizes a drive path
|
|
22
|
+
* to backslash form regardless of how the caller spelled it — so with any other spelling the lookup missed
|
|
23
|
+
* and a stale (older-version) publish sailed through the guard onto the model's screen. Keying on the URI
|
|
24
|
+
* we ourselves sent removes the round-trip entirely (`uriToPath` stays the fallback for a server that
|
|
25
|
+
* re-spells the URI). */
|
|
14
26
|
private readonly openedUris;
|
|
27
|
+
/** In-flight per-file syncs — concurrent ops on the same new file share ONE read/didOpen. Each entry owns a
|
|
28
|
+
* {@link SharedAbortScope} so ONE caller's abort no longer cancels the read the others are waiting on
|
|
29
|
+
* (HRD-LSP-12). */
|
|
15
30
|
private readonly syncing;
|
|
16
31
|
private readonly createdAt;
|
|
32
|
+
/** HRD-LSP-11: the warm-up barrier as a shared JOB, not a boolean flag set before the await (which let the
|
|
33
|
+
* second concurrent first-op skip the barrier entirely, and permanently disabled it whenever the barrier
|
|
34
|
+
* request failed or was cancelled). */
|
|
17
35
|
private warmupBarrier?;
|
|
18
36
|
private warmupDone;
|
|
19
37
|
private warmupAttempts;
|
|
20
|
-
constructor(transport: LspTransport, languageId: string, readText: LspReadText,
|
|
38
|
+
constructor(transport: LspTransport, languageId: string, readText: LspReadText,
|
|
39
|
+
/** Observability hook for swallowed degrades (graceful "none" hides real transport faults otherwise). */
|
|
40
|
+
log?: (event: string, fields: Record<string, unknown>) => void, warmup?: SessionWarmup,
|
|
41
|
+
/** design/121: when set (and the transport dispatches notifications), the session feeds this
|
|
42
|
+
* registry from `textDocument/publishDiagnostics` — with version-staleness protection: a
|
|
43
|
+
* notification versioned OLDER than the text this session last SENT for that file is dropped
|
|
44
|
+
* (the server is still churning on stale content). Absent ⇒ pre-121 behavior byte-for-byte. */
|
|
45
|
+
diagnostics?: LspDiagnosticsRegistry);
|
|
46
|
+
/** HRD-LSP-16: ops in flight on this session. The manager consults it before LRU/idle-evicting a server —
|
|
47
|
+
* closing one mid-op turns a healthy answer into `server_terminated` for a caller that did nothing wrong. */
|
|
21
48
|
get inFlight(): number;
|
|
22
49
|
private activeRequests;
|
|
23
50
|
request(op: LspOperation, params: LspRequestParams, signal?: AbortSignal): Promise<LspResult>;
|
|
24
51
|
private requestOnce;
|
|
52
|
+
/**
|
|
53
|
+
* HRD-LSP-11: run (or join) this session's ONE warm-up barrier.
|
|
54
|
+
*
|
|
55
|
+
* The old form set a boolean BEFORE awaiting the barrier request, so a second concurrent first-op read
|
|
56
|
+
* `true` and fired its real request into a still-loading project (an empty answer retries, but a PARTIAL
|
|
57
|
+
* non-empty symbol/reference list is accepted as complete — the silent half). And because the flag was
|
|
58
|
+
* never cleared, any failure/abort of that one request disabled the barrier for the session's whole life.
|
|
59
|
+
* Now: joiners await the same job, a failed barrier is re-armed (bounded by {@link WARMUP_MAX_ATTEMPTS}),
|
|
60
|
+
* and one caller's abort neither cancels the shared barrier nor makes the others wait for it.
|
|
61
|
+
*/
|
|
25
62
|
private warmupBarrierOnce;
|
|
63
|
+
/** Re-sync every opened file (+ the queried one) with its CURRENT on-disk text, in parallel. Returns the
|
|
64
|
+
* QUERIED file's outcome — the one the op's honesty depends on (HRD-LSP-7). */
|
|
26
65
|
private syncOpenedFiles;
|
|
66
|
+
/** didOpen a new file / didChange (full-text replace) an opened one whose disk content moved. Never throws:
|
|
67
|
+
* it REPORTS failure instead (`{ok:false}`) — an unreadable file no longer looks like a clean sync to the
|
|
68
|
+
* caller. Concurrent callers share one in-flight sync, each keeping its OWN cancellation (HRD-LSP-12). */
|
|
27
69
|
private syncOne;
|
|
70
|
+
/** RB-232: structural fallback classification for errors carrying no {@link lspFailureOf} brand (a
|
|
71
|
+
* third-party transport, e.g. the TOB WS lane) — abort signal and transport liveness are the only
|
|
72
|
+
* transport-neutral facts available; everything else is a server fault. Cannot produce
|
|
73
|
+
* "unsupported_operation" until that transport brands its JSON-RPC error codes (cross-repo slip). */
|
|
28
74
|
private static classifyUnbranded;
|
|
75
|
+
/** Underlying connection gone (e.g. the server crashed / the WS was idle-killed) → the manager evicts + reopens. */
|
|
29
76
|
get closed(): boolean;
|
|
77
|
+
/** Files didOpen'd on this server — the manager carries them to a HEALED session: a fresh server with no
|
|
78
|
+
* project config only "sees" its open files (e.g. tsserver inferred project), so without the carry-over,
|
|
79
|
+
* cross-file ops (references/calls) silently degrade to single-file after a heal. */
|
|
30
80
|
openedFiles(): string[];
|
|
81
|
+
/** Re-open carried files on a fresh session (heal). Best-effort per file (a deleted file just skips).
|
|
82
|
+
* Returns how many files did NOT make it, so the manager's heal log can say when a carry-over was lost
|
|
83
|
+
* instead of leaving a silently single-file server behind (HRD-LSP-1 disclosure half). */
|
|
31
84
|
warmOpen(filePaths: string[], signal?: AbortSignal): Promise<{
|
|
32
85
|
opened: number;
|
|
33
86
|
failed: number;
|
|
34
87
|
}>;
|
|
88
|
+
/**
|
|
89
|
+
* design/121: push the file's CURRENT text to the server WITHOUT an op (didOpen/didChange as
|
|
90
|
+
* appropriate). The agent's edit/write tools call this fire-and-forget so the server re-analyzes
|
|
91
|
+
* and pushes publishDiagnostics — the session's normal lazy sync only runs on the next LSP op,
|
|
92
|
+
* which may never come. Never throws (same best-effort contract as syncOne).
|
|
93
|
+
*/
|
|
35
94
|
notifyFileChanged(filePath: string, signal?: AbortSignal): Promise<void>;
|
|
36
95
|
close(): Promise<void>;
|
|
37
96
|
}
|