@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
package/dist/tools/web.d.ts
CHANGED
|
@@ -2,10 +2,33 @@ import type { AgentTool } from "../internal/harness-types.js";
|
|
|
2
2
|
import type { Brain, ToolSpec } from "../core/types.js";
|
|
3
3
|
import type { Model } from "../internal/llm.js";
|
|
4
4
|
export interface WebFetchConfig {
|
|
5
|
+
/** If set, ONLY these hostnames may be fetched (exact host match) — and the allowlist is enforced on
|
|
6
|
+
* **every redirect hop**, not just the initial URL (a redirect to a non-allowlisted host is refused
|
|
7
|
+
* before the request is made). Omitted ⇒ no host restriction (the deployment's tool-policy gate is then
|
|
8
|
+
* the only control — wire one for a multi-tenant deployment). */
|
|
5
9
|
allowHosts?: string[];
|
|
10
|
+
/** Injectable fetch (tests / a proxy). Defaults to the global `fetch`. */
|
|
6
11
|
fetchImpl?: typeof fetch;
|
|
12
|
+
/** Max response bytes to read (default 2 MB). */
|
|
7
13
|
maxBytes?: number;
|
|
14
|
+
/** Wall-clock budget for the whole fetch (connect + redirects + body read), in ms. Default 30 000.
|
|
15
|
+
* Without a local timeout, an unreachable host in a no-egress environment hangs until the OS-level
|
|
16
|
+
* TCP timeout (60-120 s+) — an agent that retries then burns wall-clock on nothing. On expiry the
|
|
17
|
+
* tool returns a routable error string, so the model can move on. */
|
|
8
18
|
timeoutMs?: number;
|
|
19
|
+
/** Optional sub-model extraction: given the (markdown) content + the caller's prompt, return a focused
|
|
20
|
+
* answer. Its output is still derived from untrusted content, so it too is returned fenced.
|
|
21
|
+
*
|
|
22
|
+
* Pre-2.13 review F1 (additive): the object return form lets a summarizer report that its own OUTPUT
|
|
23
|
+
* was cut (`truncated: true` — e.g. the sub-model hit max_tokens) as structured fact. The tool then
|
|
24
|
+
* renders the disclosure OUTSIDE the untrusted fence (a page must not be able to forge it) and stamps
|
|
25
|
+
* `details.truncated`. A plain-string return still works and claims a complete summary.
|
|
26
|
+
*
|
|
27
|
+
* ruled 2026-08-05 (grounding contract): the object form additionally carries `inputTruncated` — the
|
|
28
|
+
* summarizer did not SEE the whole page, because the content exceeded what it could feed its model.
|
|
29
|
+
* That is a different fact from `truncated` (the answer was cut) and used to be invisible: a summarizer
|
|
30
|
+
* silently clipping its input returned a plain string, and the tool then presented an answer derived
|
|
31
|
+
* from a prefix as an answer about the page. `inputChars`/`usedChars` size the gap for the disclosure. */
|
|
9
32
|
summarize?: (content: string, prompt: string, signal?: AbortSignal) => Promise<string | {
|
|
10
33
|
text: string;
|
|
11
34
|
truncated?: boolean;
|
|
@@ -13,27 +36,139 @@ export interface WebFetchConfig {
|
|
|
13
36
|
inputChars?: number;
|
|
14
37
|
usedChars?: number;
|
|
15
38
|
}>;
|
|
39
|
+
/** User-Agent header sent with every hop (批② P2-3). Default {@link DEFAULT_WEBFETCH_USER_AGENT};
|
|
40
|
+
* a deployment can brand it (CC sends `Claude-User (<cc ua>; +https://support.anthropic.com/)`). */
|
|
16
41
|
userAgent?: string;
|
|
17
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Grounding floor for a fetched page (ruled 2026-08-05, WebFetch grounding contract).
|
|
45
|
+
*
|
|
46
|
+
* A page that returns almost no EXTRACTABLE TEXT — the client-rendered shell whose whole body is a
|
|
47
|
+
* script tag plus an empty mount div is the canonical shape — still produces a perfectly well-formed
|
|
48
|
+
* summary when it is handed to an extraction sub-model, because "there is nothing here" is not an answer
|
|
49
|
+
* the model is asked for. The summary then travels inside the untrusted fence with no marker separating
|
|
50
|
+
* "derived from the page" from "invented to fill the shape of the question", and the caller has no way
|
|
51
|
+
* to tell the two apart. The bytes are the discriminator: below this floor the tool stops presenting the
|
|
52
|
+
* summary as a source and says what it actually got.
|
|
53
|
+
*
|
|
54
|
+
* 200 characters is deliberately low — high enough that a JS shell (typically under 100 chars of text,
|
|
55
|
+
* often zero) is always caught, low enough that a real but terse page (a short API response, a plain-text
|
|
56
|
+
* status endpoint) is the only false positive. A terse page is NOT accused of being unsupportable: the
|
|
57
|
+
* disclosure states the measurement and reproduces the source, which is true and useful either way. The
|
|
58
|
+
* tool genuinely cannot distinguish "this URL serves fourteen characters and they are the answer" from
|
|
59
|
+
* "this URL serves a shell", so it says what it measured instead of ruling on which one happened.
|
|
60
|
+
*/
|
|
18
61
|
export declare const WEBFETCH_GROUNDING_MIN_TEXT_CHARS = 200;
|
|
62
|
+
/** Structured grounding verdict for one fetch — rides `details.grounding` (additive) so a deployment can
|
|
63
|
+
* gate on the same fact the model-facing disclosure is built from, instead of parsing prose. */
|
|
19
64
|
export interface WebFetchGrounding {
|
|
65
|
+
/** `"low"` ⇒ the extracted text is below {@link WEBFETCH_GROUNDING_MIN_TEXT_CHARS}. */
|
|
20
66
|
level: "ok" | "low";
|
|
67
|
+
/** Extracted text length after markup removal, whitespace-collapsed. */
|
|
21
68
|
textChars: number;
|
|
69
|
+
/** Size of the body this verdict was measured against — the same value the details card reports as
|
|
70
|
+
* `bytes`, i.e. wire bytes when the response was read as bytes, characters on a `text()`-only injected
|
|
71
|
+
* fetch, and the KEPT prefix (not the original object) whenever the byte cap or a cut applied. The
|
|
72
|
+
* denominator of {@link textRatio}. */
|
|
22
73
|
bytes: number;
|
|
74
|
+
/** `textChars / bytes`, rounded to 3 decimals; 0 when nothing was retrieved. A ratio near 0 with a
|
|
75
|
+
* large `bytes` is the markup/script-dominated shape; near 1 is plain text. */
|
|
23
76
|
textRatio: number;
|
|
24
77
|
}
|
|
25
78
|
export declare function htmlToText(html: string): string;
|
|
26
79
|
export declare function webFetchToolSpec(config?: WebFetchConfig): ToolSpec;
|
|
80
|
+
/** Defined (harness) form of web_fetch — back-compat for direct execution / tests. For `spec.tools`, use the raw
|
|
81
|
+
* {@link webFetchToolSpec} (prepare-task defineTool-wraps spec.tools entries). */
|
|
27
82
|
export declare function createWebFetchTool(config?: WebFetchConfig): AgentTool;
|
|
83
|
+
/** {@link createWebFetchSummarizer}'s truncation bound — CC's `MAX_MARKDOWN_LENGTH`
|
|
84
|
+
* (WebFetchTool/utils.ts:128). Exported so a deployment wiring the reference summarizer doesn't need
|
|
85
|
+
* its own copy of this number to reason about (黑板 [1900]/[1902] — server asked for this explicitly,
|
|
86
|
+
* to avoid a value-copy of the truncation threshold drifting from this one). */
|
|
28
87
|
export declare const WEBFETCH_SUMMARY_MAX_CONTENT = 100000;
|
|
88
|
+
/** {@link createWebFetchSummarizer}'s fixed guidelines block — CC's `makeSecondaryModelPrompt`
|
|
89
|
+
* (WebFetchTool/prompt.ts, non-preapproved-domain arm, guidelines verbatim). Exported alongside
|
|
90
|
+
* {@link WEBFETCH_SUMMARY_MAX_CONTENT} for the same reason (黑板 [1900]/[1902]): a deployment composing
|
|
91
|
+
* its OWN summarizer (not this reference one) that still wants CC-parity guidance text doesn't need its
|
|
92
|
+
* own copy of this string. Not runtime-parameterized — the page content and the caller's `prompt` are
|
|
93
|
+
* interpolated AROUND this block, never inside it. */
|
|
29
94
|
export declare const WEBFETCH_SUMMARY_GUIDELINES: string;
|
|
95
|
+
/**
|
|
96
|
+
* sema's own grounding clause for the reference summarizer (ruled 2026-08-05), kept OUT of
|
|
97
|
+
* {@link WEBFETCH_SUMMARY_GUIDELINES} so that block stays the byte-verbatim CC anchor it is documented to
|
|
98
|
+
* be. Interpolated BEFORE it, so the CC block remains the prompt's fixed tail.
|
|
99
|
+
*
|
|
100
|
+
* Two failure modes observed in the field, both of which produce a confident, well-formed, wrong answer:
|
|
101
|
+
* · a page with no substantive content still gets a specific answer written for it (the code-side
|
|
102
|
+
* grounding floor catches the extreme case, but the model is the only one that can decline mid-band);
|
|
103
|
+
* · a listing of resources is judged relevant or irrelevant from the NAMES in it — "none of these files
|
|
104
|
+
* mention X, so this source has nothing on X" — which reports a property of a naming convention as a
|
|
105
|
+
* property of the data, and sends the caller away from a source that did hold the answer.
|
|
106
|
+
* Both are instructions to report the absence rather than to resolve it, which is why they belong in the
|
|
107
|
+
* prompt rather than in a post-hoc check.
|
|
108
|
+
*/
|
|
30
109
|
export declare const WEBFETCH_SUMMARY_GROUNDING_CLAUSE: string;
|
|
110
|
+
/**
|
|
111
|
+
* Characters of page content the reference summarizer will feed its model, derived from that model's own
|
|
112
|
+
* declared window (ruled 2026-08-05). Previously the only bound was the flat CC-parity
|
|
113
|
+
* {@link WEBFETCH_SUMMARY_MAX_CONTENT}, which is a property of the PAGE side and says nothing about the
|
|
114
|
+
* model on the other end: a small-window extraction model — the usual choice, since this is the "small
|
|
115
|
+
* fast model" leg — was handed ~100 000 characters and the whole call failed, so the caller got the
|
|
116
|
+
* "summarization failed" fallback (a raw dump that is then truncated anyway) instead of an answer.
|
|
117
|
+
*
|
|
118
|
+
* `headroom` exists because the character→token estimate is a floor, not a bound: {@link Model.charsPerToken}
|
|
119
|
+
* defaults to 4, and dense content (CJK, JSON, code, long URLs) tokenizes well below that, so a budget
|
|
120
|
+
* computed at face value overshoots exactly on the pages large enough to matter. The result is still
|
|
121
|
+
* clamped by the CC constant, so no deployment's input grows because of this.
|
|
122
|
+
*/
|
|
31
123
|
export declare const WEBFETCH_SUMMARY_INPUT_HEADROOM = 0.8;
|
|
124
|
+
/**
|
|
125
|
+
* Floor for the derived budget. A model whose declared dimensions leave no room after the output
|
|
126
|
+
* reservation still gets a small excerpt rather than a computation that lands at or below zero and feeds
|
|
127
|
+
* the summarizer an empty page — a call that cannot possibly answer is strictly worse than one that might.
|
|
128
|
+
*
|
|
129
|
+
* Honest scope (adversarial review round 1): this is a FLOOR, not a proof of fit. With the output
|
|
130
|
+
* reservation bounded at window/4 (see `resolveSummaryInputChars`), the floor now fires only on genuinely
|
|
131
|
+
* tiny windows (roughly under 3k tokens at the default chars-per-token) — a model whose declared
|
|
132
|
+
* dimensions leave no room gets a small excerpt whose attempt often succeeds anyway, and a failure is
|
|
133
|
+
* already disclosed by the tool's "summarization failed" head-note rather than swallowed.
|
|
134
|
+
* Refusing at construction instead was considered and declined: `maxTokens` is commonly declared equal to
|
|
135
|
+
* the window by providers of small models, so refusing would reject deployments that work today.
|
|
136
|
+
*/
|
|
32
137
|
export declare const WEBFETCH_SUMMARY_MIN_CONTENT = 4000;
|
|
138
|
+
/**
|
|
139
|
+
* Resolve the page-content budget for {@link createWebFetchSummarizer} against `model`'s window.
|
|
140
|
+
* An explicit `override` wins outright (a deployment that measured its own model beats an estimate).
|
|
141
|
+
*
|
|
142
|
+
* Fail-loud on every non-finite input, same posture as {@link resolveWebMaxBytes} (adversarial review
|
|
143
|
+
* round 1): a `NaN` anywhere in the model's declared dimensions propagates through the arithmetic and out
|
|
144
|
+
* through `Math.min`/`Math.max` unchanged, and a `NaN` budget makes `content.length > budget` false — so
|
|
145
|
+
* the clip silently stops happening and the whole oversize page is fed to the model, which is the failure
|
|
146
|
+
* this function exists to prevent, restored by a different door. An `override` below 1 is refused for the
|
|
147
|
+
* same reason in reverse: it floors to 0 and feeds the model an empty page.
|
|
148
|
+
*/
|
|
33
149
|
export declare function resolveSummaryInputChars(model: Model, override?: number): number;
|
|
150
|
+
/** Options for {@link createWebFetchSummarizer}. */
|
|
34
151
|
export interface WebFetchSummarizerOptions {
|
|
152
|
+
/** Override the derived page-content budget (see {@link resolveSummaryInputChars}). */
|
|
35
153
|
maxContentChars?: number;
|
|
36
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* 黑板 [1870] L1 / [1900] — a reference {@link WebFetchConfig.summarize} implementation: reuses a
|
|
157
|
+
* caller-supplied `brain` (rather than requiring a dedicated second model) to extract a focused answer
|
|
158
|
+
* from fetched content per the caller's `prompt`, instead of the tool dumping the whole (fenced, still
|
|
159
|
+
* untrusted) page. CC ALWAYS routes fetched content through a secondary model this way
|
|
160
|
+
* (WebFetchTool/utils.ts:484-530); a deployment that omits `summarize` entirely gets `webFetchToolSpec`'s
|
|
161
|
+
* own honest "summarization unavailable in this deployment" head-note + raw dump instead — never a
|
|
162
|
+
* silent one. Prompt shape matches CC's non-preapproved-domain secondary-model prompt (WebFetchTool/
|
|
163
|
+
* prompt.ts `makeSecondaryModelPrompt`, guidelines block verbatim).
|
|
164
|
+
*
|
|
165
|
+
* Not the only valid implementation — a deployment with a genuinely separate summarization model/service
|
|
166
|
+
* can supply its own function of the same shape to `WebFetchConfig.summarize` instead. This one exists so
|
|
167
|
+
* "just reuse whatever brain/model I already have" doesn't have to be reinvented per deployment; it was
|
|
168
|
+
* previously a private copy inside this package's own `sema-tb` CLI entry point, promoted here so other
|
|
169
|
+
* deployments (a server assembling `WebFetchConfig` for its own scenarios, for one) can reuse it directly
|
|
170
|
+
* rather than re-deriving it from source.
|
|
171
|
+
*/
|
|
37
172
|
export declare function createWebFetchSummarizer(brain: Brain, model: Model, options?: WebFetchSummarizerOptions): (content: string, prompt: string, signal?: AbortSignal) => Promise<string | {
|
|
38
173
|
text: string;
|
|
39
174
|
truncated?: boolean;
|
|
@@ -41,7 +176,23 @@ export declare function createWebFetchSummarizer(brain: Brain, model: Model, opt
|
|
|
41
176
|
inputChars?: number;
|
|
42
177
|
usedChars?: number;
|
|
43
178
|
}>;
|
|
179
|
+
/**
|
|
180
|
+
* design/102 (K-8 CC full-body) — WebSearch (BRAIN / model-service leg). The search BACKEND is deployment-injected
|
|
181
|
+
* (provider-native search / a search API / an MCP-backed service); core ships NONE — the same boundary as
|
|
182
|
+
* {@link WebFetchConfig.summarize} and the model gateway. Absent backend ⇒ the tool is not assembled
|
|
183
|
+
* ({@link assembleCodeTools} only pushes it when `search` is wired). Results are UNTRUSTED external data —
|
|
184
|
+
* {@link delimitUntrusted}-fenced like web_fetch. 🔴 `effect:"read"`, NO `egress` field: a search is
|
|
185
|
+
* idempotent/retryable; declaring `egress:true` would throw at prep (`config.egress_requires_write_effect`) AND
|
|
186
|
+
* break resume-safety (a read reconciles as safe-to-retry, a write/egress one does not).
|
|
187
|
+
*/
|
|
44
188
|
export interface WebSearchConfig {
|
|
189
|
+
/**
|
|
190
|
+
* Deployment-injected search backend. core ships none. The optional `opts` carries the model's per-call
|
|
191
|
+
* `allowed_domains`/`blocked_domains` HINTS so a backend that supports native domain filtering (e.g. a
|
|
192
|
+
* `site:` query) can apply them up front. A backend MAY ignore `opts` — core re-enforces the domain
|
|
193
|
+
* constraint on the returned results as a floor (see `createWebSearchTool`), so honoring it is an
|
|
194
|
+
* optimization, not a correctness requirement. Back-compat: existing 2-arg backends keep working.
|
|
195
|
+
*/
|
|
45
196
|
search: (query: string, signal?: AbortSignal, opts?: {
|
|
46
197
|
allowedDomains?: string[];
|
|
47
198
|
blockedDomains?: string[];
|
|
@@ -50,17 +201,50 @@ export interface WebSearchConfig {
|
|
|
50
201
|
url: string;
|
|
51
202
|
snippet: string;
|
|
52
203
|
}>>;
|
|
204
|
+
/** Max results returned to the model (default 10). */
|
|
53
205
|
maxResults?: number;
|
|
206
|
+
/** Wall-clock budget for one `search` call, in ms. Default 30 000 (RB-231, 黑板 [1937]). The backend is
|
|
207
|
+
* deployment-injected and may ignore the AbortSignal entirely, so this is enforced with BOTH an abort
|
|
208
|
+
* and a race — a hung backend must not hang the turn, and without this the deployment had no interface
|
|
209
|
+
* to bound it. */
|
|
54
210
|
timeoutMs?: number;
|
|
55
211
|
}
|
|
212
|
+
/** Clip by CODE POINT (RB-122/RB-142/RB-147 family: a UTF-16 `.slice` can split a surrogate pair). Clips
|
|
213
|
+
* RAW field text; `delimitUntrusted` owns the neutralization afterwards — clipping with `inlineUntrusted`
|
|
214
|
+
* here would fold newlines and double-neutralize. Exported for the RB-142 D-1 enumerative clipper guard
|
|
215
|
+
* (defectscan-truncation-invariant-surface) — not on the npm face (src/index.ts does not re-export it). */
|
|
56
216
|
export declare function clipCodePoints(s: string, max: number): string;
|
|
57
217
|
export declare function createWebSearchTool(config: WebSearchConfig): ToolSpec;
|
|
218
|
+
/** Options for {@link createSearxngSearchBackend}. */
|
|
58
219
|
export interface SearxngBackendOptions {
|
|
220
|
+
/** Injected fetch (tests / exotic runtimes). Defaults to `globalThis.fetch`. */
|
|
59
221
|
fetchImpl?: typeof fetch;
|
|
222
|
+
/** Per-request wall clock in ms before the request is aborted. Defaults to 10 000 — well inside
|
|
223
|
+
* WebSearchConfig's own 30 s budget so the tool-level race never fires first on a healthy instance. */
|
|
60
224
|
timeoutMs?: number;
|
|
225
|
+
/** Extra query parameters appended to every /search call (e.g. `{ language: "zh-CN" }`). */
|
|
61
226
|
extraParams?: Record<string, string>;
|
|
62
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* design/162 (core half) — a {@link WebSearchConfig.search} backend speaking SearXNG's JSON API
|
|
230
|
+
* (`GET <baseUrl>/search?q=…&format=json`). The zero-key rung of the search fallback chain: the shell
|
|
231
|
+
* installs and health-checks a local SearXNG instance; a deployment then assembles this backend from
|
|
232
|
+
* nothing but the base URL. core owns NO process management — a dead instance surfaces as the thrown
|
|
233
|
+
* fetch/HTTP error, which `createWebSearchTool` already fences and bounds (SEARCH_ERROR_EXCERPT_CHARS).
|
|
234
|
+
*
|
|
235
|
+
* The model's `allowed_domains` hint maps to a `site:` query prefix (SearXNG forwards it to engines
|
|
236
|
+
* that understand it) — an OPTIMIZATION only: the tool re-enforces the domain constraint on returned
|
|
237
|
+
* results either way, so a backend ignoring the hint is correct, just wasteful. `blocked_domains` has
|
|
238
|
+
* no reliable engine-side spelling and is left entirely to the tool's own floor.
|
|
239
|
+
*
|
|
240
|
+
* Result mapping keeps the strict {title, url, snippet} shape: SearXNG's `content` field is the
|
|
241
|
+
* snippet; rows missing a url are dropped (an engine-side info box, not a citable result).
|
|
242
|
+
*/
|
|
63
243
|
export declare function createSearxngSearchBackend(baseUrl: string, options?: SearxngBackendOptions): WebSearchConfig["search"];
|
|
244
|
+
/**
|
|
245
|
+
* One live probe of a search backend (design/162 onboarding convenience): calls it with a fixed
|
|
246
|
+
* cheap query and classifies the outcome. Never throws — the classification IS the answer.
|
|
247
|
+
*/
|
|
64
248
|
export declare function probeSearchBackend(search: WebSearchConfig["search"], options?: {
|
|
65
249
|
timeoutMs?: number;
|
|
66
250
|
}): Promise<{
|
package/dist/tools/worktree.d.ts
CHANGED
|
@@ -1,14 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 审计[485]③ / 深挖 G4 — the `EnterWorktree` / `ExitWorktree` tool pair: SESSION-level git-worktree
|
|
3
|
+
* isolation (CC 2.1.198 parity). EnterWorktree creates a managed worktree under `.sema-worktrees/`
|
|
4
|
+
* (the same {@link WORKTREE_PARENT} the subagent `isolation:"worktree"` lane uses) and REALLY switches
|
|
5
|
+
* the task's working directory into it; ExitWorktree returns to the original directory and cleans up.
|
|
6
|
+
*
|
|
7
|
+
* CC-parity semantics (198 bundle, verbatim-checked):
|
|
8
|
+
* ① worktrees live in a managed parent dir inside the repo (CC: `.claude/worktrees/`; sema:
|
|
9
|
+
* `.sema-worktrees/`) — never scattered;
|
|
10
|
+
* ② baseRef is two-state: `"head"` = the current local HEAD (unpushed commits present), `"fresh"` =
|
|
11
|
+
* the default branch tip (CC: `origin/<default-branch>` for a clean tree);
|
|
12
|
+
* ③ a second CREATING EnterWorktree (`name`) while one is active is REFUSED ("Already in a worktree
|
|
13
|
+
* session" — CC errorCode 2); switching into an EXISTING worktree via `path` is allowed (深对比残差
|
|
14
|
+
* M22 RESOLVED, live-CC anchor 2026-07-09: the previous worktree is left on disk untouched, only the
|
|
15
|
+
* new one is tracked for exit-time cleanup, and a path-entered tree is NEVER removed by ExitWorktree);
|
|
16
|
+
* ④ ExitWorktree outside a session is an honest NO-OP (CC errorCode 1), and a worktree with
|
|
17
|
+
* uncommitted files or commits is NOT deleted by default (CC refuses `remove` without
|
|
18
|
+
* `discard_changes`; sema keeps it and reports the path — inspect/merge in userland);
|
|
19
|
+
* ⑤ outside a git repository CC delegates to WorktreeCreate/WorktreeRemove hooks — sema has no such
|
|
20
|
+
* shell extension point, so the tool says so honestly and refuses (no silent degrade).
|
|
21
|
+
*
|
|
22
|
+
* cwd architecture (the load-bearing conclusion): the task's working directory IS mutable state — the
|
|
23
|
+
* hands band shares one {@link CwdRef} (`handsCwdRef` in prepare-task): Bash runs every command in
|
|
24
|
+
* `cwdRef.current` (and `cd` moves it), Read/Edit/Write resolve relative paths against it, Monitor
|
|
25
|
+
* spawns there. EnterWorktree therefore performs a REAL switch by assigning `cwdRef.current`; the
|
|
26
|
+
* Runner's per-tool cwd read reports it as `workspace_changed`, same as an observed `cd`. Path
|
|
27
|
+
* containment is untouched: the worktree lives UNDER the task root, so resolveKey's canonical-within
|
|
28
|
+
* check still holds for every subsequent fs op.
|
|
29
|
+
*
|
|
30
|
+
* ⚠️ Containment ruling (codex 终审 1.255 F4, deliberate): entering a worktree is a **cwd switch, NOT a
|
|
31
|
+
* sandbox**. resolveKey's containment anchor stays the ORIGINAL task root — it is deliberately NOT
|
|
32
|
+
* re-anchored/tightened to the worktree dir, so `../../` from inside the worktree can still reach the
|
|
33
|
+
* rest of the repository (which is WITHIN the task root and was reachable before Enter too), while
|
|
34
|
+
* anything outside the task root stays fenced exactly as before. This matches CC 2.1.198 semantics
|
|
35
|
+
* (CC worktrees live beside the repo with no containment tightening either); tightening here would buy
|
|
36
|
+
* no security (Bash/`cd` already roam the root) and would break legitimate repo-relative access. The
|
|
37
|
+
* tool description + Enter reply state this honestly so the model never assumes isolation.
|
|
38
|
+
*
|
|
39
|
+
* Security posture: both tools only ever run `git` against the task root / managed worktree (no
|
|
40
|
+
* arbitrary command surface), but they create/delete on-disk state ⇒ effect:"write" (plan mode gates
|
|
41
|
+
* them like every other write tool; read-only hands never mount them — see prepare-task).
|
|
42
|
+
*
|
|
43
|
+
* Durability (codex 终审 1.255 F2): the active session lives in a SHARED, ALL-SERIALIZABLE
|
|
44
|
+
* {@link WorktreeSessionRef} owned by prepare-task (never a closure-only var, and no captured destroy
|
|
45
|
+
* closure — Exit re-derives removal as a plain `git worktree remove`). A durable suspend stamps it into
|
|
46
|
+
* `CheckpointState.activeWorktree` (+ the cwd into `handsCwd`); resume re-seeds both, so
|
|
47
|
+
* Enter→suspend→resume→Exit behaves exactly like an unsuspended session.
|
|
48
|
+
*/
|
|
1
49
|
import type { ActiveWorktreeSession, AgentTool, ExecutionEnv } from "../internal/harness-types.js";
|
|
2
50
|
import type { CwdRef } from "./fs/index.js";
|
|
51
|
+
/** codex 终审 1.255 F2 — the ACTIVE worktree session, ALL-SERIALIZABLE (plain strings, no closures):
|
|
52
|
+
* prepare-task owns the ref, stamps `current` into `CheckpointState.activeWorktree` at a durable
|
|
53
|
+
* suspend, and re-seeds it on resume, so ExitWorktree works across the suspend/resume boundary (the
|
|
54
|
+
* tree survives on disk; removal is re-derived as a plain `git worktree remove`).
|
|
55
|
+
*
|
|
56
|
+
* REF-D3/D4: canonical definition moved to `engine/harness/types.ts` (the harness layer must never
|
|
57
|
+
* import FROM `tools/`, so it cannot point back at a definition declared here); this re-export keeps
|
|
58
|
+
* the existing `ActiveWorktreeSession` import path (including the public one via `src/index.ts`)
|
|
59
|
+
* unchanged for every consumer. */
|
|
3
60
|
export type { ActiveWorktreeSession };
|
|
61
|
+
/** The shared mutable holder for {@link ActiveWorktreeSession} — the worktree twin of {@link CwdRef}. */
|
|
4
62
|
export interface WorktreeSessionRef {
|
|
5
63
|
current?: ActiveWorktreeSession;
|
|
64
|
+
/** HRD-PTL-8 — an ExitWorktree call is in flight on `current`. RUNTIME-ONLY (deliberately not part of
|
|
65
|
+
* the durable `CheckpointState.activeWorktree` projection: a suspend cannot happen inside the exit's
|
|
66
|
+
* own await chain, and a resumed process has no in-flight exit by definition). A concurrent or
|
|
67
|
+
* re-entrant Exit reads this and is refused honestly instead of being told no session is active. */
|
|
6
68
|
exiting?: boolean;
|
|
69
|
+
/** HRD-PTL-13 — an EnterWorktree call is in flight on this ref (either form). RUNTIME-ONLY, same
|
|
70
|
+
* rationale as {@link exiting}. The single-session rule cannot be enforced by reading `current` alone:
|
|
71
|
+
* the create path assigns it only after several awaits, so two overlapping calls would both pass that
|
|
72
|
+
* check and both create a worktree, leaving the earlier one untracked (see the guard in EnterWorktree
|
|
73
|
+
* for the CAS-reject-vs-serialize trade-off). */
|
|
7
74
|
entering?: boolean;
|
|
8
75
|
}
|
|
9
76
|
export interface WorktreeToolsOptions {
|
|
77
|
+
/** The task root (the repo root the managed worktrees nest under; `git` runs `-C` here). */
|
|
10
78
|
repoRoot: string;
|
|
79
|
+
/** The task's shared mutable working directory (the hands band's `handsCwdRef`) — EnterWorktree
|
|
80
|
+
* assigns it to the worktree path (a REAL cwd switch: Bash/Read/Edit/Write/Monitor all follow),
|
|
81
|
+
* ExitWorktree restores it. */
|
|
11
82
|
cwdRef: CwdRef;
|
|
83
|
+
/** codex 终审 1.255 F2: the shared session-state ref (checkpointable — prepare-task serializes it into
|
|
84
|
+
* the durable checkpoint and re-seeds it on resume). Omitted ⇒ a private per-mount ref (same live
|
|
85
|
+
* behavior, minus durable-suspend survival — prepare-task always passes one). */
|
|
12
86
|
session?: WorktreeSessionRef;
|
|
13
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Build the EnterWorktree/ExitWorktree pair. One session-state closure per mount (= per task): the
|
|
90
|
+
* active worktree handle lives here, never in a model argument. Mounted by prepare-task only when the
|
|
91
|
+
* task has real write hands over a tracked cwd (`handsCwdRef` exists — same premise family as the
|
|
92
|
+
* Monitor mount); git-ness is probed honestly at Enter time (same posture as the subagent
|
|
93
|
+
* worktree-isolation helper — no per-task prepare-time git exec).
|
|
94
|
+
*/
|
|
14
95
|
export declare function createWorktreeTools(env: ExecutionEnv, opts: WorktreeToolsOptions): AgentTool[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/core",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.21.1",
|
|
4
4
|
"description": "Stateless, task-oriented AI agent core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BUSL-1.1",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"node": ">=20.3.0"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
|
-
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
48
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && tsc -p tsconfig.build.json --emitDeclarationOnly --removeComments false",
|
|
49
49
|
"typecheck": "tsc --noEmit",
|
|
50
50
|
"test": "vitest run --exclude \"**/*.local.test.ts\"",
|
|
51
51
|
"test:watch": "vitest",
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { ToolSpec } from "../core/types.js";
|
|
2
|
-
export interface GiteaIssueToolOptions {
|
|
3
|
-
baseUrl: string;
|
|
4
|
-
owner: string;
|
|
5
|
-
repo: string;
|
|
6
|
-
token: string;
|
|
7
|
-
defaultLabels?: number[];
|
|
8
|
-
allowModelLabels?: boolean;
|
|
9
|
-
name?: string;
|
|
10
|
-
description?: string;
|
|
11
|
-
fetchImpl?: typeof fetch;
|
|
12
|
-
}
|
|
13
|
-
export declare function createGiteaIssueTool(opts: GiteaIssueToolOptions): ToolSpec;
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { Type } from "typebox";
|
|
2
|
-
export function createGiteaIssueTool(opts) {
|
|
3
|
-
const doFetch = opts.fetchImpl ?? fetch;
|
|
4
|
-
const root = opts.baseUrl.replace(/\/+$/, "");
|
|
5
|
-
const url = `${root}/api/v1/repos/${encodeURIComponent(opts.owner)}/${encodeURIComponent(opts.repo)}/issues`;
|
|
6
|
-
const properties = {
|
|
7
|
-
title: Type.String({ description: "A concise, specific issue title." }),
|
|
8
|
-
body: Type.Optional(Type.String({ description: "Markdown body: what's wrong / what's wanted, steps, context, and any evidence." })),
|
|
9
|
-
};
|
|
10
|
-
if (opts.allowModelLabels) {
|
|
11
|
-
properties.labels = Type.Optional(Type.Array(Type.Integer(), { description: "Optional Gitea label IDs (numeric) to tag this issue." }));
|
|
12
|
-
}
|
|
13
|
-
return {
|
|
14
|
-
name: opts.name ?? "open_gitea_issue",
|
|
15
|
-
effect: "write",
|
|
16
|
-
egress: true,
|
|
17
|
-
description: opts.description ??
|
|
18
|
-
`Open an issue in the ${opts.owner}/${opts.repo} repository to report a bug or file a request ` +
|
|
19
|
-
`to the maintainer. Use it when something is broken or missing and you cannot fix it yourself. ` +
|
|
20
|
-
`Provide a clear title and a body with the problem, steps, and any evidence.`,
|
|
21
|
-
parameters: Type.Object(properties),
|
|
22
|
-
execute: async (args, ctx) => {
|
|
23
|
-
const a = args;
|
|
24
|
-
const title = String(a.title ?? "").trim();
|
|
25
|
-
if (!title) {
|
|
26
|
-
return { content: "Issue not created: a non-empty title is required.", details: { error: "empty title" }, isError: true };
|
|
27
|
-
}
|
|
28
|
-
const modelLabels = opts.allowModelLabels && Array.isArray(a.labels) ? a.labels : [];
|
|
29
|
-
const labels = [...new Set([...(opts.defaultLabels ?? []), ...modelLabels])];
|
|
30
|
-
const payload = { title };
|
|
31
|
-
if (a.body !== undefined && a.body !== null)
|
|
32
|
-
payload.body = String(a.body);
|
|
33
|
-
if (labels.length > 0)
|
|
34
|
-
payload.labels = labels;
|
|
35
|
-
let res;
|
|
36
|
-
try {
|
|
37
|
-
res = await doFetch(url, {
|
|
38
|
-
method: "POST",
|
|
39
|
-
headers: { "content-type": "application/json", authorization: `token ${opts.token}` },
|
|
40
|
-
body: JSON.stringify(payload),
|
|
41
|
-
signal: ctx.signal,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
catch (e) {
|
|
45
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
46
|
-
return { content: `Issue not created: request failed (${msg}).`, details: { error: msg }, isError: true };
|
|
47
|
-
}
|
|
48
|
-
if (!res.ok) {
|
|
49
|
-
const detail = await res.text().catch(() => "");
|
|
50
|
-
return {
|
|
51
|
-
content: `Issue not created: Gitea returned HTTP ${res.status}. ${detail.slice(0, 300)}`,
|
|
52
|
-
details: { status: res.status },
|
|
53
|
-
isError: true,
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
const PARSE_FAILED = Symbol("json-parse-failed");
|
|
57
|
-
const parsed = (await res.json().catch(() => PARSE_FAILED));
|
|
58
|
-
const number = parsed !== PARSE_FAILED && typeof parsed.number === "number" ? parsed.number : undefined;
|
|
59
|
-
if (number === undefined) {
|
|
60
|
-
return {
|
|
61
|
-
content: `Issue request returned HTTP ${res.status} but the response body was not a valid issue ` +
|
|
62
|
-
`(no number) — the issue may NOT have been created; verify before retrying.`,
|
|
63
|
-
details: { status: res.status, parsed: parsed === PARSE_FAILED ? "unparseable" : "no-number" },
|
|
64
|
-
isError: true,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
const issue = parsed;
|
|
68
|
-
const link = issue.html_url ? ` — ${issue.html_url}` : "";
|
|
69
|
-
return {
|
|
70
|
-
content: `Opened issue #${number} in ${opts.owner}/${opts.repo}${link}`,
|
|
71
|
-
details: { number, url: issue.html_url },
|
|
72
|
-
};
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
}
|