@sema-agent/core 7.7.0 → 7.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/dist/agents/agent-transcript-tool.js +2 -2
- package/dist/agents/list-agents-tool.js +2 -3
- package/dist/agents/observer.js +2 -2
- package/dist/agents/send-message-tool.js +2 -1
- package/dist/agents/subagent-steps.js +5 -4
- package/dist/agents/subagent.js +2 -3
- package/dist/core/ask-question.js +2 -2
- package/dist/core/checkpoint-store.d.ts +38 -4
- package/dist/core/context-edit.d.ts +0 -22
- package/dist/core/context-edit.js +2 -11
- package/dist/core/engine-notice.d.ts +6 -0
- package/dist/core/fs-write-gate-policy.d.ts +7 -1
- package/dist/core/fs-write-gate-policy.js +7 -7
- package/dist/core/gate-fold.js +2 -2
- package/dist/core/gate-lanes.js +4 -3
- package/dist/core/governance-codes.d.ts +1 -1
- package/dist/core/governance-codes.js +6 -0
- package/dist/core/hooks.d.ts +8 -2
- package/dist/core/hooks.js +1 -1
- package/dist/core/lsp.js +2 -2
- package/dist/core/mcp-server-spec.d.ts +17 -0
- package/dist/core/mcp.js +3 -1
- package/dist/core/memory-engine/tools.js +4 -12
- package/dist/core/permission-rules.d.ts +32 -2
- package/dist/core/permission-rules.js +43 -37
- package/dist/core/present-plan-tool.js +3 -4
- package/dist/core/runner/active-skill-scope.js +7 -4
- package/dist/core/runner/compaction-call-options.d.ts +1 -1
- package/dist/core/runner/contracts.d.ts +27 -3
- package/dist/core/runner/prepare-ask-lane.d.ts +1 -1
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +5 -4
- package/dist/core/runner/prepare-caps-and-workflow.js +16 -11
- package/dist/core/runner/prepare-defer-classify.d.ts +5 -26
- package/dist/core/runner/prepare-defer-classify.js +10 -10
- package/dist/core/runner/prepare-delegation-surface.d.ts +5 -4
- package/dist/core/runner/prepare-delegation-surface.js +15 -17
- package/dist/core/runner/prepare-gate-stations.d.ts +4 -1
- package/dist/core/runner/prepare-gate-stations.js +3 -1
- package/dist/core/runner/prepare-hands-readface.d.ts +3 -2
- package/dist/core/runner/prepare-hands-readface.js +3 -2
- package/dist/core/runner/prepare-inherited-gate.d.ts +1 -1
- package/dist/core/runner/prepare-inherited-gate.js +1 -0
- package/dist/core/runner/prepare-lsp.d.ts +4 -3
- package/dist/core/runner/prepare-lsp.js +3 -2
- package/dist/core/runner/prepare-memory-engine-session.d.ts +4 -4
- package/dist/core/runner/prepare-memory-engine-session.js +4 -2
- package/dist/core/runner/prepare-offload-wrappers.js +7 -5
- package/dist/core/runner/prepare-park-ask.d.ts +4 -0
- package/dist/core/runner/prepare-park-ask.js +4 -1
- package/dist/core/runner/prepare-project-context.d.ts +5 -23
- package/dist/core/runner/prepare-project-context.js +7 -5
- package/dist/core/runner/prepare-prompt-assembly.d.ts +1 -1
- package/dist/core/runner/prepare-protocol-tools.d.ts +5 -1
- package/dist/core/runner/prepare-protocol-tools.js +38 -21
- package/dist/core/runner/prepare-question-face.d.ts +4 -3
- package/dist/core/runner/prepare-question-face.js +5 -3
- package/dist/core/runner/prepare-run-refs.d.ts +16 -0
- package/dist/core/runner/prepare-run-refs.js +6 -0
- package/dist/core/runner/prepare-safety-scan.js +42 -2
- package/dist/core/runner/prepare-task.js +37 -19
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +5 -2
- package/dist/core/runner/prepare-tool-disclosure-mount.js +3 -1
- package/dist/core/runner/prepare-wiring-manifest.d.ts +4 -0
- package/dist/core/runner/prepare-wiring-manifest.js +3 -8
- package/dist/core/runner/run-harness-handlers.d.ts +46 -0
- package/dist/core/runner/run-harness-handlers.js +345 -0
- package/dist/core/runner/run-turn-boundary.d.ts +69 -0
- package/dist/core/runner/run-turn-boundary.js +694 -0
- package/dist/core/runner/runtask.js +47 -1043
- package/dist/core/runner/session-rule-policy.js +9 -4
- package/dist/core/runner/synthetic-tools.js +5 -8
- package/dist/core/runner/tool-disclosure.d.ts +4 -0
- package/dist/core/runner/tool-disclosure.js +9 -5
- package/dist/core/runner/tool-end-body.js +3 -2
- package/dist/core/runner/tool-face-overlay.d.ts +40 -0
- package/dist/core/runner/tool-face-overlay.js +125 -0
- package/dist/core/runner/tool-output-projection.d.ts +10 -0
- package/dist/core/runner/tool-output-projection.js +33 -10
- package/dist/core/sensitive-path-policy.d.ts +3 -0
- package/dist/core/sensitive-path-policy.js +6 -5
- package/dist/core/shared-memory/tools.js +3 -6
- package/dist/core/store-contracts/checkpoint-store-contract.js +23 -0
- package/dist/core/task-event.d.ts +10 -0
- package/dist/core/task-registry.js +4 -5
- package/dist/core/task-spec.d.ts +8 -0
- package/dist/core/tool-catalog-entries.d.ts +48 -0
- package/dist/core/tool-catalog-entries.js +174 -0
- package/dist/core/tool-conformance.d.ts +22 -0
- package/dist/core/tool-conformance.js +37 -0
- package/dist/core/tool-face.d.ts +171 -0
- package/dist/core/tool-face.js +25 -0
- package/dist/core/tool-policy.d.ts +24 -0
- package/dist/core/tool-policy.js +4 -2
- package/dist/core/tool-registry.d.ts +114 -0
- package/dist/core/tool-registry.js +114 -0
- package/dist/core/tool-result-budget.d.ts +0 -3
- package/dist/core/tool-result-budget.js +4 -3
- package/dist/core/tool-result-store.d.ts +0 -18
- package/dist/core/tool-result-store.js +2 -18
- package/dist/core/tool-roster.d.ts +450 -0
- package/dist/core/tool-roster.js +497 -0
- package/dist/core/tool-spec.d.ts +54 -3
- package/dist/core/tools.js +7 -0
- package/dist/core/wiring-manifest.d.ts +13 -0
- package/dist/core/wiring-manifest.js +2 -1
- package/dist/core/write-protect.d.ts +2 -1
- package/dist/core/write-protect.js +5 -4
- package/dist/engine/compaction/utils.d.ts +6 -0
- package/dist/engine/compaction/utils.js +19 -19
- package/dist/engine/loop/types.d.ts +6 -0
- package/dist/index.d.ts +15 -4
- package/dist/index.js +15 -4
- package/dist/orchestration/goal.js +2 -1
- package/dist/orchestration/run-spec.js +3 -5
- package/dist/orchestration/run-workflow-tool.js +2 -2
- package/dist/prompt-assembly/event-registry.js +3 -3
- package/dist/prompt-assembly/tool-catalog.d.ts +2 -2
- package/dist/tools/fs/fs-bash.d.ts +1 -1
- package/dist/tools/fs/fs-bash.js +7 -11
- package/dist/tools/fs/fs-read.js +2 -2
- package/dist/tools/fs/fs-search-tools.d.ts +0 -7
- package/dist/tools/fs/fs-search-tools.js +3 -16
- package/dist/tools/fs/fs-write.js +4 -6
- package/dist/tools/fs/repo-map.js +2 -2
- package/dist/tools/fs/safety.d.ts +2 -1
- package/dist/tools/fs/safety.js +6 -5
- package/dist/tools/monitor.js +2 -2
- package/dist/tools/scheduler-tools.js +5 -8
- package/dist/tools/task-list.js +5 -8
- package/dist/tools/todo.js +2 -2
- package/dist/tools/web.js +3 -6
- package/dist/tools/worktree.js +3 -4
- package/package.json +4 -1
- package/test/export-surface.snapshot.json +147 -7
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The STATIC TOOL CATALOG (design/388 §2.1 "静态目录"): one row per built-in / synthetic tool DEFINITION
|
|
3
|
+
* core owns — its wire name, the conditions core (or a host scenario factory) mounts it under, the
|
|
4
|
+
* `details.type` cards it mints, and its declared FACE (family / axes / contract / path target / rule
|
|
5
|
+
* vocabulary / render hints / policy bits).
|
|
6
|
+
*
|
|
7
|
+
* SINGLE SOURCE, TWO READERS. Each definition module spreads its row's `face` into the `ToolSpec` it
|
|
8
|
+
* hands `defineTool` (`...TOOL_FACES.read`), so the face a tool declares at mount time IS the face
|
|
9
|
+
* listed here — there is no second declaration to drift. The effect roster (tool-roster.ts) reads every
|
|
10
|
+
* axis off the MOUNTED INSTANCE; the static catalog (`describeToolCatalog()`) reads this table without
|
|
11
|
+
* an env or a deps object. The conformance gate (test/tool-catalog-conformance.test.ts) proves the two
|
|
12
|
+
* agree for every definition it can instantiate; the catalog completeness gate
|
|
13
|
+
* (scripts/verify-tool-catalog.mjs) proves every `defineTool` site in src/ that mints a core-owned name
|
|
14
|
+
* has a row here that declares a `family` — a missing declaration is a RED gate naming the file, never a
|
|
15
|
+
* silent `"other"`.
|
|
16
|
+
*
|
|
17
|
+
* LEAF MODULE by design: it imports vocabulary types and one leaf constant module only. Every definition
|
|
18
|
+
* module and every policy module that derives a name set from the catalog imports THIS file, so a
|
|
19
|
+
* dependency from here back into a tool module would be a load-order cycle with a `const` table in it.
|
|
20
|
+
*
|
|
21
|
+
* Keyed by DEFINITION identity (`id`), not by name — the full and the read-only shell both answer to
|
|
22
|
+
* `Bash`; a catalog predicate counts a name as a member when ANY row under that name matches.
|
|
23
|
+
*/
|
|
24
|
+
import type { ToolCatalogEntry, ToolFaceDeclaration } from "./tool-face.js";
|
|
25
|
+
/** The full shell's contract id — declared here (the leaf) and re-exported by fs-bash.ts. */
|
|
26
|
+
export declare const FULL_SHELL_CONTRACT_ID = "core.bash@1";
|
|
27
|
+
export declare const READONLY_SHELL_CONTRACT_ID = "core.bash_readonly@1";
|
|
28
|
+
/** Wire-name constants for definitions that had none (design/388 A-21: literals become references). */
|
|
29
|
+
export declare const TASK_CREATE_TOOL_NAME = "TaskCreate";
|
|
30
|
+
export declare const TASK_GET_TOOL_NAME = "TaskGet";
|
|
31
|
+
export declare const TASK_UPDATE_TOOL_NAME = "TaskUpdate";
|
|
32
|
+
export declare const TASK_LIST_TOOL_NAME = "TaskList";
|
|
33
|
+
export declare const TODO_WRITE_TOOL_NAME = "TodoWrite";
|
|
34
|
+
export declare const REFRESH_MCP_TOOLS_TOOL_NAME = "RefreshMcpTools";
|
|
35
|
+
/**
|
|
36
|
+
* Every row. Order is documentation order (hands → delegation → scaffolds → memory → scheduler → host
|
|
37
|
+
* scenarios); nothing reads the order.
|
|
38
|
+
*/
|
|
39
|
+
export declare const TOOL_CATALOG_ENTRIES: readonly ToolCatalogEntry[];
|
|
40
|
+
/**
|
|
41
|
+
* `details.type` cards the ENGINE mints outside any tool definition — the protocol channels' result
|
|
42
|
+
* cards and the fs boundary refusals (minted by the shared safety module on behalf of every fs tool).
|
|
43
|
+
*/
|
|
44
|
+
export declare const ENGINE_CARDS: Readonly<Record<string, string>>;
|
|
45
|
+
/** The declared face of one definition, by definition id — what a definition module spreads into its spec. */
|
|
46
|
+
export declare function toolFace(id: string): ToolFaceDeclaration;
|
|
47
|
+
/** Definition-id → face, for the modules that spread one (`...TOOL_FACES.read`). Frozen: a face is data. */
|
|
48
|
+
export declare const TOOL_FACES: Readonly<Record<string, ToolFaceDeclaration>>;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { TASK_OUTPUT_CONTRACT, TASK_STOP_CONTRACT } from "./task-tool-shape.js";
|
|
2
|
+
export const FULL_SHELL_CONTRACT_ID = "core.bash@1";
|
|
3
|
+
export const READONLY_SHELL_CONTRACT_ID = "core.bash_readonly@1";
|
|
4
|
+
export const TASK_CREATE_TOOL_NAME = "TaskCreate";
|
|
5
|
+
export const TASK_GET_TOOL_NAME = "TaskGet";
|
|
6
|
+
export const TASK_UPDATE_TOOL_NAME = "TaskUpdate";
|
|
7
|
+
export const TASK_LIST_TOOL_NAME = "TaskList";
|
|
8
|
+
export const TODO_WRITE_TOOL_NAME = "TodoWrite";
|
|
9
|
+
export const REFRESH_MCP_TOOLS_TOOL_NAME = "RefreshMcpTools";
|
|
10
|
+
const SHELL_RULE_FACE = { primaryParams: ["command"], params: ["command", "timeout", "description", "run_in_background"] };
|
|
11
|
+
const c = (contractId, implementationRevision = "1") => ({ contractId, implementationRevision });
|
|
12
|
+
export const TOOL_CATALOG_ENTRIES = [
|
|
13
|
+
{
|
|
14
|
+
id: "read", name: "Read", source: "builtin", definedIn: "src/tools/fs/fs-read.ts", mountedBy: ["hands"],
|
|
15
|
+
cards: ["text", "notebook", "file_unchanged", "image", "document"],
|
|
16
|
+
face: {
|
|
17
|
+
family: "file-read", effect: "read", contract: c("core.read@1"),
|
|
18
|
+
pathTarget: { param: "file_path", aliases: ["path"], access: "read" },
|
|
19
|
+
ruleFace: { params: ["file_path", "path", "offset", "limit", "pages"] },
|
|
20
|
+
renderHints: { summaryParams: ["file_path"] },
|
|
21
|
+
offload: false, compactable: true, budgetExempt: true,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "edit", name: "Edit", source: "builtin", definedIn: "src/tools/fs/fs-write.ts", mountedBy: ["hands"],
|
|
26
|
+
cards: ["edit"],
|
|
27
|
+
face: {
|
|
28
|
+
family: "file-write", effect: "write", contract: c("core.edit@1"),
|
|
29
|
+
pathTarget: { param: "file_path", aliases: ["path"], access: "edit", skillScopeEligible: true },
|
|
30
|
+
ruleFace: { params: ["file_path", "path", "old_string", "new_string", "replace_all"] },
|
|
31
|
+
renderHints: { summaryParams: ["file_path"], approvalCard: "file-edit" },
|
|
32
|
+
compactable: true,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "write", name: "Write", source: "builtin", definedIn: "src/tools/fs/fs-write.ts", mountedBy: ["hands"],
|
|
37
|
+
cards: ["create", "update"],
|
|
38
|
+
face: {
|
|
39
|
+
family: "file-write", effect: "write", contract: c("core.write@1"),
|
|
40
|
+
pathTarget: { param: "file_path", aliases: ["path"], access: "create", skillScopeEligible: true },
|
|
41
|
+
ruleFace: { params: ["file_path", "path", "content"] },
|
|
42
|
+
renderHints: { summaryParams: ["file_path"], approvalCard: "file-write" },
|
|
43
|
+
offload: false, compactable: true,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: "notebook-edit", name: "NotebookEdit", source: "builtin", definedIn: "src/tools/fs/fs-write.ts", mountedBy: ["hands"],
|
|
48
|
+
cards: ["notebook-edit"],
|
|
49
|
+
face: {
|
|
50
|
+
family: "file-write", effect: "write", contract: c("core.notebook_edit@1"),
|
|
51
|
+
pathTarget: { param: "notebook_path", aliases: ["path"], access: "edit" },
|
|
52
|
+
ruleFace: { params: ["notebook_path", "path", "cell_id", "cell_type", "edit_mode", "new_source"] },
|
|
53
|
+
renderHints: { userFacingName: "Edit Notebook", summaryParams: ["notebook_path"], approvalCard: "notebook-edit" },
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "bash", name: "Bash", source: "builtin", definedIn: "src/tools/fs/fs-bash.ts", mountedBy: ["hands"],
|
|
58
|
+
cards: ["bash", "bash_invalid_timeout"],
|
|
59
|
+
face: {
|
|
60
|
+
family: "shell", effect: "write", contentOrigin: "execution", contract: c(FULL_SHELL_CONTRACT_ID),
|
|
61
|
+
ruleFace: SHELL_RULE_FACE,
|
|
62
|
+
renderHints: { summaryParams: ["command"], approvalCard: "shell" },
|
|
63
|
+
offloadThresholdChars: 30_000, compactable: true,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "bash-readonly", name: "Bash", source: "builtin", definedIn: "src/tools/fs/fs-bash.ts", mountedBy: ["hands"],
|
|
68
|
+
cards: ["bash", "readonly_out_of_root", "bash_invalid_timeout"],
|
|
69
|
+
face: {
|
|
70
|
+
family: "shell", effect: "read", contract: c(READONLY_SHELL_CONTRACT_ID),
|
|
71
|
+
ruleFace: SHELL_RULE_FACE,
|
|
72
|
+
renderHints: { summaryParams: ["command"], approvalCard: "shell" },
|
|
73
|
+
offloadThresholdChars: 30_000, compactable: true,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: "grep", name: "Grep", source: "builtin", definedIn: "src/tools/fs/fs-search-tools.ts", mountedBy: ["hands"],
|
|
78
|
+
cards: ["grep"],
|
|
79
|
+
face: {
|
|
80
|
+
family: "search", effect: "read", contract: c("core.grep@1"),
|
|
81
|
+
pathTarget: { param: "path", access: "read" },
|
|
82
|
+
ruleFace: { params: ["pattern", "path", "glob", "type", "output_mode", "head_limit", "offset", "multiline", "context", "ignore_case", "-i", "-n", "-o", "-A", "-B", "-C"] },
|
|
83
|
+
renderHints: { userFacingName: "Search", summaryParams: ["pattern", "path"] },
|
|
84
|
+
offloadThresholdChars: 20_000, compactable: true,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: "glob", name: "Glob", source: "builtin", definedIn: "src/tools/fs/fs-search-tools.ts", mountedBy: ["hands"],
|
|
89
|
+
cards: ["glob"],
|
|
90
|
+
face: {
|
|
91
|
+
family: "search", effect: "read", contract: c("core.glob@1"),
|
|
92
|
+
pathTarget: { param: "path", access: "read" },
|
|
93
|
+
ruleFace: { params: ["pattern", "path", "max_results"] },
|
|
94
|
+
renderHints: { userFacingName: "Search", summaryParams: ["pattern", "path"] },
|
|
95
|
+
compactable: true,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{ id: "repo-map", name: "RepoMap", source: "builtin", definedIn: "src/tools/fs/repo-map.ts", mountedBy: ["hands"], cards: ["repo-map"], face: { family: "search", effect: "read", contract: c("core.repo_map@1") } },
|
|
99
|
+
{ id: "lsp", name: "LSP", source: "builtin", definedIn: "src/core/lsp.ts", mountedBy: ["optional"], cards: [], face: { family: "search", effect: "read", contract: c("core.lsp@1") } },
|
|
100
|
+
{ id: "enter-worktree", name: "EnterWorktree", source: "builtin", definedIn: "src/tools/worktree.ts", mountedBy: ["hands"], cards: ["worktree"], face: { family: "other", effect: "write", contract: c("core.enter_worktree@1") } },
|
|
101
|
+
{ id: "exit-worktree", name: "ExitWorktree", source: "builtin", definedIn: "src/tools/worktree.ts", mountedBy: ["hands"], cards: ["worktree"], face: { family: "other", effect: "write", contract: c("core.exit_worktree@1") } },
|
|
102
|
+
{ id: "task-output-hands", name: "TaskOutput", source: "builtin", definedIn: "src/tools/fs/fs-bash.ts", mountedBy: ["hands"], cards: [], face: { family: "delegate", effect: "read", contract: TASK_OUTPUT_CONTRACT } },
|
|
103
|
+
{ id: "task-stop-hands", name: "TaskStop", source: "builtin", definedIn: "src/tools/fs/fs-bash.ts", mountedBy: ["hands"], cards: [], face: { family: "delegate", effect: "write", contract: TASK_STOP_CONTRACT } },
|
|
104
|
+
{ id: "task-output", name: "TaskOutput", source: "builtin", definedIn: "src/core/task-registry.ts", mountedBy: ["delegation"], cards: ["task-output"], face: { family: "delegate", effect: "read", contract: TASK_OUTPUT_CONTRACT } },
|
|
105
|
+
{ id: "task-stop", name: "TaskStop", source: "builtin", definedIn: "src/core/task-registry.ts", mountedBy: ["delegation"], cards: ["task-stop"], face: { family: "delegate", effect: "write", contract: TASK_STOP_CONTRACT } },
|
|
106
|
+
{ id: "monitor", name: "Monitor", source: "builtin", definedIn: "src/tools/monitor.ts", mountedBy: ["backgroundTasks"], cards: ["monitor-start"], face: { family: "other", effect: "write", contract: c("core.monitor@1"), offloadThresholdChars: 10_000 } },
|
|
107
|
+
{ id: "send-message", name: "SendMessage", source: "builtin", definedIn: "src/agents/send-message-tool.ts", mountedBy: ["delegation", "hostInternals", "peerLane"], cards: ["send-message"], face: { family: "protocol", effect: "write", contract: c("core.send_message@1") } },
|
|
108
|
+
{ id: "agent-transcript", name: "AgentTranscript", source: "builtin", definedIn: "src/agents/agent-transcript-tool.ts", mountedBy: ["delegation"], cards: ["agent-transcript"], face: { family: "delegate", effect: "read", contract: c("core.agent_transcript@1") } },
|
|
109
|
+
{ id: "list-agents", name: "ListAgents", source: "builtin", definedIn: "src/agents/list-agents-tool.ts", mountedBy: ["peerLane"], cards: ["list-agents"], face: { family: "protocol", effect: "read", aliases: ["ListPeers"], contract: c("core.list_agents@1") } },
|
|
110
|
+
{ id: "workflow", name: "Workflow", source: "builtin", definedIn: "src/orchestration/run-workflow-tool.ts", mountedBy: ["workflow"], cards: ["workflow-run"], face: { family: "delegate", effect: "write", contract: c("core.workflow@1") } },
|
|
111
|
+
{ id: "report-blocked", name: "ReportBlocked", source: "builtin", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["always"], cards: [], face: { family: "scaffold", effect: "read", contract: c("core.report_blocked@1") } },
|
|
112
|
+
{ id: "report-findings", name: "ReportFindings", source: "builtin", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["always"], cards: ["report-findings"], face: { family: "scaffold", effect: "read", contract: c("core.report_findings@1") } },
|
|
113
|
+
{ id: "structured-output", name: "StructuredOutput", source: "synthetic", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["optional"], cards: [], face: { family: "scaffold", effect: "read", contract: c("core.structured_output@1") } },
|
|
114
|
+
{ id: "skill", name: "Skill", source: "builtin", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["optional"], cards: [], face: { family: "scaffold", effect: "read", contract: c("core.skill@1") } },
|
|
115
|
+
{ id: "read-tool-result", name: "ReadToolResult", source: "builtin", definedIn: "src/core/tool-result-store.ts", mountedBy: ["optional"], cards: [], face: { family: "scaffold", effect: "read", contract: c("core.read_tool_result@1"), budgetExempt: true } },
|
|
116
|
+
{ id: "tool-search", name: "ToolSearch", source: "builtin", definedIn: "src/core/runner/tool-disclosure.ts", mountedBy: ["optional"], cards: ["tool-search"], face: { family: "scaffold", effect: "read", contract: c("core.tool_search@1") } },
|
|
117
|
+
{ id: "ask-user-question", name: "AskUserQuestion", source: "builtin", definedIn: "src/core/ask-question.ts", mountedBy: ["optional"], cards: ["ask-question"], face: { family: "other", effect: "read", contract: c("core.ask_user_question@1"), renderHints: { approvalCard: "question" } } },
|
|
118
|
+
{ id: "exit-plan-mode", name: "ExitPlanMode", source: "builtin", definedIn: "src/core/present-plan-tool.ts", mountedBy: ["optional"], cards: ["exit-plan-mode"], face: { family: "plan", effect: "read", contract: c("core.exit_plan_mode@1"), renderHints: { userFacingName: "", approvalCard: "plan" } } },
|
|
119
|
+
{ id: "enter-plan-mode", name: "EnterPlanMode", source: "builtin", definedIn: "src/core/present-plan-tool.ts", mountedBy: ["optional"], cards: ["enter-plan-mode"], face: { family: "plan", effect: "read", contract: c("core.enter_plan_mode@1") } },
|
|
120
|
+
{ id: "refresh-mcp-tools", name: REFRESH_MCP_TOOLS_TOOL_NAME, source: "builtin", definedIn: "src/core/runner/prepare-protocol-tools.ts", mountedBy: ["optional"], cards: [], face: { family: "protocol", effect: "read" } },
|
|
121
|
+
{ id: "memory-search", name: "memory_search", source: "builtin", definedIn: "src/core/memory-engine/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", effect: "read", contentOrigin: "local", contract: c("core.memory_search@1", "6"), offload: false } },
|
|
122
|
+
{ id: "memory-get", name: "memory_get", source: "builtin", definedIn: "src/core/memory-engine/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", effect: "read", contentOrigin: "local", contract: c("core.memory_get@1", "6"), offload: false } },
|
|
123
|
+
{ id: "memory-index", name: "memory_index", source: "builtin", definedIn: "src/core/memory-engine/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", effect: "read", contentOrigin: "local", contract: c("core.memory_index@1"), offload: false } },
|
|
124
|
+
{ id: "memory-list", name: "memory_list", source: "builtin", definedIn: "src/core/shared-memory/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", effect: "read", contract: c("core.memory_list@1"), offload: false } },
|
|
125
|
+
{ id: "memory-read", name: "memory_read", source: "builtin", definedIn: "src/core/shared-memory/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", effect: "read", contract: c("core.memory_read@1"), offload: false } },
|
|
126
|
+
{ id: "cron-create", name: "CronCreate", source: "builtin", definedIn: "src/tools/scheduler-tools.ts", mountedBy: ["scheduler"], cards: ["cron-create"], face: { family: "other", effect: "write", contract: c("core.cron_create@1") } },
|
|
127
|
+
{ id: "cron-delete", name: "CronDelete", source: "builtin", definedIn: "src/tools/scheduler-tools.ts", mountedBy: ["scheduler"], cards: ["cron-delete"], face: { family: "other", effect: "idempotent", contract: c("core.cron_delete@1") } },
|
|
128
|
+
{ id: "cron-list", name: "CronList", source: "builtin", definedIn: "src/tools/scheduler-tools.ts", mountedBy: ["scheduler"], cards: ["cron-list"], face: { family: "other", effect: "read", contract: c("core.cron_list@1") } },
|
|
129
|
+
{ id: "schedule-wakeup", name: "ScheduleWakeup", source: "builtin", definedIn: "src/tools/scheduler-tools.ts", mountedBy: ["scheduler"], cards: ["schedule-wakeup"], face: { family: "other", effect: "write", contract: c("core.schedule_wakeup@1") } },
|
|
130
|
+
{
|
|
131
|
+
id: "web-fetch", name: "WebFetch", source: "builtin", definedIn: "src/tools/web.ts", mountedBy: ["scenario"], cards: ["web-fetch"],
|
|
132
|
+
face: { family: "web", effect: "read", contentOrigin: "external", contract: c("core.web_fetch@1"), ruleFace: { primaryParams: ["url"] }, renderHints: { summaryParams: ["url"], approvalCard: "fetch" }, compactable: true },
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: "web-search", name: "WebSearch", source: "builtin", definedIn: "src/tools/web.ts", mountedBy: ["scenario"], cards: ["web-search"],
|
|
136
|
+
face: { family: "web", effect: "read", contentOrigin: "external", contract: c("core.web_search@1"), ruleFace: { primaryParams: ["query"] }, renderHints: { summaryParams: ["query"] }, compactable: true },
|
|
137
|
+
},
|
|
138
|
+
{ id: "todo-write", name: TODO_WRITE_TOOL_NAME, source: "builtin", definedIn: "src/tools/todo.ts", mountedBy: ["scenario"], cards: ["todo"], modelGate: "task-scaffold", face: { family: "plan", effect: "idempotent", contract: c("core.todo_write@1") } },
|
|
139
|
+
{ id: "task-create", name: TASK_CREATE_TOOL_NAME, source: "builtin", definedIn: "src/tools/task-list.ts", mountedBy: ["scenario"], cards: ["task"], modelGate: "task-scaffold", face: { family: "plan", effect: "write", contract: c("core.task_create@1") } },
|
|
140
|
+
{ id: "task-get", name: TASK_GET_TOOL_NAME, source: "builtin", definedIn: "src/tools/task-list.ts", mountedBy: ["scenario"], cards: ["task"], modelGate: "task-scaffold", face: { family: "plan", effect: "read", contract: c("core.task_get@1") } },
|
|
141
|
+
{ id: "task-update", name: TASK_UPDATE_TOOL_NAME, source: "builtin", definedIn: "src/tools/task-list.ts", mountedBy: ["scenario"], cards: ["task"], modelGate: "task-scaffold", face: { family: "plan", effect: "idempotent", contract: c("core.task_update@1") } },
|
|
142
|
+
{ id: "task-list", name: TASK_LIST_TOOL_NAME, source: "builtin", definedIn: "src/tools/task-list.ts", mountedBy: ["scenario"], cards: ["task-list"], modelGate: "task-scaffold", face: { family: "plan", effect: "read", contract: c("core.task_list@1") } },
|
|
143
|
+
{ id: "agent", name: "Agent", source: "builtin", definedIn: "src/agents/subagent.ts", mountedBy: ["scenario"], cards: ["agent", "fork"], face: { family: "delegate", contentOrigin: "local", contract: c("core.agent@1") } },
|
|
144
|
+
{ id: "observer-report", name: "ObserverReport", source: "builtin", definedIn: "src/agents/observer.ts", mountedBy: ["scenario"], cards: [], face: { family: "scaffold", effect: "write", contract: c("core.observer_report@1") } },
|
|
145
|
+
{ id: "declare-done", name: "DeclareDone", source: "builtin", definedIn: "src/orchestration/goal.ts", mountedBy: ["scenario"], cards: [], face: { family: "scaffold", effect: "read" } },
|
|
146
|
+
];
|
|
147
|
+
export const ENGINE_CARDS = Object.freeze({
|
|
148
|
+
mcp: "src/core/mcp.ts",
|
|
149
|
+
a2a: "src/core/a2a.ts",
|
|
150
|
+
path_not_in_root: "src/tools/fs/safety.ts",
|
|
151
|
+
read_path_denied: "src/tools/fs/safety.ts",
|
|
152
|
+
});
|
|
153
|
+
const byId = new Map();
|
|
154
|
+
for (const e of TOOL_CATALOG_ENTRIES) {
|
|
155
|
+
if (byId.has(e.id))
|
|
156
|
+
throw new Error(`tool catalog: duplicate definition id ${JSON.stringify(e.id)}`);
|
|
157
|
+
byId.set(e.id, e);
|
|
158
|
+
}
|
|
159
|
+
export function toolFace(id) {
|
|
160
|
+
const e = byId.get(id);
|
|
161
|
+
if (e === undefined)
|
|
162
|
+
throw new Error(`tool catalog: no definition ${JSON.stringify(id)}`);
|
|
163
|
+
return structuredClone(e.face);
|
|
164
|
+
}
|
|
165
|
+
function deepFreeze(value) {
|
|
166
|
+
if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
|
|
167
|
+
Object.freeze(value);
|
|
168
|
+
for (const k of Object.keys(value))
|
|
169
|
+
deepFreeze(value[k]);
|
|
170
|
+
}
|
|
171
|
+
return value;
|
|
172
|
+
}
|
|
173
|
+
deepFreeze(TOOL_CATALOG_ENTRIES);
|
|
174
|
+
export const TOOL_FACES = Object.freeze(Object.fromEntries(TOOL_CATALOG_ENTRIES.map((e) => [e.id, e.face])));
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ToolMountTag } from "./tool-face.js";
|
|
2
|
+
export interface ToolConformanceVector {
|
|
3
|
+
id: string;
|
|
4
|
+
/** The mount conditions the vector activates. */
|
|
5
|
+
active: readonly ToolMountTag[];
|
|
6
|
+
/** Predicted names the vector cannot mount, each with the seat it lacks. */
|
|
7
|
+
absent: ReadonlyArray<{
|
|
8
|
+
name: string;
|
|
9
|
+
why: string;
|
|
10
|
+
}>;
|
|
11
|
+
/** Mounted names no tag spells, each with the seat that mounts them. */
|
|
12
|
+
extra: ReadonlyArray<{
|
|
13
|
+
name: string;
|
|
14
|
+
why: string;
|
|
15
|
+
}>;
|
|
16
|
+
/** The vector's expected core-mounted name set: predict(active) − absent + extra. */
|
|
17
|
+
expected: readonly string[];
|
|
18
|
+
}
|
|
19
|
+
/** The matrix. Vector ids are stable (a host's own conformance test keys on them). */
|
|
20
|
+
export declare const TOOL_CONFORMANCE_VECTORS: readonly ToolConformanceVector[];
|
|
21
|
+
/** The matrix as a host reads it (a frozen copy). */
|
|
22
|
+
export declare function describeToolConformanceVectors(): readonly ToolConformanceVector[];
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { predictMountedToolNames } from "./tool-registry.js";
|
|
2
|
+
const vector = (id, active, absent = [], extra = []) => {
|
|
3
|
+
const predicted = new Set(predictMountedToolNames(new Set(active)));
|
|
4
|
+
for (const a of absent)
|
|
5
|
+
predicted.delete(a.name);
|
|
6
|
+
for (const e of extra)
|
|
7
|
+
predicted.add(e.name);
|
|
8
|
+
return { id, active, absent, extra, expected: [...predicted].sort() };
|
|
9
|
+
};
|
|
10
|
+
const OFFLOAD_READER = { name: "ReadToolResult", why: "the offload store is wired by default (the deployment threshold), an `optional` seat every vector carries" };
|
|
11
|
+
export const TOOL_CONFORMANCE_VECTORS = [
|
|
12
|
+
vector("bare", ["always"], [], [OFFLOAD_READER]),
|
|
13
|
+
vector("hands-full", ["always", "hands", "backgroundTasks", "delegation"], [
|
|
14
|
+
{ name: "SendMessage", why: "needs the runner self seat (a direct prepare has none)" },
|
|
15
|
+
{ name: "AgentTranscript", why: "needs the runner self seat (a direct prepare has none)" },
|
|
16
|
+
], [OFFLOAD_READER]),
|
|
17
|
+
vector("hands-readonly", ["always", "hands"], [
|
|
18
|
+
{ name: "Edit", why: "the read-only band mounts the read half only" },
|
|
19
|
+
{ name: "Write", why: "the read-only band mounts the read half only" },
|
|
20
|
+
{ name: "NotebookEdit", why: "the read-only band mounts the read half only" },
|
|
21
|
+
{ name: "TaskOutput", why: "the background-shell pair mounts on the full shell only" },
|
|
22
|
+
{ name: "TaskStop", why: "the background-shell pair mounts on the full shell only" },
|
|
23
|
+
{ name: "EnterWorktree", why: "the worktree pair needs the tracked cwd the full shell owns" },
|
|
24
|
+
{ name: "ExitWorktree", why: "the worktree pair needs the tracked cwd the full shell owns" },
|
|
25
|
+
], [OFFLOAD_READER]),
|
|
26
|
+
vector("plan-mode", ["always", "optional"], [
|
|
27
|
+
{ name: "LSP", why: "needs a wired LSP manager" },
|
|
28
|
+
{ name: "Skill", why: "needs a skills listing" },
|
|
29
|
+
{ name: "StructuredOutput", why: "needs an output schema" },
|
|
30
|
+
{ name: "ToolSearch", why: "needs a deferred tool" },
|
|
31
|
+
{ name: "RefreshMcpTools", why: "needs a declared MCP server" },
|
|
32
|
+
{ name: "EnterPlanMode", why: "needs a checkpoint store beside plan mode" },
|
|
33
|
+
]),
|
|
34
|
+
];
|
|
35
|
+
export function describeToolConformanceVectors() {
|
|
36
|
+
return TOOL_CONFORMANCE_VECTORS;
|
|
37
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tool FACE vocabulary (design/388 §2.1–§2.2): the closed word sets and the small declaration
|
|
3
|
+
* shapes that describe a tool WITHOUT executing it — its display family, the parameter that names its
|
|
4
|
+
* path target, the parameter vocabulary a permission rule may speak about it, the render hints a shell
|
|
5
|
+
* may read, and the mount-condition tags the static catalog lists it under.
|
|
6
|
+
*
|
|
7
|
+
* Layer-0 vocabulary: nothing here reads an env, a deps object, or a tool instance. `ToolSpec`
|
|
8
|
+
* (tool-spec.ts) carries the declaration half of these shapes as optional fields; the static catalog
|
|
9
|
+
* (tool-catalog-entries.ts) lists every built-in's face; the effect roster (tool-roster.ts) reads the
|
|
10
|
+
* same shapes off the MOUNTED instance. One vocabulary, three readers, no second table.
|
|
11
|
+
*/
|
|
12
|
+
/** The display / dispatch family of a tool. INPUT to grouping and card pre-selection only — never an
|
|
13
|
+
* authorization source (a `"file-write"` family grants nothing; the path-confinable predicate reads
|
|
14
|
+
* {@link ToolPathTarget}, and the approval card is chosen by {@link ToolRenderHints.approvalCard}). */
|
|
15
|
+
export declare const TOOL_FAMILIES: readonly ["shell", "file-read", "file-write", "search", "web", "delegate", "plan", "scaffold", "memory", "protocol", "other"];
|
|
16
|
+
export type ToolFamily = (typeof TOOL_FAMILIES)[number];
|
|
17
|
+
/**
|
|
18
|
+
* The closed set of MOUNT-CONDITION tags a static catalog entry is listed under. The static half of the
|
|
19
|
+
* catalog carries an ARRAY (a tool can be mounted by more than one condition — TaskOutput rides both the
|
|
20
|
+
* hand band and the delegation surface); the effect roster records the ONE tag that actually fired.
|
|
21
|
+
*
|
|
22
|
+
* - `hands` — the hand band (an execution env is wired: `deps.executionEnv` / `executionEnvFactory`);
|
|
23
|
+
* - `backgroundTasks` — the background-task surface (`Monitor`);
|
|
24
|
+
* - `workflow` — the workflow tool surface (`Workflow`);
|
|
25
|
+
* - `delegation` — the union of the background-task and workflow surfaces (TaskOutput/TaskStop/
|
|
26
|
+
* AgentTranscript, SendMessage's first condition);
|
|
27
|
+
* - `hostInternals` — a host-internal seat is present (`RunInternals.parentNotify`);
|
|
28
|
+
* - `peerLane` — the peer-session lane is mounted;
|
|
29
|
+
* - `scheduler` — the env carries a scheduler daemon (the Cron family + ScheduleWakeup);
|
|
30
|
+
* - `memory` — an engine-memory / shared-memory session is wired;
|
|
31
|
+
* - `scenario` — mounted by a HOST scenario factory through `TaskSpec.tools` (core defines the tool,
|
|
32
|
+
* the host decides to mount it);
|
|
33
|
+
* - `always` — mounted on every task unless excluded (ReportBlocked/ReportFindings);
|
|
34
|
+
* - `optional` — mounted by a per-task opt-in or a wired seat (plan mode, an output schema, an
|
|
35
|
+
* offload store, a question face, a skills listing, an MCP configuration).
|
|
36
|
+
*/
|
|
37
|
+
export declare const TOOL_MOUNT_TAGS: readonly ["hands", "backgroundTasks", "workflow", "delegation", "hostInternals", "peerLane", "scheduler", "memory", "scenario", "always", "optional"];
|
|
38
|
+
export type ToolMountTag = (typeof TOOL_MOUNT_TAGS)[number];
|
|
39
|
+
import type { AssertAllKeysHandled } from "./ask-origin.js";
|
|
40
|
+
/** The closed set of specialised approval cards a shell may pre-select from a render hint. The hint is a
|
|
41
|
+
* PRE-FILTER: the shell owns each card's input schema and validates the call's full args before
|
|
42
|
+
* mounting the card (design/388 §2.5 boundary ①). */
|
|
43
|
+
export declare const TOOL_APPROVAL_CARDS: readonly ["file-edit", "file-write", "notebook-edit", "shell", "fetch", "plan", "question", "generic"];
|
|
44
|
+
export type ToolApprovalCard = (typeof TOOL_APPROVAL_CARDS)[number];
|
|
45
|
+
/** How a path-targeting tool touches its target. `read` never enters a write-confinement face. */
|
|
46
|
+
export declare const TOOL_PATH_ACCESSES: readonly ["read", "create", "edit"];
|
|
47
|
+
export type ToolPathAccess = (typeof TOOL_PATH_ACCESSES)[number];
|
|
48
|
+
/**
|
|
49
|
+
* The parameter that names this tool's filesystem target, and how the target is touched. Present ⇔ the
|
|
50
|
+
* tool can be confirmed BY PATH (write confinement, sensitive-path guards, edited-file tracking, the
|
|
51
|
+
* transcript-directory gate). `param` outranks every alias (NotebookEdit's `notebook_path` beats a decoy
|
|
52
|
+
* `file_path`). `skillScopeEligible` (default false) is the SEPARATE authorization domain of the
|
|
53
|
+
* active-skill `allowPaths` face — a confinable write tool is not automatically eligible there.
|
|
54
|
+
*/
|
|
55
|
+
export interface ToolPathTarget {
|
|
56
|
+
param: string;
|
|
57
|
+
aliases?: readonly string[];
|
|
58
|
+
access: ToolPathAccess;
|
|
59
|
+
skillScopeEligible?: true;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The parameter vocabulary a permission rule (`Tool(param:pattern)`) may name. DERIVED by default from
|
|
63
|
+
* the tool's schema: the SCALAR top-level parameters (string/number/integer/boolean and their enum/const/
|
|
64
|
+
* union forms) plus {@link ToolPathTarget.aliases}; object/array parameters never enter (a rule on them
|
|
65
|
+
* can never match — `matchParamRules` skips non-scalar values). A declaration can only NARROW the derived
|
|
66
|
+
* set; `primaryParams` defaults to the path target's `param` + aliases.
|
|
67
|
+
*/
|
|
68
|
+
export interface ToolRuleFace {
|
|
69
|
+
primaryParams?: readonly string[];
|
|
70
|
+
params?: readonly string[];
|
|
71
|
+
}
|
|
72
|
+
/** The roster's WIRE bounds on a tool name and a contract member (design/388 §2.5 / B20). Distinct from
|
|
73
|
+
* protocol-naming's `TOOL_NAME_MAX_CHARS` (64), the provider-facing bound the MCP/A2A namespacing helper
|
|
74
|
+
* budgets a MINTED name to — a minted name is always inside this wire bound by construction; a CALLER
|
|
75
|
+
* declaration is judged against it at prepare. */
|
|
76
|
+
export declare const TOOL_WIRE_NAME_MAX_CHARS = 128;
|
|
77
|
+
export declare const TOOL_CONTRACT_MAX_CHARS = 64;
|
|
78
|
+
/** The roster's wire bound on a KEY — a schema property name, a path-target `param`/alias, a rule-face param. A key is a
|
|
79
|
+
* SEMANTIC name every fence reads an argument by, so it is never truncated: a declaration over the bound is refused at
|
|
80
|
+
* the door (caller) or dropped with a disclosed reason (MCP intake), and a row carries every key exactly. */
|
|
81
|
+
export declare const TOOL_KEY_MAX_CHARS = 256;
|
|
82
|
+
/** The roster's bound on how many top-level keys one row carries (the same refuse/drop treatment). */
|
|
83
|
+
export declare const TOOL_KEYS_MAX = 1024;
|
|
84
|
+
/** Bounds every render-hint string is held to on the roster (design/388 §2.2 ④). */
|
|
85
|
+
export declare const RENDER_HINT_MAX_CHARS = 64;
|
|
86
|
+
export declare const RENDER_HINT_ACTIVITY_MAX_CHARS = 32;
|
|
87
|
+
export declare const RENDER_HINT_MAX_LIST = 16;
|
|
88
|
+
/**
|
|
89
|
+
* Declarative, template-free display hints (design/388 §2.2 ④, D-4). UNTRUSTED display input on the
|
|
90
|
+
* wire: the engine length-caps them at the roster mint; the shell strips control / newline / bidi
|
|
91
|
+
* characters before rendering. `resultCards` may only name cards in the tool's OWN namespace
|
|
92
|
+
* (`caller:<contractId>/<type>`) — engine cards (`builtin:*`, `mcp`, the refusal cards) are minted by
|
|
93
|
+
* the engine alone and a declaration naming one is refused at prepare.
|
|
94
|
+
*/
|
|
95
|
+
export interface ToolRenderHints {
|
|
96
|
+
userFacingName?: string;
|
|
97
|
+
activity?: string;
|
|
98
|
+
summaryParams?: readonly string[];
|
|
99
|
+
resultCards?: readonly string[];
|
|
100
|
+
approvalCard?: ToolApprovalCard;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The static FACE of a tool — the subset of `ToolSpec` a catalog entry declares and a definition module
|
|
104
|
+
* spreads into its spec. Everything here is readable without an env or a deps object; the effect roster
|
|
105
|
+
* reads the same members off the mounted instance.
|
|
106
|
+
*/
|
|
107
|
+
export interface ToolFaceDeclaration {
|
|
108
|
+
family: ToolFamily;
|
|
109
|
+
effect?: import("./tool-spec.js").ToolEffect;
|
|
110
|
+
egress?: true;
|
|
111
|
+
irreversibility?: "never" | "maybe" | "always";
|
|
112
|
+
contentOrigin?: import("./tool-spec.js").ToolContentOrigin;
|
|
113
|
+
contract?: {
|
|
114
|
+
contractId: string;
|
|
115
|
+
implementationRevision: string;
|
|
116
|
+
};
|
|
117
|
+
aliases?: string[];
|
|
118
|
+
pathTarget?: ToolPathTarget;
|
|
119
|
+
ruleFace?: ToolRuleFace;
|
|
120
|
+
renderHints?: ToolRenderHints;
|
|
121
|
+
offload?: boolean;
|
|
122
|
+
offloadThresholdChars?: number;
|
|
123
|
+
compactable?: true;
|
|
124
|
+
budgetExempt?: true;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* One row of the static tool catalog (design/388 §2.1 "静态目录"). Keyed by DEFINITION identity, not by
|
|
128
|
+
* name: two definitions may share a wire name (the full and the read-only shell both answer to `Bash`),
|
|
129
|
+
* and every catalog predicate counts a name as a member when ANY entry under it matches.
|
|
130
|
+
*/
|
|
131
|
+
export interface ToolCatalogEntry {
|
|
132
|
+
/** Definition identity — unique across the catalog (`bash`, `bash-readonly`). */
|
|
133
|
+
id: string;
|
|
134
|
+
/** Wire name; may repeat across entries. */
|
|
135
|
+
name: string;
|
|
136
|
+
/** `builtin` = a core definition mounted by core or by a host factory; `synthetic` = core mints it
|
|
137
|
+
* per task with a per-task shape (the structured-output tool). */
|
|
138
|
+
source: "builtin" | "synthetic";
|
|
139
|
+
/** Where the definition lives (repo-relative), so a catalog gate can name the file. */
|
|
140
|
+
definedIn: string;
|
|
141
|
+
/** The conditions under which core (or a host scenario) mounts this definition. */
|
|
142
|
+
mountedBy: readonly ToolMountTag[];
|
|
143
|
+
/** The `details.type` cards this definition mints on `tool_end.structured`. */
|
|
144
|
+
cards: readonly string[];
|
|
145
|
+
/** The declared face — spread into the definition's `ToolSpec` by the module that owns it. */
|
|
146
|
+
face: ToolFaceDeclaration;
|
|
147
|
+
/** A `modelGate` class the default-bundle assembler stamps on this definition's default arm. */
|
|
148
|
+
modelGate?: string;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The band-membership table over the mount tags: a host derives its hand band as the definitions listed under a
|
|
152
|
+
* TRUE row (server B-1). Every tag has a row — the fence reds `tsc` when a tag is added without one. The
|
|
153
|
+
* background-task surface is hands-derived (`backgroundTaskToolsActive` requires the shell), so a definition
|
|
154
|
+
* mounted by it alone is a band member that is NOT dual-use.
|
|
155
|
+
*/
|
|
156
|
+
export declare const MOUNT_TAG_IN_HANDS_BAND: {
|
|
157
|
+
readonly hands: true;
|
|
158
|
+
readonly backgroundTasks: true;
|
|
159
|
+
readonly workflow: false;
|
|
160
|
+
readonly delegation: true;
|
|
161
|
+
readonly hostInternals: true;
|
|
162
|
+
readonly peerLane: true;
|
|
163
|
+
readonly scheduler: false;
|
|
164
|
+
readonly memory: false;
|
|
165
|
+
readonly scenario: false;
|
|
166
|
+
readonly always: false;
|
|
167
|
+
readonly optional: false;
|
|
168
|
+
};
|
|
169
|
+
export type HandsBandTableCoversEveryMountTag = AssertAllKeysHandled<Exclude<ToolMountTag, keyof typeof MOUNT_TAG_IN_HANDS_BAND>>;
|
|
170
|
+
/** The tags whose definitions form the hand band a host derives (server B-1 `HANDS_BAND_TAGS`). */
|
|
171
|
+
export declare const HANDS_BAND_TAGS: ReadonlySet<ToolMountTag>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const TOOL_FAMILIES = ["shell", "file-read", "file-write", "search", "web", "delegate", "plan", "scaffold", "memory", "protocol", "other"];
|
|
2
|
+
export const TOOL_MOUNT_TAGS = ["hands", "backgroundTasks", "workflow", "delegation", "hostInternals", "peerLane", "scheduler", "memory", "scenario", "always", "optional"];
|
|
3
|
+
export const TOOL_APPROVAL_CARDS = ["file-edit", "file-write", "notebook-edit", "shell", "fetch", "plan", "question", "generic"];
|
|
4
|
+
export const TOOL_PATH_ACCESSES = ["read", "create", "edit"];
|
|
5
|
+
export const TOOL_WIRE_NAME_MAX_CHARS = 128;
|
|
6
|
+
export const TOOL_CONTRACT_MAX_CHARS = 64;
|
|
7
|
+
export const TOOL_KEY_MAX_CHARS = 256;
|
|
8
|
+
export const TOOL_KEYS_MAX = 1024;
|
|
9
|
+
export const RENDER_HINT_MAX_CHARS = 64;
|
|
10
|
+
export const RENDER_HINT_ACTIVITY_MAX_CHARS = 32;
|
|
11
|
+
export const RENDER_HINT_MAX_LIST = 16;
|
|
12
|
+
export const MOUNT_TAG_IN_HANDS_BAND = {
|
|
13
|
+
hands: true,
|
|
14
|
+
backgroundTasks: true,
|
|
15
|
+
workflow: false,
|
|
16
|
+
delegation: true,
|
|
17
|
+
hostInternals: true,
|
|
18
|
+
peerLane: true,
|
|
19
|
+
scheduler: false,
|
|
20
|
+
memory: false,
|
|
21
|
+
scenario: false,
|
|
22
|
+
always: false,
|
|
23
|
+
optional: false,
|
|
24
|
+
};
|
|
25
|
+
export const HANDS_BAND_TAGS = new Set(Object.keys(MOUNT_TAG_IN_HANDS_BAND).filter((t) => MOUNT_TAG_IN_HANDS_BAND[t]));
|
|
@@ -1,10 +1,34 @@
|
|
|
1
1
|
import type { AskOrigin } from "./ask-origin.js";
|
|
2
2
|
import type { Settlement } from "./gate-outcome.js";
|
|
3
3
|
/** A tool call presented to a policy before it executes. */
|
|
4
|
+
/** design/388 B6 — the per-call face (see {@link ToolCallRequest.face}). */
|
|
5
|
+
export interface ToolCallFace {
|
|
6
|
+
family: import("./tool-face.js").ToolFamily;
|
|
7
|
+
pathTarget?: {
|
|
8
|
+
param: string;
|
|
9
|
+
aliases: readonly string[];
|
|
10
|
+
access: "read" | "create" | "edit";
|
|
11
|
+
skillScopeEligible: boolean;
|
|
12
|
+
};
|
|
13
|
+
capabilityId: string;
|
|
14
|
+
contractId: string;
|
|
15
|
+
shapeDigest: string;
|
|
16
|
+
implementationRevision: string;
|
|
17
|
+
}
|
|
4
18
|
export interface ToolCallRequest {
|
|
5
19
|
toolName: string;
|
|
6
20
|
args: unknown;
|
|
7
21
|
toolCallId: string;
|
|
22
|
+
/**
|
|
23
|
+
* design/388 B6 (additive) — the mounted tool's FACE as the leg's roster minted it: the declared path target
|
|
24
|
+
* (how the target may be confirmed by path), the display family, and the engine-minted identity
|
|
25
|
+
* (`capabilityId` / `contractId` / `shapeDigest`) an exemption store keys on. Stamped at the gate entry
|
|
26
|
+
* from the live roster, so identity follows the OBJECT the call dispatches to — a caller tool that merely
|
|
27
|
+
* took a built-in's name carries its own face, never the built-in's. ABSENT when a policy is invoked
|
|
28
|
+
* outside a Runner (a bare producer): a path-confining face then reads the catalog's declaration for the
|
|
29
|
+
* NAME (the pre-388 posture, never wider), and a skill-scope face treats the write as unconfirmable.
|
|
30
|
+
*/
|
|
31
|
+
face?: ToolCallFace;
|
|
8
32
|
/**
|
|
9
33
|
* RB-108 — the LIVE working directory this call's RELATIVE path arguments will actually resolve
|
|
10
34
|
* against, read at adjudication time from the same tracked `cwdRef` the fs hand tools resolve with
|
package/dist/core/tool-policy.js
CHANGED
|
@@ -4,6 +4,7 @@ import { brandPolicyAskClass } from "./ask-class.js";
|
|
|
4
4
|
import { sanitizeAutoModeArmingRecipe } from "./auto-mode-arming.js";
|
|
5
5
|
import { join, normalize as normalizePath, posix as posixPath, sep, win32 as winPath } from "node:path";
|
|
6
6
|
import { BASH_READONLY_DEFAULT_ALLOW, parseLeadingCommandName } from "../tools/fs/index.js";
|
|
7
|
+
import { protectivePathTargetOf } from "./tool-registry.js";
|
|
7
8
|
import { boundInputHashOf } from "./canonical-json.js";
|
|
8
9
|
import { delimitUntrusted, inlineUntrusted, REVIEWER_NOTE_MAX_BODY } from "./untrusted-text.js";
|
|
9
10
|
import { isNamespacedCoveringRuleName, namespacedRuleNameCovers, parsePermissionRule } from "./permission-rules.js";
|
|
@@ -847,8 +848,9 @@ export function createTranscriptIntegrityPolicy(opts) {
|
|
|
847
848
|
? "the shell's working directory is inside the transcript directory and this is not a single read-only command (fail-closed)"
|
|
848
849
|
: "the command references the transcript directory and is not a single read-only command (fail-closed)");
|
|
849
850
|
}
|
|
850
|
-
|
|
851
|
-
|
|
851
|
+
const writeTarget = protectivePathTargetOf(req);
|
|
852
|
+
if (writeTarget !== undefined && writeTarget.access !== "read") {
|
|
853
|
+
const p = writeTargetPath(req);
|
|
852
854
|
if (typeof p === "string" && inProtectedDir(p, req.cwd)) {
|
|
853
855
|
return askReason(`"${p}" is inside the session-transcript directory`);
|
|
854
856
|
}
|