@celestea/core 2.7.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/LICENSE +21 -0
- package/README.md +95 -0
- package/contracts/data-files/checkpoint.schema.json +111 -0
- package/contracts/data-files/cli-main-jsonl-precompact.schema.json +27 -0
- package/contracts/data-files/cli-main-jsonl.schema.json +22 -0
- package/contracts/data-files/fallbacks.schema.json +71 -0
- package/contracts/data-files/index.json +124 -0
- package/contracts/data-files/pricing.schema.json +65 -0
- package/contracts/data-files/prompts.schema.json +130 -0
- package/contracts/data-files/providers.schema.json +177 -0
- package/contracts/data-files/registry-tsv.schema.json +74 -0
- package/contracts/data-files/session.schema.json +51 -0
- package/contracts/data-files/usage-ledger.schema.json +112 -0
- package/contracts/data-files/workspaces.schema.json +63 -0
- package/contracts/endpoints.json +4390 -0
- package/contracts/probe-evidence.json +219 -0
- package/contracts/route-table.snapshot.json +377 -0
- package/contracts/scope-hash-vectors.json +273 -0
- package/contracts/session-event.schema.json +441 -0
- package/contracts/sse-events.json +202 -0
- package/contracts/tools.json +730 -0
- package/dist/agent.d.ts +65 -0
- package/dist/agent.js +36 -0
- package/dist/celestea-home.d.ts +63 -0
- package/dist/celestea-home.js +96 -0
- package/dist/celestea-sources.d.ts +53 -0
- package/dist/celestea-sources.js +61 -0
- package/dist/context.d.ts +33 -0
- package/dist/context.js +55 -0
- package/dist/contracts/index.d.ts +234 -0
- package/dist/contracts/index.js +159 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.js +22 -0
- package/dist/event-bus.d.ts +60 -0
- package/dist/event-bus.js +100 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +66 -0
- package/dist/injection.d.ts +61 -0
- package/dist/injection.js +27 -0
- package/dist/json.d.ts +34 -0
- package/dist/json.js +127 -0
- package/dist/llm.d.ts +34 -0
- package/dist/llm.js +41 -0
- package/dist/memory.d.ts +72 -0
- package/dist/memory.js +123 -0
- package/dist/message.d.ts +189 -0
- package/dist/message.js +252 -0
- package/dist/plugin.d.ts +38 -0
- package/dist/plugin.js +49 -0
- package/dist/projection.d.ts +67 -0
- package/dist/projection.js +168 -0
- package/dist/question.d.ts +154 -0
- package/dist/question.js +82 -0
- package/dist/redact.d.ts +40 -0
- package/dist/redact.js +185 -0
- package/dist/repo.d.ts +14 -0
- package/dist/repo.js +87 -0
- package/dist/sandbox.d.ts +182 -0
- package/dist/sandbox.js +78 -0
- package/dist/session-event.d.ts +57 -0
- package/dist/session-event.js +425 -0
- package/dist/session-log.d.ts +71 -0
- package/dist/session-log.js +66 -0
- package/dist/skill-catalog.d.ts +29 -0
- package/dist/skill-catalog.js +52 -0
- package/dist/skills.d.ts +116 -0
- package/dist/skills.js +273 -0
- package/dist/sse-bus.d.ts +40 -0
- package/dist/sse-bus.js +105 -0
- package/dist/stream.d.ts +115 -0
- package/dist/stream.js +52 -0
- package/dist/tool-surface.d.ts +45 -0
- package/dist/tool-surface.js +98 -0
- package/dist/tool.d.ts +77 -0
- package/dist/tool.js +15 -0
- package/dist/turn-id.d.ts +37 -0
- package/dist/turn-id.js +76 -0
- package/dist/types.d.ts +396 -0
- package/dist/types.js +58 -0
- package/package.json +27 -0
|
@@ -0,0 +1,730 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Celestea engine tool specs (14 tools)",
|
|
4
|
+
"generatedAt": "2026-09-10T01:20:00Z",
|
|
5
|
+
"source": {
|
|
6
|
+
"liveEndpoint": "http://127.0.0.1:3777/api/tools (descriptions taken verbatim from the running engine)",
|
|
7
|
+
"schemas": "/src/celestea_harness/crates/tools/src/*.rs + crates/workers/src/tools.rs (hand-written ToolSpec.parameters, transcribed 1:1)",
|
|
8
|
+
"liveProbe": {
|
|
9
|
+
"checked": true,
|
|
10
|
+
"toolCount": 10,
|
|
11
|
+
"names": [
|
|
12
|
+
"http_request",
|
|
13
|
+
"list_dir",
|
|
14
|
+
"process_control",
|
|
15
|
+
"read_file",
|
|
16
|
+
"run_code",
|
|
17
|
+
"run_shell",
|
|
18
|
+
"session_send_message",
|
|
19
|
+
"spawn_worker",
|
|
20
|
+
"worker_status",
|
|
21
|
+
"write_file"
|
|
22
|
+
],
|
|
23
|
+
"note": "W783: this is the FROZEN 2026-09-10 capture of the retired engine (10 tools) and is deliberately NOT rewritten. The TypeScript host now serves 11 tools; the delta is declared in `w783Delta` below."
|
|
24
|
+
},
|
|
25
|
+
"w783Delta": {
|
|
26
|
+
"addedTool": "ask_user_question",
|
|
27
|
+
"count": "10 -> 11",
|
|
28
|
+
"sourceRef": "packages/tools/src/tools/ask-user.ts (schema copied field-for-field from @deepseek-ai/dsh-tool-ask-user)",
|
|
29
|
+
"why": "The model needs to ask the user a question mid-turn. The answer arrives through POST /api/questions/{id}/answer (NOT /api/turn, which would be steering that a parked tool call never drains) and reaches the model as an ordinary tool_result.",
|
|
30
|
+
"notInRust": "The retired engine has no counterpart: /api/tools there answered 10 tools and this tool did not exist."
|
|
31
|
+
},
|
|
32
|
+
"w804Delta": {
|
|
33
|
+
"addedTool": "read_image",
|
|
34
|
+
"count": "11 -> 12",
|
|
35
|
+
"sourceRef": "docs/feature-multimodal-attachments.md#6",
|
|
36
|
+
"why": "The model needs to look at a local image (or a user-uploaded attachment by id) and have a vision-capable model actually see it; read_file is UTF-8 text only and rejects binary.",
|
|
37
|
+
"optionalMount": "builtinTools mounts read_image only when the host supplies a session attachment store; the default registry of record stays the 7 contract tools.",
|
|
38
|
+
"endpoints": "P0 adds ZERO endpoints: uploads ride POST /api/turn as inline base64 (attachment refs only in the log), so API_ENDPOINT_COUNT stays 51."
|
|
39
|
+
},
|
|
40
|
+
"w7Delta": {
|
|
41
|
+
"renamedTool": "session_send_message -> send_message",
|
|
42
|
+
"addedTool": "stop_worker",
|
|
43
|
+
"count": "12 -> 13",
|
|
44
|
+
"sourceRef": "packages/workers/src/tools.ts (W7; no Rust counterpart)",
|
|
45
|
+
"why": "The orchestration face needs a relay named for what it does (send_message) and a stop switch that halts a worker without deleting it (STOPPED terminal; row + session kept for audit).",
|
|
46
|
+
"notInRust": "The retired engine had neither the rename nor stop_worker.",
|
|
47
|
+
"endpoints": "W7 adds ZERO endpoints: stop_worker rides the existing worker tool dispatch, so API_ENDPOINT_COUNT stays 51."
|
|
48
|
+
},
|
|
49
|
+
"w884Delta": {
|
|
50
|
+
"addedTool": "load_skill",
|
|
51
|
+
"count": "13 -> 14",
|
|
52
|
+
"sourceRef": "packages/tools/src/tools/load-skill.ts (W884; reuses packages/core/src/skills.ts)",
|
|
53
|
+
"why": "Progressive disclosure for skills (W882 discovery + the W874/W879 non-system-prompt decision): the model must be able to load ONE skill's SKILL.md body on demand. The catalog (name + description only) is injected as durable user-role history at every turn start; the body enters the conversation only when this tool is called. Read-only: no writes, no process, no network; the name goes through W882's name contract (no path traversal).",
|
|
54
|
+
"executionKeepList": "W884 also adds load_skill to EXECUTION_TOOL_NAMES: it is a pure read and is NOT in SDK_TOOLS, so folding it would make skills unreachable in execution mode while the catalog still advertises them.",
|
|
55
|
+
"endpoints": "W884 adds ZERO endpoints: the catalog rides the existing turn-start context lane and the tool rides the existing dispatch, so API_ENDPOINT_COUNT stays 61."
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"count": 18,
|
|
59
|
+
"tools": [
|
|
60
|
+
{
|
|
61
|
+
"name": "ask_user_question",
|
|
62
|
+
"description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. Send one or more questions, each with a stable id that will be echoed in the answer. The call PAUSES until the user answers, then returns `{answers:[{id,selected,custom}],timed_out:false}` as an ordinary tool result and you continue. If you recommend one option, put it first and append \"(推荐)\" to that label. The user may always type a free-text answer instead of choosing. Waiting is bounded (default 300000 ms, overridable with `timeout_ms`): on expiry the call returns `{answers:[],timed_out:true}` and NO choice is made for you — do not ask the same question again; state the assumption you are proceeding on (or stop and report) and continue with your own judgement.",
|
|
63
|
+
"parameters": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"properties": {
|
|
66
|
+
"questions": {
|
|
67
|
+
"type": "array",
|
|
68
|
+
"description": "Questions to ask the user before continuing.",
|
|
69
|
+
"items": {
|
|
70
|
+
"type": "object",
|
|
71
|
+
"additionalProperties": true,
|
|
72
|
+
"properties": {
|
|
73
|
+
"id": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"description": "Stable id for this question; echoed in the answer."
|
|
76
|
+
},
|
|
77
|
+
"question": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"description": "The specific question to ask the user."
|
|
80
|
+
},
|
|
81
|
+
"header": {
|
|
82
|
+
"type": "string",
|
|
83
|
+
"description": "Optional short heading for the question, such as \"Confirm\" or \"Choose Mode\"."
|
|
84
|
+
},
|
|
85
|
+
"detail": {
|
|
86
|
+
"type": "string",
|
|
87
|
+
"description": "Optional supporting detail shown with the question. Kept out of the option labels, so it never takes part in label matching."
|
|
88
|
+
},
|
|
89
|
+
"options": {
|
|
90
|
+
"type": "array",
|
|
91
|
+
"description": "Optional choices to show the user. If you recommend one, put it first and append \"(推荐)\" to that label.",
|
|
92
|
+
"items": {
|
|
93
|
+
"type": "object",
|
|
94
|
+
"additionalProperties": true,
|
|
95
|
+
"properties": {
|
|
96
|
+
"label": {
|
|
97
|
+
"type": "string",
|
|
98
|
+
"description": "Short user-facing option label."
|
|
99
|
+
},
|
|
100
|
+
"description": {
|
|
101
|
+
"type": "string",
|
|
102
|
+
"description": "One sentence explaining the tradeoff or impact."
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"required": [
|
|
106
|
+
"label"
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"multi_select": {
|
|
111
|
+
"type": "boolean",
|
|
112
|
+
"description": "Whether the user may select more than one option. Defaults to false."
|
|
113
|
+
},
|
|
114
|
+
"intent": {
|
|
115
|
+
"type": "object",
|
|
116
|
+
"additionalProperties": false,
|
|
117
|
+
"description": "Optional presentation intent. It changes how a capable UI renders the question, never the answer encoding; a UI that does not know the tag shows the generic option list.",
|
|
118
|
+
"properties": {
|
|
119
|
+
"kind": {
|
|
120
|
+
"type": "string",
|
|
121
|
+
"enum": [
|
|
122
|
+
"plan-review"
|
|
123
|
+
],
|
|
124
|
+
"description": "A plan submitted for review."
|
|
125
|
+
},
|
|
126
|
+
"approve": {
|
|
127
|
+
"type": "string",
|
|
128
|
+
"description": "The option label that approves the plan; every other option declines it."
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
"required": [
|
|
132
|
+
"kind",
|
|
133
|
+
"approve"
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"required": [
|
|
138
|
+
"id",
|
|
139
|
+
"question"
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
"timeout_ms": {
|
|
144
|
+
"type": "integer",
|
|
145
|
+
"minimum": 1,
|
|
146
|
+
"description": "Optional maximum wait in milliseconds for the whole batch. Default 300000; capped at 3600000. On expiry the call returns an empty answer set with timed_out:true."
|
|
147
|
+
},
|
|
148
|
+
"desc": {
|
|
149
|
+
"type": "string",
|
|
150
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"required": [
|
|
154
|
+
"questions"
|
|
155
|
+
],
|
|
156
|
+
"additionalProperties": false
|
|
157
|
+
},
|
|
158
|
+
"sourceRef": "W783: packages/tools/src/tools/ask-user.ts (schema copied from @deepseek-ai/dsh-tool-ask-user)"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"name": "browser_act",
|
|
162
|
+
"description": "Act on the page opened by browser_open: click, type into, press a key on, or scroll an element identified by its stable ref from the last snapshot. Returns the updated accessibility snapshot and screenshot. Like browser_open, this call runs with RLIMIT_AS EXEMPTED (virtual address space unbounded) and reports the isolation state in its result.",
|
|
163
|
+
"parameters": {
|
|
164
|
+
"type": "object",
|
|
165
|
+
"properties": {
|
|
166
|
+
"action": {
|
|
167
|
+
"type": "string",
|
|
168
|
+
"enum": [
|
|
169
|
+
"click",
|
|
170
|
+
"type",
|
|
171
|
+
"key",
|
|
172
|
+
"scroll"
|
|
173
|
+
],
|
|
174
|
+
"description": "What to do: click an element, type text into it, press a key, or scroll it."
|
|
175
|
+
},
|
|
176
|
+
"ref": {
|
|
177
|
+
"type": "string",
|
|
178
|
+
"description": "Stable ref from the last snapshot (required for click/type/scroll)."
|
|
179
|
+
},
|
|
180
|
+
"text": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"description": "Text to insert (action=type)."
|
|
183
|
+
},
|
|
184
|
+
"key": {
|
|
185
|
+
"type": "string",
|
|
186
|
+
"description": "Key name for action=key, e.g. Enter, Tab, Escape."
|
|
187
|
+
},
|
|
188
|
+
"delta_x": {
|
|
189
|
+
"type": "integer",
|
|
190
|
+
"description": "Horizontal scroll delta in pixels (action=scroll; default 0)."
|
|
191
|
+
},
|
|
192
|
+
"delta_y": {
|
|
193
|
+
"type": "integer",
|
|
194
|
+
"description": "Vertical scroll delta in pixels (action=scroll; default 0)."
|
|
195
|
+
},
|
|
196
|
+
"desc": {
|
|
197
|
+
"type": "string",
|
|
198
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
"required": [
|
|
202
|
+
"action"
|
|
203
|
+
],
|
|
204
|
+
"additionalProperties": false
|
|
205
|
+
},
|
|
206
|
+
"sourceRef": "packages/tools/src/tools/browser.ts (F4 step 2b; drives packages/tools/src/browser/session.ts)"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"name": "browser_open",
|
|
210
|
+
"description": "Open an absolute http(s) URL in a session-scoped headless browser and return the page's accessibility snapshot (interactive elements with stable refs) plus a PNG screenshot. Use those refs with browser_act. Requires the session's network capability (the sandbox must share the host network so the DevTools endpoint is reachable) and a session attachment store for the screenshot. This call runs with RLIMIT_AS EXEMPTED: the browser's virtual address space is NOT bounded by the sandbox, because Chromium cannot start under an address-space cap. Every other sandbox limit and the exact isolation state are reported in the result's isolation block.",
|
|
211
|
+
"parameters": {
|
|
212
|
+
"type": "object",
|
|
213
|
+
"properties": {
|
|
214
|
+
"url": {
|
|
215
|
+
"type": "string",
|
|
216
|
+
"description": "Absolute http(s) URL to open."
|
|
217
|
+
},
|
|
218
|
+
"viewport": {
|
|
219
|
+
"type": "object",
|
|
220
|
+
"description": "Optional viewport size in CSS pixels (default 800x600).",
|
|
221
|
+
"properties": {
|
|
222
|
+
"width": {
|
|
223
|
+
"type": "integer"
|
|
224
|
+
},
|
|
225
|
+
"height": {
|
|
226
|
+
"type": "integer"
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
"required": [
|
|
230
|
+
"width",
|
|
231
|
+
"height"
|
|
232
|
+
],
|
|
233
|
+
"additionalProperties": false
|
|
234
|
+
},
|
|
235
|
+
"desc": {
|
|
236
|
+
"type": "string",
|
|
237
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
"required": [
|
|
241
|
+
"url"
|
|
242
|
+
],
|
|
243
|
+
"additionalProperties": false
|
|
244
|
+
},
|
|
245
|
+
"sourceRef": "packages/tools/src/tools/browser.ts (F4 step 2b; drives packages/tools/src/browser/session.ts)"
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"name": "forget",
|
|
249
|
+
"description": "Retract a previously remembered fact by its `id` (as returned by `remember`) or by its exact `text`. This APPENDS a tombstone to the workspace's append-only memory log — history is never rewritten, the entry is hidden from future turns. Only entries in this workspace's GLOBAL memory layer can be forgotten; a project-layer MEMORY.md is read-only. The result reports the layer, the absolute file, and the id retired.",
|
|
250
|
+
"parameters": {
|
|
251
|
+
"type": "object",
|
|
252
|
+
"properties": {
|
|
253
|
+
"id": {
|
|
254
|
+
"type": "string",
|
|
255
|
+
"description": "Entry id to retract (as returned by remember)."
|
|
256
|
+
},
|
|
257
|
+
"text": {
|
|
258
|
+
"type": "string",
|
|
259
|
+
"description": "Exact text of the entry to retract (alternative to id)."
|
|
260
|
+
},
|
|
261
|
+
"desc": {
|
|
262
|
+
"type": "string",
|
|
263
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
"additionalProperties": false,
|
|
267
|
+
"required": []
|
|
268
|
+
},
|
|
269
|
+
"sourceRef": "packages/tools/src/tools/memory.ts (F3 P1; storage in packages/tools/src/memory/)"
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"name": "http_request",
|
|
273
|
+
"description": "Send an HTTP(S) request and return {status, headers(subset), body, truncated}. Only http/https URLs are allowed (file:// etc. rejected); redirects are followed up to 5 hops; the response body is truncated at 1MB (truncated:true beyond). HTTP error statuses are preserved in `status` — not tool errors; transport failures are categorized as timeout | dns | connect | redirect | invalid_url | invalid_arg | target_forbidden. SSRF policy: when CELESTEA_HTTP_ALLOW / CELESTEA_HTTP_DENY (comma-separated IP/CIDR) are set, every resolved target IP — and every redirect hop — must pass them; default (unset) allows all hosts.",
|
|
274
|
+
"parameters": {
|
|
275
|
+
"type": "object",
|
|
276
|
+
"properties": {
|
|
277
|
+
"method": {
|
|
278
|
+
"type": "string",
|
|
279
|
+
"description": "HTTP method (default GET).",
|
|
280
|
+
"enum": [
|
|
281
|
+
"GET",
|
|
282
|
+
"POST",
|
|
283
|
+
"PUT",
|
|
284
|
+
"DELETE",
|
|
285
|
+
"PATCH",
|
|
286
|
+
"HEAD"
|
|
287
|
+
]
|
|
288
|
+
},
|
|
289
|
+
"url": {
|
|
290
|
+
"type": "string",
|
|
291
|
+
"description": "Target URL; only http/https schemes are allowed."
|
|
292
|
+
},
|
|
293
|
+
"headers": {
|
|
294
|
+
"type": "object",
|
|
295
|
+
"additionalProperties": {
|
|
296
|
+
"type": "string"
|
|
297
|
+
},
|
|
298
|
+
"description": "Optional request headers as {name: value}."
|
|
299
|
+
},
|
|
300
|
+
"body": {
|
|
301
|
+
"type": "string",
|
|
302
|
+
"description": "Optional request body string."
|
|
303
|
+
},
|
|
304
|
+
"timeout_ms": {
|
|
305
|
+
"type": "integer",
|
|
306
|
+
"description": "Optional timeout in milliseconds (default 15000, maximum 60000).",
|
|
307
|
+
"minimum": 1
|
|
308
|
+
},
|
|
309
|
+
"desc": {
|
|
310
|
+
"type": "string",
|
|
311
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
"required": [
|
|
315
|
+
"url"
|
|
316
|
+
],
|
|
317
|
+
"additionalProperties": false
|
|
318
|
+
},
|
|
319
|
+
"sourceRef": "crates/tools/src/http.rs:238-254"
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
"name": "list_dir",
|
|
323
|
+
"description": "List the entry names in a directory.",
|
|
324
|
+
"parameters": {
|
|
325
|
+
"type": "object",
|
|
326
|
+
"properties": {
|
|
327
|
+
"path": {
|
|
328
|
+
"type": "string",
|
|
329
|
+
"description": "Directory path to list."
|
|
330
|
+
},
|
|
331
|
+
"desc": {
|
|
332
|
+
"type": "string",
|
|
333
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
"required": [
|
|
337
|
+
"path"
|
|
338
|
+
],
|
|
339
|
+
"additionalProperties": false
|
|
340
|
+
},
|
|
341
|
+
"sourceRef": "crates/tools/src/builtin.rs:217-230"
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
"name": "load_skill",
|
|
345
|
+
"description": "Load one skill's full instructions (its SKILL.md BODY) into the conversation by name. The per-turn skill catalog lists the available names; call this before doing a task a skill covers. The result carries the skill's `body`, its `dir` (read anything the body references from there with read_file), and the `source` layer it won — a skill's child files (references/, scripts/) are NEVER inlined. An unknown name, a name that is not a lowercase `[a-z0-9-]` slug (path traversal included), or a SKILL.md whose frontmatter is invalid fails with a structured `load_skill: code=... msg=\"...\"` error naming the reason — never a silent empty result.",
|
|
346
|
+
"parameters": {
|
|
347
|
+
"type": "object",
|
|
348
|
+
"properties": {
|
|
349
|
+
"name": {
|
|
350
|
+
"type": "string",
|
|
351
|
+
"description": "Skill name exactly as listed in the skill catalog (lowercase letters, digits, hyphens)."
|
|
352
|
+
},
|
|
353
|
+
"desc": {
|
|
354
|
+
"type": "string",
|
|
355
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
"required": [
|
|
359
|
+
"name"
|
|
360
|
+
],
|
|
361
|
+
"additionalProperties": false
|
|
362
|
+
},
|
|
363
|
+
"sourceRef": "packages/tools/src/tools/load-skill.ts (W884; reuses packages/core/src/skills.ts)"
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
"name": "process_control",
|
|
367
|
+
"description": "Control a background process started by run_shell(background=true). Handles live in the session-scoped process registry and survive across turns; a process that exits stays pollable from a bounded tombstone (most recent 32, or 10 minutes), so poll AFTER exit returns {running:false, exit_code, signal, stdout_tail(<=4KB), stderr_tail, cpu_exceeded?} instead of an unknown handle. action=poll reads the current or terminal state; action=kill sends SIGTERM, waits a grace period, then SIGKILL and returns {killed:true}; action=stdin writes one line (content + newline) to the process stdin.",
|
|
368
|
+
"parameters": {
|
|
369
|
+
"type": "object",
|
|
370
|
+
"properties": {
|
|
371
|
+
"handle": {
|
|
372
|
+
"type": "string",
|
|
373
|
+
"description": "Process handle returned by run_shell(background=true)."
|
|
374
|
+
},
|
|
375
|
+
"action": {
|
|
376
|
+
"type": "string",
|
|
377
|
+
"description": "poll | kill | stdin (see tool description).",
|
|
378
|
+
"enum": [
|
|
379
|
+
"poll",
|
|
380
|
+
"kill",
|
|
381
|
+
"stdin"
|
|
382
|
+
]
|
|
383
|
+
},
|
|
384
|
+
"content": {
|
|
385
|
+
"type": "string",
|
|
386
|
+
"description": "Line to write to the process stdin (action=stdin only)."
|
|
387
|
+
},
|
|
388
|
+
"desc": {
|
|
389
|
+
"type": "string",
|
|
390
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
391
|
+
}
|
|
392
|
+
},
|
|
393
|
+
"required": [
|
|
394
|
+
"handle",
|
|
395
|
+
"action"
|
|
396
|
+
],
|
|
397
|
+
"additionalProperties": false
|
|
398
|
+
},
|
|
399
|
+
"sourceRef": "crates/tools/src/process.rs:462-479"
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
"name": "read_file",
|
|
403
|
+
"description": "Read a UTF-8 text file and return its contents as a string. A whole read is capped at 256 KiB; pass offset (0-based line) and/or limit (line count) to page through a larger file — a paged result is an object {text, offset, limit, lineCount, totalLines, hasMore, nextOffset, truncated, totalBytes}.",
|
|
404
|
+
"parameters": {
|
|
405
|
+
"type": "object",
|
|
406
|
+
"properties": {
|
|
407
|
+
"path": {
|
|
408
|
+
"type": "string",
|
|
409
|
+
"description": "Filesystem path of the file to read."
|
|
410
|
+
},
|
|
411
|
+
"offset": {
|
|
412
|
+
"type": "integer",
|
|
413
|
+
"minimum": 0,
|
|
414
|
+
"description": "Optional 0-based line index to start from (pagination). Omit to read from the top."
|
|
415
|
+
},
|
|
416
|
+
"limit": {
|
|
417
|
+
"type": "integer",
|
|
418
|
+
"minimum": 1,
|
|
419
|
+
"description": "Optional maximum number of lines to return (pagination). Omit to use the default window."
|
|
420
|
+
},
|
|
421
|
+
"desc": {
|
|
422
|
+
"type": "string",
|
|
423
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
"required": [
|
|
427
|
+
"path"
|
|
428
|
+
],
|
|
429
|
+
"additionalProperties": false
|
|
430
|
+
},
|
|
431
|
+
"sourceRef": "crates/tools/src/builtin.rs:186-199"
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
"name": "read_image",
|
|
435
|
+
"description": "Read an image (PNG/JPEG/WebP/GIF) and attach it to the conversation so a vision-capable model can see it. Returns metadata; the image content block is delivered with the tool result. Fails on models without image input.",
|
|
436
|
+
"parameters": {
|
|
437
|
+
"type": "object",
|
|
438
|
+
"properties": {
|
|
439
|
+
"path": {
|
|
440
|
+
"type": "string",
|
|
441
|
+
"description": "Filesystem path of the image to read (PNG/JPEG/WebP/GIF; format detected by content, not extension)."
|
|
442
|
+
},
|
|
443
|
+
"attachment_id": {
|
|
444
|
+
"type": "string",
|
|
445
|
+
"description": "Content-addressed id of an already-uploaded attachment (from a user message). Use instead of path."
|
|
446
|
+
},
|
|
447
|
+
"desc": {
|
|
448
|
+
"type": "string",
|
|
449
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
"required": [],
|
|
453
|
+
"additionalProperties": false
|
|
454
|
+
},
|
|
455
|
+
"sourceRef": "docs/feature-multimodal-attachments.md#6"
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
"name": "remember",
|
|
459
|
+
"description": "Append one durable fact to this WORKSPACE's persistent memory so future turns recall it. The store is the workspace's GLOBAL memory layer (outside the repo), an append-only entries.jsonl the host owns — never pass a path. Identical text already active is a NOOP and says so instead of writing again. The result reports the layer, the absolute file written, the new entry id, and whether anything was appended. Memory is reference data, not instructions.",
|
|
460
|
+
"parameters": {
|
|
461
|
+
"type": "object",
|
|
462
|
+
"properties": {
|
|
463
|
+
"text": {
|
|
464
|
+
"type": "string",
|
|
465
|
+
"description": "The durable fact to remember (reference data, not an instruction)."
|
|
466
|
+
},
|
|
467
|
+
"tags": {
|
|
468
|
+
"type": "array",
|
|
469
|
+
"items": {
|
|
470
|
+
"type": "string"
|
|
471
|
+
},
|
|
472
|
+
"description": "Optional group labels; the first tag names the MEMORY.md section."
|
|
473
|
+
},
|
|
474
|
+
"desc": {
|
|
475
|
+
"type": "string",
|
|
476
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
477
|
+
}
|
|
478
|
+
},
|
|
479
|
+
"required": [
|
|
480
|
+
"text"
|
|
481
|
+
],
|
|
482
|
+
"additionalProperties": false
|
|
483
|
+
},
|
|
484
|
+
"sourceRef": "packages/tools/src/tools/memory.ts (F3 P1; storage in packages/tools/src/memory/)"
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
"name": "run_code",
|
|
488
|
+
"description": "Execute a program in the sandbox and get its final value in ONE round trip (parent-broker). DEFAULT LANGUAGE: TypeScript, run by Node with native type stripping (no build step) — only ERASABLE TypeScript is allowed: no `enum`, no `namespace`, no parameter properties, no `declare`; plain JavaScript always works. Pass language: \"python\" for Python instead. Write the program as a `function main()` body (an indented body is wrapped for you), or as a complete script that defines main; main() MAY be async and its resolved value (lossless JSON) is the final result. Inside the program the SDK exposes four synchronous bridges dispatched through the normal guarded tool pipeline: tools.read_file({path}) / tools.write_file({path, content}) / tools.list_dir({path}) / tools.run_shell({command}) (Python: tools.read_file(path=...) etc.); a denied or failed sub-call raises ToolCallError (catch it and continue). Bridge tools resolve relative paths against the TOOL workdir, not the program's cwd — pass absolute paths from inside the program. Only log what the model needs: a non-protocol stdout line becomes a log line (≤65536 bytes, UI render only); intermediate sub-call results are recorded in the session log but context-retained (the model sees only the final value). Hard limits: ≤20 sub-calls (the next one errors), wall clock ≤120000ms (timeout_ms, default 120000), sub-call output ledger ≤262144 bytes (truncated with a warning). No network; the same sandbox as run_shell (bwrap/raw/userspace + rlimits).",
|
|
489
|
+
"parameters": {
|
|
490
|
+
"type": "object",
|
|
491
|
+
"properties": {
|
|
492
|
+
"language": {
|
|
493
|
+
"type": "string",
|
|
494
|
+
"enum": [
|
|
495
|
+
"typescript",
|
|
496
|
+
"python"
|
|
497
|
+
],
|
|
498
|
+
"description": "Program language; default \"typescript\". TypeScript runs under Node's native type stripping (erasable syntax only: no enum/namespace/parameter properties) and needs no build; \"python\" runs under python3 -uB."
|
|
499
|
+
},
|
|
500
|
+
"code": {
|
|
501
|
+
"type": "string",
|
|
502
|
+
"description": "Program source in the chosen language: a `function main()` body (an indented body is wrapped for you) or a complete script that defines main. The engine injects the SDK preamble (tools bridge + protocol)."
|
|
503
|
+
},
|
|
504
|
+
"timeout_ms": {
|
|
505
|
+
"type": "integer",
|
|
506
|
+
"minimum": 1,
|
|
507
|
+
"maximum": 120000,
|
|
508
|
+
"description": "Optional whole-run wall clock in ms. Default 120000; hard cap 120000 (CELAESTEA_RUN_CODE_TIMEOUT_MS tunes the default, never the cap)."
|
|
509
|
+
},
|
|
510
|
+
"desc": {
|
|
511
|
+
"type": "string",
|
|
512
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
513
|
+
}
|
|
514
|
+
},
|
|
515
|
+
"required": [
|
|
516
|
+
"code"
|
|
517
|
+
],
|
|
518
|
+
"additionalProperties": false
|
|
519
|
+
},
|
|
520
|
+
"sourceRef": "crates/tools/src/run_code.rs:984-1022"
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
"name": "run_shell",
|
|
524
|
+
"description": "Run a shell command inside the sandbox (v2 OS isolation when available: namespaces + read-only root + resource limits, else the v1 userspace path; fixed workdir, sanitized env, bounded timeout and output) and return stdout, stderr, exit code, and a `sandbox` object {provider: bwrap|raw|userspace, net_isolated, tmp_private, seccomp} reporting the effective isolation (W249: network isolated and /tmp a private tmpfs by default; CELESTEA_SANDBOX_NET=1 / CELESTEA_SANDBOX_SHARE_TMP=1 restore the shared host net/tmp; CELESTEA_SANDBOX_SECCOMP=1 enables the seccomp whitelist). With background:true the command is spawned detached (no call-level timeout; resource limits still apply) and returns {background, handle, pid} immediately — control it with the process_control tool (poll / stdin / kill); background processes live in the session process registry and survive across turns. Default timeout is 30s; raise it with timeout_ms up to the cap configured by CELESTEA_SHELL_MAX_TIMEOUT_MS (default 300000ms). Optional cpu_sec overrides RLIMIT_CPU for THIS process (default 20s, foreground and background alike); values above the cap from CELESTEA_SHELL_MAX_CPU_SEC (default 600) are CLAMPED to it, and a CPU-cap kill is reported as cpu_exceeded.",
|
|
525
|
+
"parameters": {
|
|
526
|
+
"type": "object",
|
|
527
|
+
"properties": {
|
|
528
|
+
"command": {
|
|
529
|
+
"type": "string",
|
|
530
|
+
"description": "The command line to execute."
|
|
531
|
+
},
|
|
532
|
+
"workdir": {
|
|
533
|
+
"type": "string",
|
|
534
|
+
"description": "Optional working directory. Must already exist inside the sandbox root; relative paths resolve against the sandbox workdir."
|
|
535
|
+
},
|
|
536
|
+
"timeout_ms": {
|
|
537
|
+
"type": "integer",
|
|
538
|
+
"description": "Optional per-call timeout in milliseconds. Default 30000; can be raised up to the cap from CELESTEA_SHELL_MAX_TIMEOUT_MS (default 300000). Ignored when background:true.",
|
|
539
|
+
"minimum": 1
|
|
540
|
+
},
|
|
541
|
+
"cpu_sec": {
|
|
542
|
+
"type": "integer",
|
|
543
|
+
"description": "Optional per-call CPU time limit in seconds (RLIMIT_CPU) for THIS process, foreground or background. Default 20; values above CELESTEA_SHELL_MAX_CPU_SEC (default 600) are clamped to that cap. A process killed by the CPU limit reports cpu_exceeded:true with a message naming the limit.",
|
|
544
|
+
"minimum": 1
|
|
545
|
+
},
|
|
546
|
+
"background": {
|
|
547
|
+
"type": "boolean",
|
|
548
|
+
"description": "Optional, default false. When true, spawn the command detached (no call-level timeout; rlimits including cpu_sec still apply) and return {background:true, handle, pid} immediately; control the process with process_control (poll / stdin / kill). A process that exits stays pollable from a bounded tombstone (most recent 32, or 10 minutes), so poll after exit still returns exit_code/signal and the tails."
|
|
549
|
+
},
|
|
550
|
+
"notify": {
|
|
551
|
+
"type": "boolean",
|
|
552
|
+
"description": "Optional, default true. When background:true, whether a NATURAL exit may be offered to a host completion sink. No sink is wired in this deployment, so read the terminal state with process_control(action=poll); the flag is kept for hosts that install one."
|
|
553
|
+
},
|
|
554
|
+
"desc": {
|
|
555
|
+
"type": "string",
|
|
556
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
"required": [
|
|
560
|
+
"command"
|
|
561
|
+
],
|
|
562
|
+
"additionalProperties": false
|
|
563
|
+
},
|
|
564
|
+
"sourceRef": "crates/tools/src/builtin.rs:232-258"
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
"name": "send_message",
|
|
568
|
+
"description": "向 harness 内另一个会话发送消息(会话间通讯,用于多 worker 联调、交叉审计、分工协作)。target 可用会话地址(session id)或会话命名(标题/项目/工作区名;按命名指定先解析到唯一地址,命中多个返回候选清单)。content 是发送给目标会话的正文;投递的消息会成为目标会话新一轮的用户输入(唤醒语义:引擎会驱动目标会话就这条消息跑新一轮处理),因此也是 worker 回执与跨会话协作的通道。需要对方回复时在 content 里写明要求,并告诉对方用本工具 target=<你的会话地址> 发回。发送者信息自动附带。",
|
|
569
|
+
"parameters": {
|
|
570
|
+
"type": "object",
|
|
571
|
+
"properties": {
|
|
572
|
+
"target": {
|
|
573
|
+
"type": "string",
|
|
574
|
+
"description": "目标会话地址(session id)或会话命名(标题/项目名)"
|
|
575
|
+
},
|
|
576
|
+
"content": {
|
|
577
|
+
"type": "string",
|
|
578
|
+
"description": "发送给目标会话的消息正文"
|
|
579
|
+
},
|
|
580
|
+
"desc": {
|
|
581
|
+
"type": "string",
|
|
582
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
583
|
+
}
|
|
584
|
+
},
|
|
585
|
+
"required": [
|
|
586
|
+
"target",
|
|
587
|
+
"content"
|
|
588
|
+
],
|
|
589
|
+
"additionalProperties": false
|
|
590
|
+
},
|
|
591
|
+
"sourceRef": "crates/workers/src/tools.rs:75-90"
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
"name": "spawn_worker",
|
|
595
|
+
"description": "在 harness 内拉起一个 worker 会话:创建子会话(可入工作区分组)→ 命名(标题=<wid>·<短名>)→ 指定模型 → 投递自包含简报。worker 由 harness 自己的 agent-loop 驱动;看门狗按 registry 判定存活并自动重派失败项。wid 是 worker 编号(如 W101);brief 是自包含任务简报文本。返回 {ok, sessionId, title, wid}。协作闭环:worker 完成后引擎自动写报告 results/<wid>-<short>.md 并发送 WORKER_<wid>_DONE/FAILED 回执到 report_to 目标会话;回执到达会唤醒目标会话的新一轮处理(主 agent 读报告整合结论)。spawn 后应等待回执到达或经 worker_status 查询进度,再整合各 worker 结论。 mode 是可选的工作方式(缺省继承父会话);worker 报告头部会写明 mode。",
|
|
596
|
+
"parameters": {
|
|
597
|
+
"type": "object",
|
|
598
|
+
"properties": {
|
|
599
|
+
"wid": {
|
|
600
|
+
"type": "string",
|
|
601
|
+
"description": "worker 编号(如 W101)"
|
|
602
|
+
},
|
|
603
|
+
"brief": {
|
|
604
|
+
"type": "string",
|
|
605
|
+
"description": "自包含任务简报文本"
|
|
606
|
+
},
|
|
607
|
+
"title": {
|
|
608
|
+
"type": "string",
|
|
609
|
+
"description": "会话标题短名(不含 wid· 前缀,≤20 字;缺省取简报首行/文件名)"
|
|
610
|
+
},
|
|
611
|
+
"workspace": {
|
|
612
|
+
"type": "string",
|
|
613
|
+
"description": "工作区/项目根目录(cwd 分组;缺省 harness 工作区)"
|
|
614
|
+
},
|
|
615
|
+
"provider": {
|
|
616
|
+
"type": "string",
|
|
617
|
+
"description": "模型 provider(缺省取 harness 默认)"
|
|
618
|
+
},
|
|
619
|
+
"model": {
|
|
620
|
+
"type": "string",
|
|
621
|
+
"description": "模型名(缺省取 harness 默认)"
|
|
622
|
+
},
|
|
623
|
+
"reasoning_effort": {
|
|
624
|
+
"type": "string",
|
|
625
|
+
"description": "推理档位(可选)"
|
|
626
|
+
},
|
|
627
|
+
"mode": {
|
|
628
|
+
"type": "string",
|
|
629
|
+
"enum": [
|
|
630
|
+
"standard",
|
|
631
|
+
"execution"
|
|
632
|
+
],
|
|
633
|
+
"description": "worker 会话的会话模式(W729):缺省继承父会话的 mode;standard=逐步直调工具,execution=优先用一个 run_code 程序完成多步依赖调用"
|
|
634
|
+
},
|
|
635
|
+
"permission": {
|
|
636
|
+
"type": "string",
|
|
637
|
+
"description": "worker 子会话的权限预设(W9):read-only / write-read / full-access 或自定义预设 id;缺省继承 host 的权限解析(未设置=full-access)。落到子会话 meta 与 registry 行的 permission= token。"
|
|
638
|
+
},
|
|
639
|
+
"report_to": {
|
|
640
|
+
"type": "string",
|
|
641
|
+
"description": "回报目标会话 id:非空时在简报尾部注入中性回执提示;brief 轮结束后引擎机械写报告 results/<wid>-<short>.md 并发送 WORKER_<wid>_DONE/FAILED 回执到该会话 mailbox;回执到达会唤醒该目标会话新一轮处理(主 agent 读报告整合结论)"
|
|
642
|
+
},
|
|
643
|
+
"desc": {
|
|
644
|
+
"type": "string",
|
|
645
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
646
|
+
}
|
|
647
|
+
},
|
|
648
|
+
"required": [
|
|
649
|
+
"wid",
|
|
650
|
+
"brief"
|
|
651
|
+
],
|
|
652
|
+
"additionalProperties": false
|
|
653
|
+
},
|
|
654
|
+
"sourceRef": "crates/workers/src/tools.rs:53-74"
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
"name": "stop_worker",
|
|
658
|
+
"description": "停止一个正在运行的 worker:把它的 registry 行写成 STOPPED 终态(中止 driver、保留会话与行,不删除)——与 spawn_worker 配对,供人工/主 agent 叫停。wid 是 worker 编号(如 W101);reason 是可选的一行原因,落到行的 stop=<reason> token,worker_status 可见。只对处于 RUNNING 且属于本进程/host 的行生效;找不到或已终态返回 {ok:false,step:\"lookup\",error}。",
|
|
659
|
+
"parameters": {
|
|
660
|
+
"type": "object",
|
|
661
|
+
"properties": {
|
|
662
|
+
"wid": {
|
|
663
|
+
"type": "string",
|
|
664
|
+
"description": "要停止的 worker 编号(如 W101)"
|
|
665
|
+
},
|
|
666
|
+
"reason": {
|
|
667
|
+
"type": "string",
|
|
668
|
+
"description": "可选的一行原因,落成行的 stop=<reason> token;worker_status 可见。Keep it short."
|
|
669
|
+
},
|
|
670
|
+
"desc": {
|
|
671
|
+
"type": "string",
|
|
672
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
673
|
+
}
|
|
674
|
+
},
|
|
675
|
+
"required": [
|
|
676
|
+
"wid"
|
|
677
|
+
],
|
|
678
|
+
"additionalProperties": false
|
|
679
|
+
},
|
|
680
|
+
"sourceRef": "packages/workers/src/tools.ts (W7; no Rust counterpart)"
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
"name": "worker_status",
|
|
684
|
+
"description": "查询 harness 侧 worker registry(registry.tsv):返回 RUNNING/DONE/FAILED/STOPPED 汇总(RUNNING 行再按 state 标注细分 in-turn=正在跑 turn / idle=等待 mailbox 消息);可选按 wid 过滤查看单个 worker 的会话与状态。",
|
|
685
|
+
"parameters": {
|
|
686
|
+
"type": "object",
|
|
687
|
+
"properties": {
|
|
688
|
+
"wid": {
|
|
689
|
+
"type": "string",
|
|
690
|
+
"description": "worker 编号(如 W101);缺省返回全部汇总"
|
|
691
|
+
},
|
|
692
|
+
"desc": {
|
|
693
|
+
"type": "string",
|
|
694
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
695
|
+
}
|
|
696
|
+
},
|
|
697
|
+
"required": [],
|
|
698
|
+
"additionalProperties": false
|
|
699
|
+
},
|
|
700
|
+
"sourceRef": "crates/workers/src/tools.rs:91-104"
|
|
701
|
+
},
|
|
702
|
+
{
|
|
703
|
+
"name": "write_file",
|
|
704
|
+
"description": "Write text content to a file, creating or overwriting it.",
|
|
705
|
+
"parameters": {
|
|
706
|
+
"type": "object",
|
|
707
|
+
"properties": {
|
|
708
|
+
"path": {
|
|
709
|
+
"type": "string",
|
|
710
|
+
"description": "Filesystem path of the file to write."
|
|
711
|
+
},
|
|
712
|
+
"content": {
|
|
713
|
+
"type": "string",
|
|
714
|
+
"description": "Text content to write."
|
|
715
|
+
},
|
|
716
|
+
"desc": {
|
|
717
|
+
"type": "string",
|
|
718
|
+
"description": "Optional one-line label (max 80 chars) describing what this call is doing; shown on the tool card in the UI. Keep it short."
|
|
719
|
+
}
|
|
720
|
+
},
|
|
721
|
+
"required": [
|
|
722
|
+
"path",
|
|
723
|
+
"content"
|
|
724
|
+
],
|
|
725
|
+
"additionalProperties": false
|
|
726
|
+
},
|
|
727
|
+
"sourceRef": "crates/tools/src/builtin.rs:201-215"
|
|
728
|
+
}
|
|
729
|
+
]
|
|
730
|
+
}
|