@capybara-hq/kernel 0.1.0-rc.2 → 0.1.0-rc.3

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.
Files changed (133) hide show
  1. package/dist/agents/agent-lookup.js +10 -2
  2. package/dist/agents/agents.service.js +19 -6
  3. package/dist/agents/definition.d.ts +31 -8
  4. package/dist/agents/definition.js +193 -17
  5. package/dist/agents/templates.js +19 -4
  6. package/dist/catalog/catalog-content.js +4 -1
  7. package/dist/catalog/claude/agents.js +13 -10
  8. package/dist/catalog/marketplaces.service.d.ts +1 -1
  9. package/dist/channels/cards.d.ts +8 -2
  10. package/dist/channels/cards.js +16 -8
  11. package/dist/config/schema.js +2 -2
  12. package/dist/conversations/artifacts.d.ts +1 -1
  13. package/dist/conversations/artifacts.js +1 -1
  14. package/dist/conversations/event-log.d.ts +11 -0
  15. package/dist/conversations/event-log.js +19 -0
  16. package/dist/conversations/events.d.ts +23 -3
  17. package/dist/conversations/events.js +26 -14
  18. package/dist/db/kernel-schema.d.ts +2 -2
  19. package/dist/evals/recorded-tools.d.ts +27 -1
  20. package/dist/evals/recorded-tools.js +85 -10
  21. package/dist/evals/run-replay.d.ts +5 -0
  22. package/dist/evals/run-replay.js +19 -5
  23. package/dist/evals/trajectory.d.ts +2 -2
  24. package/dist/identity/settings.js +1 -1
  25. package/dist/lifecycle/kernel-lifecycle.js +5 -0
  26. package/dist/orgs/settings.service.d.ts +2 -2
  27. package/dist/orgs/settings.service.js +2 -2
  28. package/dist/runtime/context/build.d.ts +6 -6
  29. package/dist/runtime/context/build.js +18 -8
  30. package/dist/runtime/context/claude-tools.d.ts +2 -1
  31. package/dist/runtime/context/claude-tools.js +9 -10
  32. package/dist/runtime/context/legacy-text.d.ts +22 -0
  33. package/dist/runtime/context/legacy-text.js +37 -0
  34. package/dist/runtime/context/skills.d.ts +29 -11
  35. package/dist/runtime/context/skills.js +37 -30
  36. package/dist/runtime/loop.d.ts +1 -1
  37. package/dist/runtime/model-call.js +1 -1
  38. package/dist/runtime/run-finish.d.ts +1 -1
  39. package/dist/runtime/run-queue.d.ts +3 -3
  40. package/dist/runtime/run-queue.js +2 -2
  41. package/dist/runtime/run-worker.d.ts +2 -2
  42. package/dist/runtime/run-worker.js +4 -4
  43. package/dist/runtime/subagents/definition.d.ts +1 -6
  44. package/dist/runtime/subagents/definition.js +11 -12
  45. package/dist/runtime/subagents/dispatch.d.ts +2 -2
  46. package/dist/runtime/subagents/dispatch.js +2 -2
  47. package/dist/runtime/subagents/org-agents.js +2 -1
  48. package/dist/runtime/subagents/roster.d.ts +1 -1
  49. package/dist/runtime/subagents/roster.js +1 -1
  50. package/dist/runtime/subagents/skill-fork.d.ts +2 -2
  51. package/dist/runtime/subagents/skill-fork.js +2 -2
  52. package/dist/runtime/subagents/subagents.service.d.ts +3 -3
  53. package/dist/runtime/subagents/subagents.service.js +3 -3
  54. package/dist/runtime/waits.d.ts +5 -5
  55. package/dist/runtime/waits.js +5 -5
  56. package/dist/skills/catalog.d.ts +4 -4
  57. package/dist/skills/catalog.js +4 -4
  58. package/dist/skills/changes.service.d.ts +2 -2
  59. package/dist/skills/changes.service.js +5 -4
  60. package/dist/skills/invocation-keys.d.ts +1 -1
  61. package/dist/skills/invocation-keys.js +1 -1
  62. package/dist/skills/invoke.d.ts +1 -1
  63. package/dist/skills/invoke.js +5 -4
  64. package/dist/tools/approvals.service.d.ts +6 -0
  65. package/dist/tools/approvals.service.js +19 -1
  66. package/dist/tools/builtin-names.d.ts +73 -0
  67. package/dist/tools/builtin-names.js +116 -0
  68. package/dist/tools/builtins/agent.d.ts +7 -7
  69. package/dist/tools/builtins/agent.js +7 -11
  70. package/dist/tools/builtins/ask-user.d.ts +1 -1
  71. package/dist/tools/builtins/ask-user.js +2 -2
  72. package/dist/tools/builtins/builtin-tools.d.ts +2 -2
  73. package/dist/tools/builtins/builtin-tools.js +2 -2
  74. package/dist/tools/builtins/read-tool-output.d.ts +1 -1
  75. package/dist/tools/builtins/read-tool-output.js +2 -2
  76. package/dist/tools/builtins/sandbox/bash.d.ts +5 -5
  77. package/dist/tools/builtins/sandbox/bash.js +31 -28
  78. package/dist/tools/builtins/sandbox/common.d.ts +3 -3
  79. package/dist/tools/builtins/sandbox/common.js +2 -2
  80. package/dist/tools/builtins/sandbox/deliver.d.ts +1 -1
  81. package/dist/tools/builtins/sandbox/deliver.js +11 -11
  82. package/dist/tools/builtins/sandbox/edit.d.ts +1 -1
  83. package/dist/tools/builtins/sandbox/edit.js +41 -30
  84. package/dist/tools/builtins/sandbox/file-state.d.ts +34 -0
  85. package/dist/tools/builtins/sandbox/file-state.js +34 -0
  86. package/dist/tools/builtins/sandbox/glob-match.d.ts +1 -1
  87. package/dist/tools/builtins/sandbox/glob-match.js +1 -1
  88. package/dist/tools/builtins/sandbox/glob.d.ts +1 -1
  89. package/dist/tools/builtins/sandbox/glob.js +4 -4
  90. package/dist/tools/builtins/sandbox/grep.d.ts +7 -4
  91. package/dist/tools/builtins/sandbox/grep.js +147 -30
  92. package/dist/tools/builtins/sandbox/index.d.ts +1 -1
  93. package/dist/tools/builtins/sandbox/index.js +1 -1
  94. package/dist/tools/builtins/sandbox/read.d.ts +2 -2
  95. package/dist/tools/builtins/sandbox/read.js +21 -14
  96. package/dist/tools/builtins/sandbox/write.d.ts +1 -1
  97. package/dist/tools/builtins/sandbox/write.js +37 -33
  98. package/dist/tools/builtins/skill-load.d.ts +3 -3
  99. package/dist/tools/builtins/skill-load.js +32 -16
  100. package/dist/tools/builtins/skill-write.d.ts +4 -4
  101. package/dist/tools/builtins/skill-write.js +10 -10
  102. package/dist/tools/builtins/tool-search.d.ts +13 -9
  103. package/dist/tools/builtins/tool-search.js +25 -14
  104. package/dist/tools/connectors.service.js +4 -4
  105. package/dist/tools/display-names.d.ts +9 -0
  106. package/dist/tools/display-names.js +24 -0
  107. package/dist/tools/drift.js +5 -5
  108. package/dist/tools/elicitation.js +1 -1
  109. package/dist/tools/info.d.ts +20 -4
  110. package/dist/tools/info.js +55 -32
  111. package/dist/tools/legacy-data.d.ts +34 -0
  112. package/dist/tools/legacy-data.js +76 -0
  113. package/dist/tools/legacy-keys.d.ts +51 -0
  114. package/dist/tools/legacy-keys.js +115 -0
  115. package/dist/tools/naming.d.ts +1 -5
  116. package/dist/tools/naming.js +1 -7
  117. package/dist/tools/outputs.js +1 -1
  118. package/dist/tools/pipeline.d.ts +13 -7
  119. package/dist/tools/pipeline.js +97 -39
  120. package/dist/tools/policy.d.ts +1 -14
  121. package/dist/tools/policy.js +13 -19
  122. package/dist/tools/questions.controller.d.ts +1 -1
  123. package/dist/tools/questions.controller.js +1 -1
  124. package/dist/tools/questions.service.d.ts +1 -1
  125. package/dist/tools/registry.d.ts +16 -21
  126. package/dist/tools/registry.js +29 -37
  127. package/dist/tools/resources.d.ts +1 -1
  128. package/dist/tools/resources.js +1 -1
  129. package/dist/tools/tools.module.js +1 -1
  130. package/package.json +2 -2
  131. package/src/migrations/0063_tool_keys_claude_code.sql +220 -0
  132. package/dist/tools/builtins/sandbox/names.d.ts +0 -7
  133. package/dist/tools/builtins/sandbox/names.js +0 -20
@@ -0,0 +1,73 @@
1
+ import type { AgentToolRef } from "../agents/definition.js";
2
+ import type { ToolKind } from "./info.js";
3
+ /**
4
+ * The names (model-visible keys) of the kernel's builtin tools, following Claude Code (tool naming
5
+ * spec §4.1). Plain constants: `BuiltinTools`, the tool factories, the registry, policy and the
6
+ * runtime import them from here. The web keeps its own copy (`apps/web/src/lib/agents.ts`,
7
+ * `lib/timeline.ts`), checked equal by `test/tools/builtin-names.test.ts`. The release-candidate
8
+ * names are in `legacy-keys.ts`, never here.
9
+ */
10
+ export declare const BUILTIN: {
11
+ readonly Bash: "Bash";
12
+ readonly Read: "Read";
13
+ readonly Write: "Write";
14
+ readonly Edit: "Edit";
15
+ readonly Glob: "Glob";
16
+ readonly Grep: "Grep";
17
+ readonly Deliver: "Deliver";
18
+ readonly Skill: "Skill";
19
+ readonly SkillWrite: "SkillWrite";
20
+ readonly AskUserQuestion: "AskUserQuestion";
21
+ readonly ReadToolOutput: "ReadToolOutput";
22
+ readonly ToolSearch: "ToolSearch";
23
+ readonly Agent: "Agent";
24
+ };
25
+ export type BuiltinName = (typeof BUILTIN)[keyof typeof BUILTIN];
26
+ /** The builtin tools that run in the conversation's sandbox. */
27
+ export declare const SANDBOX_TOOL_NAMES: readonly BuiltinName[];
28
+ /** Sandbox tools that need approval when the org setting `sandboxToolPolicy` is `ask` (not the read-only ones). */
29
+ export declare const SANDBOX_ASK_TOOL_NAMES: ReadonlySet<string>;
30
+ /**
31
+ * Every builtin name. Saving an agent checks builtin refs against this list, not against what is
32
+ * registered now, so the order the implementations land in never affects a saved definition.
33
+ * `SkillWrite` is available only when a definition names it; `ToolSearch` and `Skill` are added
34
+ * by the registry; `Agent` dispatches sub-agents and its description is built per agent.
35
+ */
36
+ export declare const BUILTIN_TOOL_NAMES: readonly BuiltinName[];
37
+ /** The builtin that loads a skill (added by the registry when the log has a skills catalog). */
38
+ export declare const SKILL_LOAD: "Skill";
39
+ /** The builtin that searches the tool catalog (added by the registry by org setting and threshold). */
40
+ export declare const TOOL_SEARCH: "ToolSearch";
41
+ /** The builtin that dispatches sub-agents. */
42
+ export declare const AGENT_TOOL: "Agent";
43
+ /**
44
+ * Tool keys on the spec 3.6 R3 fixed list ("allowed is not confirmed"): their policy is at least
45
+ * `ask` and remembered grants never let them through. `SkillWrite` changes shared skills.
46
+ * Connector and extension tools express the same rule with `annotations.requiresUserInteraction`.
47
+ */
48
+ export declare const R3_FIXED_ASK_TOOL_KEYS: ReadonlySet<string>;
49
+ /**
50
+ * R3 keys that apply only to shared agents: a private agent's skills are not shared, so its
51
+ * `SkillWrite` takes effect without asking (R4).
52
+ */
53
+ export declare const R3_SHARED_AGENT_ONLY_TOOL_KEYS: ReadonlySet<string>;
54
+ /**
55
+ * Tools a sub-agent never gets (sub-agents spec §5.3, §5.5): `Agent` (depth 1), `AskUserQuestion`
56
+ * (the person does not see the child), `Deliver` (delivering files is the parent's job) and
57
+ * `SkillWrite`.
58
+ */
59
+ export declare const CHILD_REMOVED_TOOLS: readonly ["Agent", "AskUserQuestion", "Deliver", "SkillWrite"];
60
+ /**
61
+ * The tools of a new agent created without `tools` (`ToolSearch` is added by the registry, never
62
+ * by a definition). Only for create requests; updates and stored versions get no defaults.
63
+ */
64
+ export declare const DEFAULT_AGENT_TOOLS: AgentToolRef[];
65
+ /** Kinds of the builtin tools (display only); a builtin missing here is a plain `tool`. */
66
+ export declare const BUILTIN_TOOL_KINDS: Readonly<Record<string, ToolKind>>;
67
+ /**
68
+ * Input fields left out when matching a replayed call with a recorded one (full-run replay), per
69
+ * tool: display-only arguments the model writes that do not change what the tool does. `Bash`'s
70
+ * `description` became required in UI refresh B, so a recording without it and a replayed call
71
+ * with one (or a different wording) still match.
72
+ */
73
+ export declare const MATCH_IGNORED_FIELDS: Readonly<Record<string, readonly string[]>>;
@@ -0,0 +1,116 @@
1
+ /**
2
+ * The names (model-visible keys) of the kernel's builtin tools, following Claude Code (tool naming
3
+ * spec §4.1). Plain constants: `BuiltinTools`, the tool factories, the registry, policy and the
4
+ * runtime import them from here. The web keeps its own copy (`apps/web/src/lib/agents.ts`,
5
+ * `lib/timeline.ts`), checked equal by `test/tools/builtin-names.test.ts`. The release-candidate
6
+ * names are in `legacy-keys.ts`, never here.
7
+ */
8
+ export const BUILTIN = {
9
+ Bash: "Bash",
10
+ Read: "Read",
11
+ Write: "Write",
12
+ Edit: "Edit",
13
+ Glob: "Glob",
14
+ Grep: "Grep",
15
+ Deliver: "Deliver",
16
+ Skill: "Skill",
17
+ SkillWrite: "SkillWrite",
18
+ AskUserQuestion: "AskUserQuestion",
19
+ ReadToolOutput: "ReadToolOutput",
20
+ ToolSearch: "ToolSearch",
21
+ Agent: "Agent",
22
+ };
23
+ /** The builtin tools that run in the conversation's sandbox. */
24
+ export const SANDBOX_TOOL_NAMES = [
25
+ BUILTIN.Bash,
26
+ BUILTIN.Read,
27
+ BUILTIN.Write,
28
+ BUILTIN.Edit,
29
+ BUILTIN.Glob,
30
+ BUILTIN.Grep,
31
+ BUILTIN.Deliver,
32
+ ];
33
+ /** Sandbox tools that need approval when the org setting `sandboxToolPolicy` is `ask` (not the read-only ones). */
34
+ export const SANDBOX_ASK_TOOL_NAMES = new Set([
35
+ BUILTIN.Bash,
36
+ BUILTIN.Write,
37
+ BUILTIN.Edit,
38
+ BUILTIN.Deliver,
39
+ ]);
40
+ /**
41
+ * Every builtin name. Saving an agent checks builtin refs against this list, not against what is
42
+ * registered now, so the order the implementations land in never affects a saved definition.
43
+ * `SkillWrite` is available only when a definition names it; `ToolSearch` and `Skill` are added
44
+ * by the registry; `Agent` dispatches sub-agents and its description is built per agent.
45
+ */
46
+ export const BUILTIN_TOOL_NAMES = [
47
+ BUILTIN.AskUserQuestion,
48
+ BUILTIN.ReadToolOutput,
49
+ BUILTIN.ToolSearch,
50
+ BUILTIN.Skill,
51
+ BUILTIN.SkillWrite,
52
+ ...SANDBOX_TOOL_NAMES,
53
+ BUILTIN.Agent,
54
+ ];
55
+ /** The builtin that loads a skill (added by the registry when the log has a skills catalog). */
56
+ export const SKILL_LOAD = BUILTIN.Skill;
57
+ /** The builtin that searches the tool catalog (added by the registry by org setting and threshold). */
58
+ export const TOOL_SEARCH = BUILTIN.ToolSearch;
59
+ /** The builtin that dispatches sub-agents. */
60
+ export const AGENT_TOOL = BUILTIN.Agent;
61
+ /**
62
+ * Tool keys on the spec 3.6 R3 fixed list ("allowed is not confirmed"): their policy is at least
63
+ * `ask` and remembered grants never let them through. `SkillWrite` changes shared skills.
64
+ * Connector and extension tools express the same rule with `annotations.requiresUserInteraction`.
65
+ */
66
+ export const R3_FIXED_ASK_TOOL_KEYS = new Set([BUILTIN.SkillWrite]);
67
+ /**
68
+ * R3 keys that apply only to shared agents: a private agent's skills are not shared, so its
69
+ * `SkillWrite` takes effect without asking (R4).
70
+ */
71
+ export const R3_SHARED_AGENT_ONLY_TOOL_KEYS = new Set([
72
+ BUILTIN.SkillWrite,
73
+ ]);
74
+ /**
75
+ * Tools a sub-agent never gets (sub-agents spec §5.3, §5.5): `Agent` (depth 1), `AskUserQuestion`
76
+ * (the person does not see the child), `Deliver` (delivering files is the parent's job) and
77
+ * `SkillWrite`.
78
+ */
79
+ export const CHILD_REMOVED_TOOLS = [
80
+ BUILTIN.Agent,
81
+ BUILTIN.AskUserQuestion,
82
+ BUILTIN.Deliver,
83
+ BUILTIN.SkillWrite,
84
+ ];
85
+ /**
86
+ * The tools of a new agent created without `tools` (`ToolSearch` is added by the registry, never
87
+ * by a definition). Only for create requests; updates and stored versions get no defaults.
88
+ */
89
+ export const DEFAULT_AGENT_TOOLS = [
90
+ { kind: "builtin", name: BUILTIN.AskUserQuestion },
91
+ { kind: "builtin", name: BUILTIN.ReadToolOutput },
92
+ ];
93
+ /** Kinds of the builtin tools (display only); a builtin missing here is a plain `tool`. */
94
+ export const BUILTIN_TOOL_KINDS = {
95
+ [BUILTIN.Bash]: "command",
96
+ [BUILTIN.Read]: "read",
97
+ [BUILTIN.Write]: "edit",
98
+ [BUILTIN.Edit]: "edit",
99
+ [BUILTIN.Glob]: "search",
100
+ [BUILTIN.Grep]: "search",
101
+ [BUILTIN.Deliver]: "tool",
102
+ [BUILTIN.ToolSearch]: "meta",
103
+ [BUILTIN.Skill]: "meta",
104
+ [BUILTIN.SkillWrite]: "meta",
105
+ [BUILTIN.ReadToolOutput]: "meta",
106
+ [BUILTIN.AskUserQuestion]: "meta",
107
+ };
108
+ /**
109
+ * Input fields left out when matching a replayed call with a recorded one (full-run replay), per
110
+ * tool: display-only arguments the model writes that do not change what the tool does. `Bash`'s
111
+ * `description` became required in UI refresh B, so a recording without it and a replayed call
112
+ * with one (or a different wording) still match.
113
+ */
114
+ export const MATCH_IGNORED_FIELDS = {
115
+ [BUILTIN.Bash]: ["description"],
116
+ };
@@ -3,15 +3,15 @@ import { z } from "zod";
3
3
  import type { EventPayload } from "../../conversations/events.js";
4
4
  import { type RosterEntry } from "../../runtime/subagents/roster.js";
5
5
  import type { BuiltinTool } from "../registry.js";
6
+ export { AGENT_TOOL } from "../builtin-names.js";
6
7
  /**
7
- * The `agent` builtin tool (sub-agents spec §4): dispatches a sub-agent. Its description is built
8
+ * The `Agent` builtin tool (sub-agents spec §4): dispatches a sub-agent. Its description is built
8
9
  * per parent agent version from the roster ({@link agentToolSpec}); the tool pipeline handles the
9
10
  * call itself (dispatch, suspend, resume), so {@link agentTool}'s `run` is only a guard.
10
11
  */
11
- export declare const AGENT_TOOL = "agent";
12
12
  /** How a sub-agent's run ended (`subagent_finished.status`). */
13
13
  export type SubagentStatus = EventPayload<"subagent_finished">["status"];
14
- /** The input of an `agent` call (§4.2). */
14
+ /** The input of an `Agent` call (§4.2). */
15
15
  export declare const AgentToolInput: z.ZodObject<{
16
16
  description: z.ZodString;
17
17
  prompt: z.ZodString;
@@ -26,7 +26,7 @@ export declare const AgentToolInput: z.ZodObject<{
26
26
  }, z.core.$strict>;
27
27
  export type AgentToolInputT = z.infer<typeof AgentToolInput>;
28
28
  /**
29
- * The `agent` tool definition of a parent agent version (§4.3): the fixed text with
29
+ * The `Agent` tool definition of a parent agent version (§4.3): the fixed text with
30
30
  * `maxConcurrent`, then one line per roster entry in roster order. Built at tool resolution, so the
31
31
  * spec hash changes with the roster or the limit (logged per request in `tool_specs`).
32
32
  */
@@ -45,7 +45,7 @@ export declare const AGENT_REFUSALS: {
45
45
  };
46
46
  /**
47
47
  * The parent run was stopped while this sub-agent worked (§4.4, §12): the result of a stopped
48
- * parent's open `agent` call, and the text of a child stopped with its parent.
48
+ * parent's open `Agent` call, and the text of a child stopped with its parent.
49
49
  */
50
50
  export declare const AGENT_STOPPED_WITH_RUN_TEXT = "The run was stopped while this sub-agent was working; it was stopped too.";
51
51
  /**
@@ -65,7 +65,7 @@ export declare function agentResultText(r: {
65
65
  ownModel?: boolean;
66
66
  abortedBy?: "user" | "parent";
67
67
  /**
68
- * Phase D: the report of a person's fork invocation, whose parent need not have the `agent`
68
+ * Phase D: the report of a person's fork invocation, whose parent need not have the `Agent`
69
69
  * tool: the status line leaves out the resume hint (batch 3 review m2).
70
70
  */
71
71
  noResumeHint?: boolean;
@@ -75,7 +75,7 @@ export declare function agentResultText(r: {
75
75
  };
76
76
  /**
77
77
  * The builtin. `defaultPolicy: "allow"` (§4.6): a sub-agent runs only tools its parent may run,
78
- * each under its own policy. The tool pipeline dispatches `agent` calls itself; `run` answers only
78
+ * each under its own policy. The tool pipeline dispatches `Agent` calls itself; `run` answers only
79
79
  * when a call reaches it anyway.
80
80
  */
81
81
  export declare const agentTool: BuiltinTool;
@@ -1,12 +1,8 @@
1
1
  import { z } from "zod";
2
2
  import { ROSTER_DESCRIPTION_MAX } from "../../runtime/subagents/roster.js";
3
- /**
4
- * The `agent` builtin tool (sub-agents spec §4): dispatches a sub-agent. Its description is built
5
- * per parent agent version from the roster ({@link agentToolSpec}); the tool pipeline handles the
6
- * call itself (dispatch, suspend, resume), so {@link agentTool}'s `run` is only a guard.
7
- */
8
- export const AGENT_TOOL = "agent";
9
- /** The input of an `agent` call (§4.2). */
3
+ import { AGENT_TOOL } from "../builtin-names.js";
4
+ export { AGENT_TOOL } from "../builtin-names.js";
5
+ /** The input of an `Agent` call (§4.2). */
10
6
  export const AgentToolInput = z
11
7
  .object({
12
8
  description: z.string().min(1).max(80),
@@ -86,7 +82,7 @@ function rosterLine(e) {
86
82
  : `${line} (the agent "${inert(e.agentName).replaceAll('"', "'")}", with its own tools and model)`;
87
83
  }
88
84
  /**
89
- * The `agent` tool definition of a parent agent version (§4.3): the fixed text with
85
+ * The `Agent` tool definition of a parent agent version (§4.3): the fixed text with
90
86
  * `maxConcurrent`, then one line per roster entry in roster order. Built at tool resolution, so the
91
87
  * spec hash changes with the roster or the limit (logged per request in `tool_specs`).
92
88
  */
@@ -105,7 +101,7 @@ export function agentToolSpec(roster, maxConcurrent) {
105
101
  * `agentToolSpec([general-purpose], 4)`.
106
102
  */
107
103
  const SPEC = {
108
- name: "agent",
104
+ name: "Agent",
109
105
  description: "Dispatch a sub-agent: a fresh agent with its own context that works on one task and returns its " +
110
106
  "final reply as this tool's result. The sub-agent sees only your prompt, not this conversation, so " +
111
107
  "include everything it needs and say what its final reply must contain. It shares your sandbox " +
@@ -134,7 +130,7 @@ export const AGENT_REFUSALS = {
134
130
  };
135
131
  /**
136
132
  * The parent run was stopped while this sub-agent worked (§4.4, §12): the result of a stopped
137
- * parent's open `agent` call, and the text of a child stopped with its parent.
133
+ * parent's open `Agent` call, and the text of a child stopped with its parent.
138
134
  */
139
135
  export const AGENT_STOPPED_WITH_RUN_TEXT = "The run was stopped while this sub-agent was working; it was stopped too.";
140
136
  /** `12345` → `12,345` (no locale data involved, so the text is the same on every replica). */
@@ -210,7 +206,7 @@ export function agentResultText(r) {
210
206
  }
211
207
  /**
212
208
  * The builtin. `defaultPolicy: "allow"` (§4.6): a sub-agent runs only tools its parent may run,
213
- * each under its own policy. The tool pipeline dispatches `agent` calls itself; `run` answers only
209
+ * each under its own policy. The tool pipeline dispatches `Agent` calls itself; `run` answers only
214
210
  * when a call reaches it anyway.
215
211
  */
216
212
  export const agentTool = {
@@ -18,7 +18,7 @@ export declare function questionsForm(questions: Question[]): InputForm;
18
18
  /** 答案 → 给模型的结果文本:`User answered: "<question>" = "<answer>"; …`。 */
19
19
  export declare function answerText(questions: Question[], answer: FormAnswer): string;
20
20
  /**
21
- * 内置工具 `ask_user`:用通用的输入请求机制实现——首次调用返回 `input_required`,
21
+ * 内置工具 `AskUserQuestion`:用通用的输入请求机制实现——首次调用返回 `input_required`,
22
22
  * 内核暂停运行并展示表单;用户回答(或超时)后用同一 input 再次调用,按 `ctx.resume` 生成结果。
23
23
  * 默认 allow(提问本身就是让用户参与,不再审批)。
24
24
  */
@@ -1,6 +1,6 @@
1
1
  import { ToolError } from "@capybara-hq/plugin-sdk";
2
2
  const SPEC = {
3
- name: "ask_user",
3
+ name: "AskUserQuestion",
4
4
  description: "Ask the user one or more multiple-choice questions and wait for the answers. Use it when you " +
5
5
  "need the user's preference or decision to continue, or when a request is ambiguous; do not use " +
6
6
  "it for questions you can answer yourself. Each question has a short header, 2-4 options with a " +
@@ -103,7 +103,7 @@ const text = (t, zh, en) => ({
103
103
  display: { summary: { zh, en } },
104
104
  });
105
105
  /**
106
- * 内置工具 `ask_user`:用通用的输入请求机制实现——首次调用返回 `input_required`,
106
+ * 内置工具 `AskUserQuestion`:用通用的输入请求机制实现——首次调用返回 `input_required`,
107
107
  * 内核暂停运行并展示表单;用户回答(或超时)后用同一 input 再次调用,按 `ctx.resume` 生成结果。
108
108
  * 默认 allow(提问本身就是让用户参与,不再审批)。
109
109
  */
@@ -9,9 +9,9 @@ import { ToolOutputs } from "../outputs.js";
9
9
  import type { BuiltinTool } from "../registry.js";
10
10
  /**
11
11
  * The kernel's builtin tools, built once from the injected services (their specs: names,
12
- * descriptions and schemas, are the factories' own and unchanged). `tool_search` and `skill_load`
12
+ * descriptions and schemas, are the factories' own and unchanged). `ToolSearch` and `Skill`
13
13
  * are added to a run by the registry (`forAgent`: organization setting and threshold, a skills
14
- * catalog snapshot), not by agent definitions; `skill_write` only when a definition names it.
14
+ * catalog snapshot), not by agent definitions; `SkillWrite` only when a definition names it.
15
15
  */
16
16
  export declare class BuiltinTools {
17
17
  private readonly tools;
@@ -25,9 +25,9 @@ import { skillWriteTool } from "./skill-write.js";
25
25
  import { toolSearchTool } from "./tool-search.js";
26
26
  /**
27
27
  * The kernel's builtin tools, built once from the injected services (their specs: names,
28
- * descriptions and schemas, are the factories' own and unchanged). `tool_search` and `skill_load`
28
+ * descriptions and schemas, are the factories' own and unchanged). `ToolSearch` and `Skill`
29
29
  * are added to a run by the registry (`forAgent`: organization setting and threshold, a skills
30
- * catalog snapshot), not by agent definitions; `skill_write` only when a definition names it.
30
+ * catalog snapshot), not by agent definitions; `SkillWrite` only when a definition names it.
31
31
  */
32
32
  let BuiltinTools = class BuiltinTools {
33
33
  tools;
@@ -11,7 +11,7 @@ export declare function readPage(id: string, content: string, opts: {
11
11
  charOffset: number;
12
12
  budget: number;
13
13
  }): string;
14
- /** 内置工具 `read_tool_output`:读本会话未过期的输出存档(只读、默认 allow)。 */
14
+ /** 内置工具 `ReadToolOutput`:读本会话未过期的输出存档(只读、默认 allow)。 */
15
15
  export declare function readToolOutputTool(deps: {
16
16
  outputs: Pick<ToolOutputs, "load">;
17
17
  config: Pick<KernelConfigService, "get">;
@@ -8,7 +8,7 @@ const DEFAULT_LIMIT = 200;
8
8
  */
9
9
  const FOOTER_RESERVE = 200;
10
10
  const SPEC = {
11
- name: "read_tool_output",
11
+ name: "ReadToolOutput",
12
12
  description: "Read a saved tool output by its id, page by page. Large tool results are truncated in the " +
13
13
  "conversation and saved in full; the truncation notice gives the output id. Lines are numbered " +
14
14
  "from 0. Each call returns up to `limit` lines starting at line `offset`, capped at a maximum " +
@@ -85,7 +85,7 @@ export function readPage(id, content, opts) {
85
85
  const footer = `[Lines ${offset}–${last} of ${total}]`;
86
86
  return [parts.join("\n"), ...(cut === null ? [] : [cut]), footer].join("\n");
87
87
  }
88
- /** 内置工具 `read_tool_output`:读本会话未过期的输出存档(只读、默认 allow)。 */
88
+ /** 内置工具 `ReadToolOutput`:读本会话未过期的输出存档(只读、默认 allow)。 */
89
89
  export function readToolOutputTool(deps) {
90
90
  return {
91
91
  spec: SPEC,
@@ -1,16 +1,16 @@
1
- import { type ExecResult } from "@capybara-hq/plugin-sdk";
1
+ import type { ExecResult } from "@capybara-hq/plugin-sdk";
2
2
  import type { BuiltinTool } from "../../registry.js";
3
3
  import { type SandboxToolDeps } from "./common.js";
4
- /** 不给 `timeoutSeconds` 时的命令超时(秒),不超过 `sandbox.limits.maxCommandSeconds`。 */
4
+ /** The command timeout in seconds when `timeout` is not given, at most `sandbox.limits.maxCommandSeconds`. */
5
5
  export declare const BASH_DEFAULT_TIMEOUT_SECONDS = 120;
6
6
  /** The longest `description` (the shell row shows it instead of the command). */
7
7
  export declare const BASH_DESCRIPTION_MAX_CHARS = 120;
8
- /** bash 结果超过这么多字符即转存(走现有输出存档,模型用 read_tool_output 分页读)。 */
8
+ /** bash 结果超过这么多字符即转存(走现有输出存档,模型用 ReadToolOutput 分页读)。 */
9
9
  export declare const BASH_SPILL_CHARS = 30000;
10
10
  /**
11
11
  * 命令结果 → 给模型的文本。`budgetClamped`:运行的时限把超时收紧到了 `seconds`(Ruling M20),超时说明改为
12
- * 指向 `runtime.maxRunSeconds`,而不是让模型加大 timeoutSeconds。
12
+ * 指向 `runtime.maxRunSeconds`,而不是让模型加大 timeout。
13
13
  */
14
14
  export declare function formatExec(r: ExecResult, seconds: number, budgetClamped?: boolean): string;
15
- /** 内置工具 `sandbox_bash`:在本对话的沙箱里执行命令。 */
15
+ /** 内置工具 `Bash`:在本对话的沙箱里执行命令。 */
16
16
  export declare function sandboxBashTool(deps: SandboxToolDeps): BuiltinTool;
@@ -1,15 +1,14 @@
1
- import { ToolError } from "@capybara-hq/plugin-sdk";
2
1
  import { clip, display, inSandbox, runBudgetNote, runTimeLeftMs, sandboxBaseTimeoutMs, unavailableWhenNoSandbox, withNotices, } from "./common.js";
3
- /** 不给 `timeoutSeconds` 时的命令超时(秒),不超过 `sandbox.limits.maxCommandSeconds`。 */
2
+ /** The command timeout in seconds when `timeout` is not given, at most `sandbox.limits.maxCommandSeconds`. */
4
3
  export const BASH_DEFAULT_TIMEOUT_SECONDS = 120;
5
4
  /** The longest `description` (the shell row shows it instead of the command). */
6
5
  export const BASH_DESCRIPTION_MAX_CHARS = 120;
7
- /** bash 结果超过这么多字符即转存(走现有输出存档,模型用 read_tool_output 分页读)。 */
6
+ /** bash 结果超过这么多字符即转存(走现有输出存档,模型用 ReadToolOutput 分页读)。 */
8
7
  export const BASH_SPILL_CHARS = 30_000;
9
8
  /** 一次命令最多收集的输出字节(stdout + stderr);超出的丢弃并在结果里说明。 */
10
9
  const MAX_OUTPUT_BYTES = 4 * 1024 * 1024;
11
10
  const SPEC = {
12
- name: "sandbox_bash",
11
+ name: "Bash",
13
12
  // Display only (the tool row; not in the fingerprint, never sent to the model).
14
13
  keyArgs: ["command"],
15
14
  description: "Run a shell command (bash) in this conversation's sandbox, an isolated Linux machine. " +
@@ -20,10 +19,10 @@ const SPEC = {
20
19
  "Files the user attached to the conversation are under /workspace/attachments, " +
21
20
  "and skill files under /skills (read-only). Each call runs in a fresh shell (no state such as " +
22
21
  "cd or environment variables carries over). The result has stdout, stderr and the exit code; " +
23
- "long output is saved and can be paged with read_tool_output. A command that runs longer than " +
24
- "timeoutSeconds is stopped. Prefer sandbox_read, sandbox_write, sandbox_edit, sandbox_glob and " +
25
- "sandbox_grep for reading, writing and searching files. To give a file to the user, use " +
26
- "sandbox_deliver. Other sub-agents of this conversation may run commands in this sandbox at " +
22
+ "long output is saved and can be paged with ReadToolOutput. A command that runs longer than " +
23
+ "timeout milliseconds is stopped. Prefer Read, Write, Edit, Glob and " +
24
+ "Grep for reading, writing and searching files. To give a file to the user, use " +
25
+ "Deliver. Other sub-agents of this conversation may run commands in this sandbox at " +
27
26
  "the same time. Always pass description: a few words saying what the command is for; the " +
28
27
  "user sees it instead of the command.",
29
28
  inputSchema: {
@@ -40,21 +39,21 @@ const SPEC = {
40
39
  maxLength: BASH_DESCRIPTION_MAX_CHARS,
41
40
  description: 'What this command does, in a few words (e.g. "Generate the final PDF"). Shown to the user.',
42
41
  },
43
- timeoutSeconds: {
42
+ timeout: {
44
43
  type: "integer",
45
44
  minimum: 1,
46
- description: `Seconds before the command is stopped. Default ${BASH_DEFAULT_TIMEOUT_SECONDS}; the deployment sets a maximum (7200 by default).`,
45
+ description: `Milliseconds before the command is stopped. Default ${BASH_DEFAULT_TIMEOUT_SECONDS * 1000}; the deployment sets a maximum (7200000 by default); a larger value is lowered to it.`,
47
46
  },
48
47
  },
49
48
  required: ["command", "description"],
50
49
  additionalProperties: false,
51
50
  },
52
51
  };
53
- /** 本次命令的超时(秒):给定的值,或默认值(不超过上限)。 */
54
- const secondsFor = (input, max) => input.timeoutSeconds ?? Math.min(BASH_DEFAULT_TIMEOUT_SECONDS, max);
52
+ /** This command's timeout in milliseconds: the given value or the default, at most the maximum. */
53
+ const msFor = (input, maxSeconds) => Math.min(input.timeout ?? BASH_DEFAULT_TIMEOUT_SECONDS * 1000, maxSeconds * 1000);
55
54
  /**
56
55
  * 命令结果 → 给模型的文本。`budgetClamped`:运行的时限把超时收紧到了 `seconds`(Ruling M20),超时说明改为
57
- * 指向 `runtime.maxRunSeconds`,而不是让模型加大 timeoutSeconds。
56
+ * 指向 `runtime.maxRunSeconds`,而不是让模型加大 timeout。
58
57
  */
59
58
  export function formatExec(r, seconds, budgetClamped = false) {
60
59
  const parts = [];
@@ -68,7 +67,7 @@ export function formatExec(r, seconds, budgetClamped = false) {
68
67
  parts.push(`[timedOut: the command did not finish within ${seconds}s and was stopped. ${runBudgetNote(seconds)} The sandbox is still usable; split the work into shorter steps that save progress to files under /workspace, or run long jobs in the background and check on them in a later run.]`);
69
68
  }
70
69
  else if (r.timedOut) {
71
- parts.push(`[timedOut: the command did not finish within ${seconds}s and was stopped. The sandbox is still usable; pass a larger timeoutSeconds (up to the deployment maximum), or split the work into shorter steps that save progress to files under /workspace.]`);
70
+ parts.push(`[timedOut: the command did not finish within ${seconds}s and was stopped. The sandbox is still usable; pass a larger timeout in milliseconds (up to the deployment maximum), or split the work into shorter steps that save progress to files under /workspace.]`);
72
71
  }
73
72
  else if (r.exitCode === null) {
74
73
  parts.push("[The command was stopped before it finished; its effects may be partial. Check the sandbox state before retrying.]");
@@ -80,7 +79,7 @@ export function formatExec(r, seconds, budgetClamped = false) {
80
79
  }
81
80
  return parts.join("\n");
82
81
  }
83
- /** 内置工具 `sandbox_bash`:在本对话的沙箱里执行命令。 */
82
+ /** 内置工具 `Bash`:在本对话的沙箱里执行命令。 */
84
83
  export function sandboxBashTool(deps) {
85
84
  return {
86
85
  spec: SPEC,
@@ -91,33 +90,37 @@ export function sandboxBashTool(deps) {
91
90
  timeoutMs: (input) => {
92
91
  const cfg = deps.config.get();
93
92
  const max = cfg.sandbox.limits.maxCommandSeconds;
94
- return Math.min(secondsFor(input, max), max) * 1000 + sandboxBaseTimeoutMs(cfg);
93
+ return msFor(input, max) + sandboxBaseTimeoutMs(cfg);
95
94
  },
96
95
  async run(input, ctx) {
97
96
  const { command, description } = input;
98
97
  const max = deps.config.get().sandbox.limits.maxCommandSeconds;
99
- const req = input.timeoutSeconds;
100
- if (req !== undefined && req > max) {
101
- throw new ToolError(`timeoutSeconds ${req} is over the limit of ${max} seconds; pass a value of at most ${max}.`);
102
- }
103
- const asked = secondsFor(input, max);
104
- // 运行截止前命令要自己超时(Ruling M20):在拿到沙箱之后算,等锁与恢复用掉的时间一并扣掉
105
- let seconds = asked;
98
+ const requested = input.timeout;
99
+ const maxMs = max * 1000;
100
+ const askedMs = msFor(input, max);
101
+ // The run's deadline makes the command time out itself first (Ruling M20): counted after the
102
+ // sandbox is obtained, so the time spent waiting for the lock and resuming is deducted
103
+ let ms = askedMs;
106
104
  const { value: r, notices } = await inSandbox(deps, ctx, ({ h, p, signal }) => {
107
- const left = Math.floor(runTimeLeftMs(ctx.runDeadline) / 1000);
108
- seconds = Math.max(1, Math.min(asked, left));
105
+ const left = Math.floor(runTimeLeftMs(ctx.runDeadline) / 1000) * 1000;
106
+ ms = Math.max(1000, Math.min(askedMs, left));
109
107
  return p.exec(h, {
110
108
  command,
111
109
  cwd: "/workspace",
112
- timeoutMs: seconds * 1000,
110
+ timeoutMs: ms,
113
111
  maxOutputBytes: MAX_OUTPUT_BYTES,
114
112
  signal,
115
113
  });
116
114
  });
117
- const clamped = seconds < asked;
115
+ const seconds = ms / 1000;
116
+ const clamped = ms < askedMs;
118
117
  const shown = clip(command, 120);
118
+ const lowered = requested !== undefined && requested > maxMs
119
+ ? `\n[timeout ${requested} ms is over the deployment maximum; it was lowered to ${maxMs} ms.]`
120
+ : "";
121
+ const text = formatExec(r, seconds, clamped) + lowered;
119
122
  return {
120
- content: [{ type: "text", text: withNotices(notices, formatExec(r, seconds, clamped)) }],
123
+ content: [{ type: "text", text: withNotices(notices, text) }],
121
124
  isError: r.timedOut || r.exitCode === null,
122
125
  // display only: a non-zero exit shows as failed on the row, `isError` stays as it was
123
126
  view: {
@@ -12,8 +12,8 @@ export interface SandboxToolDeps {
12
12
  sandbox: Pick<SandboxService, "available" | "withSandbox"> & Partial<Pick<SandboxService, "pathLease">>;
13
13
  attachments: Pick<AttachmentsService, "listForConversation" | "openForConversation">;
14
14
  storage: Pick<StorageService, "kernel" | "available">;
15
- /** `publishChanged`: `sandbox_deliver` announces `changed: files` (UI refresh B). */
16
- eventLog: Pick<EventLog, "append"> & Partial<Pick<EventLog, "publishChanged">>;
15
+ /** `publishChanged`: `Deliver` announces `changed: files` (UI refresh B). */
16
+ eventLog: Pick<EventLog, "append" | "latestFileState"> & Partial<Pick<EventLog, "publishChanged">>;
17
17
  config: Pick<KernelConfigService, "get">;
18
18
  }
19
19
  /** 回调拿到的沙箱:句柄、提供方与「调用 signal + 锁丢失」合并后的 signal(每个提供方调用都传它)。 */
@@ -80,7 +80,7 @@ export declare function clip(s: string, max: number): string;
80
80
  export declare function withNotices(notices: readonly string[], text: string): string;
81
81
  /** 校验沙箱内路径(`validateSandboxPath`);不合法抛给模型可执行的错误。 */
82
82
  export declare function checkPath(path: string, field?: string): string;
83
- /** 写入类工具的路径:`/skills` 是技能文件的只读副本。 */
83
+ /** A writing tool's `file_path`: `/skills` is the read-only copy of the skill files. */
84
84
  export declare function checkWritable(path: string): string;
85
85
  /** POSIX shell 单引号转义。 */
86
86
  export declare function shellQuote(s: string): string;
@@ -78,9 +78,9 @@ export function checkPath(path, field = "path") {
78
78
  }
79
79
  return path.length > 1 && path.endsWith("/") ? path.slice(0, -1) : path;
80
80
  }
81
- /** 写入类工具的路径:`/skills` 是技能文件的只读副本。 */
81
+ /** A writing tool's `file_path`: `/skills` is the read-only copy of the skill files. */
82
82
  export function checkWritable(path) {
83
- const p = checkPath(path);
83
+ const p = checkPath(path, "file_path");
84
84
  if (p === "/skills" || p.startsWith("/skills/")) {
85
85
  throw new ToolError(`Path ${clip(p, 200)} is read-only (/skills holds skill files); pass a path under /workspace or /tmp instead.`);
86
86
  }
@@ -1,5 +1,5 @@
1
1
  import type { BuiltinTool } from "../../registry.js";
2
2
  import { type SandboxToolDeps } from "./common.js";
3
3
  export declare function contentTypeFor(name: string): string;
4
- /** 内置工具 `sandbox_deliver`:把沙箱里的文件存进对象存储,写 `artifact_created`,用户可下载。 */
4
+ /** 内置工具 `Deliver`:把沙箱里的文件存进对象存储,写 `artifact_created`,用户可下载。 */
5
5
  export declare function sandboxDeliverTool(deps: SandboxToolDeps): BuiltinTool;