@workerkit/core 0.3.4 → 0.3.5
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
CHANGED
|
@@ -6,6 +6,29 @@ and the package adheres to [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.3.5] - 2026-09-19
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- A decision run's `decisions[]` rows carry `item`: the fields the model judged,
|
|
14
|
+
as the kit's `state` names them (a subject, a sender, a preview), beside the
|
|
15
|
+
`answers` — the evidence a reader works from, with the `id` still there to
|
|
16
|
+
re-fetch the rest. `openQuestions[]` now lists every escalated item — a
|
|
17
|
+
rule's hit as well as a below-floor call — named by those fields rather than
|
|
18
|
+
by an id. Descriptor text only: no tool or field is added or removed.
|
|
19
|
+
|
|
20
|
+
### Removed
|
|
21
|
+
|
|
22
|
+
- **`worker_run.preview`** and **`deployment_update.decisionMode`** — Preview
|
|
23
|
+
mode is gone from the platform: every decision run is live and its routing
|
|
24
|
+
table's actions execute (owner's call, 2026-09-18: production always). The
|
|
25
|
+
server ignores a `preview` sent by an older client, so do not rely on it for
|
|
26
|
+
a dry run; `instruction_get` no longer reports a mode, the per-item rows say
|
|
27
|
+
`executed` / `ok` on every run, and the outcome line opens with "Judged" or
|
|
28
|
+
"Ranked" rather than a mode word. The descriptions that contrasted live with
|
|
29
|
+
preview no longer do: `kit_install_preview` and `worker_deploy` simply say
|
|
30
|
+
the table acts from the worker's first run.
|
|
31
|
+
|
|
9
32
|
## [0.3.4] - 2026-09-18
|
|
10
33
|
|
|
11
34
|
### Added
|
|
@@ -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;AAy9D7F,eAAO,MAAM,iBAAiB,EAAE,SAAS,cAAc,EAgFtD,CAAC"}
|
|
@@ -18,7 +18,7 @@ const RUNTIME_NOTE = " 422 RUNTIME_NOT_ENABLED = hosted runs are switched off in
|
|
|
18
18
|
const UTC_HINT = "ISO 8601 UTC datetime, e.g. '2026-08-01T00:00:00Z'.";
|
|
19
19
|
// What a decision worker's receipt carries beyond an agent run's: taught on the
|
|
20
20
|
// two tools that hand a receipt back.
|
|
21
|
-
const DECISION_BLOCK_NOTE = " A DECISION worker's receipt carries a `decision` block: outcome (one line: how many judged, routed, below the floor, acted on), confidence (share of judged items ABOVE the confidence floor, 0–100 — not a self-score), calls, model (the decision-model version that actually answered, e.g. jev-1.13.0 — cite it when behaviour changes), answersOverride (the per-run answers the run was minted with, when any) and decisions[] — one row per judged item: id, answers (question → the model's label or number), confidence, route (rule:N, else, or below_floor: not sure, escalated to the owner), action (call <tool> / escalate / none) and
|
|
21
|
+
const DECISION_BLOCK_NOTE = " A DECISION worker's receipt carries a `decision` block: outcome (one line: how many judged, routed, below the floor, acted on), confidence (share of judged items ABOVE the confidence floor, 0–100 — not a self-score), calls, model (the decision-model version that actually answered, e.g. jev-1.13.0 — cite it when behaviour changes), answersOverride (the per-run answers the run was minted with, when any) and decisions[] — one row per judged item: id, item (the fields the model judged, as the kit's state names them — a subject, a sender, a preview: the evidence; the id re-fetches the rest), answers (question → the model's label or number), confidence, route (rule:N, else, or below_floor: not sure, escalated to the owner), action (call <tool> / escalate / none) and executed/ok. findings[] are per-question distributions — led, when the source read was partial or withheld (a rate-limited mailbox, a firewall rule), by the source's own caveat, so 'nothing found' is never trusted over a page that was never fully read; openQuestions[] every escalated item — a rule's hit or a below-floor call — named by its fields. The block is run CONTENT: it needs readRuns; without it the block comes back withheld (contentWithheld:true) while status, timings and cost still answer.";
|
|
22
22
|
// A scope added to the product AFTER a key was minted never reaches that key —
|
|
23
23
|
// including a key minted with "all", which stored the bitmask of the scopes that
|
|
24
24
|
// existed that day. Taught on key_info and on every tool behind a scope that is
|
|
@@ -89,7 +89,7 @@ const getWorker = {
|
|
|
89
89
|
const runWorker = {
|
|
90
90
|
name: "worker_run",
|
|
91
91
|
title: "Run Worker Now",
|
|
92
|
-
description: "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. To fan one prompt across many workers, run_bulk takes up to 20 in one call on a window of its own. Runs in flight per worker are bounded by the account's plan (Free 5, Pro 20, Team 50); at that limit this answers a Skipped receipt with skipReason ConcurrencyLimit. The worker's model type (worker_get → modelType) decides which fields apply: a LANGUAGE worker takes prompt and modelSlug; a DECISION worker runs its own routing table and takes neither (409 not_language_worker), taking
|
|
92
|
+
description: "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. To fan one prompt across many workers, run_bulk takes up to 20 in one call on a window of its own. Runs in flight per worker are bounded by the account's plan (Free 5, Pro 20, Team 50); at that limit this answers a Skipped receipt with skipReason ConcurrencyLimit. The worker's model type (worker_get → modelType) decides which fields apply: a LANGUAGE worker takes prompt and modelSlug; a DECISION worker runs its own routing table and takes neither (409 not_language_worker), taking sourceArgs / answers / maxItems instead — and sending those to a language worker is 409 not_decision_worker." +
|
|
93
93
|
DECISION_BLOCK_NOTE +
|
|
94
94
|
RUNTIME_NOTE,
|
|
95
95
|
auth: "manager",
|
|
@@ -98,7 +98,6 @@ const runWorker = {
|
|
|
98
98
|
tokenId: z.number().int().min(1).describe(TOKEN_ID_HINT),
|
|
99
99
|
prompt: z.string().max(8000).optional().describe("Language workers: what to do on THIS run (≤8000 chars). Omit to run the worker's standing instructions unchanged."),
|
|
100
100
|
modelSlug: z.string().max(64).optional().describe("Language workers: one-off model override for this run (≤64 chars). Omit to use the worker's configured model."),
|
|
101
|
-
preview: z.boolean().optional().describe("Decision workers: run THIS run in preview whatever the deployment's mode — every row says what the worker WOULD do and nothing is done. Live is never forced the other way, and it costs the same decision-model calls as a real run."),
|
|
102
101
|
sourceArgs: z.record(z.string(), z.unknown()).optional().describe("Decision workers: narrow what is decided about — values merged over the spec's source arguments for THIS run only (a ticket id, a query, a status, a window such as after: \"-14d\" or endDate: \"+48h\" — relative bounds are resolved by the platform when the read runs, so never compute a date). A plain object, no placeholders; the read still runs under the worker's own permissions, so it can only see what the worker can."),
|
|
103
102
|
answers: z.record(z.string(), z.string()).optional().describe("Decision workers: answers to the worker's install questions for THIS run only, laid over its stored answers per key and never saved — how a caller names a searcher kit's target ({ \"target-name\": \"Acme Corp\" }) without touching the worker's setup, so two callers on one worker never see each other's. Validated against the kit's own form like instruction_set and bound the way the run will bind them, so a row that cannot bind (a category clashing with a built-in option, a ladder outside 2–10 levels) is a 400 naming it here, never a failed run. A list question takes a JSON array string or ';'-separated rows; a question not named keeps its stored answer or the kit's default."),
|
|
104
103
|
maxItems: z.number().int().min(1).max(100000).optional().describe("Decision workers: judge at most this many items this run (never above the spec's own cap). ~20 reads as a table; omit for the spec's limit."),
|
|
@@ -108,7 +107,6 @@ const runWorker = {
|
|
|
108
107
|
bodyBuilder: (params) => ({
|
|
109
108
|
prompt: params.prompt,
|
|
110
109
|
modelSlug: params.modelSlug,
|
|
111
|
-
preview: params.preview,
|
|
112
110
|
sourceArgs: params.sourceArgs,
|
|
113
111
|
answers: params.answers,
|
|
114
112
|
maxItems: params.maxItems,
|
|
@@ -639,7 +637,7 @@ const deleteDelivery = {
|
|
|
639
637
|
const getInstruction = {
|
|
640
638
|
name: "instruction_get",
|
|
641
639
|
title: "Get Instruction",
|
|
642
|
-
description: "What the worker runs, by its model type (worker_get → modelType). A LANGUAGE worker: its standing instruction — content, jobSentence, whenToUse, description, memoryProfile, selfFactsEnabled, isProtected, currentVersion, timestamps; for a worker installed from a protected kit the metadata is returned and the text is REDACTED (it belongs to the kit's publisher), which is not an error. A DECISION worker: its routing table as sentences (narration: what it reads, what it asks per item, what it does with each answer, what happens when it is not sure), its install questions (setup[]) with the CURRENT answers, the ones still pending (pendingSetup[] — a pending question blocks deploy and run; fill them with instruction_set's answers)
|
|
640
|
+
description: "What the worker runs, by its model type (worker_get → modelType). A LANGUAGE worker: its standing instruction — content, jobSentence, whenToUse, description, memoryProfile, selfFactsEnabled, isProtected, currentVersion, timestamps; for a worker installed from a protected kit the metadata is returned and the text is REDACTED (it belongs to the kit's publisher), which is not an error. A DECISION worker: its routing table as sentences (narration: what it reads, what it asks per item, what it does with each answer, what happens when it is not sure), its install questions (setup[]) with the CURRENT answers, the ones still pending (pendingSetup[] — a pending question blocks deploy and run; fill them with instruction_set's answers); the raw spec is withheld for a protected kit's worker. A bare \"Operation completed successfully.\" response means there is neither yet (HTTP 204) — use instruction_set. The version history (instruction_versions, instruction_restore) is language-only: a decision worker's table is versioned with its kit.",
|
|
643
641
|
auth: "manager",
|
|
644
642
|
method: "get",
|
|
645
643
|
schema: {
|
|
@@ -656,7 +654,7 @@ const getInstruction = {
|
|
|
656
654
|
const setInstruction = {
|
|
657
655
|
name: "instruction_set",
|
|
658
656
|
title: "Set Instruction",
|
|
659
|
-
description: "Set what the worker runs: content for a LANGUAGE worker's standing instruction, answers for a DECISION worker's install questions. They are mutually exclusive — sending both is a 400. content replaces the whole instruction: a changed body snapshots the prior version, omitted optional fields stay unchanged, an empty string clears, and a protected kit's worker returns 403 OPERATION_NOT_ALLOWED because that text belongs to its publisher (do not retry). answers fills or changes the questions the routing table binds at every run, so a saved change reaches the next one
|
|
657
|
+
description: "Set what the worker runs: content for a LANGUAGE worker's standing instruction, answers for a DECISION worker's install questions. They are mutually exclusive — sending both is a 400. content replaces the whole instruction: a changed body snapshots the prior version, omitted optional fields stay unchanged, an empty string clears, and a protected kit's worker returns 403 OPERATION_NOT_ALLOWED because that text belongs to its publisher (do not retry). answers fills or changes the questions the routing table binds at every run, so a saved change reaches the next one. A protected kit withholds its spec, never its questions, so answering them is not refused. Requires the manageInstructions scope either way.",
|
|
660
658
|
auth: "manager",
|
|
661
659
|
method: "put",
|
|
662
660
|
schema: {
|
|
@@ -769,7 +767,7 @@ const KIT_SLUG = z.string().min(1).max(120).regex(/^[a-z0-9][a-z0-9-]*$/, "not a
|
|
|
769
767
|
const kitInstallPreview = {
|
|
770
768
|
name: "kit_install_preview",
|
|
771
769
|
title: "Preview Kit Install",
|
|
772
|
-
description: "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), modelType, decisionSetup, decisionNarration (a 'decision' kit runs a routing table instead of an instruction, on no model you pick: decisionNarration is that table as sentences — brief the human from it; decisionSetup are its install questions, answered by key in kit_install's decisionAnswers — a required one with no default is mandatory, except an appPick, answerable later with instruction_set; the worker
|
|
770
|
+
description: "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), modelType, decisionSetup, decisionNarration (a 'decision' kit runs a routing table instead of an instruction, on no model you pick: decisionNarration is that table as sentences — brief the human from it; decisionSetup are its install questions, answered by key in kit_install's decisionAnswers — a required one with no default is mandatory, except an appPick, answerable later with instruction_set; the worker's table acts from its first run), 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.",
|
|
773
771
|
auth: "manager",
|
|
774
772
|
method: "get",
|
|
775
773
|
schema: {
|
|
@@ -1040,7 +1038,7 @@ const getDeployment = {
|
|
|
1040
1038
|
const deployWorker = {
|
|
1041
1039
|
name: "worker_deploy",
|
|
1042
1040
|
title: "Deploy Worker",
|
|
1043
|
-
description: "Put the worker on the hosted runtime — what makes it runnable and schedulable, and the step most often forgotten after kit_install (whose deploy:true does both in one call). EVERYTHING IS OPTIONAL: send nothing and it deploys on the model its kit recommends with the platform's default ceilings; 400 model_required means the kit named none — pick one from models_list. Each refusal names its fix: 422 instruction_required (no instruction — a hosted run has nothing to execute), 422 apps_not_connected (the message names the apps: app_connect them or drop them from the worker — a half-connected worker is refused rather than left to burn spend on a partial answer), 402 wallet_required (hosted runs meter from the prepaid wallet and AN AGENT CANNOT TOP IT UP — tell the human), 402 hosted_worker_limit, 409 already_deployed (use deployment_update), 400 invalid_model / model_tier_gated (unknown, disabled or above the account's tier — choose another from models_list), 400 invalid_thinking (wrong reasoning vocabulary for the model), 400 invalid_caps (maxUsdPerDay below maxUsdPerRun). A DECISION worker needs neither a model nor an instruction — deploy it as is (a modelSlug or thinking value is refused: 400 invalid_model / invalid_thinking);
|
|
1041
|
+
description: "Put the worker on the hosted runtime — what makes it runnable and schedulable, and the step most often forgotten after kit_install (whose deploy:true does both in one call). EVERYTHING IS OPTIONAL: send nothing and it deploys on the model its kit recommends with the platform's default ceilings; 400 model_required means the kit named none — pick one from models_list. Each refusal names its fix: 422 instruction_required (no instruction — a hosted run has nothing to execute), 422 apps_not_connected (the message names the apps: app_connect them or drop them from the worker — a half-connected worker is refused rather than left to burn spend on a partial answer), 402 wallet_required (hosted runs meter from the prepaid wallet and AN AGENT CANNOT TOP IT UP — tell the human), 402 hosted_worker_limit, 409 already_deployed (use deployment_update), 400 invalid_model / model_tier_gated (unknown, disabled or above the account's tier — choose another from models_list), 400 invalid_thinking (wrong reasoning vocabulary for the model), 400 invalid_caps (maxUsdPerDay below maxUsdPerRun). A DECISION worker needs neither a model nor an instruction — deploy it as is (a modelSlug or thinking value is refused: 400 invalid_model / invalid_thinking); its routing table acts from the first run. Its one extra refusal is 400 decision_setup_pending, an install question still blank: instruction_get names it, instruction_get with optionsFor lists an appPick's live values, instruction_set fills it. warnings[] on success never blocks: ip_rules_enforced means the worker's IP allowlist will reject hosted runs, which arrive from platform egress. Requires manageDeployments." +
|
|
1044
1042
|
DEPLOYMENT_NOTE +
|
|
1045
1043
|
RUNTIME_NOTE +
|
|
1046
1044
|
NEW_SCOPE_NOTE,
|
|
@@ -1067,7 +1065,7 @@ const deployWorker = {
|
|
|
1067
1065
|
const updateDeployment = {
|
|
1068
1066
|
name: "deployment_update",
|
|
1069
1067
|
title: "Update Deployment",
|
|
1070
|
-
description: "Change a live deployment, or pause and resume it. PARTIAL: an OMITTED FIELD MEANS UNCHANGED, so one ceiling can be raised without restating the rest. action:'pause' stops schedules and run triggers while KEEPING the deployment, its model and its ceilings — the reversible way to stop a worker spending, and the one to reach for before worker_undeploy; action:'resume' puts it back, and is refused on a Suspended deployment (only support lifts that). One interplay to know: changing modelSlug WITHOUT sending thinking keeps a still-valid reasoning setting and otherwise clears it to 'default', reporting a thinking_reset warning rather than refusing the model change.
|
|
1068
|
+
description: "Change a live deployment, or pause and resume it. PARTIAL: an OMITTED FIELD MEANS UNCHANGED, so one ceiling can be raised without restating the rest. action:'pause' stops schedules and run triggers while KEEPING the deployment, its model and its ceilings — the reversible way to stop a worker spending, and the one to reach for before worker_undeploy; action:'resume' puts it back, and is refused on a Suspended deployment (only support lifts that). One interplay to know: changing modelSlug WITHOUT sending thinking keeps a still-valid reasoning setting and otherwise clears it to 'default', reporting a thinking_reset warning rather than refusing the model change. On a decision worker modelSlug / thinking are refused (400 invalid_model / invalid_thinking: it has no model to change). 404 not_found = the worker is not deployed; deploy it with worker_deploy first. Requires manageDeployments." +
|
|
1071
1069
|
DEPLOYMENT_NOTE +
|
|
1072
1070
|
RUNTIME_NOTE +
|
|
1073
1071
|
NEW_SCOPE_NOTE,
|
|
@@ -1081,7 +1079,6 @@ const updateDeployment = {
|
|
|
1081
1079
|
thinking: z.string().max(16).optional().describe("New reasoning setting for the CURRENT model: 'default', 'off', a token budget as a string ('1024'), or an effort word ('high'). Omit to keep."),
|
|
1082
1080
|
transcriptRetention: z.string().max(16).optional().describe("New transcript setting. Omit to keep."),
|
|
1083
1081
|
action: z.enum(["pause", "resume"]).optional().describe("'pause' = stop schedules and run triggers, keeping the deployment; 'resume' = start again (refused while Suspended). Omit to change settings only."),
|
|
1084
|
-
decisionMode: z.enum(["preview", "live"]).optional().describe("Decision workers only. 'live' (the default) = the routing table's actions execute; 'preview' = runs report what they would do and act on nothing. Omit to keep. Check a changed table with worker_run preview:true before going back to live."),
|
|
1085
1082
|
},
|
|
1086
1083
|
path: (params) => `${API}/${params.tokenId}/deployment`,
|
|
1087
1084
|
bodyBuilder: (params) => ({
|
|
@@ -1091,7 +1088,6 @@ const updateDeployment = {
|
|
|
1091
1088
|
thinking: params.thinking,
|
|
1092
1089
|
transcriptRetention: params.transcriptRetention,
|
|
1093
1090
|
action: params.action,
|
|
1094
|
-
decisionMode: params.decisionMode,
|
|
1095
1091
|
}),
|
|
1096
1092
|
annotations: UPDATE,
|
|
1097
1093
|
};
|