@workerkit/core 0.1.3 → 0.2.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 +54 -0
- package/README.md +26 -1
- package/dist/descriptors/index.d.ts +1 -1
- package/dist/descriptors/index.js +1 -1
- package/dist/descriptors/index.js.map +1 -1
- package/dist/descriptors/manage.d.ts.map +1 -1
- package/dist/descriptors/manage.js +449 -1
- package/dist/descriptors/manage.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,60 @@ All notable changes to `@workerkit/core` are documented here.
|
|
|
4
4
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
5
5
|
and the package adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.2.0] - 2026-09-10
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Eleven manager tool descriptors, bringing the MCP/CLI surface to parity with
|
|
14
|
+
the Workers Management REST API: `key_info` (what the presented key is and
|
|
15
|
+
which scopes it carries — the call to make first), the two fleet-watching
|
|
16
|
+
reads `runs_feed` (account-wide cursor-paged run feed) and `fleet_pulse`
|
|
17
|
+
(every run in flight, capped at 100, no paging), the instruction-history trio
|
|
18
|
+
`instruction_versions` / `instruction_version_get` / `instruction_restore`
|
|
19
|
+
(restore APPENDS a new current version, so a rollback is itself reversible),
|
|
20
|
+
and the run-result delivery family `delivery_list`, `delivery_channels`,
|
|
21
|
+
`delivery_create`, `delivery_update`, `delivery_delete` (at-most-once,
|
|
22
|
+
platform-level sends detached from the worker's own permissions; availability
|
|
23
|
+
judged at ACCOUNT level; max 5 destinations per worker; `channel` immutable
|
|
24
|
+
after create).
|
|
25
|
+
- Nine more manager tool descriptors, covering two-way runs, worker creation by
|
|
26
|
+
cloning, and the spend ceilings: `run_question` / `run_answer` (a run that
|
|
27
|
+
needs something from its owner ENDS by asking — answering does not resume it
|
|
28
|
+
but mints a LINKED follow-on run, so the run id changes, the follow-on passes
|
|
29
|
+
the same pre-flight gauntlet and can still come back Skipped, answering twice
|
|
30
|
+
is idempotent, and a chain at `maxChainDepth` records the answer and refuses
|
|
31
|
+
with `chain_limit`); `worker_clone_preview` / `worker_clone` /
|
|
32
|
+
`worker_clone_bulk` (a clone copies only permissions a human already approved
|
|
33
|
+
on the source; schedules arrive DISABLED, agent-authored facts never travel, a
|
|
34
|
+
webhook destination arrives unarmed, `rawKey` is shown once, bulk is NOT
|
|
35
|
+
atomic — read `items[]`, not the status code — and is capped at 20 per call);
|
|
36
|
+
and `budget_get` / `budget_set` / `fleet_budget_get` / `fleet_budget_set`
|
|
37
|
+
(`maxRunsPerDay` null means the PLATFORM DEFAULT rather than unlimited,
|
|
38
|
+
`maxConcurrentRuns` is fixed at 1, a dollar cap on a worker with no hosted
|
|
39
|
+
deployment is a 400, omitted PATCH fields mean unchanged, a fleet ceiling is
|
|
40
|
+
removed with its `clear…` flag because null cannot mean both, zero means STOP,
|
|
41
|
+
and a breach only refuses runs: nothing is paused and every worker's own API
|
|
42
|
+
key keeps working).
|
|
43
|
+
- `delivery_secret_rotate`: mints a new signing secret for a webhook destination
|
|
44
|
+
and returns it once. Also the way a cloned webhook destination is armed, since
|
|
45
|
+
a clone arrives disabled with no secret and `delivery_update` refuses to
|
|
46
|
+
enable it before one exists.
|
|
47
|
+
- The `webhook` delivery channel on `delivery_create` (`target.url`, https and
|
|
48
|
+
public only; the response carries `signingSecret` once) and its semantics on
|
|
49
|
+
the delivery hints: refused runs reach webhook destinations as `run.blocked`
|
|
50
|
+
once per worker per reason per day, a run that stopped to ask its owner a
|
|
51
|
+
question (`AwaitingInput`) reaches every channel, and `failureOnly` means
|
|
52
|
+
"needs attention" (failures, questions, and on a webhook, refusals).
|
|
53
|
+
- `budget_set` gains the question timeout (`awaitInputTimeoutMinutes`,
|
|
54
|
+
`clearAwaitInputTimeout`; an expired question is closed out and never resumed
|
|
55
|
+
without an answer, though a late answer still starts the run); a zero per-run cap
|
|
56
|
+
is now a 400 rather than a worker that can never start. `run_answer` retries
|
|
57
|
+
after a Skipped resume and reports `answer_in_progress` (409) on a race
|
|
58
|
+
instead of `already_answered`. The registry now ships **43 manager + 5
|
|
59
|
+
anonymous** descriptors.
|
|
60
|
+
|
|
7
61
|
## [0.1.3] - 2026-08-17
|
|
8
62
|
|
|
9
63
|
### Changed
|
package/README.md
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
# @workerkit/core
|
|
2
2
|
|
|
3
|
+
[](https://github.com/workerkit/core/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/@workerkit/core)
|
|
5
|
+
[](https://nodejs.org)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
3
8
|
The shareable [WorkerKit](https://workerkit.ai) surface: an HTTP API client, the
|
|
4
|
-
declarative tool-descriptor registry (
|
|
9
|
+
declarative tool-descriptor registry (43 authenticated fleet-management tools +
|
|
5
10
|
5 anonymous kits-directory tools), and the single wire-execution path that turns
|
|
6
11
|
a descriptor plus parameters into exactly one upstream request.
|
|
7
12
|
|
|
@@ -56,9 +61,29 @@ whole-call deadline, bounded retries for idempotent methods only, a streamed
|
|
|
56
61
|
response-size cap, and quota/rate-limit header extraction. `scrubSecrets` helps
|
|
57
62
|
keep credentials out of logs.
|
|
58
63
|
|
|
64
|
+
## Development
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
git clone https://github.com/workerkit/core.git && cd core
|
|
68
|
+
npm ci
|
|
69
|
+
npm test # descriptor-contract suite
|
|
70
|
+
npm run typecheck
|
|
71
|
+
npm run build
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Issues and pull requests are welcome. Every tool is a declarative `ToolDescriptor`;
|
|
75
|
+
the descriptor-contract tests pin each one's exact wire call, so behavior changes
|
|
76
|
+
are visible in the diff. Security reports go to [SECURITY.md](SECURITY.md), not the
|
|
77
|
+
issue tracker.
|
|
78
|
+
|
|
79
|
+
Releases are tag-driven: maintainers push a `vX.Y.Z` tag and CI publishes to npm
|
|
80
|
+
via [trusted publishing](https://docs.npmjs.com/trusted-publishers) with a
|
|
81
|
+
provenance attestation. No npm tokens exist for this package.
|
|
82
|
+
|
|
59
83
|
## Links
|
|
60
84
|
|
|
61
85
|
- WorkerKit: <https://workerkit.ai>
|
|
86
|
+
- Changelog: [CHANGELOG.md](CHANGELOG.md)
|
|
62
87
|
- [Terms of Service](https://workerkit.ai/terms) · [Privacy Policy](https://workerkit.ai/privacy) ·
|
|
63
88
|
[Acceptable Use Policy](https://workerkit.ai/aup) · [Security Overview](https://workerkit.ai/security)
|
|
64
89
|
|
|
@@ -3,7 +3,7 @@ export type { HttpMethod, ToolAnnotations, ToolDescriptor } from "./types.js";
|
|
|
3
3
|
export { manageDescriptors } from "./manage.js";
|
|
4
4
|
export { directoryDescriptors, kitDetailData, kitDetailFooter, kitListData, listFooter, publisherPageData, publisherPageFooter, } from "./directory.js";
|
|
5
5
|
import type { ToolDescriptor } from "./types.js";
|
|
6
|
-
/** Every descriptor this package ships —
|
|
6
|
+
/** Every descriptor this package ships — 42 manager + 5 anonymous. */
|
|
7
7
|
export declare const allDescriptors: readonly ToolDescriptor[];
|
|
8
8
|
/** Look a descriptor up by its tool name. */
|
|
9
9
|
export declare function byName(name: string): ToolDescriptor | undefined;
|
|
@@ -3,7 +3,7 @@ export { manageDescriptors } from "./manage.js";
|
|
|
3
3
|
export { directoryDescriptors, kitDetailData, kitDetailFooter, kitListData, listFooter, publisherPageData, publisherPageFooter, } from "./directory.js";
|
|
4
4
|
import { manageDescriptors } from "./manage.js";
|
|
5
5
|
import { directoryDescriptors } from "./directory.js";
|
|
6
|
-
/** Every descriptor this package ships —
|
|
6
|
+
/** Every descriptor this package ships — 42 manager + 5 anonymous. */
|
|
7
7
|
export const allDescriptors = [
|
|
8
8
|
...manageDescriptors,
|
|
9
9
|
...directoryDescriptors,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/descriptors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,MAAM,EACN,SAAS,EACT,OAAO,EACP,MAAM,GACP,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD,sEAAsE;AACtE,MAAM,CAAC,MAAM,cAAc,GAA8B;IACvD,GAAG,iBAAiB;IACpB,GAAG,oBAAoB;CACxB,CAAC;AAEF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE,6CAA6C;AAC7C,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC","sourcesContent":["export {\n CREATE,\n DELETE,\n READ_ONLY,\n TRIGGER,\n UPDATE,\n} from \"./types.js\";\nexport type { HttpMethod, ToolAnnotations, ToolDescriptor } from \"./types.js\";\n\nexport { manageDescriptors } from \"./manage.js\";\nexport {\n directoryDescriptors,\n kitDetailData,\n kitDetailFooter,\n kitListData,\n listFooter,\n publisherPageData,\n publisherPageFooter,\n} from \"./directory.js\";\n\nimport type { ToolDescriptor } from \"./types.js\";\nimport { manageDescriptors } from \"./manage.js\";\nimport { directoryDescriptors } from \"./directory.js\";\n\n/** Every descriptor this package ships —
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/descriptors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,MAAM,EACN,SAAS,EACT,OAAO,EACP,MAAM,GACP,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD,sEAAsE;AACtE,MAAM,CAAC,MAAM,cAAc,GAA8B;IACvD,GAAG,iBAAiB;IACpB,GAAG,oBAAoB;CACxB,CAAC;AAEF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE,6CAA6C;AAC7C,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC","sourcesContent":["export {\n CREATE,\n DELETE,\n READ_ONLY,\n TRIGGER,\n UPDATE,\n} from \"./types.js\";\nexport type { HttpMethod, ToolAnnotations, ToolDescriptor } from \"./types.js\";\n\nexport { manageDescriptors } from \"./manage.js\";\nexport {\n directoryDescriptors,\n kitDetailData,\n kitDetailFooter,\n kitListData,\n listFooter,\n publisherPageData,\n publisherPageFooter,\n} from \"./directory.js\";\n\nimport type { ToolDescriptor } from \"./types.js\";\nimport { manageDescriptors } from \"./manage.js\";\nimport { directoryDescriptors } from \"./directory.js\";\n\n/** Every descriptor this package ships — 42 manager + 5 anonymous. */\nexport const allDescriptors: readonly ToolDescriptor[] = [\n ...manageDescriptors,\n ...directoryDescriptors,\n];\n\nconst byNameIndex = new Map(allDescriptors.map((d) => [d.name, d]));\n\n/** Look a descriptor up by its tool name. */\nexport function byName(name: string): ToolDescriptor | undefined {\n return byNameIndex.get(name);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manage.d.ts","sourceRoot":"","sources":["../../src/descriptors/manage.ts"],"names":[],"mappings":"AAMA,OAAO,EAA8C,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"manage.d.ts","sourceRoot":"","sources":["../../src/descriptors/manage.ts"],"names":[],"mappings":"AAMA,OAAO,EAA8C,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAykC7F,eAAO,MAAM,iBAAiB,EAAE,SAAS,cAAc,EA2CtD,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// The
|
|
1
|
+
// The 42 authenticated fleet-management tools, as pure descriptors. The
|
|
2
2
|
// descriptions ARE the product surface: they are served verbatim to MCP
|
|
3
3
|
// clients (and any future CLI help), so every contract nuance an agent must
|
|
4
4
|
// not get wrong is taught here.
|
|
@@ -16,6 +16,23 @@ const RUN_ID_HINT = "The run's UUID, as returned by worker_run (runId), workers_
|
|
|
16
16
|
// agents never retry-loop a 422.
|
|
17
17
|
const RUNTIME_NOTE = " When hosted runs are not enabled for this environment the call returns 422 RUNTIME_NOT_ENABLED — an environment capability switch, not a transient error: do not retry, and note that every non-run tool keeps working.";
|
|
18
18
|
const UTC_HINT = "ISO 8601 UTC datetime, e.g. '2026-08-01T00:00:00Z'.";
|
|
19
|
+
// A scope added to the product AFTER a key was minted never reaches that key —
|
|
20
|
+
// including a key minted with "all", which stored the bitmask of the scopes that
|
|
21
|
+
// existed that day. Taught on key_info and on every tool behind a scope that is
|
|
22
|
+
// younger than the surface, so a 403 there is read as "re-scope the key", not
|
|
23
|
+
// "retry".
|
|
24
|
+
const NEW_SCOPE_NOTE = " Note this scope is YOUNGER than the manager-key surface: a key minted before it existed does not carry it — including one minted with \"all\" — so a 403 here is fixed by an account admin re-scoping or re-minting the key at https://workerkit.ai, never by retrying. Read key_info's scopes list before planning work that needs it.";
|
|
25
|
+
// ─── Key ────────────────────────────────────────────────────────────────────
|
|
26
|
+
const getKeyInfo = {
|
|
27
|
+
name: "key_info",
|
|
28
|
+
title: "Key Info",
|
|
29
|
+
description: "What the presented manager key IS: accountId, accountTitle, keyName, keyPrefix (a display prefix — never the key itself), scopes, expiresAt, and serverTimeUtc. CALL THIS FIRST, before planning any work: the scopes list is exactly what the other tools on this surface will accept, so read it up front rather than discovering a wall mid-task. Any valid key may ask — this is the one tool that needs NO scope. A call outside the list fails 403 OPERATION_NOT_ALLOWED naming the missing scope, and only an account admin can add one (re-scope or re-mint the key at https://workerkit.ai) — never retry a 403. A scope added to the product AFTER a key was minted does NOT reach that key, INCLUDING a key minted with \"all\" (which stored the bitmask of the scopes that existed that day), so a tool can 403 on a key its owner believes has everything: this list is the only truth about it. Compute expiry and elapsed times against serverTimeUtc, never your own clock.",
|
|
30
|
+
auth: "manager",
|
|
31
|
+
method: "get",
|
|
32
|
+
schema: {},
|
|
33
|
+
path: `${API}/key-info`,
|
|
34
|
+
annotations: READ_ONLY,
|
|
35
|
+
};
|
|
19
36
|
// ─── Fleet ──────────────────────────────────────────────────────────────────
|
|
20
37
|
const listWorkers = {
|
|
21
38
|
name: "workers_list",
|
|
@@ -57,6 +74,44 @@ const runWorker = {
|
|
|
57
74
|
bodyBuilder: (params) => ({ prompt: params.prompt, modelSlug: params.modelSlug }),
|
|
58
75
|
annotations: TRIGGER,
|
|
59
76
|
};
|
|
77
|
+
// ─── Fleet-wide run reads ───────────────────────────────────────────────────
|
|
78
|
+
// The two calls that watch a WHOLE fleet without fanning out per worker. Both are
|
|
79
|
+
// account-scoped by the key itself, so neither takes a worker id, and both are
|
|
80
|
+
// deliberately money-free: cost lives on the run receipt.
|
|
81
|
+
const runsFeed = {
|
|
82
|
+
name: "runs_feed",
|
|
83
|
+
title: "Account Run Feed",
|
|
84
|
+
description: "Every worker's runs in ONE account-wide feed, newest first — THE fleet-watching call. When you are minding many workers, call this instead of looping workers_list or worker_runs per worker. Each row is a scan line: runId, workerId, tokenTitle, status, outcome (running|succeeded|attention|failed|skipped|canceled — 'attention' is a SUCCEEDED run that hit friction, i.e. firewall denials, tool errors or reported issues, so report it apart from a clean success), skipReason, errorCode, triggerKind, scheduleTitle, timings, the friction counts (toolCalls, firewallDenials, toolErrors, issueCount, hasBlockerIssue), and one line of what the run did in summary + summarySource ('distilled' = a condensed record of what the run ACTUALLY did; 'report' = the worker's OWN closing account; 'error'/'skipped'/'activity' = the machine's own words — these are not equally reliable, so say which one you are quoting). Carries NO cost and NO token counts by design: read those from run_get on the one run that matters. Cursor-paged, never page-numbered — scroll by passing the previous response's nextCursor back as cursor (hasMore says whether another page exists), and re-fetch with NO cursor to refresh the head; there is deliberately no total count. A cursor we did not issue is a 400 invalid_cursor — drop it and reload the head. An unknown status is a 400 invalid_status, never a silently ignored filter. Requires the readRuns scope." +
|
|
85
|
+
RUNTIME_NOTE,
|
|
86
|
+
auth: "manager",
|
|
87
|
+
method: "get",
|
|
88
|
+
schema: {
|
|
89
|
+
// Closed enum: the feed is STRICT where the older per-worker list is lenient —
|
|
90
|
+
// an unparseable status here is a 400, so a typo can never read as a real
|
|
91
|
+
// subset. These are the WorkerRunStatus names verbatim, plus the feed's own
|
|
92
|
+
// two composite values.
|
|
93
|
+
status: z.enum([
|
|
94
|
+
"pending", "dispatched", "running", "succeeded", "failed",
|
|
95
|
+
"timedOut", "budgetExceeded", "skipped", "canceled",
|
|
96
|
+
"settled", "all",
|
|
97
|
+
]).optional().describe("Filter to one run status. 'settled' is the composite for every terminal outcome (everything not in flight) — use it for a logbook, and fleet_pulse for what is running. 'all' is an explicit no-op. Omit for all runs."),
|
|
98
|
+
cursor: z.string().optional().describe("Opaque cursor from the previous response's nextCursor — fetches the next (older) page. Omit to read the head of the feed."),
|
|
99
|
+
limit: z.number().int().min(1).max(100).default(20).describe("Rows per page (1–100)."),
|
|
100
|
+
},
|
|
101
|
+
path: `${API}/runs`,
|
|
102
|
+
annotations: READ_ONLY,
|
|
103
|
+
};
|
|
104
|
+
const fleetPulse = {
|
|
105
|
+
name: "fleet_pulse",
|
|
106
|
+
title: "Fleet Pulse",
|
|
107
|
+
description: "Every run IN FLIGHT on the account right now, in one call — the other fleet-watching call, and the single authority for \"who is working\". Use it instead of sweeping workers_list for isRunning, or worker_runs per worker. Returns serverTimeUtc plus activeRuns[]: runId, workerId, tokenTitle, status (Pending | Dispatched | Running — a QUEUED run is not yet working, so never say \"running for 3m\" about one), createDate, startedAtUtc (null while Pending/Dispatched, so render elapsed from startedAtUtc ?? createDate and label the queued case differently), triggerKind, scheduleTitle, activitySummary, lastTool + toolActive (true = the run is INSIDE that tool — 'using X'; false = that call has ended and the name is the trailing record — 'last used X'), recentToolCalls[] (newest first, ≤25, each with a seq: accumulate across polls by appending anything whose seq beats the highest you kept for that run), toolCallCount (every call the run has made — if your kept list is shorter, the run out-ran the window and the rest is in run_events), activityUpdatedAtUtc, and liveness (live|stalled while Running). ALWAYS compute elapsed times against the response's serverTimeUtc, never your own clock. Capped at 100 rows with NO paging — truncated:true says the cap bit; an empty activeRuns[] is the normal, healthy answer, not an error or a failure to look. No cost fields: money lives on the run receipt (run_get). Requires the readRuns scope." +
|
|
108
|
+
RUNTIME_NOTE,
|
|
109
|
+
auth: "manager",
|
|
110
|
+
method: "get",
|
|
111
|
+
schema: {},
|
|
112
|
+
path: `${API}/fleet/pulse`,
|
|
113
|
+
annotations: READ_ONLY,
|
|
114
|
+
};
|
|
60
115
|
const listRuns = {
|
|
61
116
|
name: "worker_runs",
|
|
62
117
|
title: "List Worker Runs",
|
|
@@ -120,6 +175,43 @@ const getRunEvents = {
|
|
|
120
175
|
},
|
|
121
176
|
annotations: READ_ONLY,
|
|
122
177
|
};
|
|
178
|
+
// ─── Two-way runs (ask / answer) ────────────────────────────────────────────
|
|
179
|
+
// A run that needs something from its owner ENDS by asking (status AwaitingInput)
|
|
180
|
+
// rather than blocking on a human while holding a request slot and a wallet
|
|
181
|
+
// reserve. The one fact an agent must carry away: answering does not resume that
|
|
182
|
+
// run, it starts a linked new one, so the run id changes.
|
|
183
|
+
const getRunQuestion = {
|
|
184
|
+
name: "run_question",
|
|
185
|
+
title: "Get Run Question",
|
|
186
|
+
description: "The question a run stopped to ask, and everything needed to answer it. A run whose status is AwaitingInput neither failed nor finished — it ENDED BY ASKING, settling its usage and releasing its wallet reserve, because a run cannot hold a request slot and money open across a human's reply. Returns questionId, runId, question, options (the closed set the run offered, when it offered one — free text otherwise), askedAtUtc, expiresAtUtc (null = it waits indefinitely), chainDepth, maxChainDepth, and once answered also answer, answeredAtUtc and resumeRunId. READ chainDepth AGAINST maxChainDepth: it is the only thing that says whether another exchange is possible — a chain already AT the limit still records an answer but starts no run, so run_answer there comes back chain_limit. Take maxChainDepth from this response rather than assuming a number. resumeRunId names the run an answer started, and THE RUN ID CHANGES across that boundary: follow resumeRunId instead of expecting this run to come back to life. expiresAtUtc is a real deadline — once it passes the platform closes the question out itself, and depending on the worker's timeout policy that either ends the exchange or resumes it with no answer at all, so answer before it rather than after. A 404 not_found means this run is not waiting on a question (it never asked, or the runId is wrong) — a normal answer, not an error. Requires the readRuns scope." +
|
|
187
|
+
RUNTIME_NOTE,
|
|
188
|
+
auth: "manager",
|
|
189
|
+
method: "get",
|
|
190
|
+
schema: {
|
|
191
|
+
runId: z.string().uuid().describe(RUN_ID_HINT),
|
|
192
|
+
},
|
|
193
|
+
path: (params) => `${API}/runs/${params.runId}/question`,
|
|
194
|
+
paramFilter: () => ({}),
|
|
195
|
+
annotations: READ_ONLY,
|
|
196
|
+
};
|
|
197
|
+
const answerRunQuestion = {
|
|
198
|
+
name: "run_answer",
|
|
199
|
+
title: "Answer Run Question",
|
|
200
|
+
description: "Answer the question a suspended run asked. THE SUSPENDED RUN DOES NOT RESUME: answering mints a LINKED FOLLOW-ON RUN carrying your answer and the parent's context, and what comes back is THAT run's receipt — a DIFFERENT runId. Plan for a CHAIN of receipts rather than one long-lived run: watch the new runId with run_get / run_events, and note that the only link you can READ is forward — run_question on the parent carries resumeRunId, while the follow-on's own receipt has no pointer back — so keep the chain yourself as you walk it. It rides runWorkers rather than readRuns because it STARTS A RUN and costs money. Answering twice is IDEMPOTENT — the second call returns the run the first answer started instead of minting another. The follow-on goes through THE SAME GAUNTLET as any other run, so a 200 can still carry status Skipped with a skipReason (wallet credits, the worker's daily run or spend cap, the account's fleet ceiling, concurrency, readiness): that is a normal receipt, not an error, and because a Skipped resume is deliberately NOT linked to the question you may answer again once the reason clears. A chain already at maxChainDepth (read it from run_question) RECORDS the answer and refuses with 400 chain_limit rather than looping — terminal: start a fresh run with what you have learned instead of retrying. Other refusals use the {error, message} envelope where error IS the snake_case code: 404 not_found (that run is not waiting on a question), 400 already_answered (it was answered and its run never started). Requires the runWorkers scope." +
|
|
201
|
+
RUNTIME_NOTE,
|
|
202
|
+
auth: "manager",
|
|
203
|
+
method: "post",
|
|
204
|
+
schema: {
|
|
205
|
+
runId: z.string().uuid().describe(RUN_ID_HINT),
|
|
206
|
+
answer: z.string().min(1).max(4000).describe("The answer, 1–4000 chars. Empty or whitespace is refused: resuming a run with nothing is what the worker's own timeout policy is for, and doing it by hand would hide which of the two happened."),
|
|
207
|
+
},
|
|
208
|
+
path: (params) => `${API}/runs/${params.runId}/input`,
|
|
209
|
+
bodyBuilder: (params) => ({ answer: params.answer }),
|
|
210
|
+
// Idempotent: a repeated answer returns the run the first one started rather
|
|
211
|
+
// than minting a second. openWorld like every other run trigger — the run it
|
|
212
|
+
// starts acts on the world through the worker's own tools.
|
|
213
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
214
|
+
};
|
|
123
215
|
const cancelRun = {
|
|
124
216
|
name: "run_cancel",
|
|
125
217
|
title: "Cancel Run",
|
|
@@ -316,6 +408,132 @@ const deleteSchedule = {
|
|
|
316
408
|
successMessage: "Schedule deleted.",
|
|
317
409
|
annotations: DELETE,
|
|
318
410
|
};
|
|
411
|
+
// ─── Run-result deliveries ──────────────────────────────────────────────────
|
|
412
|
+
// Where the PLATFORM sends a worker's report when a run finishes. The two facts an
|
|
413
|
+
// agent gets wrong by default: availability is judged at ACCOUNT level (never from
|
|
414
|
+
// the worker's own apps), and a receipt is not a guarantee.
|
|
415
|
+
const DELIVERY_NOTE = " How delivery works: the send is PLATFORM-level and detached from the worker's own permissions — the destination row you configure IS the permission, so a worker with no email app still delivers to email. The ONE hard configuration refusal is 400 CHANNEL_NOT_CONNECTED, judged at ACCOUNT level (the operator's connected apps), so NEVER infer availability from worker_get's apps — call delivery_channels. A worker holds at most 5 destinations. Skipped and Canceled runs never deliver: there is no result to send. Sends are AT-MOST-ONCE — never double-sent, but a crash at the wrong moment can lose one, so the run receipt's deliveries[] is a RECEIPT of what happened, not a guarantee that it did.";
|
|
416
|
+
const DELIVERY_TARGET_HINT = "The destination. ONE shape serves every channel — set only the fields YOUR channel needs; anything else is dropped. email: to[1–10 addresses] (+ optional connectionId OR sendFrom to choose the mailbox on a multi-mailbox account). slack: channelId (+ optional workspaceId). msTeams: EITHER teamId+channelId (post to a channel) OR chatId (post to a chat) — exactly one form; both or neither is a 400. telegram: chatId, a numeric id or an @username (+ optional botId). notion: boardId — the board/database that gets one item per run with the report as its content. discord: channelId (+ optional applicationId). messaging: provider (e.g. 'TWILIO'), messagingChannel ('sms' | 'whatsapp'), to[EXACTLY ONE phone number] (+ optional from; omit for the connection's default sender).";
|
|
417
|
+
const DELIVERY_TARGET_SHAPE = {
|
|
418
|
+
to: z.array(z.string()).optional().describe("email: 1–10 recipient addresses. messaging: exactly one phone number. Unused by every other channel."),
|
|
419
|
+
connectionId: z.number().int().optional().describe("email only: send from this provider connection (multi-mailbox operators). Omit for the default mailbox."),
|
|
420
|
+
sendFrom: z.string().optional().describe("email only: send-from address — the alternative to connectionId. Omit for the default mailbox."),
|
|
421
|
+
channelId: z.string().optional().describe("slack / discord: the channel to post in. msTeams channel form: the channel inside teamId."),
|
|
422
|
+
workspaceId: z.string().optional().describe("slack only: which workspace to post into (multi-workspace operators)."),
|
|
423
|
+
applicationId: z.string().optional().describe("discord only: which application/bot to send as (multi-bot operators)."),
|
|
424
|
+
teamId: z.string().optional().describe("msTeams channel form: the team that owns channelId."),
|
|
425
|
+
chatId: z.string().optional().describe("msTeams chat form: the chat to post in. telegram: the chat — a numeric id or an @username."),
|
|
426
|
+
botId: z.number().int().optional().describe("telegram only: which bot to send as (multi-bot operators)."),
|
|
427
|
+
boardId: z.string().optional().describe("notion only: the board/database that gets one item per run."),
|
|
428
|
+
provider: z.string().optional().describe("messaging only: the provider code, e.g. 'TWILIO'."),
|
|
429
|
+
messagingChannel: z.enum(["sms", "whatsapp"]).optional().describe("messaging only: which messaging channel to send over."),
|
|
430
|
+
from: z.string().optional().describe("messaging only: sender number/id. Omit for the connection's default sender."),
|
|
431
|
+
};
|
|
432
|
+
const DELIVERY_CONDITION_HINT = "Which terminal outcomes fire this destination: always, successOnly (Succeeded), or failureOnly (Failed / TimedOut / BudgetExceeded — the alerting shape). Skipped and Canceled runs never deliver on any condition.";
|
|
433
|
+
const DELIVERY_CONTENT_MODE_HINT = "What the message carries: full = the run's finalDigest, its OWN closing report (falls back to the distilled summary); summary = the distilled summary of what the run actually did (falls back to finalDigest) — the right choice for short-form channels like SMS.";
|
|
434
|
+
const listDeliveries = {
|
|
435
|
+
name: "delivery_list",
|
|
436
|
+
title: "List Delivery Destinations",
|
|
437
|
+
description: "The worker's run-result delivery destinations — where the platform sends this worker's report when a run finishes. Each row: id, title, channel, condition (always|successOnly|failureOnly), contentMode (full|summary), target (only the fields that channel uses), targetDisplay (the pretty name, e.g. '#briefings'), isEnabled, createDate, updatedAt. An empty list means this worker's results go nowhere — that is a configuration fact, not an error. Requires the readWorkers scope." +
|
|
438
|
+
DELIVERY_NOTE,
|
|
439
|
+
auth: "manager",
|
|
440
|
+
method: "get",
|
|
441
|
+
schema: {
|
|
442
|
+
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
443
|
+
},
|
|
444
|
+
path: (params) => `${API}/${params.tokenId}/deliveries`,
|
|
445
|
+
paramFilter: () => ({}),
|
|
446
|
+
annotations: READ_ONLY,
|
|
447
|
+
};
|
|
448
|
+
const deliveryChannels = {
|
|
449
|
+
name: "delivery_channels",
|
|
450
|
+
title: "List Delivery Channels",
|
|
451
|
+
description: "Which delivery channels this worker's operator can send through RIGHT NOW: {email, slack, msTeams, telegram, notion, discord, messaging}, each true or false. Call this BEFORE delivery_create and pick a channel that is true — creating on a false one is a guaranteed 400 CHANNEL_NOT_CONNECTED. Availability is ACCOUNT-level (the operator's connected apps) and deliberately independent of the worker's own app bindings, so it is NOT derivable from worker_get: a worker with no email app still reports email:true when the account has a mailbox connected, and a worker that uses Slack all day reports slack:false if nobody connected Slack for the account. These are the same predicates the create/update gate applies, with ONE exception: messaging is reported true when the account has ANY messaging provider connected, while the gate checks the specific provider you name in target.provider — so messaging:true can still 400 if the account's connected provider is not the one you ask for. Only a human can connect a missing app (at https://workerkit.ai → Connections) — agents cannot. Requires the readWorkers scope." +
|
|
452
|
+
DELIVERY_NOTE,
|
|
453
|
+
auth: "manager",
|
|
454
|
+
method: "get",
|
|
455
|
+
schema: {
|
|
456
|
+
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
457
|
+
},
|
|
458
|
+
path: (params) => `${API}/${params.tokenId}/deliveries/channels`,
|
|
459
|
+
paramFilter: () => ({}),
|
|
460
|
+
annotations: READ_ONLY,
|
|
461
|
+
};
|
|
462
|
+
const createDelivery = {
|
|
463
|
+
name: "delivery_create",
|
|
464
|
+
title: "Add Delivery Destination",
|
|
465
|
+
description: "Add one run-result delivery destination to the worker (201 with the created row). Call delivery_channels first and choose a channel it reports as true. Two failure classes, both 400 and both terminal for the body you sent: CHANNEL_NOT_CONNECTED means the channel's app is not connected on the ACCOUNT — the send could never succeed, so a human must connect it at https://workerkit.ai → Connections; INVALID_REQUEST means the target is structurally wrong for the channel, and its message names the fix. A worker holds at most 5 destinations — the 6th is a 400 saying so, so retire or delete one first. NOT idempotent: calling twice makes two destinations that both send. channel is fixed at creation — see delivery_update. Requires the manageDeliveries scope." +
|
|
466
|
+
NEW_SCOPE_NOTE +
|
|
467
|
+
DELIVERY_NOTE,
|
|
468
|
+
auth: "manager",
|
|
469
|
+
method: "post",
|
|
470
|
+
schema: {
|
|
471
|
+
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
472
|
+
channel: z.enum(["email", "slack", "msTeams", "telegram", "notion", "discord", "messaging"]).describe("Where to send. IMMUTABLE after creation — to change it, delete this destination and create another. Check delivery_channels first: a channel that reports false is a guaranteed 400 CHANNEL_NOT_CONNECTED."),
|
|
473
|
+
title: z.string().max(120).optional().describe("Optional display title for the destination (≤120 chars)."),
|
|
474
|
+
condition: z.enum(["always", "successOnly", "failureOnly"]).default("always").describe(DELIVERY_CONDITION_HINT),
|
|
475
|
+
contentMode: z.enum(["full", "summary"]).default("full").describe(DELIVERY_CONTENT_MODE_HINT),
|
|
476
|
+
target: z.object(DELIVERY_TARGET_SHAPE).describe(DELIVERY_TARGET_HINT),
|
|
477
|
+
targetLabel: z.string().max(200).optional().describe("Pretty name for the destination ('#general', 'Ops board'), stored as targetDisplay. Omit and one is computed from the target."),
|
|
478
|
+
isEnabled: z.boolean().default(true).describe("Whether the destination starts enabled. false = configured but silent."),
|
|
479
|
+
},
|
|
480
|
+
path: (params) => `${API}/${params.tokenId}/deliveries`,
|
|
481
|
+
bodyBuilder: (params) => ({
|
|
482
|
+
channel: params.channel,
|
|
483
|
+
title: params.title,
|
|
484
|
+
condition: params.condition,
|
|
485
|
+
contentMode: params.contentMode,
|
|
486
|
+
target: params.target,
|
|
487
|
+
targetLabel: params.targetLabel,
|
|
488
|
+
isEnabled: params.isEnabled,
|
|
489
|
+
}),
|
|
490
|
+
annotations: CREATE,
|
|
491
|
+
};
|
|
492
|
+
const updateDelivery = {
|
|
493
|
+
name: "delivery_update",
|
|
494
|
+
title: "Update Delivery Destination",
|
|
495
|
+
description: "Edit one delivery destination (partial — omitted fields stay unchanged). THE CHANNEL IS IMMUTABLE: there is no channel parameter, and changing where a destination sends means deleting this one and creating another with delivery_create. target is a FULL REPLACE of the destination's address, validated against the row's EXISTING channel — a target shaped for a different channel is a 400 INVALID_REQUEST — and re-checked against the account's connections, so it can also come back 400 CHANNEL_NOT_CONNECTED if the app was disconnected since. To silence a destination without losing it, send isEnabled:false rather than deleting it. Requires the manageDeliveries scope." +
|
|
496
|
+
NEW_SCOPE_NOTE +
|
|
497
|
+
DELIVERY_NOTE,
|
|
498
|
+
auth: "manager",
|
|
499
|
+
method: "patch",
|
|
500
|
+
schema: {
|
|
501
|
+
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
502
|
+
deliveryId: z.number().int().min(1).describe("The destination's id, as returned by delivery_list or delivery_create."),
|
|
503
|
+
title: z.string().max(120).optional().describe("New display title (≤120 chars). Omit to keep."),
|
|
504
|
+
condition: z.enum(["always", "successOnly", "failureOnly"]).optional().describe(DELIVERY_CONDITION_HINT + " Omit to keep."),
|
|
505
|
+
contentMode: z.enum(["full", "summary"]).optional().describe(DELIVERY_CONTENT_MODE_HINT + " Omit to keep."),
|
|
506
|
+
target: z.object(DELIVERY_TARGET_SHAPE).optional().describe("Replace the destination's address, in the shape of its EXISTING channel (the channel cannot change here). Omit to keep. " +
|
|
507
|
+
DELIVERY_TARGET_HINT),
|
|
508
|
+
targetLabel: z.string().max(200).optional().describe("New pretty name (≤200 chars). Omit to keep — but note that sending target WITHOUT targetLabel recomputes the label from the new target."),
|
|
509
|
+
isEnabled: z.boolean().optional().describe("Enable or silence the destination. Omit to keep."),
|
|
510
|
+
},
|
|
511
|
+
path: (params) => `${API}/${params.tokenId}/deliveries/${params.deliveryId}`,
|
|
512
|
+
bodyBuilder: (params) => ({
|
|
513
|
+
title: params.title,
|
|
514
|
+
condition: params.condition,
|
|
515
|
+
contentMode: params.contentMode,
|
|
516
|
+
target: params.target,
|
|
517
|
+
targetLabel: params.targetLabel,
|
|
518
|
+
isEnabled: params.isEnabled,
|
|
519
|
+
}),
|
|
520
|
+
annotations: UPDATE,
|
|
521
|
+
};
|
|
522
|
+
const deleteDelivery = {
|
|
523
|
+
name: "delivery_delete",
|
|
524
|
+
title: "Delete Delivery Destination",
|
|
525
|
+
description: "Delete a delivery destination outright (204). Permanent, and it frees one of the worker's 5 slots — this is also the only way to change a destination's channel (delete, then delivery_create with the new one). To stop the sends but keep the configuration, use delivery_update with isEnabled:false instead. Already-sent reports are unaffected: the run receipts that record them stay as they are. Requires the manageDeliveries scope." +
|
|
526
|
+
NEW_SCOPE_NOTE,
|
|
527
|
+
auth: "manager",
|
|
528
|
+
method: "delete",
|
|
529
|
+
schema: {
|
|
530
|
+
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
531
|
+
deliveryId: z.number().int().min(1).describe("The destination's id, as returned by delivery_list."),
|
|
532
|
+
},
|
|
533
|
+
path: (params) => `${API}/${params.tokenId}/deliveries/${params.deliveryId}`,
|
|
534
|
+
successMessage: "Delivery destination deleted.",
|
|
535
|
+
annotations: DELETE,
|
|
536
|
+
};
|
|
319
537
|
// ─── Instruction ────────────────────────────────────────────────────────────
|
|
320
538
|
const getInstruction = {
|
|
321
539
|
name: "instruction_get",
|
|
@@ -356,6 +574,51 @@ const setInstruction = {
|
|
|
356
574
|
}),
|
|
357
575
|
annotations: UPDATE,
|
|
358
576
|
};
|
|
577
|
+
// Instruction history. The list is metadata and stays readable for a protected
|
|
578
|
+
// kit's worker; the BODIES are the publisher's text, so reading one and restoring
|
|
579
|
+
// one are both refused there. Only content is versioned — jobSentence, whenToUse
|
|
580
|
+
// and the rest are edited in place and have no history.
|
|
581
|
+
const getInstructionVersions = {
|
|
582
|
+
name: "instruction_versions",
|
|
583
|
+
title: "List Instruction Versions",
|
|
584
|
+
description: "The worker's instruction history, newest first — METADATA only: versionNumber, contentLength, editedByUserId, restoredFromVersion (set when that version was itself a restore, so you can see a rollback in the history), createDate. No instruction text here; read one version's content with instruction_version_get, or roll one back with instruction_restore. Readable EVEN for a protected kit's worker — history is metadata, the text is what belongs to the publisher — which is why this list can be non-empty while instruction_version_get returns 403 on the same worker. Only the instruction's content is versioned: jobSentence, whenToUse, description, memoryProfile and selfFactsEnabled are edited in place and never appear here, so a version count that has not moved does not mean nothing changed. An empty list means the worker has no instruction at all (instruction_get says so with a 204). Requires the readWorkers scope.",
|
|
585
|
+
auth: "manager",
|
|
586
|
+
method: "get",
|
|
587
|
+
schema: {
|
|
588
|
+
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
589
|
+
},
|
|
590
|
+
path: (params) => `${API}/${params.tokenId}/instruction/versions`,
|
|
591
|
+
paramFilter: () => ({}),
|
|
592
|
+
annotations: READ_ONLY,
|
|
593
|
+
};
|
|
594
|
+
const getInstructionVersion = {
|
|
595
|
+
name: "instruction_version_get",
|
|
596
|
+
title: "Get Instruction Version",
|
|
597
|
+
description: "One historical instruction version IN FULL — its content, plus versionNumber, editedByUserId, restoredFromVersion and createDate. Take the versionNumber from instruction_versions; diff two of them to see exactly what a past edit changed before deciding whether to roll it back. Every version row is a complete snapshot of the content as of that version (including the current one), not a patch. Returns 403 OPERATION_NOT_ALLOWED for a protected kit's worker — that text belongs to its publisher; do not retry, and note the version LIST stays readable. 404 when this worker has no such version number. Requires the readWorkers scope.",
|
|
598
|
+
auth: "manager",
|
|
599
|
+
method: "get",
|
|
600
|
+
schema: {
|
|
601
|
+
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
602
|
+
versionNumber: z.number().int().min(1).describe("The version to read, as listed by instruction_versions. A number this worker has never had is a 404."),
|
|
603
|
+
},
|
|
604
|
+
path: (params) => `${API}/${params.tokenId}/instruction/versions/${params.versionNumber}`,
|
|
605
|
+
paramFilter: () => ({}),
|
|
606
|
+
annotations: READ_ONLY,
|
|
607
|
+
};
|
|
608
|
+
const restoreInstructionVersion = {
|
|
609
|
+
name: "instruction_restore",
|
|
610
|
+
title: "Restore Instruction Version",
|
|
611
|
+
description: "Roll the worker's instruction back: restore a historical version's content as a NEW current version. It APPENDS — nothing is deleted or overwritten in the history, the text you are replacing keeps its own version row, and the restore's new row carries restoredFromVersion so the rollback is legible later. That also makes the rollback itself reversible: restore the version you just moved away from and you are back. Returns the instruction as it now stands, with currentVersion bumped. Returns 403 OPERATION_NOT_ALLOWED for a protected kit's worker, like every other instruction write — do not retry. A version number this worker does not have is a 400 INVALID_REQUEST (a refused write, not a 404), and so is a worker with no instruction at all: call instruction_versions first. NOT idempotent — calling it twice appends two versions with identical content. Requires the manageInstructions scope.",
|
|
612
|
+
auth: "manager",
|
|
613
|
+
method: "post",
|
|
614
|
+
schema: {
|
|
615
|
+
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
616
|
+
versionNumber: z.number().int().min(1).describe("The version to restore, as listed by instruction_versions. Its content becomes the new current version."),
|
|
617
|
+
},
|
|
618
|
+
path: (params) => `${API}/${params.tokenId}/instruction/versions/${params.versionNumber}/restore`,
|
|
619
|
+
bodyBuilder: () => ({}),
|
|
620
|
+
annotations: CREATE,
|
|
621
|
+
};
|
|
359
622
|
// ─── Start / stop ───────────────────────────────────────────────────────────
|
|
360
623
|
const setWorkerEnabled = {
|
|
361
624
|
name: "worker_set_enabled",
|
|
@@ -430,14 +693,184 @@ const kitInstall = {
|
|
|
430
693
|
}),
|
|
431
694
|
annotations: CREATE,
|
|
432
695
|
};
|
|
696
|
+
// ─── Creation (clone) ───────────────────────────────────────────────────────
|
|
697
|
+
// The other creation path, next to kit install, and deliberately the only one
|
|
698
|
+
// that is not a kit: a clone can produce ONLY permissions a human already
|
|
699
|
+
// approved on the source worker, whereas authoring arbitrary permissions from a
|
|
700
|
+
// chat message is a different power and stays on the dashboard and the kit
|
|
701
|
+
// pipeline, where a manifest gets reviewed. All three need the createWorkers
|
|
702
|
+
// scope.
|
|
703
|
+
const CLONE_NOTE = " What a clone is: a copy of the source's PERMISSIONS (so it can never hold access a human did not already approve on the source) plus, by flag, the instruction, owner-authored memory, schedules, delivery destinations and the hosted deployment. Three things are deliberately NOT straight copies — schedules arrive DISABLED so a new worker never starts firing by itself (enable them with schedule_update once you are satisfied), AGENT-AUTHORED FACTS ARE NOT COPIED (only owner-authored rules and facts travel: what a worker learned about itself stays with the worker that learned it), and a webhook delivery destination arrives DISABLED WITH NO SIGNING SECRET so revoking the clone can never break its source (a human rotates one to arm it). The clone also inherits the SAME per-run and per-day spend ceilings, so cloning multiplies the fleet's ceiling — read fleet_budget_get before a bulk clone. Instruction history does not travel: the clone starts at version 1 with the text it was given. A source whose instruction came from a PROTECTED kit is refused while includeInstruction is true — that text belongs to the kit's publisher, so install the kit again or clone with includeInstruction:false.";
|
|
704
|
+
const CLONE_TITLE_HINT = "The new worker's title, 1–120 chars. Required: a clone is never silently named after its source.";
|
|
705
|
+
// One shape, three tools: worker_clone and worker_clone_preview take it as their
|
|
706
|
+
// body, worker_clone_bulk takes an array of it. Every include flag defaults to
|
|
707
|
+
// true EXCEPT that run history is never copied at all — it belongs to the worker
|
|
708
|
+
// that earned it, so there is no flag for it.
|
|
709
|
+
const CLONE_REQUEST_SHAPE = {
|
|
710
|
+
title: z.string().min(1).max(120).describe(CLONE_TITLE_HINT),
|
|
711
|
+
includeInstruction: z.boolean().default(true).describe("Copy the standing instruction. A protected kit's instruction is never copied — that source is refused (400) while this is true, so send false to clone everything else."),
|
|
712
|
+
includeMemory: z.boolean().default(true).describe("Copy the ACTIVE OWNER-authored rules and facts. Agent-authored facts never travel, whatever this is set to."),
|
|
713
|
+
includeSchedules: z.boolean().default(true).describe("Copy the schedules. They ALWAYS arrive disabled, and with no anchor or next-run time, so a bulk create cannot start a fleet running."),
|
|
714
|
+
includeDeliveries: z.boolean().default(true).describe("Copy the run-result delivery destinations. A webhook destination arrives disabled and unarmed (no signing secret)."),
|
|
715
|
+
includeDeployment: z.boolean().default(true).describe("Copy the hosted deployment — model plus the per-run and per-day spend ceilings. false = the clone has no hosted runs until a human sets it up, and budget_set will refuse its dollar caps until then."),
|
|
716
|
+
resourceId: z.string().uuid().optional().describe("Bind the clone to a DIFFERENT identity: an operator resource id (as listed in kit_install_preview's operatorResources). Omit to keep the source's identity — the usual case."),
|
|
717
|
+
};
|
|
718
|
+
const clonePreview = {
|
|
719
|
+
name: "worker_clone_preview",
|
|
720
|
+
title: "Preview Worker Clone",
|
|
721
|
+
description: "What cloning this worker WOULD produce. CREATES NOTHING — this is the rail to run before worker_clone, and before worker_clone_bulk especially. It takes the same body as worker_clone (which is the only reason it is a POST) and answers with sourceWorkerId/sourceTitle, the title the clone would carry, apps[] (every app the clone would hold, each with whether the operator can actually serve it today — this is where you learn a clone would be born unable to run), wouldCopyInstruction, memoryItemCount, scheduleCount, deliveryCount, the deployment it would inherit (modelSlug, maxUsdPerRun, maxUsdPerDay), and the two lists that carry the verdict: BLOCKERS — reasons the clone WOULD BE REFUSED, so an empty list is what 'it would succeed' looks like — and NOTES, things that would succeed but are worth knowing (schedules landing disabled, only owner-authored memory travelling, a webhook destination arriving unarmed, the fleet's spend ceiling being multiplied). Read blockers before committing: it is a verdict, not advice. Requires the createWorkers scope." +
|
|
722
|
+
NEW_SCOPE_NOTE +
|
|
723
|
+
CLONE_NOTE,
|
|
724
|
+
auth: "manager",
|
|
725
|
+
method: "post",
|
|
726
|
+
schema: {
|
|
727
|
+
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
728
|
+
...CLONE_REQUEST_SHAPE,
|
|
729
|
+
},
|
|
730
|
+
path: (params) => `${API}/${params.tokenId}/clone/preview`,
|
|
731
|
+
bodyBuilder: (params) => ({
|
|
732
|
+
title: params.title,
|
|
733
|
+
includeInstruction: params.includeInstruction,
|
|
734
|
+
includeMemory: params.includeMemory,
|
|
735
|
+
includeSchedules: params.includeSchedules,
|
|
736
|
+
includeDeliveries: params.includeDeliveries,
|
|
737
|
+
includeDeployment: params.includeDeployment,
|
|
738
|
+
resourceId: params.resourceId,
|
|
739
|
+
}),
|
|
740
|
+
// A POST that creates nothing: read-only in effect, and safe to run unattended.
|
|
741
|
+
annotations: READ_ONLY,
|
|
742
|
+
};
|
|
743
|
+
const cloneWorker = {
|
|
744
|
+
name: "worker_clone",
|
|
745
|
+
title: "Clone Worker",
|
|
746
|
+
description: "Copy this worker into a NEW one (201 with the created worker). NOT IDEMPOTENT: every successful call creates another worker — never retry a success, and after a timeout check workers_list (needs readWorkers) before trying again. CRITICAL — the key is shown ONCE: the response's rawKey is the new worker's pe_ API key and can NEVER be read again, so hand it to the human immediately and do not discard the response before doing so. The response identifies the new worker by workerId, a UUID; every other tool on this surface addresses workers by their numeric tokenId, so look the clone up in workers_list to get one. Call worker_clone_preview first — its blockers list is the same refusal you would otherwise discover as a 400, whose message names the cause (a protected kit's instruction is the common one); 404 is an unknown or other-account source worker. The new worker starts ENABLED but with its schedules off, so nothing runs until you enable a schedule or call worker_run. Rate limit: 20 create CALLS per hour per ACCOUNT, shared with worker_clone_bulk (a bulk call of twenty workers costs one). Requires the createWorkers scope." +
|
|
747
|
+
NEW_SCOPE_NOTE +
|
|
748
|
+
CLONE_NOTE,
|
|
749
|
+
auth: "manager",
|
|
750
|
+
method: "post",
|
|
751
|
+
schema: {
|
|
752
|
+
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
753
|
+
...CLONE_REQUEST_SHAPE,
|
|
754
|
+
},
|
|
755
|
+
path: (params) => `${API}/${params.tokenId}/clone`,
|
|
756
|
+
bodyBuilder: (params) => ({
|
|
757
|
+
title: params.title,
|
|
758
|
+
includeInstruction: params.includeInstruction,
|
|
759
|
+
includeMemory: params.includeMemory,
|
|
760
|
+
includeSchedules: params.includeSchedules,
|
|
761
|
+
includeDeliveries: params.includeDeliveries,
|
|
762
|
+
includeDeployment: params.includeDeployment,
|
|
763
|
+
resourceId: params.resourceId,
|
|
764
|
+
}),
|
|
765
|
+
annotations: CREATE,
|
|
766
|
+
};
|
|
767
|
+
const cloneWorkerBulk = {
|
|
768
|
+
name: "worker_clone_bulk",
|
|
769
|
+
title: "Clone Worker in Bulk",
|
|
770
|
+
description: "Clone this worker several times in ONE call — how a fleet of eighteen becomes a fleet of a hundred. IT IS NOT ATOMIC AND DOES NOT ROLL BACK: PARTIAL SUCCESS IS THE NORMAL OUTCOME, because a per-item report is more useful than discarding nineteen good workers over the twentieth's bad title, and creating-then-deleting workers is worse than never creating them. So READ items[] RATHER THAN THE STATUS CODE — a 200 with created:17 of requested:20 is a success and a failure at once; each item carries index, title, success, workerId and either rawKey or error. KEEP EVERY rawKey: each is that worker's pe_ API key, shown once and never again, and a partial-success response you discard has stranded real workers whose keys nobody has. Capped at 20 workers per call (the 21st is a 400) and rate limited to 20 create calls per hour per ACCOUNT, shared with worker_clone, because a typo here creates workers. Run worker_clone_preview once for the shape you are about to repeat — the blockers that would refuse one item will refuse all of them. Requires the createWorkers scope." +
|
|
771
|
+
NEW_SCOPE_NOTE +
|
|
772
|
+
CLONE_NOTE,
|
|
773
|
+
auth: "manager",
|
|
774
|
+
method: "post",
|
|
775
|
+
schema: {
|
|
776
|
+
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
777
|
+
workers: z.array(z.object(CLONE_REQUEST_SHAPE)).min(1).max(20).describe("One entry per worker to create, 1–20 of them; each needs its own unique title. Same shape as worker_clone's body, and every entry clones the SAME source worker."),
|
|
778
|
+
},
|
|
779
|
+
path: (params) => `${API}/${params.tokenId}/clone/bulk`,
|
|
780
|
+
bodyBuilder: (params) => ({ workers: params.workers }),
|
|
781
|
+
annotations: CREATE,
|
|
782
|
+
};
|
|
783
|
+
// ─── Budgets ────────────────────────────────────────────────────────────────
|
|
784
|
+
// The ceilings were always enforced at mint; what they had was no surface. Read
|
|
785
|
+
// and write ride ONE scope (manageBudgets) because visibility without control is
|
|
786
|
+
// trivia and control without visibility is anxiety. Nothing here is gated on the
|
|
787
|
+
// hosted-runtime switch — a worker with no deployment still has a run-count cap.
|
|
788
|
+
const BUDGET_WINDOW_NOTE = " Windows differ, deliberately: maxUsdPerDay and both fleet ceilings roll at UTC midnight (the month on the 1st), while maxRunsPerDay is counted over the WORKER'S OWN day — its timeZoneId, UTC only when it has none — because the scheduler that fires those runs is already zone-aware.";
|
|
789
|
+
const getWorkerBudget = {
|
|
790
|
+
name: "budget_get",
|
|
791
|
+
title: "Get Worker Budget",
|
|
792
|
+
description: "One worker's spend and rate ceilings: maxUsdPerRun, maxUsdPerDay, maxRunsPerDay, maxConcurrentRuns, modelSlug, hasDeployment (plus workerId and its deprecated alias tokenId). Four readings an agent gets wrong by default. (1) maxRunsPerDay NULL MEANS THE PLATFORM DEFAULT, NOT UNLIMITED — the gate substitutes the platform's own number, so never report a null as 'no limit'. (2) maxUsdPerRun is the amount RESERVED from the wallet at dispatch, so it is also what a run must be able to AFFORD before it starts; and the day cap is counted against those RESERVATIONS rather than settled cost, so a worker reserving $0.50 under a $2/day cap is skipped on its fifth run of the day even if each one really cost a cent (the reservation is refunded when a later gate skips the run). (3) maxConcurrentRuns is enforced at mint but is CURRENTLY FIXED AT 1 rather than configurable — it is reported so the number you see is the number the gate uses, and budget_set has no parameter for it. (4) hasDeployment FALSE means hosted runs are not set up for this worker, and then the dollar figures come back as 0 because there is no deployment to read them from — that 0 means 'no deployment', NOT 'capped at zero', so check hasDeployment before quoting any ceiling. Per-worker caps do not compose; the ceiling above them is fleet_budget_get. Requires the manageBudgets scope — reading a ceiling rides the same scope as changing it." +
|
|
793
|
+
BUDGET_WINDOW_NOTE +
|
|
794
|
+
NEW_SCOPE_NOTE,
|
|
795
|
+
auth: "manager",
|
|
796
|
+
method: "get",
|
|
797
|
+
schema: {
|
|
798
|
+
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
799
|
+
},
|
|
800
|
+
path: (params) => `${API}/${params.tokenId}/budget`,
|
|
801
|
+
paramFilter: () => ({}),
|
|
802
|
+
annotations: READ_ONLY,
|
|
803
|
+
};
|
|
804
|
+
const setWorkerBudget = {
|
|
805
|
+
name: "budget_set",
|
|
806
|
+
title: "Set Worker Budget",
|
|
807
|
+
description: "Change one worker's ceilings, and get the whole budget back as it now stands. PARTIAL: every field is optional and an OMITTED FIELD MEANS UNCHANGED, so you can raise one ceiling without restating the rest and without racing another writer's edit to a different field. Three traps. Setting maxUsdPerRun or maxUsdPerDay on a worker with NO HOSTED DEPLOYMENT is a 400 — there is nothing for a dollar cap to bind to, and budget_get's hasDeployment says which workers those are; maxRunsPerDay, by contrast, can be set on any worker. There is NO way to clear maxRunsPerDay back to the platform default here, because null already means 'leave it alone': send an explicit number instead. And LOWERING maxUsdPerRun below what a run needs does not fail loudly — it makes that worker's next run a Skipped receipt with a skipReason, which is a receipt an agent must go and read. maxConcurrentRuns is not settable (fixed at 1) and is absent from this call by design. A ZERO dollar cap means STOP, not unlimited. Requires the manageBudgets scope." +
|
|
808
|
+
BUDGET_WINDOW_NOTE +
|
|
809
|
+
NEW_SCOPE_NOTE,
|
|
810
|
+
auth: "manager",
|
|
811
|
+
method: "patch",
|
|
812
|
+
schema: {
|
|
813
|
+
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
814
|
+
maxUsdPerRun: z.number().min(0).max(1000).optional().describe("Hard per-run ceiling in USD, 0–1000 — also the amount reserved from the wallet at dispatch. Needs a hosted deployment. Omit to keep."),
|
|
815
|
+
maxUsdPerDay: z.number().min(0).max(100000).optional().describe("Ceiling on this worker's reserved spend per UTC day, 0–100000. Needs a hosted deployment. Omit to keep."),
|
|
816
|
+
maxRunsPerDay: z.number().int().min(1).max(10000).optional().describe("Runs per the worker's own day, 1–10000. Omit to keep — there is no value here that restores the platform default."),
|
|
817
|
+
},
|
|
818
|
+
path: (params) => `${API}/${params.tokenId}/budget`,
|
|
819
|
+
bodyBuilder: (params) => ({
|
|
820
|
+
maxUsdPerRun: params.maxUsdPerRun,
|
|
821
|
+
maxUsdPerDay: params.maxUsdPerDay,
|
|
822
|
+
maxRunsPerDay: params.maxRunsPerDay,
|
|
823
|
+
}),
|
|
824
|
+
annotations: UPDATE,
|
|
825
|
+
};
|
|
826
|
+
const getFleetBudget = {
|
|
827
|
+
name: "fleet_budget_get",
|
|
828
|
+
title: "Get Fleet Budget",
|
|
829
|
+
description: "The ACCOUNT-WIDE spend ceiling and what has been spent against it — the brake above the per-worker caps, which exists because per-worker caps DO NOT COMPOSE: eighteen workers each capped at a dollar a day is an eighteen-dollar-a-day fleet. Returns maxUsdPerDay and maxUsdPerMonth (each ABSENT when no ceiling of that kind is set — and note that a ceiling of ZERO MEANS STOP, not unlimited), autoPauseOnBreach, spentTodayUsd, spentThisMonthUsd, lastBreachAtUtc, lastBreachScope ('fleet.day' | 'fleet.month') and serverTimeUtc — compute headroom and when a window rolls against serverTimeUtc, never your own clock. The spend figures are SETTLED model spend plus BYOK platform fees, read from run receipts rather than the wallet ledger: top-ups, worker-assistant spend and app-usage billing are neither counted here nor governed by this ceiling, so this number will not match a wallet balance. A run is refused once spend REACHES the ceiling (>=, not >), arriving as a Skipped receipt whose errorCode is fleet_spend_cap. Account-scoped by the key itself, so it takes no worker id. Requires the manageBudgets scope." +
|
|
830
|
+
NEW_SCOPE_NOTE,
|
|
831
|
+
auth: "manager",
|
|
832
|
+
method: "get",
|
|
833
|
+
schema: {},
|
|
834
|
+
path: `${API}/fleet/budget`,
|
|
835
|
+
annotations: READ_ONLY,
|
|
836
|
+
};
|
|
837
|
+
const setFleetBudget = {
|
|
838
|
+
name: "fleet_budget_set",
|
|
839
|
+
title: "Set Fleet Budget",
|
|
840
|
+
description: "Set or clear the account-wide ceiling, and get the fleet budget back with fresh spend figures. ABSENT MEANS UNCHANGED, so REMOVING a ceiling needs the matching CLEAR FLAG — clearMaxUsdPerDay / clearMaxUsdPerMonth — because null cannot mean both 'leave it alone' and 'none'. Sending a value and its clear flag together is contradictory and CLEAR WINS: dropping a ceiling is the safer reading of a confused request than raising one. ZERO IS NOT UNLIMITED — a ceiling of 0 stops the whole fleet, because a run is refused once spend reaches it. autoPauseOnBreach is the loud one: when a ceiling trips it DISABLES EVERY WORKER ON THE ACCOUNT rather than only refusing the run that tripped it — each worker's own API key stops working and its schedules stop firing — and nothing turns them back on when the window rolls, so a human, or worker_set_enabled one worker at a time, has to start them again. It is off by default; turn it on deliberately, and tell the human you did. A breach raises its event once per window rather than on every refused run, and lastBreachAtUtc/lastBreachScope on the response are how you see that it happened. Requires the manageBudgets scope." +
|
|
841
|
+
NEW_SCOPE_NOTE,
|
|
842
|
+
auth: "manager",
|
|
843
|
+
method: "patch",
|
|
844
|
+
schema: {
|
|
845
|
+
maxUsdPerDay: z.number().min(0).max(1000000).optional().describe("Account-wide ceiling on settled run spend per UTC day, 0–1000000. Omit to keep; use clearMaxUsdPerDay to remove it."),
|
|
846
|
+
clearMaxUsdPerDay: z.boolean().optional().describe("true = REMOVE the daily ceiling (no account-wide day limit). Wins over maxUsdPerDay if both are sent."),
|
|
847
|
+
maxUsdPerMonth: z.number().min(0).max(1000000).optional().describe("Account-wide ceiling per UTC month, 0–1000000. Omit to keep; use clearMaxUsdPerMonth to remove it."),
|
|
848
|
+
clearMaxUsdPerMonth: z.boolean().optional().describe("true = REMOVE the monthly ceiling. Wins over maxUsdPerMonth if both are sent."),
|
|
849
|
+
autoPauseOnBreach: z.boolean().optional().describe("true = disable EVERY worker on the account when a ceiling trips, instead of only refusing the run that tripped it. Re-enabling is manual. Omit to keep."),
|
|
850
|
+
},
|
|
851
|
+
path: `${API}/fleet/budget`,
|
|
852
|
+
bodyBuilder: (params) => ({
|
|
853
|
+
maxUsdPerDay: params.maxUsdPerDay,
|
|
854
|
+
clearMaxUsdPerDay: params.clearMaxUsdPerDay,
|
|
855
|
+
maxUsdPerMonth: params.maxUsdPerMonth,
|
|
856
|
+
clearMaxUsdPerMonth: params.clearMaxUsdPerMonth,
|
|
857
|
+
autoPauseOnBreach: params.autoPauseOnBreach,
|
|
858
|
+
}),
|
|
859
|
+
annotations: UPDATE,
|
|
860
|
+
};
|
|
433
861
|
// ─── Export ─────────────────────────────────────────────────────────────────
|
|
434
862
|
export const manageDescriptors = [
|
|
863
|
+
getKeyInfo,
|
|
435
864
|
listWorkers,
|
|
436
865
|
getWorker,
|
|
437
866
|
runWorker,
|
|
867
|
+
runsFeed,
|
|
868
|
+
fleetPulse,
|
|
438
869
|
listRuns,
|
|
439
870
|
getRun,
|
|
440
871
|
getRunEvents,
|
|
872
|
+
getRunQuestion,
|
|
873
|
+
answerRunQuestion,
|
|
441
874
|
cancelRun,
|
|
442
875
|
clearRunDigest,
|
|
443
876
|
scoreRun,
|
|
@@ -449,10 +882,25 @@ export const manageDescriptors = [
|
|
|
449
882
|
createSchedule,
|
|
450
883
|
updateSchedule,
|
|
451
884
|
deleteSchedule,
|
|
885
|
+
listDeliveries,
|
|
886
|
+
deliveryChannels,
|
|
887
|
+
createDelivery,
|
|
888
|
+
updateDelivery,
|
|
889
|
+
deleteDelivery,
|
|
452
890
|
getInstruction,
|
|
453
891
|
setInstruction,
|
|
892
|
+
getInstructionVersions,
|
|
893
|
+
getInstructionVersion,
|
|
894
|
+
restoreInstructionVersion,
|
|
454
895
|
setWorkerEnabled,
|
|
455
896
|
kitInstallPreview,
|
|
456
897
|
kitInstall,
|
|
898
|
+
clonePreview,
|
|
899
|
+
cloneWorker,
|
|
900
|
+
cloneWorkerBulk,
|
|
901
|
+
getWorkerBudget,
|
|
902
|
+
setWorkerBudget,
|
|
903
|
+
getFleetBudget,
|
|
904
|
+
setFleetBudget,
|
|
457
905
|
];
|
|
458
906
|
//# sourceMappingURL=manage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manage.js","sourceRoot":"","sources":["../../src/descriptors/manage.ts"],"names":[],"mappings":"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","sourcesContent":["// The 22 authenticated fleet-management tools, as pure descriptors. The\n// descriptions ARE the product surface: they are served verbatim to MCP\n// clients (and any future CLI help), so every contract nuance an agent must\n// not get wrong is taught here.\n\nimport { z } from \"../zod.js\";\nimport { CREATE, DELETE, READ_ONLY, TRIGGER, UPDATE, type ToolDescriptor } from \"./types.js\";\n\n// The graded-outcome vocabulary, taught wherever a score can be read or written.\n// The null-vs-zero line is the one an agent gets wrong by default: absent means\n// nobody judged the run, and reporting that as a zero would invent a failure.\nconst SCORE_NOTE =\n \" Success grading: selfScore (0-100) is the run's OWN assessment of how much of its task it accomplished, written by a grading pass over what it actually did — a self-report, not a measurement. ownerScore (0-100) is the human's grade and OVERRIDES selfScore wherever both exist. selfScoreReason is a one-line explainer for selfScore. All three are null when the run was never assessed (stateless workers and very short runs are never graded) — null means NOT ASSESSED, never zero: do not report an unassessed run as scoring 0, and do not average nulls into a success rate.\";\n\nconst API = \"/api/manage/workers\";\n\n// ─── Shared phrasing ────────────────────────────────────────────────────────\n\nconst TOKEN_ID_HINT =\n \"The worker's numeric token ID, as returned by workers_list. A 404 not_found means the worker does not exist OR belongs to another account — the two are indistinguishable by design.\";\n\nconst RUN_ID_HINT =\n \"The run's UUID, as returned by worker_run (runId), workers_list (currentRunId / lastRun.runId), or worker_runs.\";\n\n// The whole runs family shares this degradation mode; teach it once per tool so\n// agents never retry-loop a 422.\nconst RUNTIME_NOTE =\n \" When hosted runs are not enabled for this environment the call returns 422 RUNTIME_NOT_ENABLED — an environment capability switch, not a transient error: do not retry, and note that every non-run tool keeps working.\";\n\nconst UTC_HINT = \"ISO 8601 UTC datetime, e.g. '2026-08-01T00:00:00Z'.\";\n\n// ─── Fleet ──────────────────────────────────────────────────────────────────\n\nconst listWorkers: ToolDescriptor = {\n name: \"workers_list\",\n title: \"List Workers\",\n description:\n \"List every AI worker on this account with live status: title, avatar, status (active|paused|expired), isEnabled, expiresAt, lastRun (the newest SETTLED run — in-flight runs never appear here), schedule rollup (total/enabled/nextRunUtc), and live state (isRunning, inFlightRuns, currentRunId — poll run_get with currentRunId to watch it). Compute elapsed/next-run times against the response's serverTimeUtc, never your own clock. IMPORTANT: lastRun.resultText is the report the worker itself wrote and requires the manager key to hold the readRuns scope IN ADDITION to readWorkers — with readWorkers only it is null, which does NOT mean the run produced no report; check your key's scopes before concluding anything from a null. Scope model for every tool here: a 403 OPERATION_NOT_ALLOWED names the missing scope — the key must be re-minted with broader scopes by an account admin at https://workerkit.ai (do not retry the call).\",\n auth: \"manager\",\n method: \"get\",\n schema: {},\n path: API,\n annotations: READ_ONLY,\n};\n\nconst getWorker: ToolDescriptor = {\n name: \"worker_get\",\n title: \"Get Worker\",\n description:\n \"One worker in full: everything workers_list shows plus timeZoneId, maxRunsPerDay, kit provenance (templateId/slug/name), hasInstruction, isProtected, jobSentence, readiness (status ready|blocked with actionable issues — worker_inactive, no_identity, app_not_connected incl. candidateProviders, no_instruction), and 30-day activity (runs by outcome, success rate, cost; null while hosted runs are not enabled for the environment).\",\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n },\n path: (params) => `${API}/${params.tokenId}`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\n// ─── Runs ───────────────────────────────────────────────────────────────────\n\nconst runWorker: ToolDescriptor = {\n name: \"worker_run\",\n title: \"Run Worker Now\",\n description:\n \"Trigger the worker to run now (recorded as an API-triggered run, attributed to the manager key's minter). The response is the minted run's RECEIPT — read status before assuming it ran: policy rejections (kill switch, usage window, daily run/spend cap, concurrency, wallet credits, readiness, or a rejected BYOK provider key) come back as HTTP 200 with status Skipped and a skipReason telling the story; that is a normal receipt, NOT an error. Most skips clear on their own (a cap resets, concurrency frees up, credits top up) — but skipReason 'ByokKeyInvalid' / errorCode 'byok_key_invalid' means the ACCOUNT's own model-provider API key was rejected by the provider, arrives with errorDetail null (no prose), and is owner-fixable ONLY: never retry it, report it to the human so they can re-add or remove the key. Structural refusals are 409 (not_deployed, deployment_paused, deployment_suspended, model_unavailable) and 404 for an unknown worker; run-endpoint errors use the {error, message} envelope where error IS the snake_case code. prompt = what to do THIS run; omit it and the worker runs on its standing instructions. Rate limit: 30 run-triggers per minute per ACCOUNT (all of this account's keys and clients share it; other accounts do not affect you). On a 429 back off for the Retry-After — never tighten a loop in response.\" +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"post\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n prompt: z.string().max(8000).optional().describe(\n \"What to do on THIS run (≤8000 chars). Omit to run the worker's standing instructions unchanged.\"\n ),\n modelSlug: z.string().max(64).optional().describe(\n \"One-off model override for this run (≤64 chars). Omit to use the worker's configured model.\"\n ),\n },\n path: (params) => `${API}/${params.tokenId}/run`,\n bodyBuilder: (params) => ({ prompt: params.prompt, modelSlug: params.modelSlug }),\n annotations: TRIGGER,\n};\n\nconst listRuns: ToolDescriptor = {\n name: \"worker_runs\",\n title: \"List Worker Runs\",\n description:\n \"The worker's run history, newest first, paginated ({runs, page, pageSize, totalCount}). Each entry: runId, status, skipReason, triggerKind, modelSlug, timings, turns, modelCostUsd, billingMode, byokFeeUsd, toolCalls, firewallDenials, issue counts, and the grades (selfScore, ownerScore). billingMode ('Platform' | 'Byok') says whose provider key paid: on a Byok run modelCostUsd is the provider's LIST price and was NOT charged to the wallet — the wallet impact is byokFeeUsd alone (often $0.00). Never sum modelCostUsd as spend without checking billingMode. Requires the readRuns scope.\" +\n SCORE_NOTE +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n // Closed enum on purpose: the backend silently DROPS an unparseable status\n // filter and returns the full unfiltered history — \"cancelled\"/\"error\" would\n // read as the real subset. These are the WorkerRunStatus names verbatim.\n status: z.enum([\n \"pending\", \"dispatched\", \"running\", \"succeeded\", \"failed\",\n \"timedOut\", \"budgetExceeded\", \"skipped\", \"canceled\",\n ]).optional().describe(\"Filter by run status. Omit for all runs.\"),\n page: z.number().int().min(1).default(1).describe(\"1-based page number.\"),\n pageSize: z.number().int().min(1).max(100).default(20).describe(\"Results per page (max 100).\"),\n fromUtc: z.string().optional().describe(`Only runs started at/after this time. ${UTC_HINT}`),\n toUtc: z.string().optional().describe(`Only runs started at/before this time. ${UTC_HINT}`),\n },\n path: (params) => `${API}/${params.tokenId}/runs`,\n paramFilter: (params) => {\n const { tokenId: _tokenId, ...query } = params;\n return query;\n },\n annotations: READ_ONLY,\n};\n\nconst getRun: ToolDescriptor = {\n name: \"run_get\",\n title: \"Get Run\",\n description:\n \"One run's full receipt: status, trigger, timings, token/cost metering (including billingMode 'Platform'|'Byok' and byokFeeUsd — on a Byok run modelCostUsd is the provider's list price and was NOT charged to the wallet), finalDigest (the worker's report), runPrompt/runContext, liveness (live|stalled) and lastActivity while in flight, errorCode/errorDetail, issues, and the grades (selfScore, selfScoreReason, ownerScore — set or change ownerScore with run_score). Note: footprint, turnsTimeline, issues, and priceSnapshot arrive as raw JSON strings — parse them before reasoning over their contents. Requires readRuns.\" +\n SCORE_NOTE +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"get\",\n schema: {\n runId: z.string().uuid().describe(RUN_ID_HINT),\n },\n path: (params) => `${API}/runs/${params.runId}`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst getRunEvents: ToolDescriptor = {\n name: \"run_events\",\n title: \"Get Run Events\",\n description:\n \"The run's live step feed ({events, lastSeq, status, finishedAtUtc}). To watch a run: call with afterSeq=0, then repeat with afterSeq=<the lastSeq you received> while status is non-terminal; stop once the run settles. WAIT AT LEAST 3-5 SECONDS BETWEEN POLLS — a run's events advance at turn speed, not faster. Polling has its own per-account window (120/min; watching many runs at once shares it), separate from the rest of the surface, so a paced watch loop never starves your other calls. Each event: seq, atUtc, kind, turn, label, ok, ms, detail (raw JSON string). Requires readRuns.\" +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"get\",\n schema: {\n runId: z.string().uuid().describe(RUN_ID_HINT),\n afterSeq: z.number().int().min(0).default(0).describe(\n \"Return only events with seq greater than this. Pass the previous response's lastSeq to poll incrementally — with at least 3-5s between polls (the poll window is 120/min per account).\"\n ),\n limit: z.number().int().min(1).max(500).default(200).describe(\"Maximum events to return.\"),\n },\n path: (params) => `${API}/runs/${params.runId}/events`,\n paramFilter: (params) => {\n const { runId: _runId, ...query } = params;\n return query;\n },\n annotations: READ_ONLY,\n};\n\nconst cancelRun: ToolDescriptor = {\n name: \"run_cancel\",\n title: \"Cancel Run\",\n description:\n \"Cancel a run. In-flight runs stop at their next heartbeat; an already-settled run refuses with 409 run_not_cancelable — that is a normal outcome meaning there is nothing left to cancel, not a retry signal. Requires the runWorkers scope.\" +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"post\",\n schema: {\n runId: z.string().uuid().describe(RUN_ID_HINT),\n },\n path: (params) => `${API}/runs/${params.runId}/cancel`,\n bodyBuilder: () => ({}),\n annotations: CREATE,\n};\n\nconst clearRunDigest: ToolDescriptor = {\n name: \"run_clear_digest\",\n title: \"Clear Run Report\",\n description:\n \"Scrub a settled run's report so the worker stops being handed it — a SCRUB, not a delete: finalDigest and distilledDigest are nulled and the surviving receipt is returned (status, timings, counts, cost and metering all stay — the wallet ledger references them). The run still appears in the worker's previous-runs block reading \\\"(that run left no report)\\\", and agent-reported issues are NOT cleared. Use when a contextual worker keeps carrying something wrong forward from a past run. Requires manageMemory (not readRuns) — this mutates what the worker remembers. 409 run_not_settled while the run is in flight; idempotent once settled.\" +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"delete\",\n schema: {\n runId: z.string().uuid().describe(RUN_ID_HINT),\n },\n path: (params) => `${API}/runs/${params.runId}/digest`,\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },\n};\n\nconst scoreRun: ToolDescriptor = {\n name: \"run_score\",\n title: \"Grade Run\",\n description:\n \"Set the OWNER's success grade on a settled run: score 0-100, or null to withdraw a grade you set earlier. Numbers only — there is no text lane, by design. The grade overrides the run's own selfScore everywhere both appear, INCLUDING the previous-runs block a contextual worker reads before its next run, which is why this needs the manageMemory scope rather than readRuns: grading changes what the worker is told about itself. Anchors to grade against: 100 = everything asked was done; 75 = core done, minor parts missing; 50 = about half, or done but unverified; 25 = attempted, little achieved; 0 = nothing achieved. 409 run_not_settled while the run is still in flight — grade it after it finishes. Idempotent: re-sending the same score changes nothing.\" +\n SCORE_NOTE +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"put\",\n schema: {\n runId: z.string().uuid().describe(RUN_ID_HINT),\n score: z.number().int().min(0).max(100).nullable().describe(\n \"The grade, 0-100. Pass null to clear YOUR grade and fall back to the run's own selfScore. Required — there is no 'leave unchanged' value, so read the current grade with run_get first if you need it.\"\n ),\n },\n path: (params) => `${API}/runs/${params.runId}/score`,\n bodyBuilder: (params) => ({ score: params.score }),\n annotations: UPDATE,\n};\n\n// ─── Memory ─────────────────────────────────────────────────────────────────\n\nconst getMemory: ToolDescriptor = {\n name: \"memory_get\",\n title: \"Get Worker Memory\",\n description:\n \"The worker's memory: memoryProfile (stateless|contextual), selfFactsEnabled, rules (what the worker must DO — injected into every run), facts (what IS true — injected), recallFacts (searchable tier), pendingProposalCount, and a usage meter with every cap (rules, injected facts, char pools, recall) including recallFull — the only signal that the worker can no longer save new facts on its own.\",\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n },\n path: (params) => `${API}/${params.tokenId}/memory`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst addMemoryItem: ToolDescriptor = {\n name: \"memory_add\",\n title: \"Add Memory Rule or Fact\",\n description:\n \"Add a rule or a fact to the worker's memory. kind='rule' = something the worker must DO, phrased as an instruction; kind='fact' = something TRUE about this worker's world. Single line, ≤300 chars. Items land owner-authored and are injected into every run. Caps are enforced at write time (15 rules; 25 injected facts within a 4,000-char pool) — a cap violation is a 400 whose message names the fix (retire or delete something first). Requires the manageMemory scope.\",\n auth: \"manager\",\n method: \"post\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n kind: z.enum([\"rule\", \"fact\"]).describe(\n \"rule = what the worker must DO (injected instruction). fact = what IS true about the worker's world.\"\n ),\n text: z.string().min(1).max(300).describe(\"The rule/fact text. Single line, 1–300 chars.\"),\n },\n path: (params) => `${API}/${params.tokenId}/memory/${params.kind === \"rule\" ? \"rules\" : \"facts\"}`,\n bodyBuilder: (params) => ({ text: params.text }),\n annotations: CREATE,\n};\n\nconst updateMemoryItem: ToolDescriptor = {\n name: \"memory_update\",\n title: \"Update Memory Item\",\n description:\n \"Edit a rule/fact's text, retire or reactivate it (status), or move a FACT between the injected and searchable tiers (scope). Omitted fields stay unchanged. Prefer retiring (status='retired') over deleting — it keeps provenance. Promoting a fact to 'injected' is charged against the injected pool and can 400 on a full pool; rules are always injected — sending scope='recall' for a rule is a 400. Requires manageMemory.\",\n auth: \"manager\",\n method: \"patch\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n itemId: z.number().int().min(1).describe(\"The memory item's id, as returned by memory_get or memory_add.\"),\n text: z.string().min(1).max(300).optional().describe(\"New text (single line, 1–300 chars). Omit to keep.\"),\n status: z.enum([\"active\", \"retired\"]).optional().describe(\"Retire or reactivate. Omit to keep.\"),\n scope: z.enum([\"injected\", \"recall\"]).optional().describe(\n \"Facts only: injected (every run) or recall (searchable). Omit to keep.\"\n ),\n },\n path: (params) => `${API}/${params.tokenId}/memory/items/${params.itemId}`,\n bodyBuilder: (params) => ({ text: params.text, status: params.status, scope: params.scope }),\n annotations: UPDATE,\n};\n\nconst deleteMemoryItem: ToolDescriptor = {\n name: \"memory_delete\",\n title: \"Delete Memory Item\",\n description:\n \"Delete a rule/fact outright. Permanent — prefer memory_update with status='retired' to keep provenance. Requires manageMemory.\",\n auth: \"manager\",\n method: \"delete\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n itemId: z.number().int().min(1).describe(\"The memory item's id, as returned by memory_get.\"),\n },\n path: (params) => `${API}/${params.tokenId}/memory/items/${params.itemId}`,\n successMessage: \"Memory item deleted.\",\n annotations: DELETE,\n};\n\n// ─── Schedules ──────────────────────────────────────────────────────────────\n\nconst listSchedules: ToolDescriptor = {\n name: \"schedules_list\",\n title: \"List Schedules\",\n description:\n \"The worker's schedules. Each row: id, title, scheduleType (EveryNMinutes|EveryNHours|DailyAtTime|OneShot), intervalValue, timeOfDayMinutes, timeZoneId, effectiveTimeZoneId (the schedule's own zone, else the worker's, else UTC), anchorUtc, computed nextRunUtc, isEnabled.\",\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n },\n path: (params) => `${API}/${params.tokenId}/schedules`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst SCHEDULE_TYPE_HINT =\n \"EveryNMinutes (intervalValue 1–1440), EveryNHours (intervalValue 1–168), DailyAtTime (timeOfDayMinutes required — wall-clock minutes past midnight in the effective time zone, DST-correct), or OneShot (anchorUtc required, must be in the future). Input is parsed case-insensitively; responses always return the PascalCase form.\";\n\n// Plan walls, not transient errors. Note the envelope: the machine-readable code\n// is in `feature`, while `error` holds the literal string \"feature_gated\" — the\n// one place on this surface where `error` is not the code.\nconst SCHEDULE_GATE_HINT =\n \" Two plan walls return 402 {error:'feature_gated', feature, upgradeTrigger, message}: feature 'schedule_cadence' means minute-based schedules are not in this plan (use EveryNHours or DailyAtTime), and 'schedule_count' means the worker is at its recurring-schedule cap (a OneShot is never counted). Both are terminal — do NOT retry; either pick an allowed cadence or tell the human to upgrade.\";\n\nconst createSchedule: ToolDescriptor = {\n name: \"schedule_create\",\n title: \"Create Schedule\",\n description:\n \"Create a schedule for the worker. Per-type required fields: \" + SCHEDULE_TYPE_HINT +\n \" Omit timeZoneId to follow the worker's own time zone (the normal case). Requires the manageSchedules scope.\" +\n SCHEDULE_GATE_HINT,\n auth: \"manager\",\n method: \"post\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n scheduleType: z.enum([\"EveryNMinutes\", \"EveryNHours\", \"DailyAtTime\", \"OneShot\"]).describe(SCHEDULE_TYPE_HINT),\n title: z.string().max(120).optional().describe(\n \"Optional display title, ≤120 chars (the column's own limit; a longer title is truncated upstream, not rejected).\"\n ),\n intervalValue: z.number().int().min(1).optional().describe(\n \"EveryNMinutes: 1–1440. EveryNHours: 1–168. Required for those types, ignored otherwise.\"\n ),\n timeOfDayMinutes: z.number().int().min(0).max(1439).optional().describe(\n \"DailyAtTime only: wall-clock minutes past midnight in the effective time zone (e.g. 540 = 09:00). DST-correct.\"\n ),\n timeZoneId: z.string().optional().describe(\n \"IANA time zone (e.g. 'America/New_York') overriding the worker's zone. Omit to follow the worker.\"\n ),\n anchorUtc: z.string().optional().describe(`OneShot only: when to fire, must be in the future. ${UTC_HINT}`),\n isEnabled: z.boolean().default(true).describe(\"Whether the schedule starts enabled.\"),\n },\n path: (params) => `${API}/${params.tokenId}/schedules`,\n bodyBuilder: (params) => ({\n title: params.title,\n scheduleType: params.scheduleType,\n intervalValue: params.intervalValue,\n timeOfDayMinutes: params.timeOfDayMinutes,\n timeZoneId: params.timeZoneId,\n anchorUtc: params.anchorUtc,\n isEnabled: params.isEnabled,\n }),\n annotations: CREATE,\n};\n\nconst updateSchedule: ToolDescriptor = {\n name: \"schedule_update\",\n title: \"Update Schedule\",\n description:\n \"Edit a schedule (partial — omitted fields stay unchanged; timeZoneId='' clears the override so the schedule follows the worker's zone again). nextRunUtc is recomputed on every edit. Per-type field rules: \" +\n SCHEDULE_TYPE_HINT + \" Requires manageSchedules.\" + SCHEDULE_GATE_HINT,\n auth: \"manager\",\n method: \"patch\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n scheduleId: z.number().int().min(1).describe(\"The schedule's id, as returned by schedules_list.\"),\n scheduleType: z.enum([\"EveryNMinutes\", \"EveryNHours\", \"DailyAtTime\", \"OneShot\"]).optional().describe(\n \"Change the schedule type. \" + SCHEDULE_TYPE_HINT\n ),\n title: z.string().max(120).optional().describe(\n \"New display title, ≤120 chars (truncated upstream, not rejected).\"\n ),\n intervalValue: z.number().int().min(1).optional().describe(\"New interval (see type rules).\"),\n timeOfDayMinutes: z.number().int().min(0).max(1439).optional().describe(\"DailyAtTime: new wall-clock minutes past midnight.\"),\n timeZoneId: z.string().optional().describe(\"IANA zone override; empty string '' clears it (follow the worker).\"),\n anchorUtc: z.string().optional().describe(`OneShot: new fire time. ${UTC_HINT}`),\n isEnabled: z.boolean().optional().describe(\"Enable or disable the schedule.\"),\n },\n path: (params) => `${API}/${params.tokenId}/schedules/${params.scheduleId}`,\n bodyBuilder: (params) => ({\n title: params.title,\n scheduleType: params.scheduleType,\n intervalValue: params.intervalValue,\n timeOfDayMinutes: params.timeOfDayMinutes,\n timeZoneId: params.timeZoneId,\n anchorUtc: params.anchorUtc,\n isEnabled: params.isEnabled,\n }),\n annotations: UPDATE,\n};\n\nconst deleteSchedule: ToolDescriptor = {\n name: \"schedule_delete\",\n title: \"Delete Schedule\",\n description:\n \"Delete a schedule. To pause it instead, use schedule_update with isEnabled=false. Requires manageSchedules.\",\n auth: \"manager\",\n method: \"delete\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n scheduleId: z.number().int().min(1).describe(\"The schedule's id, as returned by schedules_list.\"),\n },\n path: (params) => `${API}/${params.tokenId}/schedules/${params.scheduleId}`,\n successMessage: \"Schedule deleted.\",\n annotations: DELETE,\n};\n\n// ─── Instruction ────────────────────────────────────────────────────────────\n\nconst getInstruction: ToolDescriptor = {\n name: \"instruction_get\",\n title: \"Get Instruction\",\n description:\n \"The worker's standing instruction: content, jobSentence, whenToUse, description, memoryProfile, selfFactsEnabled, isProtected, currentVersion, timestamps. A bare \\\"Operation completed successfully.\\\" response means the worker has NO instruction yet (HTTP 204) — use instruction_set to create one. For a worker installed from a protected kit, metadata is returned but the instruction text is REDACTED (it belongs to the kit's publisher) — that is not an error.\",\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n },\n path: (params) => `${API}/${params.tokenId}/instruction`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst setInstruction: ToolDescriptor = {\n name: \"instruction_set\",\n title: \"Set Instruction\",\n description:\n \"Create or replace the worker's standing instruction (the prompt/workflow text handed to every run). A changed body snapshots the prior version. Omitted optional fields stay unchanged; empty string clears. Returns 403 OPERATION_NOT_ALLOWED for a protected kit's worker — that text belongs to its publisher; do not retry. Requires the manageInstructions scope.\",\n auth: \"manager\",\n method: \"put\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n content: z.string().min(1).max(100000).describe(\"The instruction text (1–100,000 chars). Required — this replaces the whole content.\"),\n jobSentence: z.string().max(200).optional().describe(\"The worker's one-liner (≤200). Omit = unchanged; '' = clear.\"),\n whenToUse: z.string().max(500).optional().describe(\"Trigger text: when this worker should be used (≤500). Omit = unchanged; '' = clear.\"),\n description: z.string().max(2000).optional().describe(\"Longer display-only description (≤2000). Omit = unchanged; '' = clear.\"),\n memoryProfile: z.enum([\"stateless\", \"contextual\"]).optional().describe(\n \"Worker class: stateless (fresh each run) or contextual (carries prior-run reports). Omit = unchanged.\"\n ),\n selfFactsEnabled: z.boolean().optional().describe(\n \"Whether the worker may save its own facts during runs. Set true when the content tells the worker to save facts. Omit = unchanged.\"\n ),\n },\n path: (params) => `${API}/${params.tokenId}/instruction`,\n bodyBuilder: (params) => ({\n content: params.content,\n jobSentence: params.jobSentence,\n whenToUse: params.whenToUse,\n description: params.description,\n memoryProfile: params.memoryProfile,\n selfFactsEnabled: params.selfFactsEnabled,\n }),\n annotations: UPDATE,\n};\n\n// ─── Start / stop ───────────────────────────────────────────────────────────\n\nconst setWorkerEnabled: ToolDescriptor = {\n name: \"worker_set_enabled\",\n title: \"Start or Stop Worker\",\n description:\n \"Start (enabled=true) or stop (enabled=false) a worker. Stopping pauses the WHOLE worker: its own API key stops working AND its schedules stop firing; re-enabling restores both. Returns {tokenId, isEnabled}. Idempotent. Requires the manageState scope.\",\n auth: \"manager\",\n method: \"post\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n enabled: z.boolean().describe(\"true = start the worker; false = stop it (key + schedules pause together).\"),\n },\n path: (params) => `${API}/${params.tokenId}/enabled`,\n bodyBuilder: (params) => ({ enabled: params.enabled }),\n annotations: UPDATE,\n};\n\n// ─── Kit install ────────────────────────────────────────────────────────────\n// The one place on this surface an agent can CREATE a worker: install a kit from\n// the public directory. Both tools need the installKits scope (keys minted\n// before the scope existed — including old \"all\" keys — lack it until an\n// account admin re-scopes them).\n\nconst KITS_API = \"/api/manage/kits\";\n\nconst KIT_SLUG_HINT =\n \"The kit's slug, as returned by kits_search / kit_get on the public WorkerKit Directory server. 404 not_found = no such kit (or another account's private kit — indistinguishable by design).\";\n\n// Pinned to the backend's slug alphabet ([a-z0-9-], ≤120). Not cosmetic: encodeURIComponent\n// leaves dots intact and the WHATWG URL parser collapses \".\" / \"..\" segments client-side, so\n// an unpinned slug could walk the request off /api/manage/kits before it ever leaves this\n// process. No real slug can contain a dot, so nothing legitimate is refused.\nconst KIT_SLUG = z.string().min(1).max(120).regex(/^[a-z0-9][a-z0-9-]*$/, \"not a valid kit slug\");\n\nconst kitInstallPreview: ToolDescriptor = {\n name: \"kit_install_preview\",\n title: \"Preview Kit Install\",\n description:\n \"The kit's install form plus this account's current ability to satisfy it — call this BEFORE kit_install and gather every answer it demands. Creates nothing. Requires the installKits scope (403 names it). Returns: requiredInputs (EVERY key is mandatory at install — collect a value for each from the human, keys are exact), memorySetup (questions whose answers become the worker's first memory; only required:true entries are mandatory), categorySlots (pick ONE member per slot via categoryChoices; each member carries connection — prefer a connected one — and connectionProvider, which when set means also pass categoryChoices[].resourceId picked from operatorResources, ideally one with hasActiveConnection and a matching provider), apps + appsNeedingConnection (the connection state the new worker would START with; installing anyway is allowed — the worker starts blocked and a human finishes at connectAppsUrl), operator (which operator the install targets), limits (currentWorkers/maxWorkers — at the cap the install returns 402), kitPageUrl (the human install page). Preview is advisory: the install response's readiness block is the verdict. For the kit's full permissions manifest and instruction use kit_get on the public Directory server.\",\n auth: \"manager\",\n method: \"get\",\n schema: {\n slug: KIT_SLUG.describe(KIT_SLUG_HINT),\n operatorId: z.string().uuid().optional().describe(\n \"Operator (workspace) to install into. Omit to use the account's default operator.\"\n ),\n },\n path: (params) => `${KITS_API}/${encodeURIComponent(String(params.slug))}/install-preview`,\n paramFilter: (params) => {\n const { slug: _slug, ...query } = params;\n return query;\n },\n annotations: READ_ONLY,\n};\n\nconst kitInstall: ToolDescriptor = {\n name: \"kit_install\",\n title: \"Install Kit\",\n description:\n \"Install a directory kit as a NEW worker on this account. NOT idempotent: every successful call creates another worker — never retry a success, and on a timeout check workers_list (needs the readWorkers scope) before trying again. Requires the installKits scope. Call kit_install_preview first and supply every requiredInputs key in inputs (a missing or unknown key is a 400 naming it), answers to required memorySetup questions in memoryAnswers, and one categoryChoices entry per slot (member with connectionProvider set → also pass resourceId from the preview's operatorResources). CRITICAL — secrets shown ONCE: the response's install.rawKey (the worker's pe_ API key) and install.triggers[].signingSecret can NEVER be read again; deliver them to the human immediately and do not discard the response before doing so. The response also carries readiness (status ready|blocked with actionable issues, e.g. app_not_connected + candidateProviders; null means the readiness check itself failed AFTER the install succeeded — do not retry the install, read readiness via worker_get), workerUrl (the worker's dashboard page — hand it to the human), and connectAppsUrl (where the human connects missing apps in the browser; agents cannot connect apps). A 402 {error:'limit_exceeded'} is the plan's worker cap — terminal, do not retry; tell the human to upgrade or free a slot. Rate: 10 installs/hour per account.\",\n auth: \"manager\",\n method: \"post\",\n schema: {\n slug: KIT_SLUG.describe(KIT_SLUG_HINT),\n operatorId: z.string().uuid().optional().describe(\n \"Operator (workspace) to install into. Omit to use the account's default operator.\"\n ),\n title: z.string().max(100).optional().describe(\n \"Name for the new worker (≤100 chars). Omit to use the kit's name.\"\n ),\n avatar: z.string().max(40).optional().describe(\n \"Avatar slug for the new worker. Omit for the default.\"\n ),\n categoryChoices: z.array(z.object({\n categoryCode: z.string().describe(\"The slot's categoryCode from the preview.\"),\n memberCode: z.string().describe(\"The chosen member's code (e.g. 'gmail').\"),\n resourceId: z.string().uuid().optional().describe(\n \"For members with connectionProvider set: the identity to bind, from the preview's operatorResources.\"\n ),\n })).optional().describe(\n \"One entry per categorySlots slot. Omitted slots resolve to the kit's first offered member on safe defaults.\"\n ),\n inputs: z.record(z.string(), z.string()).optional().describe(\n \"Answers to requiredInputs, keyed EXACTLY by each entry's key. Every key is mandatory; values are single-line, 1-200 chars.\"\n ),\n memoryAnswers: z.record(z.string(), z.string()).optional().describe(\n \"Answers to memorySetup questions by key. Entries with required:true are mandatory. Keep this separate from inputs — mixing the two maps is a 400.\"\n ),\n },\n path: (params) => `${KITS_API}/${encodeURIComponent(String(params.slug))}/install`,\n bodyBuilder: (params) => ({\n operatorId: params.operatorId,\n title: params.title,\n avatar: params.avatar,\n categoryChoices: params.categoryChoices,\n inputs: params.inputs,\n memoryAnswers: params.memoryAnswers,\n }),\n annotations: CREATE,\n};\n\n// ─── Export ─────────────────────────────────────────────────────────────────\n\nexport const manageDescriptors: readonly ToolDescriptor[] = [\n listWorkers,\n getWorker,\n runWorker,\n listRuns,\n getRun,\n getRunEvents,\n cancelRun,\n clearRunDigest,\n scoreRun,\n getMemory,\n addMemoryItem,\n updateMemoryItem,\n deleteMemoryItem,\n listSchedules,\n createSchedule,\n updateSchedule,\n deleteSchedule,\n getInstruction,\n setInstruction,\n setWorkerEnabled,\n kitInstallPreview,\n kitInstall,\n];\n"]}
|
|
1
|
+
{"version":3,"file":"manage.js","sourceRoot":"","sources":["../../src/descriptors/manage.ts"],"names":[],"mappings":"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","sourcesContent":["// The 42 authenticated fleet-management tools, as pure descriptors. The\n// descriptions ARE the product surface: they are served verbatim to MCP\n// clients (and any future CLI help), so every contract nuance an agent must\n// not get wrong is taught here.\n\nimport { z } from \"../zod.js\";\nimport { CREATE, DELETE, READ_ONLY, TRIGGER, UPDATE, type ToolDescriptor } from \"./types.js\";\n\n// The graded-outcome vocabulary, taught wherever a score can be read or written.\n// The null-vs-zero line is the one an agent gets wrong by default: absent means\n// nobody judged the run, and reporting that as a zero would invent a failure.\nconst SCORE_NOTE =\n \" Success grading: selfScore (0-100) is the run's OWN assessment of how much of its task it accomplished, written by a grading pass over what it actually did — a self-report, not a measurement. ownerScore (0-100) is the human's grade and OVERRIDES selfScore wherever both exist. selfScoreReason is a one-line explainer for selfScore. All three are null when the run was never assessed (stateless workers and very short runs are never graded) — null means NOT ASSESSED, never zero: do not report an unassessed run as scoring 0, and do not average nulls into a success rate.\";\n\nconst API = \"/api/manage/workers\";\n\n// ─── Shared phrasing ────────────────────────────────────────────────────────\n\nconst TOKEN_ID_HINT =\n \"The worker's numeric token ID, as returned by workers_list. A 404 not_found means the worker does not exist OR belongs to another account — the two are indistinguishable by design.\";\n\nconst RUN_ID_HINT =\n \"The run's UUID, as returned by worker_run (runId), workers_list (currentRunId / lastRun.runId), or worker_runs.\";\n\n// The whole runs family shares this degradation mode; teach it once per tool so\n// agents never retry-loop a 422.\nconst RUNTIME_NOTE =\n \" When hosted runs are not enabled for this environment the call returns 422 RUNTIME_NOT_ENABLED — an environment capability switch, not a transient error: do not retry, and note that every non-run tool keeps working.\";\n\nconst UTC_HINT = \"ISO 8601 UTC datetime, e.g. '2026-08-01T00:00:00Z'.\";\n\n// A scope added to the product AFTER a key was minted never reaches that key —\n// including a key minted with \"all\", which stored the bitmask of the scopes that\n// existed that day. Taught on key_info and on every tool behind a scope that is\n// younger than the surface, so a 403 there is read as \"re-scope the key\", not\n// \"retry\".\nconst NEW_SCOPE_NOTE =\n \" Note this scope is YOUNGER than the manager-key surface: a key minted before it existed does not carry it — including one minted with \\\"all\\\" — so a 403 here is fixed by an account admin re-scoping or re-minting the key at https://workerkit.ai, never by retrying. Read key_info's scopes list before planning work that needs it.\";\n\n// ─── Key ────────────────────────────────────────────────────────────────────\n\nconst getKeyInfo: ToolDescriptor = {\n name: \"key_info\",\n title: \"Key Info\",\n description:\n \"What the presented manager key IS: accountId, accountTitle, keyName, keyPrefix (a display prefix — never the key itself), scopes, expiresAt, and serverTimeUtc. CALL THIS FIRST, before planning any work: the scopes list is exactly what the other tools on this surface will accept, so read it up front rather than discovering a wall mid-task. Any valid key may ask — this is the one tool that needs NO scope. A call outside the list fails 403 OPERATION_NOT_ALLOWED naming the missing scope, and only an account admin can add one (re-scope or re-mint the key at https://workerkit.ai) — never retry a 403. A scope added to the product AFTER a key was minted does NOT reach that key, INCLUDING a key minted with \\\"all\\\" (which stored the bitmask of the scopes that existed that day), so a tool can 403 on a key its owner believes has everything: this list is the only truth about it. Compute expiry and elapsed times against serverTimeUtc, never your own clock.\",\n auth: \"manager\",\n method: \"get\",\n schema: {},\n path: `${API}/key-info`,\n annotations: READ_ONLY,\n};\n\n// ─── Fleet ──────────────────────────────────────────────────────────────────\n\nconst listWorkers: ToolDescriptor = {\n name: \"workers_list\",\n title: \"List Workers\",\n description:\n \"List every AI worker on this account with live status: title, avatar, status (active|paused|expired), isEnabled, expiresAt, lastRun (the newest SETTLED run — in-flight runs never appear here), schedule rollup (total/enabled/nextRunUtc), and live state (isRunning, inFlightRuns, currentRunId — poll run_get with currentRunId to watch it). Compute elapsed/next-run times against the response's serverTimeUtc, never your own clock. IMPORTANT: lastRun.resultText is the report the worker itself wrote and requires the manager key to hold the readRuns scope IN ADDITION to readWorkers — with readWorkers only it is null, which does NOT mean the run produced no report; check your key's scopes before concluding anything from a null. Scope model for every tool here: a 403 OPERATION_NOT_ALLOWED names the missing scope — the key must be re-minted with broader scopes by an account admin at https://workerkit.ai (do not retry the call).\",\n auth: \"manager\",\n method: \"get\",\n schema: {},\n path: API,\n annotations: READ_ONLY,\n};\n\nconst getWorker: ToolDescriptor = {\n name: \"worker_get\",\n title: \"Get Worker\",\n description:\n \"One worker in full: everything workers_list shows plus timeZoneId, maxRunsPerDay, kit provenance (templateId/slug/name), hasInstruction, isProtected, jobSentence, readiness (status ready|blocked with actionable issues — worker_inactive, no_identity, app_not_connected incl. candidateProviders, no_instruction), and 30-day activity (runs by outcome, success rate, cost; null while hosted runs are not enabled for the environment).\",\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n },\n path: (params) => `${API}/${params.tokenId}`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\n// ─── Runs ───────────────────────────────────────────────────────────────────\n\nconst runWorker: ToolDescriptor = {\n name: \"worker_run\",\n title: \"Run Worker Now\",\n description:\n \"Trigger the worker to run now (recorded as an API-triggered run, attributed to the manager key's minter). The response is the minted run's RECEIPT — read status before assuming it ran: policy rejections (kill switch, usage window, daily run/spend cap, concurrency, wallet credits, readiness, or a rejected BYOK provider key) come back as HTTP 200 with status Skipped and a skipReason telling the story; that is a normal receipt, NOT an error. Most skips clear on their own (a cap resets, concurrency frees up, credits top up) — but skipReason 'ByokKeyInvalid' / errorCode 'byok_key_invalid' means the ACCOUNT's own model-provider API key was rejected by the provider, arrives with errorDetail null (no prose), and is owner-fixable ONLY: never retry it, report it to the human so they can re-add or remove the key. Structural refusals are 409 (not_deployed, deployment_paused, deployment_suspended, model_unavailable) and 404 for an unknown worker; run-endpoint errors use the {error, message} envelope where error IS the snake_case code. prompt = what to do THIS run; omit it and the worker runs on its standing instructions. Rate limit: 30 run-triggers per minute per ACCOUNT (all of this account's keys and clients share it; other accounts do not affect you). On a 429 back off for the Retry-After — never tighten a loop in response.\" +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"post\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n prompt: z.string().max(8000).optional().describe(\n \"What to do on THIS run (≤8000 chars). Omit to run the worker's standing instructions unchanged.\"\n ),\n modelSlug: z.string().max(64).optional().describe(\n \"One-off model override for this run (≤64 chars). Omit to use the worker's configured model.\"\n ),\n },\n path: (params) => `${API}/${params.tokenId}/run`,\n bodyBuilder: (params) => ({ prompt: params.prompt, modelSlug: params.modelSlug }),\n annotations: TRIGGER,\n};\n\n// ─── Fleet-wide run reads ───────────────────────────────────────────────────\n// The two calls that watch a WHOLE fleet without fanning out per worker. Both are\n// account-scoped by the key itself, so neither takes a worker id, and both are\n// deliberately money-free: cost lives on the run receipt.\n\nconst runsFeed: ToolDescriptor = {\n name: \"runs_feed\",\n title: \"Account Run Feed\",\n description:\n \"Every worker's runs in ONE account-wide feed, newest first — THE fleet-watching call. When you are minding many workers, call this instead of looping workers_list or worker_runs per worker. Each row is a scan line: runId, workerId, tokenTitle, status, outcome (running|succeeded|attention|failed|skipped|canceled — 'attention' is a SUCCEEDED run that hit friction, i.e. firewall denials, tool errors or reported issues, so report it apart from a clean success), skipReason, errorCode, triggerKind, scheduleTitle, timings, the friction counts (toolCalls, firewallDenials, toolErrors, issueCount, hasBlockerIssue), and one line of what the run did in summary + summarySource ('distilled' = a condensed record of what the run ACTUALLY did; 'report' = the worker's OWN closing account; 'error'/'skipped'/'activity' = the machine's own words — these are not equally reliable, so say which one you are quoting). Carries NO cost and NO token counts by design: read those from run_get on the one run that matters. Cursor-paged, never page-numbered — scroll by passing the previous response's nextCursor back as cursor (hasMore says whether another page exists), and re-fetch with NO cursor to refresh the head; there is deliberately no total count. A cursor we did not issue is a 400 invalid_cursor — drop it and reload the head. An unknown status is a 400 invalid_status, never a silently ignored filter. Requires the readRuns scope.\" +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"get\",\n schema: {\n // Closed enum: the feed is STRICT where the older per-worker list is lenient —\n // an unparseable status here is a 400, so a typo can never read as a real\n // subset. These are the WorkerRunStatus names verbatim, plus the feed's own\n // two composite values.\n status: z.enum([\n \"pending\", \"dispatched\", \"running\", \"succeeded\", \"failed\",\n \"timedOut\", \"budgetExceeded\", \"skipped\", \"canceled\",\n \"settled\", \"all\",\n ]).optional().describe(\n \"Filter to one run status. 'settled' is the composite for every terminal outcome (everything not in flight) — use it for a logbook, and fleet_pulse for what is running. 'all' is an explicit no-op. Omit for all runs.\"\n ),\n cursor: z.string().optional().describe(\n \"Opaque cursor from the previous response's nextCursor — fetches the next (older) page. Omit to read the head of the feed.\"\n ),\n limit: z.number().int().min(1).max(100).default(20).describe(\"Rows per page (1–100).\"),\n },\n path: `${API}/runs`,\n annotations: READ_ONLY,\n};\n\nconst fleetPulse: ToolDescriptor = {\n name: \"fleet_pulse\",\n title: \"Fleet Pulse\",\n description:\n \"Every run IN FLIGHT on the account right now, in one call — the other fleet-watching call, and the single authority for \\\"who is working\\\". Use it instead of sweeping workers_list for isRunning, or worker_runs per worker. Returns serverTimeUtc plus activeRuns[]: runId, workerId, tokenTitle, status (Pending | Dispatched | Running — a QUEUED run is not yet working, so never say \\\"running for 3m\\\" about one), createDate, startedAtUtc (null while Pending/Dispatched, so render elapsed from startedAtUtc ?? createDate and label the queued case differently), triggerKind, scheduleTitle, activitySummary, lastTool + toolActive (true = the run is INSIDE that tool — 'using X'; false = that call has ended and the name is the trailing record — 'last used X'), recentToolCalls[] (newest first, ≤25, each with a seq: accumulate across polls by appending anything whose seq beats the highest you kept for that run), toolCallCount (every call the run has made — if your kept list is shorter, the run out-ran the window and the rest is in run_events), activityUpdatedAtUtc, and liveness (live|stalled while Running). ALWAYS compute elapsed times against the response's serverTimeUtc, never your own clock. Capped at 100 rows with NO paging — truncated:true says the cap bit; an empty activeRuns[] is the normal, healthy answer, not an error or a failure to look. No cost fields: money lives on the run receipt (run_get). Requires the readRuns scope.\" +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"get\",\n schema: {},\n path: `${API}/fleet/pulse`,\n annotations: READ_ONLY,\n};\n\nconst listRuns: ToolDescriptor = {\n name: \"worker_runs\",\n title: \"List Worker Runs\",\n description:\n \"The worker's run history, newest first, paginated ({runs, page, pageSize, totalCount}). Each entry: runId, status, skipReason, triggerKind, modelSlug, timings, turns, modelCostUsd, billingMode, byokFeeUsd, toolCalls, firewallDenials, issue counts, and the grades (selfScore, ownerScore). billingMode ('Platform' | 'Byok') says whose provider key paid: on a Byok run modelCostUsd is the provider's LIST price and was NOT charged to the wallet — the wallet impact is byokFeeUsd alone (often $0.00). Never sum modelCostUsd as spend without checking billingMode. Requires the readRuns scope.\" +\n SCORE_NOTE +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n // Closed enum on purpose: the backend silently DROPS an unparseable status\n // filter and returns the full unfiltered history — \"cancelled\"/\"error\" would\n // read as the real subset. These are the WorkerRunStatus names verbatim.\n status: z.enum([\n \"pending\", \"dispatched\", \"running\", \"succeeded\", \"failed\",\n \"timedOut\", \"budgetExceeded\", \"skipped\", \"canceled\",\n ]).optional().describe(\"Filter by run status. Omit for all runs.\"),\n page: z.number().int().min(1).default(1).describe(\"1-based page number.\"),\n pageSize: z.number().int().min(1).max(100).default(20).describe(\"Results per page (max 100).\"),\n fromUtc: z.string().optional().describe(`Only runs started at/after this time. ${UTC_HINT}`),\n toUtc: z.string().optional().describe(`Only runs started at/before this time. ${UTC_HINT}`),\n },\n path: (params) => `${API}/${params.tokenId}/runs`,\n paramFilter: (params) => {\n const { tokenId: _tokenId, ...query } = params;\n return query;\n },\n annotations: READ_ONLY,\n};\n\nconst getRun: ToolDescriptor = {\n name: \"run_get\",\n title: \"Get Run\",\n description:\n \"One run's full receipt: status, trigger, timings, token/cost metering (including billingMode 'Platform'|'Byok' and byokFeeUsd — on a Byok run modelCostUsd is the provider's list price and was NOT charged to the wallet), finalDigest (the worker's report), runPrompt/runContext, liveness (live|stalled) and lastActivity while in flight, errorCode/errorDetail, issues, and the grades (selfScore, selfScoreReason, ownerScore — set or change ownerScore with run_score). Note: footprint, turnsTimeline, issues, and priceSnapshot arrive as raw JSON strings — parse them before reasoning over their contents. Requires readRuns.\" +\n SCORE_NOTE +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"get\",\n schema: {\n runId: z.string().uuid().describe(RUN_ID_HINT),\n },\n path: (params) => `${API}/runs/${params.runId}`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst getRunEvents: ToolDescriptor = {\n name: \"run_events\",\n title: \"Get Run Events\",\n description:\n \"The run's live step feed ({events, lastSeq, status, finishedAtUtc}). To watch a run: call with afterSeq=0, then repeat with afterSeq=<the lastSeq you received> while status is non-terminal; stop once the run settles. WAIT AT LEAST 3-5 SECONDS BETWEEN POLLS — a run's events advance at turn speed, not faster. Polling has its own per-account window (120/min; watching many runs at once shares it), separate from the rest of the surface, so a paced watch loop never starves your other calls. Each event: seq, atUtc, kind, turn, label, ok, ms, detail (raw JSON string). Requires readRuns.\" +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"get\",\n schema: {\n runId: z.string().uuid().describe(RUN_ID_HINT),\n afterSeq: z.number().int().min(0).default(0).describe(\n \"Return only events with seq greater than this. Pass the previous response's lastSeq to poll incrementally — with at least 3-5s between polls (the poll window is 120/min per account).\"\n ),\n limit: z.number().int().min(1).max(500).default(200).describe(\"Maximum events to return.\"),\n },\n path: (params) => `${API}/runs/${params.runId}/events`,\n paramFilter: (params) => {\n const { runId: _runId, ...query } = params;\n return query;\n },\n annotations: READ_ONLY,\n};\n\n// ─── Two-way runs (ask / answer) ────────────────────────────────────────────\n// A run that needs something from its owner ENDS by asking (status AwaitingInput)\n// rather than blocking on a human while holding a request slot and a wallet\n// reserve. The one fact an agent must carry away: answering does not resume that\n// run, it starts a linked new one, so the run id changes.\n\nconst getRunQuestion: ToolDescriptor = {\n name: \"run_question\",\n title: \"Get Run Question\",\n description:\n \"The question a run stopped to ask, and everything needed to answer it. A run whose status is AwaitingInput neither failed nor finished — it ENDED BY ASKING, settling its usage and releasing its wallet reserve, because a run cannot hold a request slot and money open across a human's reply. Returns questionId, runId, question, options (the closed set the run offered, when it offered one — free text otherwise), askedAtUtc, expiresAtUtc (null = it waits indefinitely), chainDepth, maxChainDepth, and once answered also answer, answeredAtUtc and resumeRunId. READ chainDepth AGAINST maxChainDepth: it is the only thing that says whether another exchange is possible — a chain already AT the limit still records an answer but starts no run, so run_answer there comes back chain_limit. Take maxChainDepth from this response rather than assuming a number. resumeRunId names the run an answer started, and THE RUN ID CHANGES across that boundary: follow resumeRunId instead of expecting this run to come back to life. expiresAtUtc is a real deadline — once it passes the platform closes the question out itself, and depending on the worker's timeout policy that either ends the exchange or resumes it with no answer at all, so answer before it rather than after. A 404 not_found means this run is not waiting on a question (it never asked, or the runId is wrong) — a normal answer, not an error. Requires the readRuns scope.\" +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"get\",\n schema: {\n runId: z.string().uuid().describe(RUN_ID_HINT),\n },\n path: (params) => `${API}/runs/${params.runId}/question`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst answerRunQuestion: ToolDescriptor = {\n name: \"run_answer\",\n title: \"Answer Run Question\",\n description:\n \"Answer the question a suspended run asked. THE SUSPENDED RUN DOES NOT RESUME: answering mints a LINKED FOLLOW-ON RUN carrying your answer and the parent's context, and what comes back is THAT run's receipt — a DIFFERENT runId. Plan for a CHAIN of receipts rather than one long-lived run: watch the new runId with run_get / run_events, and note that the only link you can READ is forward — run_question on the parent carries resumeRunId, while the follow-on's own receipt has no pointer back — so keep the chain yourself as you walk it. It rides runWorkers rather than readRuns because it STARTS A RUN and costs money. Answering twice is IDEMPOTENT — the second call returns the run the first answer started instead of minting another. The follow-on goes through THE SAME GAUNTLET as any other run, so a 200 can still carry status Skipped with a skipReason (wallet credits, the worker's daily run or spend cap, the account's fleet ceiling, concurrency, readiness): that is a normal receipt, not an error, and because a Skipped resume is deliberately NOT linked to the question you may answer again once the reason clears. A chain already at maxChainDepth (read it from run_question) RECORDS the answer and refuses with 400 chain_limit rather than looping — terminal: start a fresh run with what you have learned instead of retrying. Other refusals use the {error, message} envelope where error IS the snake_case code: 404 not_found (that run is not waiting on a question), 400 already_answered (it was answered and its run never started). Requires the runWorkers scope.\" +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"post\",\n schema: {\n runId: z.string().uuid().describe(RUN_ID_HINT),\n answer: z.string().min(1).max(4000).describe(\n \"The answer, 1–4000 chars. Empty or whitespace is refused: resuming a run with nothing is what the worker's own timeout policy is for, and doing it by hand would hide which of the two happened.\"\n ),\n },\n path: (params) => `${API}/runs/${params.runId}/input`,\n bodyBuilder: (params) => ({ answer: params.answer }),\n // Idempotent: a repeated answer returns the run the first one started rather\n // than minting a second. openWorld like every other run trigger — the run it\n // starts acts on the world through the worker's own tools.\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },\n};\n\nconst cancelRun: ToolDescriptor = {\n name: \"run_cancel\",\n title: \"Cancel Run\",\n description:\n \"Cancel a run. In-flight runs stop at their next heartbeat; an already-settled run refuses with 409 run_not_cancelable — that is a normal outcome meaning there is nothing left to cancel, not a retry signal. Requires the runWorkers scope.\" +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"post\",\n schema: {\n runId: z.string().uuid().describe(RUN_ID_HINT),\n },\n path: (params) => `${API}/runs/${params.runId}/cancel`,\n bodyBuilder: () => ({}),\n annotations: CREATE,\n};\n\nconst clearRunDigest: ToolDescriptor = {\n name: \"run_clear_digest\",\n title: \"Clear Run Report\",\n description:\n \"Scrub a settled run's report so the worker stops being handed it — a SCRUB, not a delete: finalDigest and distilledDigest are nulled and the surviving receipt is returned (status, timings, counts, cost and metering all stay — the wallet ledger references them). The run still appears in the worker's previous-runs block reading \\\"(that run left no report)\\\", and agent-reported issues are NOT cleared. Use when a contextual worker keeps carrying something wrong forward from a past run. Requires manageMemory (not readRuns) — this mutates what the worker remembers. 409 run_not_settled while the run is in flight; idempotent once settled.\" +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"delete\",\n schema: {\n runId: z.string().uuid().describe(RUN_ID_HINT),\n },\n path: (params) => `${API}/runs/${params.runId}/digest`,\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },\n};\n\nconst scoreRun: ToolDescriptor = {\n name: \"run_score\",\n title: \"Grade Run\",\n description:\n \"Set the OWNER's success grade on a settled run: score 0-100, or null to withdraw a grade you set earlier. Numbers only — there is no text lane, by design. The grade overrides the run's own selfScore everywhere both appear, INCLUDING the previous-runs block a contextual worker reads before its next run, which is why this needs the manageMemory scope rather than readRuns: grading changes what the worker is told about itself. Anchors to grade against: 100 = everything asked was done; 75 = core done, minor parts missing; 50 = about half, or done but unverified; 25 = attempted, little achieved; 0 = nothing achieved. 409 run_not_settled while the run is still in flight — grade it after it finishes. Idempotent: re-sending the same score changes nothing.\" +\n SCORE_NOTE +\n RUNTIME_NOTE,\n auth: \"manager\",\n method: \"put\",\n schema: {\n runId: z.string().uuid().describe(RUN_ID_HINT),\n score: z.number().int().min(0).max(100).nullable().describe(\n \"The grade, 0-100. Pass null to clear YOUR grade and fall back to the run's own selfScore. Required — there is no 'leave unchanged' value, so read the current grade with run_get first if you need it.\"\n ),\n },\n path: (params) => `${API}/runs/${params.runId}/score`,\n bodyBuilder: (params) => ({ score: params.score }),\n annotations: UPDATE,\n};\n\n// ─── Memory ─────────────────────────────────────────────────────────────────\n\nconst getMemory: ToolDescriptor = {\n name: \"memory_get\",\n title: \"Get Worker Memory\",\n description:\n \"The worker's memory: memoryProfile (stateless|contextual), selfFactsEnabled, rules (what the worker must DO — injected into every run), facts (what IS true — injected), recallFacts (searchable tier), pendingProposalCount, and a usage meter with every cap (rules, injected facts, char pools, recall) including recallFull — the only signal that the worker can no longer save new facts on its own.\",\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n },\n path: (params) => `${API}/${params.tokenId}/memory`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst addMemoryItem: ToolDescriptor = {\n name: \"memory_add\",\n title: \"Add Memory Rule or Fact\",\n description:\n \"Add a rule or a fact to the worker's memory. kind='rule' = something the worker must DO, phrased as an instruction; kind='fact' = something TRUE about this worker's world. Single line, ≤300 chars. Items land owner-authored and are injected into every run. Caps are enforced at write time (15 rules; 25 injected facts within a 4,000-char pool) — a cap violation is a 400 whose message names the fix (retire or delete something first). Requires the manageMemory scope.\",\n auth: \"manager\",\n method: \"post\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n kind: z.enum([\"rule\", \"fact\"]).describe(\n \"rule = what the worker must DO (injected instruction). fact = what IS true about the worker's world.\"\n ),\n text: z.string().min(1).max(300).describe(\"The rule/fact text. Single line, 1–300 chars.\"),\n },\n path: (params) => `${API}/${params.tokenId}/memory/${params.kind === \"rule\" ? \"rules\" : \"facts\"}`,\n bodyBuilder: (params) => ({ text: params.text }),\n annotations: CREATE,\n};\n\nconst updateMemoryItem: ToolDescriptor = {\n name: \"memory_update\",\n title: \"Update Memory Item\",\n description:\n \"Edit a rule/fact's text, retire or reactivate it (status), or move a FACT between the injected and searchable tiers (scope). Omitted fields stay unchanged. Prefer retiring (status='retired') over deleting — it keeps provenance. Promoting a fact to 'injected' is charged against the injected pool and can 400 on a full pool; rules are always injected — sending scope='recall' for a rule is a 400. Requires manageMemory.\",\n auth: \"manager\",\n method: \"patch\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n itemId: z.number().int().min(1).describe(\"The memory item's id, as returned by memory_get or memory_add.\"),\n text: z.string().min(1).max(300).optional().describe(\"New text (single line, 1–300 chars). Omit to keep.\"),\n status: z.enum([\"active\", \"retired\"]).optional().describe(\"Retire or reactivate. Omit to keep.\"),\n scope: z.enum([\"injected\", \"recall\"]).optional().describe(\n \"Facts only: injected (every run) or recall (searchable). Omit to keep.\"\n ),\n },\n path: (params) => `${API}/${params.tokenId}/memory/items/${params.itemId}`,\n bodyBuilder: (params) => ({ text: params.text, status: params.status, scope: params.scope }),\n annotations: UPDATE,\n};\n\nconst deleteMemoryItem: ToolDescriptor = {\n name: \"memory_delete\",\n title: \"Delete Memory Item\",\n description:\n \"Delete a rule/fact outright. Permanent — prefer memory_update with status='retired' to keep provenance. Requires manageMemory.\",\n auth: \"manager\",\n method: \"delete\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n itemId: z.number().int().min(1).describe(\"The memory item's id, as returned by memory_get.\"),\n },\n path: (params) => `${API}/${params.tokenId}/memory/items/${params.itemId}`,\n successMessage: \"Memory item deleted.\",\n annotations: DELETE,\n};\n\n// ─── Schedules ──────────────────────────────────────────────────────────────\n\nconst listSchedules: ToolDescriptor = {\n name: \"schedules_list\",\n title: \"List Schedules\",\n description:\n \"The worker's schedules. Each row: id, title, scheduleType (EveryNMinutes|EveryNHours|DailyAtTime|OneShot), intervalValue, timeOfDayMinutes, timeZoneId, effectiveTimeZoneId (the schedule's own zone, else the worker's, else UTC), anchorUtc, computed nextRunUtc, isEnabled.\",\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n },\n path: (params) => `${API}/${params.tokenId}/schedules`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst SCHEDULE_TYPE_HINT =\n \"EveryNMinutes (intervalValue 1–1440), EveryNHours (intervalValue 1–168), DailyAtTime (timeOfDayMinutes required — wall-clock minutes past midnight in the effective time zone, DST-correct), or OneShot (anchorUtc required, must be in the future). Input is parsed case-insensitively; responses always return the PascalCase form.\";\n\n// Plan walls, not transient errors. Note the envelope: the machine-readable code\n// is in `feature`, while `error` holds the literal string \"feature_gated\" — the\n// one place on this surface where `error` is not the code.\nconst SCHEDULE_GATE_HINT =\n \" Two plan walls return 402 {error:'feature_gated', feature, upgradeTrigger, message}: feature 'schedule_cadence' means minute-based schedules are not in this plan (use EveryNHours or DailyAtTime), and 'schedule_count' means the worker is at its recurring-schedule cap (a OneShot is never counted). Both are terminal — do NOT retry; either pick an allowed cadence or tell the human to upgrade.\";\n\nconst createSchedule: ToolDescriptor = {\n name: \"schedule_create\",\n title: \"Create Schedule\",\n description:\n \"Create a schedule for the worker. Per-type required fields: \" + SCHEDULE_TYPE_HINT +\n \" Omit timeZoneId to follow the worker's own time zone (the normal case). Requires the manageSchedules scope.\" +\n SCHEDULE_GATE_HINT,\n auth: \"manager\",\n method: \"post\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n scheduleType: z.enum([\"EveryNMinutes\", \"EveryNHours\", \"DailyAtTime\", \"OneShot\"]).describe(SCHEDULE_TYPE_HINT),\n title: z.string().max(120).optional().describe(\n \"Optional display title, ≤120 chars (the column's own limit; a longer title is truncated upstream, not rejected).\"\n ),\n intervalValue: z.number().int().min(1).optional().describe(\n \"EveryNMinutes: 1–1440. EveryNHours: 1–168. Required for those types, ignored otherwise.\"\n ),\n timeOfDayMinutes: z.number().int().min(0).max(1439).optional().describe(\n \"DailyAtTime only: wall-clock minutes past midnight in the effective time zone (e.g. 540 = 09:00). DST-correct.\"\n ),\n timeZoneId: z.string().optional().describe(\n \"IANA time zone (e.g. 'America/New_York') overriding the worker's zone. Omit to follow the worker.\"\n ),\n anchorUtc: z.string().optional().describe(`OneShot only: when to fire, must be in the future. ${UTC_HINT}`),\n isEnabled: z.boolean().default(true).describe(\"Whether the schedule starts enabled.\"),\n },\n path: (params) => `${API}/${params.tokenId}/schedules`,\n bodyBuilder: (params) => ({\n title: params.title,\n scheduleType: params.scheduleType,\n intervalValue: params.intervalValue,\n timeOfDayMinutes: params.timeOfDayMinutes,\n timeZoneId: params.timeZoneId,\n anchorUtc: params.anchorUtc,\n isEnabled: params.isEnabled,\n }),\n annotations: CREATE,\n};\n\nconst updateSchedule: ToolDescriptor = {\n name: \"schedule_update\",\n title: \"Update Schedule\",\n description:\n \"Edit a schedule (partial — omitted fields stay unchanged; timeZoneId='' clears the override so the schedule follows the worker's zone again). nextRunUtc is recomputed on every edit. Per-type field rules: \" +\n SCHEDULE_TYPE_HINT + \" Requires manageSchedules.\" + SCHEDULE_GATE_HINT,\n auth: \"manager\",\n method: \"patch\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n scheduleId: z.number().int().min(1).describe(\"The schedule's id, as returned by schedules_list.\"),\n scheduleType: z.enum([\"EveryNMinutes\", \"EveryNHours\", \"DailyAtTime\", \"OneShot\"]).optional().describe(\n \"Change the schedule type. \" + SCHEDULE_TYPE_HINT\n ),\n title: z.string().max(120).optional().describe(\n \"New display title, ≤120 chars (truncated upstream, not rejected).\"\n ),\n intervalValue: z.number().int().min(1).optional().describe(\"New interval (see type rules).\"),\n timeOfDayMinutes: z.number().int().min(0).max(1439).optional().describe(\"DailyAtTime: new wall-clock minutes past midnight.\"),\n timeZoneId: z.string().optional().describe(\"IANA zone override; empty string '' clears it (follow the worker).\"),\n anchorUtc: z.string().optional().describe(`OneShot: new fire time. ${UTC_HINT}`),\n isEnabled: z.boolean().optional().describe(\"Enable or disable the schedule.\"),\n },\n path: (params) => `${API}/${params.tokenId}/schedules/${params.scheduleId}`,\n bodyBuilder: (params) => ({\n title: params.title,\n scheduleType: params.scheduleType,\n intervalValue: params.intervalValue,\n timeOfDayMinutes: params.timeOfDayMinutes,\n timeZoneId: params.timeZoneId,\n anchorUtc: params.anchorUtc,\n isEnabled: params.isEnabled,\n }),\n annotations: UPDATE,\n};\n\nconst deleteSchedule: ToolDescriptor = {\n name: \"schedule_delete\",\n title: \"Delete Schedule\",\n description:\n \"Delete a schedule. To pause it instead, use schedule_update with isEnabled=false. Requires manageSchedules.\",\n auth: \"manager\",\n method: \"delete\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n scheduleId: z.number().int().min(1).describe(\"The schedule's id, as returned by schedules_list.\"),\n },\n path: (params) => `${API}/${params.tokenId}/schedules/${params.scheduleId}`,\n successMessage: \"Schedule deleted.\",\n annotations: DELETE,\n};\n\n// ─── Run-result deliveries ──────────────────────────────────────────────────\n// Where the PLATFORM sends a worker's report when a run finishes. The two facts an\n// agent gets wrong by default: availability is judged at ACCOUNT level (never from\n// the worker's own apps), and a receipt is not a guarantee.\n\nconst DELIVERY_NOTE =\n \" How delivery works: the send is PLATFORM-level and detached from the worker's own permissions — the destination row you configure IS the permission, so a worker with no email app still delivers to email. The ONE hard configuration refusal is 400 CHANNEL_NOT_CONNECTED, judged at ACCOUNT level (the operator's connected apps), so NEVER infer availability from worker_get's apps — call delivery_channels. A worker holds at most 5 destinations. Skipped and Canceled runs never deliver: there is no result to send. Sends are AT-MOST-ONCE — never double-sent, but a crash at the wrong moment can lose one, so the run receipt's deliveries[] is a RECEIPT of what happened, not a guarantee that it did.\";\n\nconst DELIVERY_TARGET_HINT =\n \"The destination. ONE shape serves every channel — set only the fields YOUR channel needs; anything else is dropped. email: to[1–10 addresses] (+ optional connectionId OR sendFrom to choose the mailbox on a multi-mailbox account). slack: channelId (+ optional workspaceId). msTeams: EITHER teamId+channelId (post to a channel) OR chatId (post to a chat) — exactly one form; both or neither is a 400. telegram: chatId, a numeric id or an @username (+ optional botId). notion: boardId — the board/database that gets one item per run with the report as its content. discord: channelId (+ optional applicationId). messaging: provider (e.g. 'TWILIO'), messagingChannel ('sms' | 'whatsapp'), to[EXACTLY ONE phone number] (+ optional from; omit for the connection's default sender).\";\n\nconst DELIVERY_TARGET_SHAPE = {\n to: z.array(z.string()).optional().describe(\n \"email: 1–10 recipient addresses. messaging: exactly one phone number. Unused by every other channel.\"\n ),\n connectionId: z.number().int().optional().describe(\n \"email only: send from this provider connection (multi-mailbox operators). Omit for the default mailbox.\"\n ),\n sendFrom: z.string().optional().describe(\n \"email only: send-from address — the alternative to connectionId. Omit for the default mailbox.\"\n ),\n channelId: z.string().optional().describe(\n \"slack / discord: the channel to post in. msTeams channel form: the channel inside teamId.\"\n ),\n workspaceId: z.string().optional().describe(\"slack only: which workspace to post into (multi-workspace operators).\"),\n applicationId: z.string().optional().describe(\"discord only: which application/bot to send as (multi-bot operators).\"),\n teamId: z.string().optional().describe(\"msTeams channel form: the team that owns channelId.\"),\n chatId: z.string().optional().describe(\n \"msTeams chat form: the chat to post in. telegram: the chat — a numeric id or an @username.\"\n ),\n botId: z.number().int().optional().describe(\"telegram only: which bot to send as (multi-bot operators).\"),\n boardId: z.string().optional().describe(\"notion only: the board/database that gets one item per run.\"),\n provider: z.string().optional().describe(\"messaging only: the provider code, e.g. 'TWILIO'.\"),\n messagingChannel: z.enum([\"sms\", \"whatsapp\"]).optional().describe(\"messaging only: which messaging channel to send over.\"),\n from: z.string().optional().describe(\"messaging only: sender number/id. Omit for the connection's default sender.\"),\n};\n\nconst DELIVERY_CONDITION_HINT =\n \"Which terminal outcomes fire this destination: always, successOnly (Succeeded), or failureOnly (Failed / TimedOut / BudgetExceeded — the alerting shape). Skipped and Canceled runs never deliver on any condition.\";\n\nconst DELIVERY_CONTENT_MODE_HINT =\n \"What the message carries: full = the run's finalDigest, its OWN closing report (falls back to the distilled summary); summary = the distilled summary of what the run actually did (falls back to finalDigest) — the right choice for short-form channels like SMS.\";\n\nconst listDeliveries: ToolDescriptor = {\n name: \"delivery_list\",\n title: \"List Delivery Destinations\",\n description:\n \"The worker's run-result delivery destinations — where the platform sends this worker's report when a run finishes. Each row: id, title, channel, condition (always|successOnly|failureOnly), contentMode (full|summary), target (only the fields that channel uses), targetDisplay (the pretty name, e.g. '#briefings'), isEnabled, createDate, updatedAt. An empty list means this worker's results go nowhere — that is a configuration fact, not an error. Requires the readWorkers scope.\" +\n DELIVERY_NOTE,\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n },\n path: (params) => `${API}/${params.tokenId}/deliveries`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst deliveryChannels: ToolDescriptor = {\n name: \"delivery_channels\",\n title: \"List Delivery Channels\",\n description:\n \"Which delivery channels this worker's operator can send through RIGHT NOW: {email, slack, msTeams, telegram, notion, discord, messaging}, each true or false. Call this BEFORE delivery_create and pick a channel that is true — creating on a false one is a guaranteed 400 CHANNEL_NOT_CONNECTED. Availability is ACCOUNT-level (the operator's connected apps) and deliberately independent of the worker's own app bindings, so it is NOT derivable from worker_get: a worker with no email app still reports email:true when the account has a mailbox connected, and a worker that uses Slack all day reports slack:false if nobody connected Slack for the account. These are the same predicates the create/update gate applies, with ONE exception: messaging is reported true when the account has ANY messaging provider connected, while the gate checks the specific provider you name in target.provider — so messaging:true can still 400 if the account's connected provider is not the one you ask for. Only a human can connect a missing app (at https://workerkit.ai → Connections) — agents cannot. Requires the readWorkers scope.\" +\n DELIVERY_NOTE,\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n },\n path: (params) => `${API}/${params.tokenId}/deliveries/channels`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst createDelivery: ToolDescriptor = {\n name: \"delivery_create\",\n title: \"Add Delivery Destination\",\n description:\n \"Add one run-result delivery destination to the worker (201 with the created row). Call delivery_channels first and choose a channel it reports as true. Two failure classes, both 400 and both terminal for the body you sent: CHANNEL_NOT_CONNECTED means the channel's app is not connected on the ACCOUNT — the send could never succeed, so a human must connect it at https://workerkit.ai → Connections; INVALID_REQUEST means the target is structurally wrong for the channel, and its message names the fix. A worker holds at most 5 destinations — the 6th is a 400 saying so, so retire or delete one first. NOT idempotent: calling twice makes two destinations that both send. channel is fixed at creation — see delivery_update. Requires the manageDeliveries scope.\" +\n NEW_SCOPE_NOTE +\n DELIVERY_NOTE,\n auth: \"manager\",\n method: \"post\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n channel: z.enum([\"email\", \"slack\", \"msTeams\", \"telegram\", \"notion\", \"discord\", \"messaging\"]).describe(\n \"Where to send. IMMUTABLE after creation — to change it, delete this destination and create another. Check delivery_channels first: a channel that reports false is a guaranteed 400 CHANNEL_NOT_CONNECTED.\"\n ),\n title: z.string().max(120).optional().describe(\"Optional display title for the destination (≤120 chars).\"),\n condition: z.enum([\"always\", \"successOnly\", \"failureOnly\"]).default(\"always\").describe(DELIVERY_CONDITION_HINT),\n contentMode: z.enum([\"full\", \"summary\"]).default(\"full\").describe(DELIVERY_CONTENT_MODE_HINT),\n target: z.object(DELIVERY_TARGET_SHAPE).describe(DELIVERY_TARGET_HINT),\n targetLabel: z.string().max(200).optional().describe(\n \"Pretty name for the destination ('#general', 'Ops board'), stored as targetDisplay. Omit and one is computed from the target.\"\n ),\n isEnabled: z.boolean().default(true).describe(\"Whether the destination starts enabled. false = configured but silent.\"),\n },\n path: (params) => `${API}/${params.tokenId}/deliveries`,\n bodyBuilder: (params) => ({\n channel: params.channel,\n title: params.title,\n condition: params.condition,\n contentMode: params.contentMode,\n target: params.target,\n targetLabel: params.targetLabel,\n isEnabled: params.isEnabled,\n }),\n annotations: CREATE,\n};\n\nconst updateDelivery: ToolDescriptor = {\n name: \"delivery_update\",\n title: \"Update Delivery Destination\",\n description:\n \"Edit one delivery destination (partial — omitted fields stay unchanged). THE CHANNEL IS IMMUTABLE: there is no channel parameter, and changing where a destination sends means deleting this one and creating another with delivery_create. target is a FULL REPLACE of the destination's address, validated against the row's EXISTING channel — a target shaped for a different channel is a 400 INVALID_REQUEST — and re-checked against the account's connections, so it can also come back 400 CHANNEL_NOT_CONNECTED if the app was disconnected since. To silence a destination without losing it, send isEnabled:false rather than deleting it. Requires the manageDeliveries scope.\" +\n NEW_SCOPE_NOTE +\n DELIVERY_NOTE,\n auth: \"manager\",\n method: \"patch\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n deliveryId: z.number().int().min(1).describe(\"The destination's id, as returned by delivery_list or delivery_create.\"),\n title: z.string().max(120).optional().describe(\"New display title (≤120 chars). Omit to keep.\"),\n condition: z.enum([\"always\", \"successOnly\", \"failureOnly\"]).optional().describe(\n DELIVERY_CONDITION_HINT + \" Omit to keep.\"\n ),\n contentMode: z.enum([\"full\", \"summary\"]).optional().describe(DELIVERY_CONTENT_MODE_HINT + \" Omit to keep.\"),\n target: z.object(DELIVERY_TARGET_SHAPE).optional().describe(\n \"Replace the destination's address, in the shape of its EXISTING channel (the channel cannot change here). Omit to keep. \" +\n DELIVERY_TARGET_HINT\n ),\n targetLabel: z.string().max(200).optional().describe(\n \"New pretty name (≤200 chars). Omit to keep — but note that sending target WITHOUT targetLabel recomputes the label from the new target.\"\n ),\n isEnabled: z.boolean().optional().describe(\"Enable or silence the destination. Omit to keep.\"),\n },\n path: (params) => `${API}/${params.tokenId}/deliveries/${params.deliveryId}`,\n bodyBuilder: (params) => ({\n title: params.title,\n condition: params.condition,\n contentMode: params.contentMode,\n target: params.target,\n targetLabel: params.targetLabel,\n isEnabled: params.isEnabled,\n }),\n annotations: UPDATE,\n};\n\nconst deleteDelivery: ToolDescriptor = {\n name: \"delivery_delete\",\n title: \"Delete Delivery Destination\",\n description:\n \"Delete a delivery destination outright (204). Permanent, and it frees one of the worker's 5 slots — this is also the only way to change a destination's channel (delete, then delivery_create with the new one). To stop the sends but keep the configuration, use delivery_update with isEnabled:false instead. Already-sent reports are unaffected: the run receipts that record them stay as they are. Requires the manageDeliveries scope.\" +\n NEW_SCOPE_NOTE,\n auth: \"manager\",\n method: \"delete\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n deliveryId: z.number().int().min(1).describe(\"The destination's id, as returned by delivery_list.\"),\n },\n path: (params) => `${API}/${params.tokenId}/deliveries/${params.deliveryId}`,\n successMessage: \"Delivery destination deleted.\",\n annotations: DELETE,\n};\n\n// ─── Instruction ────────────────────────────────────────────────────────────\n\nconst getInstruction: ToolDescriptor = {\n name: \"instruction_get\",\n title: \"Get Instruction\",\n description:\n \"The worker's standing instruction: content, jobSentence, whenToUse, description, memoryProfile, selfFactsEnabled, isProtected, currentVersion, timestamps. A bare \\\"Operation completed successfully.\\\" response means the worker has NO instruction yet (HTTP 204) — use instruction_set to create one. For a worker installed from a protected kit, metadata is returned but the instruction text is REDACTED (it belongs to the kit's publisher) — that is not an error.\",\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n },\n path: (params) => `${API}/${params.tokenId}/instruction`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst setInstruction: ToolDescriptor = {\n name: \"instruction_set\",\n title: \"Set Instruction\",\n description:\n \"Create or replace the worker's standing instruction (the prompt/workflow text handed to every run). A changed body snapshots the prior version. Omitted optional fields stay unchanged; empty string clears. Returns 403 OPERATION_NOT_ALLOWED for a protected kit's worker — that text belongs to its publisher; do not retry. Requires the manageInstructions scope.\",\n auth: \"manager\",\n method: \"put\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n content: z.string().min(1).max(100000).describe(\"The instruction text (1–100,000 chars). Required — this replaces the whole content.\"),\n jobSentence: z.string().max(200).optional().describe(\"The worker's one-liner (≤200). Omit = unchanged; '' = clear.\"),\n whenToUse: z.string().max(500).optional().describe(\"Trigger text: when this worker should be used (≤500). Omit = unchanged; '' = clear.\"),\n description: z.string().max(2000).optional().describe(\"Longer display-only description (≤2000). Omit = unchanged; '' = clear.\"),\n memoryProfile: z.enum([\"stateless\", \"contextual\"]).optional().describe(\n \"Worker class: stateless (fresh each run) or contextual (carries prior-run reports). Omit = unchanged.\"\n ),\n selfFactsEnabled: z.boolean().optional().describe(\n \"Whether the worker may save its own facts during runs. Set true when the content tells the worker to save facts. Omit = unchanged.\"\n ),\n },\n path: (params) => `${API}/${params.tokenId}/instruction`,\n bodyBuilder: (params) => ({\n content: params.content,\n jobSentence: params.jobSentence,\n whenToUse: params.whenToUse,\n description: params.description,\n memoryProfile: params.memoryProfile,\n selfFactsEnabled: params.selfFactsEnabled,\n }),\n annotations: UPDATE,\n};\n\n// Instruction history. The list is metadata and stays readable for a protected\n// kit's worker; the BODIES are the publisher's text, so reading one and restoring\n// one are both refused there. Only content is versioned — jobSentence, whenToUse\n// and the rest are edited in place and have no history.\n\nconst getInstructionVersions: ToolDescriptor = {\n name: \"instruction_versions\",\n title: \"List Instruction Versions\",\n description:\n \"The worker's instruction history, newest first — METADATA only: versionNumber, contentLength, editedByUserId, restoredFromVersion (set when that version was itself a restore, so you can see a rollback in the history), createDate. No instruction text here; read one version's content with instruction_version_get, or roll one back with instruction_restore. Readable EVEN for a protected kit's worker — history is metadata, the text is what belongs to the publisher — which is why this list can be non-empty while instruction_version_get returns 403 on the same worker. Only the instruction's content is versioned: jobSentence, whenToUse, description, memoryProfile and selfFactsEnabled are edited in place and never appear here, so a version count that has not moved does not mean nothing changed. An empty list means the worker has no instruction at all (instruction_get says so with a 204). Requires the readWorkers scope.\",\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n },\n path: (params) => `${API}/${params.tokenId}/instruction/versions`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst getInstructionVersion: ToolDescriptor = {\n name: \"instruction_version_get\",\n title: \"Get Instruction Version\",\n description:\n \"One historical instruction version IN FULL — its content, plus versionNumber, editedByUserId, restoredFromVersion and createDate. Take the versionNumber from instruction_versions; diff two of them to see exactly what a past edit changed before deciding whether to roll it back. Every version row is a complete snapshot of the content as of that version (including the current one), not a patch. Returns 403 OPERATION_NOT_ALLOWED for a protected kit's worker — that text belongs to its publisher; do not retry, and note the version LIST stays readable. 404 when this worker has no such version number. Requires the readWorkers scope.\",\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n versionNumber: z.number().int().min(1).describe(\n \"The version to read, as listed by instruction_versions. A number this worker has never had is a 404.\"\n ),\n },\n path: (params) => `${API}/${params.tokenId}/instruction/versions/${params.versionNumber}`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst restoreInstructionVersion: ToolDescriptor = {\n name: \"instruction_restore\",\n title: \"Restore Instruction Version\",\n description:\n \"Roll the worker's instruction back: restore a historical version's content as a NEW current version. It APPENDS — nothing is deleted or overwritten in the history, the text you are replacing keeps its own version row, and the restore's new row carries restoredFromVersion so the rollback is legible later. That also makes the rollback itself reversible: restore the version you just moved away from and you are back. Returns the instruction as it now stands, with currentVersion bumped. Returns 403 OPERATION_NOT_ALLOWED for a protected kit's worker, like every other instruction write — do not retry. A version number this worker does not have is a 400 INVALID_REQUEST (a refused write, not a 404), and so is a worker with no instruction at all: call instruction_versions first. NOT idempotent — calling it twice appends two versions with identical content. Requires the manageInstructions scope.\",\n auth: \"manager\",\n method: \"post\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n versionNumber: z.number().int().min(1).describe(\n \"The version to restore, as listed by instruction_versions. Its content becomes the new current version.\"\n ),\n },\n path: (params) => `${API}/${params.tokenId}/instruction/versions/${params.versionNumber}/restore`,\n bodyBuilder: () => ({}),\n annotations: CREATE,\n};\n\n// ─── Start / stop ───────────────────────────────────────────────────────────\n\nconst setWorkerEnabled: ToolDescriptor = {\n name: \"worker_set_enabled\",\n title: \"Start or Stop Worker\",\n description:\n \"Start (enabled=true) or stop (enabled=false) a worker. Stopping pauses the WHOLE worker: its own API key stops working AND its schedules stop firing; re-enabling restores both. Returns {tokenId, isEnabled}. Idempotent. Requires the manageState scope.\",\n auth: \"manager\",\n method: \"post\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n enabled: z.boolean().describe(\"true = start the worker; false = stop it (key + schedules pause together).\"),\n },\n path: (params) => `${API}/${params.tokenId}/enabled`,\n bodyBuilder: (params) => ({ enabled: params.enabled }),\n annotations: UPDATE,\n};\n\n// ─── Kit install ────────────────────────────────────────────────────────────\n// The one place on this surface an agent can CREATE a worker: install a kit from\n// the public directory. Both tools need the installKits scope (keys minted\n// before the scope existed — including old \"all\" keys — lack it until an\n// account admin re-scopes them).\n\nconst KITS_API = \"/api/manage/kits\";\n\nconst KIT_SLUG_HINT =\n \"The kit's slug, as returned by kits_search / kit_get on the public WorkerKit Directory server. 404 not_found = no such kit (or another account's private kit — indistinguishable by design).\";\n\n// Pinned to the backend's slug alphabet ([a-z0-9-], ≤120). Not cosmetic: encodeURIComponent\n// leaves dots intact and the WHATWG URL parser collapses \".\" / \"..\" segments client-side, so\n// an unpinned slug could walk the request off /api/manage/kits before it ever leaves this\n// process. No real slug can contain a dot, so nothing legitimate is refused.\nconst KIT_SLUG = z.string().min(1).max(120).regex(/^[a-z0-9][a-z0-9-]*$/, \"not a valid kit slug\");\n\nconst kitInstallPreview: ToolDescriptor = {\n name: \"kit_install_preview\",\n title: \"Preview Kit Install\",\n description:\n \"The kit's install form plus this account's current ability to satisfy it — call this BEFORE kit_install and gather every answer it demands. Creates nothing. Requires the installKits scope (403 names it). Returns: requiredInputs (EVERY key is mandatory at install — collect a value for each from the human, keys are exact), memorySetup (questions whose answers become the worker's first memory; only required:true entries are mandatory), categorySlots (pick ONE member per slot via categoryChoices; each member carries connection — prefer a connected one — and connectionProvider, which when set means also pass categoryChoices[].resourceId picked from operatorResources, ideally one with hasActiveConnection and a matching provider), apps + appsNeedingConnection (the connection state the new worker would START with; installing anyway is allowed — the worker starts blocked and a human finishes at connectAppsUrl), operator (which operator the install targets), limits (currentWorkers/maxWorkers — at the cap the install returns 402), kitPageUrl (the human install page). Preview is advisory: the install response's readiness block is the verdict. For the kit's full permissions manifest and instruction use kit_get on the public Directory server.\",\n auth: \"manager\",\n method: \"get\",\n schema: {\n slug: KIT_SLUG.describe(KIT_SLUG_HINT),\n operatorId: z.string().uuid().optional().describe(\n \"Operator (workspace) to install into. Omit to use the account's default operator.\"\n ),\n },\n path: (params) => `${KITS_API}/${encodeURIComponent(String(params.slug))}/install-preview`,\n paramFilter: (params) => {\n const { slug: _slug, ...query } = params;\n return query;\n },\n annotations: READ_ONLY,\n};\n\nconst kitInstall: ToolDescriptor = {\n name: \"kit_install\",\n title: \"Install Kit\",\n description:\n \"Install a directory kit as a NEW worker on this account. NOT idempotent: every successful call creates another worker — never retry a success, and on a timeout check workers_list (needs the readWorkers scope) before trying again. Requires the installKits scope. Call kit_install_preview first and supply every requiredInputs key in inputs (a missing or unknown key is a 400 naming it), answers to required memorySetup questions in memoryAnswers, and one categoryChoices entry per slot (member with connectionProvider set → also pass resourceId from the preview's operatorResources). CRITICAL — secrets shown ONCE: the response's install.rawKey (the worker's pe_ API key) and install.triggers[].signingSecret can NEVER be read again; deliver them to the human immediately and do not discard the response before doing so. The response also carries readiness (status ready|blocked with actionable issues, e.g. app_not_connected + candidateProviders; null means the readiness check itself failed AFTER the install succeeded — do not retry the install, read readiness via worker_get), workerUrl (the worker's dashboard page — hand it to the human), and connectAppsUrl (where the human connects missing apps in the browser; agents cannot connect apps). A 402 {error:'limit_exceeded'} is the plan's worker cap — terminal, do not retry; tell the human to upgrade or free a slot. Rate: 10 installs/hour per account.\",\n auth: \"manager\",\n method: \"post\",\n schema: {\n slug: KIT_SLUG.describe(KIT_SLUG_HINT),\n operatorId: z.string().uuid().optional().describe(\n \"Operator (workspace) to install into. Omit to use the account's default operator.\"\n ),\n title: z.string().max(100).optional().describe(\n \"Name for the new worker (≤100 chars). Omit to use the kit's name.\"\n ),\n avatar: z.string().max(40).optional().describe(\n \"Avatar slug for the new worker. Omit for the default.\"\n ),\n categoryChoices: z.array(z.object({\n categoryCode: z.string().describe(\"The slot's categoryCode from the preview.\"),\n memberCode: z.string().describe(\"The chosen member's code (e.g. 'gmail').\"),\n resourceId: z.string().uuid().optional().describe(\n \"For members with connectionProvider set: the identity to bind, from the preview's operatorResources.\"\n ),\n })).optional().describe(\n \"One entry per categorySlots slot. Omitted slots resolve to the kit's first offered member on safe defaults.\"\n ),\n inputs: z.record(z.string(), z.string()).optional().describe(\n \"Answers to requiredInputs, keyed EXACTLY by each entry's key. Every key is mandatory; values are single-line, 1-200 chars.\"\n ),\n memoryAnswers: z.record(z.string(), z.string()).optional().describe(\n \"Answers to memorySetup questions by key. Entries with required:true are mandatory. Keep this separate from inputs — mixing the two maps is a 400.\"\n ),\n },\n path: (params) => `${KITS_API}/${encodeURIComponent(String(params.slug))}/install`,\n bodyBuilder: (params) => ({\n operatorId: params.operatorId,\n title: params.title,\n avatar: params.avatar,\n categoryChoices: params.categoryChoices,\n inputs: params.inputs,\n memoryAnswers: params.memoryAnswers,\n }),\n annotations: CREATE,\n};\n\n// ─── Creation (clone) ───────────────────────────────────────────────────────\n// The other creation path, next to kit install, and deliberately the only one\n// that is not a kit: a clone can produce ONLY permissions a human already\n// approved on the source worker, whereas authoring arbitrary permissions from a\n// chat message is a different power and stays on the dashboard and the kit\n// pipeline, where a manifest gets reviewed. All three need the createWorkers\n// scope.\n\nconst CLONE_NOTE =\n \" What a clone is: a copy of the source's PERMISSIONS (so it can never hold access a human did not already approve on the source) plus, by flag, the instruction, owner-authored memory, schedules, delivery destinations and the hosted deployment. Three things are deliberately NOT straight copies — schedules arrive DISABLED so a new worker never starts firing by itself (enable them with schedule_update once you are satisfied), AGENT-AUTHORED FACTS ARE NOT COPIED (only owner-authored rules and facts travel: what a worker learned about itself stays with the worker that learned it), and a webhook delivery destination arrives DISABLED WITH NO SIGNING SECRET so revoking the clone can never break its source (a human rotates one to arm it). The clone also inherits the SAME per-run and per-day spend ceilings, so cloning multiplies the fleet's ceiling — read fleet_budget_get before a bulk clone. Instruction history does not travel: the clone starts at version 1 with the text it was given. A source whose instruction came from a PROTECTED kit is refused while includeInstruction is true — that text belongs to the kit's publisher, so install the kit again or clone with includeInstruction:false.\";\n\nconst CLONE_TITLE_HINT =\n \"The new worker's title, 1–120 chars. Required: a clone is never silently named after its source.\";\n\n// One shape, three tools: worker_clone and worker_clone_preview take it as their\n// body, worker_clone_bulk takes an array of it. Every include flag defaults to\n// true EXCEPT that run history is never copied at all — it belongs to the worker\n// that earned it, so there is no flag for it.\nconst CLONE_REQUEST_SHAPE = {\n title: z.string().min(1).max(120).describe(CLONE_TITLE_HINT),\n includeInstruction: z.boolean().default(true).describe(\n \"Copy the standing instruction. A protected kit's instruction is never copied — that source is refused (400) while this is true, so send false to clone everything else.\"\n ),\n includeMemory: z.boolean().default(true).describe(\n \"Copy the ACTIVE OWNER-authored rules and facts. Agent-authored facts never travel, whatever this is set to.\"\n ),\n includeSchedules: z.boolean().default(true).describe(\n \"Copy the schedules. They ALWAYS arrive disabled, and with no anchor or next-run time, so a bulk create cannot start a fleet running.\"\n ),\n includeDeliveries: z.boolean().default(true).describe(\n \"Copy the run-result delivery destinations. A webhook destination arrives disabled and unarmed (no signing secret).\"\n ),\n includeDeployment: z.boolean().default(true).describe(\n \"Copy the hosted deployment — model plus the per-run and per-day spend ceilings. false = the clone has no hosted runs until a human sets it up, and budget_set will refuse its dollar caps until then.\"\n ),\n resourceId: z.string().uuid().optional().describe(\n \"Bind the clone to a DIFFERENT identity: an operator resource id (as listed in kit_install_preview's operatorResources). Omit to keep the source's identity — the usual case.\"\n ),\n};\n\nconst clonePreview: ToolDescriptor = {\n name: \"worker_clone_preview\",\n title: \"Preview Worker Clone\",\n description:\n \"What cloning this worker WOULD produce. CREATES NOTHING — this is the rail to run before worker_clone, and before worker_clone_bulk especially. It takes the same body as worker_clone (which is the only reason it is a POST) and answers with sourceWorkerId/sourceTitle, the title the clone would carry, apps[] (every app the clone would hold, each with whether the operator can actually serve it today — this is where you learn a clone would be born unable to run), wouldCopyInstruction, memoryItemCount, scheduleCount, deliveryCount, the deployment it would inherit (modelSlug, maxUsdPerRun, maxUsdPerDay), and the two lists that carry the verdict: BLOCKERS — reasons the clone WOULD BE REFUSED, so an empty list is what 'it would succeed' looks like — and NOTES, things that would succeed but are worth knowing (schedules landing disabled, only owner-authored memory travelling, a webhook destination arriving unarmed, the fleet's spend ceiling being multiplied). Read blockers before committing: it is a verdict, not advice. Requires the createWorkers scope.\" +\n NEW_SCOPE_NOTE +\n CLONE_NOTE,\n auth: \"manager\",\n method: \"post\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n ...CLONE_REQUEST_SHAPE,\n },\n path: (params) => `${API}/${params.tokenId}/clone/preview`,\n bodyBuilder: (params) => ({\n title: params.title,\n includeInstruction: params.includeInstruction,\n includeMemory: params.includeMemory,\n includeSchedules: params.includeSchedules,\n includeDeliveries: params.includeDeliveries,\n includeDeployment: params.includeDeployment,\n resourceId: params.resourceId,\n }),\n // A POST that creates nothing: read-only in effect, and safe to run unattended.\n annotations: READ_ONLY,\n};\n\nconst cloneWorker: ToolDescriptor = {\n name: \"worker_clone\",\n title: \"Clone Worker\",\n description:\n \"Copy this worker into a NEW one (201 with the created worker). NOT IDEMPOTENT: every successful call creates another worker — never retry a success, and after a timeout check workers_list (needs readWorkers) before trying again. CRITICAL — the key is shown ONCE: the response's rawKey is the new worker's pe_ API key and can NEVER be read again, so hand it to the human immediately and do not discard the response before doing so. The response identifies the new worker by workerId, a UUID; every other tool on this surface addresses workers by their numeric tokenId, so look the clone up in workers_list to get one. Call worker_clone_preview first — its blockers list is the same refusal you would otherwise discover as a 400, whose message names the cause (a protected kit's instruction is the common one); 404 is an unknown or other-account source worker. The new worker starts ENABLED but with its schedules off, so nothing runs until you enable a schedule or call worker_run. Rate limit: 20 create CALLS per hour per ACCOUNT, shared with worker_clone_bulk (a bulk call of twenty workers costs one). Requires the createWorkers scope.\" +\n NEW_SCOPE_NOTE +\n CLONE_NOTE,\n auth: \"manager\",\n method: \"post\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n ...CLONE_REQUEST_SHAPE,\n },\n path: (params) => `${API}/${params.tokenId}/clone`,\n bodyBuilder: (params) => ({\n title: params.title,\n includeInstruction: params.includeInstruction,\n includeMemory: params.includeMemory,\n includeSchedules: params.includeSchedules,\n includeDeliveries: params.includeDeliveries,\n includeDeployment: params.includeDeployment,\n resourceId: params.resourceId,\n }),\n annotations: CREATE,\n};\n\nconst cloneWorkerBulk: ToolDescriptor = {\n name: \"worker_clone_bulk\",\n title: \"Clone Worker in Bulk\",\n description:\n \"Clone this worker several times in ONE call — how a fleet of eighteen becomes a fleet of a hundred. IT IS NOT ATOMIC AND DOES NOT ROLL BACK: PARTIAL SUCCESS IS THE NORMAL OUTCOME, because a per-item report is more useful than discarding nineteen good workers over the twentieth's bad title, and creating-then-deleting workers is worse than never creating them. So READ items[] RATHER THAN THE STATUS CODE — a 200 with created:17 of requested:20 is a success and a failure at once; each item carries index, title, success, workerId and either rawKey or error. KEEP EVERY rawKey: each is that worker's pe_ API key, shown once and never again, and a partial-success response you discard has stranded real workers whose keys nobody has. Capped at 20 workers per call (the 21st is a 400) and rate limited to 20 create calls per hour per ACCOUNT, shared with worker_clone, because a typo here creates workers. Run worker_clone_preview once for the shape you are about to repeat — the blockers that would refuse one item will refuse all of them. Requires the createWorkers scope.\" +\n NEW_SCOPE_NOTE +\n CLONE_NOTE,\n auth: \"manager\",\n method: \"post\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n workers: z.array(z.object(CLONE_REQUEST_SHAPE)).min(1).max(20).describe(\n \"One entry per worker to create, 1–20 of them; each needs its own unique title. Same shape as worker_clone's body, and every entry clones the SAME source worker.\"\n ),\n },\n path: (params) => `${API}/${params.tokenId}/clone/bulk`,\n bodyBuilder: (params) => ({ workers: params.workers }),\n annotations: CREATE,\n};\n\n// ─── Budgets ────────────────────────────────────────────────────────────────\n// The ceilings were always enforced at mint; what they had was no surface. Read\n// and write ride ONE scope (manageBudgets) because visibility without control is\n// trivia and control without visibility is anxiety. Nothing here is gated on the\n// hosted-runtime switch — a worker with no deployment still has a run-count cap.\n\nconst BUDGET_WINDOW_NOTE =\n \" Windows differ, deliberately: maxUsdPerDay and both fleet ceilings roll at UTC midnight (the month on the 1st), while maxRunsPerDay is counted over the WORKER'S OWN day — its timeZoneId, UTC only when it has none — because the scheduler that fires those runs is already zone-aware.\";\n\nconst getWorkerBudget: ToolDescriptor = {\n name: \"budget_get\",\n title: \"Get Worker Budget\",\n description:\n \"One worker's spend and rate ceilings: maxUsdPerRun, maxUsdPerDay, maxRunsPerDay, maxConcurrentRuns, modelSlug, hasDeployment (plus workerId and its deprecated alias tokenId). Four readings an agent gets wrong by default. (1) maxRunsPerDay NULL MEANS THE PLATFORM DEFAULT, NOT UNLIMITED — the gate substitutes the platform's own number, so never report a null as 'no limit'. (2) maxUsdPerRun is the amount RESERVED from the wallet at dispatch, so it is also what a run must be able to AFFORD before it starts; and the day cap is counted against those RESERVATIONS rather than settled cost, so a worker reserving $0.50 under a $2/day cap is skipped on its fifth run of the day even if each one really cost a cent (the reservation is refunded when a later gate skips the run). (3) maxConcurrentRuns is enforced at mint but is CURRENTLY FIXED AT 1 rather than configurable — it is reported so the number you see is the number the gate uses, and budget_set has no parameter for it. (4) hasDeployment FALSE means hosted runs are not set up for this worker, and then the dollar figures come back as 0 because there is no deployment to read them from — that 0 means 'no deployment', NOT 'capped at zero', so check hasDeployment before quoting any ceiling. Per-worker caps do not compose; the ceiling above them is fleet_budget_get. Requires the manageBudgets scope — reading a ceiling rides the same scope as changing it.\" +\n BUDGET_WINDOW_NOTE +\n NEW_SCOPE_NOTE,\n auth: \"manager\",\n method: \"get\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n },\n path: (params) => `${API}/${params.tokenId}/budget`,\n paramFilter: () => ({}),\n annotations: READ_ONLY,\n};\n\nconst setWorkerBudget: ToolDescriptor = {\n name: \"budget_set\",\n title: \"Set Worker Budget\",\n description:\n \"Change one worker's ceilings, and get the whole budget back as it now stands. PARTIAL: every field is optional and an OMITTED FIELD MEANS UNCHANGED, so you can raise one ceiling without restating the rest and without racing another writer's edit to a different field. Three traps. Setting maxUsdPerRun or maxUsdPerDay on a worker with NO HOSTED DEPLOYMENT is a 400 — there is nothing for a dollar cap to bind to, and budget_get's hasDeployment says which workers those are; maxRunsPerDay, by contrast, can be set on any worker. There is NO way to clear maxRunsPerDay back to the platform default here, because null already means 'leave it alone': send an explicit number instead. And LOWERING maxUsdPerRun below what a run needs does not fail loudly — it makes that worker's next run a Skipped receipt with a skipReason, which is a receipt an agent must go and read. maxConcurrentRuns is not settable (fixed at 1) and is absent from this call by design. A ZERO dollar cap means STOP, not unlimited. Requires the manageBudgets scope.\" +\n BUDGET_WINDOW_NOTE +\n NEW_SCOPE_NOTE,\n auth: \"manager\",\n method: \"patch\",\n schema: {\n tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),\n maxUsdPerRun: z.number().min(0).max(1000).optional().describe(\n \"Hard per-run ceiling in USD, 0–1000 — also the amount reserved from the wallet at dispatch. Needs a hosted deployment. Omit to keep.\"\n ),\n maxUsdPerDay: z.number().min(0).max(100000).optional().describe(\n \"Ceiling on this worker's reserved spend per UTC day, 0–100000. Needs a hosted deployment. Omit to keep.\"\n ),\n maxRunsPerDay: z.number().int().min(1).max(10000).optional().describe(\n \"Runs per the worker's own day, 1–10000. Omit to keep — there is no value here that restores the platform default.\"\n ),\n },\n path: (params) => `${API}/${params.tokenId}/budget`,\n bodyBuilder: (params) => ({\n maxUsdPerRun: params.maxUsdPerRun,\n maxUsdPerDay: params.maxUsdPerDay,\n maxRunsPerDay: params.maxRunsPerDay,\n }),\n annotations: UPDATE,\n};\n\nconst getFleetBudget: ToolDescriptor = {\n name: \"fleet_budget_get\",\n title: \"Get Fleet Budget\",\n description:\n \"The ACCOUNT-WIDE spend ceiling and what has been spent against it — the brake above the per-worker caps, which exists because per-worker caps DO NOT COMPOSE: eighteen workers each capped at a dollar a day is an eighteen-dollar-a-day fleet. Returns maxUsdPerDay and maxUsdPerMonth (each ABSENT when no ceiling of that kind is set — and note that a ceiling of ZERO MEANS STOP, not unlimited), autoPauseOnBreach, spentTodayUsd, spentThisMonthUsd, lastBreachAtUtc, lastBreachScope ('fleet.day' | 'fleet.month') and serverTimeUtc — compute headroom and when a window rolls against serverTimeUtc, never your own clock. The spend figures are SETTLED model spend plus BYOK platform fees, read from run receipts rather than the wallet ledger: top-ups, worker-assistant spend and app-usage billing are neither counted here nor governed by this ceiling, so this number will not match a wallet balance. A run is refused once spend REACHES the ceiling (>=, not >), arriving as a Skipped receipt whose errorCode is fleet_spend_cap. Account-scoped by the key itself, so it takes no worker id. Requires the manageBudgets scope.\" +\n NEW_SCOPE_NOTE,\n auth: \"manager\",\n method: \"get\",\n schema: {},\n path: `${API}/fleet/budget`,\n annotations: READ_ONLY,\n};\n\nconst setFleetBudget: ToolDescriptor = {\n name: \"fleet_budget_set\",\n title: \"Set Fleet Budget\",\n description:\n \"Set or clear the account-wide ceiling, and get the fleet budget back with fresh spend figures. ABSENT MEANS UNCHANGED, so REMOVING a ceiling needs the matching CLEAR FLAG — clearMaxUsdPerDay / clearMaxUsdPerMonth — because null cannot mean both 'leave it alone' and 'none'. Sending a value and its clear flag together is contradictory and CLEAR WINS: dropping a ceiling is the safer reading of a confused request than raising one. ZERO IS NOT UNLIMITED — a ceiling of 0 stops the whole fleet, because a run is refused once spend reaches it. autoPauseOnBreach is the loud one: when a ceiling trips it DISABLES EVERY WORKER ON THE ACCOUNT rather than only refusing the run that tripped it — each worker's own API key stops working and its schedules stop firing — and nothing turns them back on when the window rolls, so a human, or worker_set_enabled one worker at a time, has to start them again. It is off by default; turn it on deliberately, and tell the human you did. A breach raises its event once per window rather than on every refused run, and lastBreachAtUtc/lastBreachScope on the response are how you see that it happened. Requires the manageBudgets scope.\" +\n NEW_SCOPE_NOTE,\n auth: \"manager\",\n method: \"patch\",\n schema: {\n maxUsdPerDay: z.number().min(0).max(1000000).optional().describe(\n \"Account-wide ceiling on settled run spend per UTC day, 0–1000000. Omit to keep; use clearMaxUsdPerDay to remove it.\"\n ),\n clearMaxUsdPerDay: z.boolean().optional().describe(\n \"true = REMOVE the daily ceiling (no account-wide day limit). Wins over maxUsdPerDay if both are sent.\"\n ),\n maxUsdPerMonth: z.number().min(0).max(1000000).optional().describe(\n \"Account-wide ceiling per UTC month, 0–1000000. Omit to keep; use clearMaxUsdPerMonth to remove it.\"\n ),\n clearMaxUsdPerMonth: z.boolean().optional().describe(\n \"true = REMOVE the monthly ceiling. Wins over maxUsdPerMonth if both are sent.\"\n ),\n autoPauseOnBreach: z.boolean().optional().describe(\n \"true = disable EVERY worker on the account when a ceiling trips, instead of only refusing the run that tripped it. Re-enabling is manual. Omit to keep.\"\n ),\n },\n path: `${API}/fleet/budget`,\n bodyBuilder: (params) => ({\n maxUsdPerDay: params.maxUsdPerDay,\n clearMaxUsdPerDay: params.clearMaxUsdPerDay,\n maxUsdPerMonth: params.maxUsdPerMonth,\n clearMaxUsdPerMonth: params.clearMaxUsdPerMonth,\n autoPauseOnBreach: params.autoPauseOnBreach,\n }),\n annotations: UPDATE,\n};\n\n// ─── Export ─────────────────────────────────────────────────────────────────\n\nexport const manageDescriptors: readonly ToolDescriptor[] = [\n getKeyInfo,\n listWorkers,\n getWorker,\n runWorker,\n runsFeed,\n fleetPulse,\n listRuns,\n getRun,\n getRunEvents,\n getRunQuestion,\n answerRunQuestion,\n cancelRun,\n clearRunDigest,\n scoreRun,\n getMemory,\n addMemoryItem,\n updateMemoryItem,\n deleteMemoryItem,\n listSchedules,\n createSchedule,\n updateSchedule,\n deleteSchedule,\n listDeliveries,\n deliveryChannels,\n createDelivery,\n updateDelivery,\n deleteDelivery,\n getInstruction,\n setInstruction,\n getInstructionVersions,\n getInstructionVersion,\n restoreInstructionVersion,\n setWorkerEnabled,\n kitInstallPreview,\n kitInstall,\n clonePreview,\n cloneWorker,\n cloneWorkerBulk,\n getWorkerBudget,\n setWorkerBudget,\n getFleetBudget,\n setFleetBudget,\n];\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @workerkit/core — the shareable WorkerKit surface: the HTTP client, the
|
|
2
|
-
// tool-descriptor registry (
|
|
2
|
+
// tool-descriptor registry (42 manager + 5 anonymous directory tools), the
|
|
3
3
|
// single wire-execution path, and the pure formatting/redaction helpers.
|
|
4
4
|
// Deliberately MCP-free: MCP (or CLI) presentation lives with the consumer.
|
|
5
5
|
export { PortEdenClient, WorkerKitClient, ResponseTooLargeError, } from "./client.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,yEAAyE;AACzE,4EAA4E;AAE5E,OAAO,EACL,cAAc,EACd,eAAe,EACf,qBAAqB,GACtB,MAAM,aAAa,CAAC;AASrB,cAAc,wBAAwB,CAAC;AAEvC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,EAAE,CAAC,EAAE,MAAM,UAAU,CAAC","sourcesContent":["// @workerkit/core — the shareable WorkerKit surface: the HTTP client, the\n// tool-descriptor registry (
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,yEAAyE;AACzE,4EAA4E;AAE5E,OAAO,EACL,cAAc,EACd,eAAe,EACf,qBAAqB,GACtB,MAAM,aAAa,CAAC;AASrB,cAAc,wBAAwB,CAAC;AAEvC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,EAAE,CAAC,EAAE,MAAM,UAAU,CAAC","sourcesContent":["// @workerkit/core — the shareable WorkerKit surface: the HTTP client, the\n// tool-descriptor registry (42 manager + 5 anonymous directory tools), the\n// single wire-execution path, and the pure formatting/redaction helpers.\n// Deliberately MCP-free: MCP (or CLI) presentation lives with the consumer.\n\nexport {\n PortEdenClient,\n WorkerKitClient,\n ResponseTooLargeError,\n} from \"./client.js\";\nexport type {\n ApiResult,\n ClientLogger,\n ClientOptions,\n QuotaInfo,\n RequestOpts,\n} from \"./client.js\";\n\nexport * from \"./descriptors/index.js\";\n\nexport { executeTool } from \"./execute.js\";\nexport type { ExecuteToolOpts } from \"./execute.js\";\n\nexport { isSuccess, quotaSuffix, retryAfterSuffix } from \"./errors.js\";\n\nexport { SECRET_PATTERNS, scrubSecrets } from \"./redact.js\";\n\nexport { z } from \"./zod.js\";\n"]}
|