@desplega.ai/agent-swarm 1.158.0 → 1.159.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/dist/{acp-adapter-xaq4n6pc.js → acp-adapter-qhch0n2v.js} +1 -1
- package/dist/{actions-p9hz5yat.js → actions-dtsh1mfb.js} +33 -29
- package/dist/{anthropic-messages-51pz26qe.js → anthropic-messages-f2h06k64.js} +8 -3
- package/dist/{app-g26wdcz6.js → app-y1b9srva.js} +10 -9
- package/dist/{assistant-wydfqkb3.js → assistant-31hwy5xj.js} +34 -30
- package/dist/{azure-openai-responses-8gksqtmz.js → azure-openai-responses-0k1mfax5.js} +12 -13
- package/dist/{boot-reembed-se8zmdcp.js → boot-reembed-48d2qpkt.js} +11 -11
- package/dist/{boot-reembed-g5ckg9yb.js → boot-reembed-w0bryhkr.js} +12 -12
- package/dist/{boot-scrub-logs-wfxqan61.js → boot-scrub-logs-t65wbrn7.js} +9 -8
- package/dist/{boot-seeds-s3q01xj3.js → boot-seeds-h7c32hvm.js} +12 -11
- package/dist/{claude-adapter-tv2x4f36.js → claude-adapter-1t6611ne.js} +26 -21
- package/dist/{claude-managed-adapter-41b2s7fd.js → claude-managed-adapter-werp659j.js} +4 -2
- package/dist/{claude-managed-setup-60g8aazx.js → claude-managed-setup-y6rdgbc1.js} +11 -2
- package/dist/claude-sdk-session-zhkyk8yw.js +29319 -0
- package/dist/{cli-vj6h9kc2.js → cli-0m7wct0d.js} +59 -1
- package/dist/{cli-wscdvcqz.js → cli-0n2e4x49.js} +1 -1
- package/dist/cli-0xqde53b.js +176 -0
- package/dist/{cli-xberxa1r.js → cli-10ym38qc.js} +2 -2
- package/dist/{cli-5b6b62tz.js → cli-13hw4z91.js} +1 -1
- package/dist/{cli-rqz8qbw7.js → cli-20035trh.js} +50 -18
- package/dist/{cli-k0g1sjzm.js → cli-31nkw3g3.js} +3 -3
- package/dist/cli-3gvrr8vj.js +1422 -0
- package/dist/{cli-c07r9a2m.js → cli-48527fpw.js} +9 -8
- package/dist/{cli-24k806sc.js → cli-4aj25szq.js} +2 -2
- package/dist/{cli-7gtvvpbh.js → cli-4tvgz99m.js} +7 -7
- package/dist/cli-503ya656.js +455 -0
- package/dist/{cli-cw9zck8j.js → cli-5f2hq128.js} +8 -4
- package/dist/{cli-s8eet254.js → cli-68bmme5p.js} +11078 -27833
- package/dist/{cli-ftfvggzx.js → cli-79aq9cgb.js} +794 -563
- package/dist/cli-7cxw8b60.js +14910 -0
- package/dist/cli-7kyk9jr3.js +22 -0
- package/dist/cli-7zttzetj.js +324 -0
- package/dist/{cli-y95wp3tg.js → cli-96qd5psa.js} +1 -1
- package/dist/{cli-g8djp6qe.js → cli-9yg65c1j.js} +22 -0
- package/dist/{cli-3gmcwfyx.js → cli-ardpzhjm.js} +5 -5
- package/dist/{cli-7s3syk22.js → cli-b6thtzac.js} +5 -5
- package/dist/{cli-00w2c66p.js → cli-bgv70kym.js} +13 -2
- package/dist/{cli-j55n64b6.js → cli-bv0a38v9.js} +163 -44
- package/dist/cli-ca2w7zv7.js +115 -0
- package/dist/cli-cpvsaqsw.js +333 -0
- package/dist/cli-cygyqj3b.js +754 -0
- package/dist/{cli-x24pshtq.js → cli-dvjpkkjd.js} +6 -6
- package/dist/{cli-5d10vd2m.js → cli-e0ndxhtk.js} +4 -4
- package/dist/{cli-4198qc9v.js → cli-e4xnc0qp.js} +15 -3
- package/dist/{cli-rjehvrts.js → cli-eg7cdg68.js} +8 -8
- package/dist/cli-ejpygnqz.js +3815 -0
- package/dist/{cli-fgqxwrpv.js → cli-fjtp3463.js} +1631 -127
- package/dist/{cli-zt1227k1.js → cli-fkqhbg8g.js} +5 -3
- package/dist/{cli-47m6dkd3.js → cli-g9df2m37.js} +409 -168
- package/dist/cli-gzyh0j0g.js +8455 -0
- package/dist/cli-hgqfttfc.js +183 -0
- package/dist/cli-hj65wsts.js +17755 -0
- package/dist/cli-j9z8mfx3.js +476 -0
- package/dist/{cli-aehm1rbq.js → cli-kc3dp84d.js} +1135 -61
- package/dist/{cli-h38x0qhg.js → cli-kdnehe0t.js} +4 -3
- package/dist/{cli-20cj37vt.js → cli-m4excttz.js} +136 -2216
- package/dist/{cli-8qmme6vd.js → cli-mg24hkt4.js} +2 -2
- package/dist/{cli-xhaeg2nc.js → cli-mzkqpxee.js} +1 -1
- package/dist/{cli-q67y4wzm.js → cli-phsaj4xq.js} +24 -2
- package/dist/{cli-pw9rj5t9.js → cli-pqetb83f.js} +1 -176
- package/dist/{cli-rj19hc34.js → cli-qjxy52w7.js} +1 -1
- package/dist/{cli-53sz8gkz.js → cli-qv4jv8bx.js} +1 -1
- package/dist/cli-qvnnx4ct.js +1051 -0
- package/dist/cli-rb9m6rpe.js +4980 -0
- package/dist/{cli-tt9k8r35.js → cli-rfezr056.js} +476 -909
- package/dist/{cli-ggm92wcn.js → cli-rgjprct3.js} +1 -0
- package/dist/{cli-9httdpyq.js → cli-rrqmqr1s.js} +1 -1
- package/dist/cli-rykfmgwg.js +102 -0
- package/dist/{cli-eetrvv91.js → cli-t3p77qk1.js} +1 -1
- package/dist/{cli-68w09sjw.js → cli-vn0qv9cj.js} +25 -88
- package/dist/{cli-987hg0aa.js → cli-vwbbaecp.js} +2 -2
- package/dist/cli-wd9hz40d.js +69 -0
- package/dist/{cli-j57qkrpq.js → cli-wgjx0q33.js} +13 -13
- package/dist/cli-xgpf00sk.js +2149 -0
- package/dist/{cli-mcnhgnn1.js → cli-ykk5jaax.js} +184 -26
- package/dist/{cli-aky8tctm.js → cli-z9x0sh1t.js} +3 -3
- package/dist/{cli-1hkrch3k.js → cli-zw65mab6.js} +5 -5
- package/dist/cli.js +38 -29
- package/dist/cloudflare-workers-ai-system-one-1sg586qv.js +46 -0
- package/dist/{codex-adapter-cnm8wk11.js → codex-adapter-jqfqqa21.js} +21 -14
- package/dist/{codex-hook-9hptmdhj.js → codex-hook-5eys3dya.js} +2 -2
- package/dist/{codex-session-runner-gfg547zj.js → codex-session-runner-zd341dsm.js} +21 -14
- package/dist/{commands-e3bn0p75.js → commands-vfsysz4s.js} +9 -8
- package/dist/{db-03v9kzr2.js → db-s3znhvbn.js} +15 -10
- package/dist/{dispatcher-nrmg8yht.js → dispatcher-5xn0c7rf.js} +32 -28
- package/dist/{dsh-adapter-k03nfqa6.js → dsh-adapter-894mgfvs.js} +3 -3
- package/dist/{e2b-93x1k0j5.js → e2b-ez07znam.js} +4 -3
- package/dist/execute-71ysgv35.js +965 -0
- package/dist/{google-generative-ai-bxmv50nc.js → google-generative-ai-1nfcdphp.js} +5 -4
- package/dist/{google-vertex-809af514.js → google-vertex-1tqcd7b1.js} +5 -4
- package/dist/{handlers-aqcedbyb.js → handlers-5w4jwycr.js} +35 -31
- package/dist/{hook-7vkskkre.js → hook-853bxrr6.js} +16 -13
- package/dist/{hook-ybvmrmhq.js → hook-z0hbxj85.js} +16 -13
- package/dist/{http-2eqa8t24.js → http-akc3wy3m.js} +600 -123
- package/dist/{index-f6cryxwe.js → index-4a5njnm1.js} +2 -59
- package/dist/{index-a3vn96n8.js → index-5sz16ksh.js} +187 -47
- package/dist/{index-c6zsv1bd.js → index-bjmjh9h4.js} +11 -11
- package/dist/{index-chgdkq36.js → index-cd151qkq.js} +32 -28
- package/dist/{index-x71bvq0p.js → index-k661dzzr.js} +33 -29
- package/dist/{index-1yks3qcr.js → index-ttpbhnjg.js} +32 -28
- package/dist/{keepalive-vtkf5n99.js → keepalive-8p9rpvz5.js} +11 -10
- package/dist/{lead-h3sp357x.js → lead-jp69z5h3.js} +49 -45
- package/dist/llama-cpp-classify-t2tccams.js +335 -0
- package/dist/{maintenance-jzeqtk3q.js → maintenance-fwx4ev0k.js} +12 -12
- package/dist/{mistral-conversations-zx0kn554.js → mistral-conversations-bhvwqcnk.js} +14 -17
- package/dist/{oauth-refresh-sweep-qp3dzmdp.js → oauth-refresh-sweep-cwcq1ctx.js} +10 -9
- package/dist/{onboard-tmsp0qbz.js → onboard-2b4q0t84.js} +6 -5
- package/dist/{openai-codex-responses-4vjqzvjp.js → openai-codex-responses-nekthgks.js} +21 -8
- package/dist/{openai-completions-9hjrqbw8.js → openai-completions-hxtzwj0s.js} +8 -11
- package/dist/{openai-responses-7b1pn0xt.js → openai-responses-w4r118w7.js} +22 -17
- package/dist/{opencode-adapter-x6x2da1z.js → opencode-adapter-zz7xvjj6.js} +6 -4
- package/dist/{openrouter-images-9f9ek4rw.js → openrouter-images-b6sqqjgn.js} +4 -6
- package/dist/{otel-impl-9mz73q65.js → otel-impl-g8rs4vwr.js} +1 -1
- package/dist/{pi-messages-txpjj39q.js → pi-messages-vxdt8v7j.js} +2 -1
- package/dist/{pi-mono-adapter-m6dvv0dz.js → pi-mono-adapter-n0me28wt.js} +29 -17
- package/dist/pricing-refresh-0v77385v.js +39 -0
- package/dist/{rbac-roles-c9wqz83x.js → rbac-roles-krjyazbj.js} +10 -9
- package/dist/{render-v2-gryrh9h8.js → render-v2-3wjsp9aw.js} +10 -9
- package/dist/runtime-ktjysacx.js +24 -0
- package/dist/{setup-q9720bt6.js → setup-yeqryke6.js} +6 -5
- package/dist/typesafe-system-one-96960jxp.js +27 -0
- package/dist/{virtual-modules-3htpgn8x.js → virtual-modules-dzdeq1sf.js} +21 -13
- package/dist/{work-objects-b76x7deb.js → work-objects-3pakpkw0.js} +35 -31
- package/dist/{worker-6vrxbv41.js → worker-85testgj.js} +49 -45
- package/openapi.json +863 -14
- package/package.json +9 -8
- package/src/be/db/agents.ts +20 -0
- package/src/be/db/tasks/human-free.ts +442 -0
- package/src/be/db/tasks/read.ts +56 -1
- package/src/be/db/tasks/write.ts +107 -11
- package/src/be/db.ts +89 -165
- package/src/be/harness-model-support.ts +182 -0
- package/src/be/human-free-drain.ts +67 -0
- package/src/be/migrations/182_task_human_free_flag.sql +63 -0
- package/src/be/migrations/183_human_free_reclassify_queue.sql +25 -0
- package/src/be/migrations/184_model_catalog.sql +120 -0
- package/src/be/model-catalog-store.ts +644 -0
- package/src/be/model-tier-keys.ts +31 -0
- package/src/be/model-tier-resolution.ts +489 -0
- package/src/be/model-validation.ts +112 -0
- package/src/be/models-catalog.ts +61 -7
- package/src/be/modelsdev-cache.json +82 -0
- package/src/be/modelsdev-cache.ts +2 -0
- package/src/be/pricing-refresh.ts +154 -12
- package/src/be/scripts/typecheck.ts +15 -0
- package/src/be/seed-scripts/catalog/task-failure-audit.ts +61 -9
- package/src/be/swarm-config-guard.ts +6 -0
- package/src/cli.tsx +10 -0
- package/src/commands/claude-managed-setup.ts +3 -1
- package/src/commands/runner.ts +76 -2
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/heartbeat/heartbeat.ts +64 -15
- package/src/heartbeat/templates.ts +2 -2
- package/src/http/agents.ts +49 -1
- package/src/http/index.ts +8 -0
- package/src/http/models-catalog.ts +357 -8
- package/src/http/poll.ts +45 -2
- package/src/http/schedules.ts +36 -6
- package/src/http/session-data.ts +2 -5
- package/src/http/stats.ts +6 -8
- package/src/http/tasks.ts +26 -1
- package/src/http/usage-cache.ts +56 -15
- package/src/http/workflows.ts +35 -8
- package/src/prompts/session-templates.ts +1 -0
- package/src/providers/claude-managed-models.ts +47 -161
- package/src/providers/codex-adapter.ts +4 -4
- package/src/providers/codex-models.ts +65 -198
- package/src/providers/reasoning-effort.ts +44 -140
- package/src/rbac/legacy-policy.ts +25 -0
- package/src/rbac/permissions.ts +10 -0
- package/src/scripts-runtime/sdk-allowlist.ts +4 -0
- package/src/scripts-runtime/types/stdlib.d.ts +15 -0
- package/src/scripts-runtime/types/swarm-extension.d.ts +3 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +15 -0
- package/src/server.ts +6 -0
- package/src/slack/message-text.ts +56 -2
- package/src/slack/thread-buffer.ts +10 -2
- package/src/tests/agents-list-model-display.test.ts +4 -6
- package/src/tests/base-prompt.test.ts +3 -0
- package/src/tests/claude-adapter.test.ts +10 -0
- package/src/tests/claude-managed-adapter.test.ts +12 -18
- package/src/tests/codex-adapter.test.ts +2 -1
- package/src/tests/codex-gpt6-release.test.ts +66 -5
- package/src/tests/context-window.test.ts +7 -5
- package/src/tests/db-extraction-contract.test.ts +1 -0
- package/src/tests/db-task-read-contract.test.ts +5 -1
- package/src/tests/db-task-write-contract.test.ts +4 -1
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/explicit-model-validation.test.ts +332 -0
- package/src/tests/harness-model-support.test.ts +374 -0
- package/src/tests/heartbeat-checklist-config.test.ts +71 -0
- package/src/tests/heartbeat-checklist.test.ts +4 -2
- package/src/tests/heartbeat-orphan-resume.test.ts +48 -0
- package/src/tests/human-free-flag.test.ts +279 -0
- package/src/tests/human-free-oracle.ts +57 -0
- package/src/tests/human-free-reclassify.test.ts +669 -0
- package/src/tests/migration-046-budgets.test.ts +3 -3
- package/src/tests/model-catalog-migration.test.ts +134 -0
- package/src/tests/model-catalog-table.test.ts +249 -0
- package/src/tests/model-catalog-write-access.test.ts +387 -0
- package/src/tests/model-tier-resolution.test.ts +519 -0
- package/src/tests/models-catalog.test.ts +1 -1
- package/src/tests/multi-runtime-enabled-stats.test.ts +65 -1
- package/src/tests/package-publish.test.ts +137 -36
- package/src/tests/pricing-routes.test.ts +2 -2
- package/src/tests/rbac-engine.test.ts +42 -2
- package/src/tests/reasoning-effort.test.ts +109 -0
- package/src/tests/refresh-modelsdev-carryforward.test.ts +5 -5
- package/src/tests/runtime-model-catalog.test.ts +86 -0
- package/src/tests/script-connections.test.ts +5 -0
- package/src/tests/seed-scripts.test.ts +89 -0
- package/src/tests/session-costs.test.ts +14 -11
- package/src/tests/slack-message-text.test.ts +101 -0
- package/src/tests/slack-thread-buffer-context.test.ts +93 -0
- package/src/tests/task-cascade-fail.test.ts +148 -2
- package/src/tests/tool-annotations.test.ts +1 -1
- package/src/tests/usage-cache.test.ts +166 -0
- package/src/tests/workflow-executors.test.ts +5 -2
- package/src/tests/workflow-system-one-decision-review.test.ts +1021 -0
- package/src/tests/workflow-system-one-decision-save-warnings.test.ts +365 -0
- package/src/tests/workflow-system-one-decision.test.ts +2063 -0
- package/src/tools/model-catalog/index.ts +137 -0
- package/src/tools/schedules/create-schedule.ts +16 -1
- package/src/tools/schedules/patch-schedule.ts +17 -0
- package/src/tools/schedules/update-schedule.ts +17 -0
- package/src/tools/send-task.ts +14 -0
- package/src/tools/task-action.ts +12 -0
- package/src/tools/tool-config.ts +3 -1
- package/src/tools/workflows/create-workflow.ts +9 -2
- package/src/tools/workflows/patch-workflow-node.ts +17 -7
- package/src/tools/workflows/patch-workflow.ts +9 -2
- package/src/tools/workflows/update-workflow.ts +9 -2
- package/src/types.ts +30 -1
- package/src/utils/context-window.ts +47 -53
- package/src/utils/harness-cli-version.ts +115 -0
- package/src/utils/harness-model-error.ts +33 -0
- package/src/utils/runtime-model-catalog.ts +137 -0
- package/src/workflows/approval-resolution.ts +39 -0
- package/src/workflows/definition.ts +7 -0
- package/src/workflows/engine.ts +69 -1
- package/src/workflows/executors/agent-task.ts +9 -0
- package/src/workflows/executors/base.ts +53 -0
- package/src/workflows/executors/human-in-the-loop.ts +8 -8
- package/src/workflows/executors/index.ts +1 -0
- package/src/workflows/executors/registry.ts +2 -0
- package/src/workflows/executors/system-one-decision.ts +1232 -0
- package/src/workflows/executors/system-one-providers.ts +301 -0
- package/src/workflows/executors/workflow-llm.ts +13 -1
- package/src/workflows/readiness.ts +86 -0
- package/src/workflows/recovery.ts +12 -12
- package/src/workflows/resume.ts +23 -9
- package/templates/schedules/daily-blocker-digest/content.md +4 -5
- package/templates/skills/agent-browser/SKILL.md +6 -5
- package/templates/skills/agent-browser/content.md +6 -5
- package/templates/skills/heartbeat-runbook/config.json +1 -1
- package/templates/skills/heartbeat-runbook/content.md +2 -2
- package/templates/skills/swarm-scripts/SKILL.md +1 -1
- package/templates/skills/swarm-scripts/content.md +1 -1
- package/templates/skills/workflow-iterate/content.md +81 -1
- package/templates/workflows/claude-code-changelog-watch/content.md +2 -0
- package/templates/workflows/pr-review-status-sweep/content.md +2 -0
- package/dist/claude-sdk-session-t442qz6f.js +0 -39108
- package/dist/cli-0xjkj1j7.js +0 -61
- package/dist/cli-65hjmev5.js +0 -1141
- package/dist/cli-aw1jwp1r.js +0 -14075
- package/dist/cli-h967nb6r.js +0 -6603
- package/dist/cli-vapyk8sw.js +0 -20
- package/dist/cli-ws6rqycm.js +0 -247
- package/dist/pricing-refresh-v1cbr9te.js +0 -27
- package/src/providers/modelsdev-reasoning.json +0 -6453
- package/dist/{codex-login-x3jk4etn.js → codex-login-he9vrn90.js} +3 -3
- package/dist/{index-f24115ge.js → index-2wsdsnmm.js} +3 -3
package/src/http/tasks.ts
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
pauseTask,
|
|
28
28
|
promoteDraftTask,
|
|
29
29
|
resumeTask,
|
|
30
|
+
settleSupersededTaskDependents,
|
|
30
31
|
supersedeTask,
|
|
31
32
|
updateAgentStatusFromCapacity,
|
|
32
33
|
updateTaskClaudeSessionId,
|
|
@@ -34,6 +35,7 @@ import {
|
|
|
34
35
|
updateTaskTitle,
|
|
35
36
|
updateTaskVcs,
|
|
36
37
|
} from "../be/db";
|
|
38
|
+
import { explicitModelErrorForAgent } from "../be/model-validation";
|
|
37
39
|
import {
|
|
38
40
|
getTaskSteeringFields,
|
|
39
41
|
markSteeringUndeliverable,
|
|
@@ -102,6 +104,9 @@ const AgentTaskSummarySchema = AgentTaskSchema.pick({
|
|
|
102
104
|
scheduleId: true,
|
|
103
105
|
model: true,
|
|
104
106
|
modelTier: true,
|
|
107
|
+
resolvedModel: true,
|
|
108
|
+
modelSource: true,
|
|
109
|
+
modelAlias: true,
|
|
105
110
|
effort: true,
|
|
106
111
|
provider: true,
|
|
107
112
|
requestedByUserId: true,
|
|
@@ -266,6 +271,11 @@ const createTask = route({
|
|
|
266
271
|
requestedByUserId: z.string().optional(),
|
|
267
272
|
model: z.string().optional(),
|
|
268
273
|
modelTier: ModelTierSchema.optional(),
|
|
274
|
+
/**
|
|
275
|
+
* Accept a `model` the catalog does not list. Without it an unknown id is a 400; with it
|
|
276
|
+
* the id is stored as given (a fresh launch, a private deployment).
|
|
277
|
+
*/
|
|
278
|
+
allowCustomModel: z.boolean().optional(),
|
|
269
279
|
effort: ReasoningEffortSchema.optional(),
|
|
270
280
|
/**
|
|
271
281
|
* Create in `draft` status instead of the normal pending/unassigned/offered
|
|
@@ -287,7 +297,10 @@ const createTask = route({
|
|
|
287
297
|
}),
|
|
288
298
|
responses: {
|
|
289
299
|
201: { description: "Task created", schema: AgentTaskSchema },
|
|
290
|
-
400: {
|
|
300
|
+
400: {
|
|
301
|
+
description:
|
|
302
|
+
"Validation error, an unknown `model` (set `allowCustomModel` to store a custom id), or agentId/offeredTo targets an extension identity",
|
|
303
|
+
},
|
|
291
304
|
422: {
|
|
292
305
|
description: "Task creation blocked by an extension",
|
|
293
306
|
schema: z.object({
|
|
@@ -860,6 +873,17 @@ export async function handleTasks(
|
|
|
860
873
|
if (lead) defaultAgentId = lead.id;
|
|
861
874
|
}
|
|
862
875
|
|
|
876
|
+
const modelError = await explicitModelErrorForAgent({
|
|
877
|
+
model: splitLegacyModelAlias({ model: parsed.body.model, modelTier: parsed.body.modelTier })
|
|
878
|
+
.model,
|
|
879
|
+
allowCustomModel: parsed.body.allowCustomModel,
|
|
880
|
+
agentId: defaultAgentId,
|
|
881
|
+
});
|
|
882
|
+
if (modelError) {
|
|
883
|
+
jsonError(res, modelError, 400);
|
|
884
|
+
return true;
|
|
885
|
+
}
|
|
886
|
+
|
|
863
887
|
const parentTask = parsed.body.parentTaskId
|
|
864
888
|
? await getTaskById(parsed.body.parentTaskId)
|
|
865
889
|
: null;
|
|
@@ -1750,6 +1774,7 @@ export async function handleTasks(
|
|
|
1750
1774
|
// `skipped` covers parent_not_found / lead_not_found edge cases — the
|
|
1751
1775
|
// supersede already landed, so log + roll forward without a resume task.
|
|
1752
1776
|
if (followUp.kind !== "created") {
|
|
1777
|
+
await settleSupersededTaskDependents(parsed.params.id, null);
|
|
1753
1778
|
console.warn(
|
|
1754
1779
|
`[Supersede] Task ${parsed.params.id.slice(0, 8)} superseded but resume creation skipped (${
|
|
1755
1780
|
followUp.kind === "skipped" ? followUp.reason : followUp.kind
|
package/src/http/usage-cache.ts
CHANGED
|
@@ -3,30 +3,71 @@
|
|
|
3
3
|
* `/api/attribution/by-person`). Each open usage page polls them, and every
|
|
4
4
|
* reply aggregates the whole window.
|
|
5
5
|
*
|
|
6
|
-
* A key holds the request filters
|
|
7
|
-
* `
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* A key holds only the request filters. An entry is fresh for
|
|
7
|
+
* `USAGE_CACHE_TTL_MS` (the time bucket). Past that it is served as-is while one
|
|
8
|
+
* background load revalidates it, until its total age reaches
|
|
9
|
+
* `USAGE_CACHE_MAX_STALE_MS`; an older or missing entry blocks on a load.
|
|
10
|
+
* Concurrent misses for one key share that load.
|
|
11
|
+
*
|
|
12
|
+
* The key deliberately carries no data version. The old one changed on every
|
|
13
|
+
* new task or session, and the swarm creates one every few seconds, so it
|
|
14
|
+
* almost never hit. The cost is staleness: the first request past the bucket
|
|
15
|
+
* still gets the old value and only starts the refresh, so a new session shows
|
|
16
|
+
* up on the request after that. A client polling once per bucket sees it about
|
|
17
|
+
* one poll later. A credential plan or name change clears the cache.
|
|
11
18
|
*/
|
|
12
19
|
|
|
13
20
|
export const USAGE_CACHE_TTL_MS = 30_000;
|
|
21
|
+
export const USAGE_CACHE_MAX_STALE_MS = 120_000;
|
|
14
22
|
const MAX_ENTRIES = 100;
|
|
15
23
|
|
|
16
|
-
const entries = new Map<string, {
|
|
24
|
+
const entries = new Map<string, { fetchedAt: number; value: unknown }>();
|
|
25
|
+
const loading = new Map<string, Promise<unknown>>();
|
|
26
|
+
// Bumped by `clearUsageCache`, so a load that started before the clear cannot
|
|
27
|
+
// write its (now outdated) result back.
|
|
28
|
+
let generation = 0;
|
|
29
|
+
|
|
30
|
+
function load<T>(key: string, loader: () => Promise<T>): Promise<T> {
|
|
31
|
+
const running = loading.get(key);
|
|
32
|
+
if (running) return running as Promise<T>;
|
|
33
|
+
|
|
34
|
+
const startedIn = generation;
|
|
35
|
+
const promise: Promise<T> = Promise.resolve()
|
|
36
|
+
.then(loader)
|
|
37
|
+
.then((value) => {
|
|
38
|
+
if (startedIn === generation) {
|
|
39
|
+
entries.delete(key);
|
|
40
|
+
// Map order is insertion order, so the first key is the oldest entry.
|
|
41
|
+
if (entries.size >= MAX_ENTRIES) entries.delete(entries.keys().next().value as string);
|
|
42
|
+
entries.set(key, { fetchedAt: Date.now(), value });
|
|
43
|
+
}
|
|
44
|
+
return value;
|
|
45
|
+
})
|
|
46
|
+
.finally(() => {
|
|
47
|
+
if (loading.get(key) === promise) loading.delete(key);
|
|
48
|
+
});
|
|
49
|
+
loading.set(key, promise);
|
|
50
|
+
return promise;
|
|
51
|
+
}
|
|
17
52
|
|
|
18
|
-
export async function cachedUsageReport<T>(key: string,
|
|
19
|
-
const now = Date.now();
|
|
53
|
+
export async function cachedUsageReport<T>(key: string, loader: () => Promise<T>): Promise<T> {
|
|
20
54
|
const hit = entries.get(key);
|
|
21
|
-
if (hit
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
55
|
+
if (hit) {
|
|
56
|
+
const age = Date.now() - hit.fetchedAt;
|
|
57
|
+
if (age < USAGE_CACHE_TTL_MS) return hit.value as T;
|
|
58
|
+
if (age < USAGE_CACHE_MAX_STALE_MS) {
|
|
59
|
+
// Keep serving the stale value; a failed refresh retries on the next request.
|
|
60
|
+
load(key, loader).catch((error) => {
|
|
61
|
+
console.error(`[usage-cache] background refresh failed for ${key.split(":")[0]}:`, error);
|
|
62
|
+
});
|
|
63
|
+
return hit.value as T;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return load(key, loader);
|
|
28
67
|
}
|
|
29
68
|
|
|
30
69
|
export function clearUsageCache(): void {
|
|
70
|
+
generation++;
|
|
31
71
|
entries.clear();
|
|
72
|
+
loading.clear();
|
|
32
73
|
}
|
package/src/http/workflows.ts
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
CooldownConfigSchema,
|
|
22
22
|
InputValueSchema,
|
|
23
23
|
TriggerConfigSchema,
|
|
24
|
+
type WorkflowDefinition,
|
|
24
25
|
WorkflowDefinitionSchema,
|
|
25
26
|
WorkflowEdgeSchema,
|
|
26
27
|
WorkflowNodePatchSchema,
|
|
@@ -37,6 +38,7 @@ import { definitionNodeIds, generateEdges, validateDefinition } from "../workflo
|
|
|
37
38
|
import { TriggerSchemaError } from "../workflows/engine";
|
|
38
39
|
import { validateJsonSchema } from "../workflows/json-schema-validator";
|
|
39
40
|
import { patchWorkflowDefinition } from "../workflows/patch-definition";
|
|
41
|
+
import { workflowSaveWarnings } from "../workflows/readiness";
|
|
40
42
|
import { cancelWorkflowRun, retryFailedRun } from "../workflows/resume";
|
|
41
43
|
import { handleWebhookTrigger, WebhookError } from "../workflows/triggers";
|
|
42
44
|
import { snapshotAndUpdateWorkflow } from "../workflows/version";
|
|
@@ -49,6 +51,14 @@ import { jsonError, parseBody, triggerSchemaErrorResponse } from "./utils";
|
|
|
49
51
|
/** `Workflow` decorated with the caller-scoped favorite flag (always set once `withFavoriteFlags` runs). */
|
|
50
52
|
const WorkflowWithFavoriteSchema = WorkflowSchema.extend({ favorite: z.boolean() });
|
|
51
53
|
|
|
54
|
+
/**
|
|
55
|
+
* `Workflow` returned by a save (create / update / patch). `warnings` is present only when the
|
|
56
|
+
* save succeeded but a node cannot run yet, e.g. a system-one-decision node whose provider key is not configured.
|
|
57
|
+
*/
|
|
58
|
+
const WorkflowSaveResponseSchema = WorkflowSchema.extend({
|
|
59
|
+
warnings: z.array(z.string()).optional(),
|
|
60
|
+
});
|
|
61
|
+
|
|
52
62
|
/** `/api/workflows` slim list item — mirrors `WorkflowSummary` in src/types.ts (no exported schema there). */
|
|
53
63
|
const WorkflowSummarySchema = WorkflowSchema.omit({
|
|
54
64
|
definition: true,
|
|
@@ -85,6 +95,14 @@ const WorkflowRunPageSchema = z.object({
|
|
|
85
95
|
|
|
86
96
|
const SuccessResponseSchema = z.object({ success: z.literal(true) });
|
|
87
97
|
|
|
98
|
+
/** Adds `warnings` to a just-saved workflow when a node in it cannot run yet. */
|
|
99
|
+
async function withSaveWarnings<T extends { definition: WorkflowDefinition }>(
|
|
100
|
+
workflow: T,
|
|
101
|
+
): Promise<T & { warnings?: string[] }> {
|
|
102
|
+
const warnings = await workflowSaveWarnings(workflow.definition, getExecutorRegistry());
|
|
103
|
+
return warnings.length > 0 ? { ...workflow, warnings } : workflow;
|
|
104
|
+
}
|
|
105
|
+
|
|
88
106
|
// ─── Route Definitions ───────────────────────────────────────────────────────
|
|
89
107
|
|
|
90
108
|
const listWorkflowsRoute = route({
|
|
@@ -137,7 +155,7 @@ const createWorkflowRoute = route({
|
|
|
137
155
|
vcsRepo: z.string().min(1).optional(),
|
|
138
156
|
}),
|
|
139
157
|
responses: {
|
|
140
|
-
201: { description: "Workflow created", schema:
|
|
158
|
+
201: { description: "Workflow created", schema: WorkflowSaveResponseSchema },
|
|
141
159
|
400: { description: "Invalid definition" },
|
|
142
160
|
},
|
|
143
161
|
});
|
|
@@ -188,7 +206,10 @@ const updateWorkflowRoute = route({
|
|
|
188
206
|
enabled: z.boolean().optional(),
|
|
189
207
|
}),
|
|
190
208
|
responses: {
|
|
191
|
-
200: {
|
|
209
|
+
200: {
|
|
210
|
+
description: "Workflow updated (version snapshot created)",
|
|
211
|
+
schema: WorkflowSaveResponseSchema,
|
|
212
|
+
},
|
|
192
213
|
400: { description: "Invalid definition" },
|
|
193
214
|
404: { description: "Workflow not found" },
|
|
194
215
|
},
|
|
@@ -203,7 +224,10 @@ const patchWorkflowRoute = route({
|
|
|
203
224
|
params: z.object({ id: z.string() }),
|
|
204
225
|
body: WorkflowPatchSchema.extend({ key: AssetKeySchema.optional() }),
|
|
205
226
|
responses: {
|
|
206
|
-
200: {
|
|
227
|
+
200: {
|
|
228
|
+
description: "Workflow patched (version snapshot created)",
|
|
229
|
+
schema: WorkflowSaveResponseSchema,
|
|
230
|
+
},
|
|
207
231
|
400: { description: "Invalid patch or resulting definition" },
|
|
208
232
|
404: { description: "Workflow not found" },
|
|
209
233
|
},
|
|
@@ -218,7 +242,10 @@ const patchWorkflowNodeRoute = route({
|
|
|
218
242
|
params: z.object({ id: z.string(), nodeId: z.string() }),
|
|
219
243
|
body: WorkflowNodePatchSchema,
|
|
220
244
|
responses: {
|
|
221
|
-
200: {
|
|
245
|
+
200: {
|
|
246
|
+
description: "Node patched (version snapshot created)",
|
|
247
|
+
schema: WorkflowSaveResponseSchema,
|
|
248
|
+
},
|
|
222
249
|
400: { description: "Invalid patch or resulting definition" },
|
|
223
250
|
404: { description: "Workflow or node not found" },
|
|
224
251
|
},
|
|
@@ -583,7 +610,7 @@ export async function handleWorkflows(
|
|
|
583
610
|
},
|
|
584
611
|
"api",
|
|
585
612
|
);
|
|
586
|
-
createWorkflowRoute.respond(res, 201, workflow);
|
|
613
|
+
createWorkflowRoute.respond(res, 201, await withSaveWarnings(workflow));
|
|
587
614
|
return true;
|
|
588
615
|
}
|
|
589
616
|
|
|
@@ -638,7 +665,7 @@ export async function handleWorkflows(
|
|
|
638
665
|
);
|
|
639
666
|
return true;
|
|
640
667
|
}
|
|
641
|
-
patchWorkflowNodeRoute.respond(res, 200, result.workflow);
|
|
668
|
+
patchWorkflowNodeRoute.respond(res, 200, await withSaveWarnings(result.workflow));
|
|
642
669
|
return true;
|
|
643
670
|
}
|
|
644
671
|
|
|
@@ -695,7 +722,7 @@ export async function handleWorkflows(
|
|
|
695
722
|
);
|
|
696
723
|
return true;
|
|
697
724
|
}
|
|
698
|
-
patchWorkflowRoute.respond(res, 200, result.workflow);
|
|
725
|
+
patchWorkflowRoute.respond(res, 200, await withSaveWarnings(result.workflow));
|
|
699
726
|
return true;
|
|
700
727
|
}
|
|
701
728
|
|
|
@@ -766,7 +793,7 @@ export async function handleWorkflows(
|
|
|
766
793
|
res.end();
|
|
767
794
|
return true;
|
|
768
795
|
}
|
|
769
|
-
updateWorkflowRoute.respond(res, 200, workflow);
|
|
796
|
+
updateWorkflowRoute.respond(res, 200, await withSaveWarnings(workflow));
|
|
770
797
|
return true;
|
|
771
798
|
}
|
|
772
799
|
|
|
@@ -202,6 +202,7 @@ agent-fs is the shared drive between agents and people. Documents (reports, dige
|
|
|
202
202
|
Pages: only for polished artifacts shared with a wider audience or explicitly requested; see \`pages\` skill.
|
|
203
203
|
A tool a person will use, with data and actions: build an app. See the \`apps\` skill.
|
|
204
204
|
Link env: \`APP_URL\` for pages, \`MCP_BASE_URL\` for the API, \`AGENT_FS_LIVE_URL\` for files. Report missing variables.
|
|
205
|
+
For a file anyone outside the swarm opens, use an \`agent-fs share-create\` link; \`AGENT_FS_LIVE_URL\` links are for signed-in teammates.
|
|
205
206
|
`,
|
|
206
207
|
variables: [],
|
|
207
208
|
category: "system",
|
|
@@ -1,48 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* sourced from https://platform.claude.com/docs/en/about-claude/pricing
|
|
5
|
-
* (verified 2026-09-02).
|
|
2
|
+
* Anthropic-managed Claude model facts, read from the model catalog
|
|
3
|
+
* (model-catalog phase 4). Rates are USD per million tokens (Mtok).
|
|
6
4
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* `
|
|
10
|
-
*
|
|
11
|
-
*
|
|
5
|
+
* There is no hand-maintained model list or price table any more: both come
|
|
6
|
+
* from the runtime catalog (`src/utils/runtime-model-catalog.ts` — the API's
|
|
7
|
+
* `model_catalog` + overlay rows, pulled over HTTP; the vendored models.dev
|
|
8
|
+
* snapshot offline). A new Claude model is listed and priced as soon as it
|
|
9
|
+
* lands in `model_catalog`, with no code change and no redeploy.
|
|
12
10
|
*
|
|
13
|
-
*
|
|
11
|
+
* The managed-agents API does NOT report dollar cost on the
|
|
12
|
+
* `span.model_request_end` event — only token counts. The adapter computes
|
|
13
|
+
* USD locally via {@link computeClaudeManagedCostUsd}, then folds in
|
|
14
|
+
* Anthropic's $0.08/session-hour runtime fee. The API server recomputes the
|
|
15
|
+
* canonical price against the pricing table.
|
|
14
16
|
*
|
|
15
17
|
* Cache nomenclature mapping:
|
|
16
|
-
* - `cache_read_input_tokens` →
|
|
17
|
-
* - `cache_creation_input_tokens` →
|
|
18
|
-
* - regular `input_tokens` (uncached) →
|
|
19
|
-
*
|
|
20
|
-
* Anthropic's pricing page lists 5-minute and 1-hour cache TTLs separately;
|
|
21
|
-
* managed-agents currently uses the 5-minute breakpoint by default, which is
|
|
22
|
-
* the rate captured here. If a future SDK release surfaces TTL on the usage
|
|
23
|
-
* payload, refine these by TTL.
|
|
18
|
+
* - `cache_read_input_tokens` → catalog `cache_read`
|
|
19
|
+
* - `cache_creation_input_tokens` → catalog `cache_write` (5-minute TTL)
|
|
20
|
+
* - regular `input_tokens` (uncached) → catalog `input`
|
|
24
21
|
*/
|
|
22
|
+
import { harnessModelIds } from "@desplega/model-catalog";
|
|
23
|
+
import { runtimeCatalogModel, runtimeCatalogSection } from "../utils/runtime-model-catalog";
|
|
25
24
|
|
|
26
|
-
/**
|
|
27
|
-
export
|
|
28
|
-
"claude-
|
|
29
|
-
|
|
30
|
-
"claude-opus-5-5",
|
|
31
|
-
"claude-opus-5",
|
|
32
|
-
"claude-fable-5",
|
|
33
|
-
"claude-mythos-5",
|
|
34
|
-
"claude-sonnet-5-5",
|
|
35
|
-
"claude-sonnet-5",
|
|
36
|
-
"claude-sonnet-4-6",
|
|
37
|
-
"claude-opus-4-8",
|
|
38
|
-
"claude-opus-4-7",
|
|
39
|
-
"claude-opus-4-6",
|
|
40
|
-
"claude-haiku-4-5",
|
|
41
|
-
] as const;
|
|
42
|
-
|
|
43
|
-
export type ClaudeManagedModel = (typeof CLAUDE_MANAGED_MODELS)[number];
|
|
25
|
+
/** Managed-agents-selectable Claude models from the catalog, newest first. */
|
|
26
|
+
export function listClaudeManagedModels(): string[] {
|
|
27
|
+
return harnessModelIds("claude-managed", runtimeCatalogSection("anthropic"));
|
|
28
|
+
}
|
|
44
29
|
|
|
45
|
-
/** Token rates per million tokens (USD). */
|
|
46
30
|
export interface ClaudeManagedTokenPricing {
|
|
47
31
|
/** USD per million uncached input tokens. */
|
|
48
32
|
inputPerMillion: number;
|
|
@@ -54,131 +38,39 @@ export interface ClaudeManagedTokenPricing {
|
|
|
54
38
|
cacheWritePerMillion: number;
|
|
55
39
|
}
|
|
56
40
|
|
|
57
|
-
|
|
58
|
-
export interface ClaudeManagedModelPricing extends ClaudeManagedTokenPricing {
|
|
59
|
-
scheduledChange?: {
|
|
60
|
-
/** ISO timestamp at which the replacement rates take effect. */
|
|
61
|
-
effectiveAt: string;
|
|
62
|
-
pricing: ClaudeManagedTokenPricing;
|
|
63
|
-
};
|
|
64
|
-
}
|
|
41
|
+
export type ClaudeManagedModelPricing = ClaudeManagedTokenPricing;
|
|
65
42
|
|
|
66
43
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* - claude-fable-5-1: $10 / $50 / $0.25 / $12.50 (verified 2026-09-02)
|
|
71
|
-
* - claude-mythos-5-1: $10 / $50 / $0.25 / $12.50 (invite only, verified 2026-09-02)
|
|
72
|
-
* - claude-fable-5: $10 / $50 / $1.00 / $12.50 (verified 2026-06-10)
|
|
73
|
-
* - claude-mythos-5: $10 / $50 / $1.00 / $12.50 (limited availability, verified 2026-06-10)
|
|
74
|
-
* - claude-opus-5-5: $4 / $20 / $0.20 / $5.00 (verified 2026-09-22)
|
|
75
|
-
* - claude-opus-5: $5 / $25 / $0.50 / $6.25 (verified 2026-07-25)
|
|
76
|
-
* - claude-sonnet-5-5: $2 / $10 / $0.20 / $2.50 (verified 2026-09-28)
|
|
77
|
-
* - claude-sonnet-5: $2 / $10 / $0.20 / $2.50 (standard rate, verified 2026-08-29)
|
|
78
|
-
* - claude-sonnet-4-6: $3 / $15 / $0.30 / $3.75 (in / out / cache-read / cache-write)
|
|
79
|
-
* - claude-opus-4-8: $5 / $25 / $0.50 / $6.25 (verified 2026-05-28)
|
|
80
|
-
* - claude-opus-4-7: $15 / $75 / $1.50 / $18.75 (STALE — was correct at launch, Anthropic has since dropped Opus to $5/$25)
|
|
81
|
-
* - claude-opus-4-6: $5 / $25 / $0.50 / $6.25 (verified 2026-05-28)
|
|
82
|
-
* - claude-haiku-4-5: $1 / $5 / $0.10 / $1.25
|
|
44
|
+
* Catalog pricing for a managed model. Dated ids fall back to their undated
|
|
45
|
+
* family id. Missing cache rates follow Anthropic's published multipliers
|
|
46
|
+
* (read = 0.1 × input, 5-minute write = 1.25 × input).
|
|
83
47
|
*/
|
|
84
|
-
export
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
"claude-opus-5-5": {
|
|
98
|
-
inputPerMillion: 4.0,
|
|
99
|
-
outputPerMillion: 20.0,
|
|
100
|
-
cacheReadPerMillion: 0.2,
|
|
101
|
-
cacheWritePerMillion: 5.0,
|
|
102
|
-
},
|
|
103
|
-
"claude-opus-5": {
|
|
104
|
-
inputPerMillion: 5.0,
|
|
105
|
-
outputPerMillion: 25.0,
|
|
106
|
-
cacheReadPerMillion: 0.5,
|
|
107
|
-
cacheWritePerMillion: 6.25,
|
|
108
|
-
},
|
|
109
|
-
"claude-fable-5": {
|
|
110
|
-
inputPerMillion: 10.0,
|
|
111
|
-
outputPerMillion: 50.0,
|
|
112
|
-
cacheReadPerMillion: 1.0,
|
|
113
|
-
cacheWritePerMillion: 12.5,
|
|
114
|
-
},
|
|
115
|
-
"claude-mythos-5": {
|
|
116
|
-
inputPerMillion: 10.0,
|
|
117
|
-
outputPerMillion: 50.0,
|
|
118
|
-
cacheReadPerMillion: 1.0,
|
|
119
|
-
cacheWritePerMillion: 12.5,
|
|
120
|
-
},
|
|
121
|
-
"claude-sonnet-5-5": {
|
|
122
|
-
inputPerMillion: 2.0,
|
|
123
|
-
outputPerMillion: 10.0,
|
|
124
|
-
cacheReadPerMillion: 0.2,
|
|
125
|
-
cacheWritePerMillion: 2.5,
|
|
126
|
-
},
|
|
127
|
-
"claude-sonnet-5": {
|
|
128
|
-
inputPerMillion: 2.0,
|
|
129
|
-
outputPerMillion: 10.0,
|
|
130
|
-
cacheReadPerMillion: 0.2,
|
|
131
|
-
cacheWritePerMillion: 2.5,
|
|
132
|
-
},
|
|
133
|
-
"claude-sonnet-4-6": {
|
|
134
|
-
inputPerMillion: 3.0,
|
|
135
|
-
outputPerMillion: 15.0,
|
|
136
|
-
cacheReadPerMillion: 0.3,
|
|
137
|
-
cacheWritePerMillion: 3.75,
|
|
138
|
-
},
|
|
139
|
-
"claude-opus-4-8": {
|
|
140
|
-
inputPerMillion: 5.0,
|
|
141
|
-
outputPerMillion: 25.0,
|
|
142
|
-
cacheReadPerMillion: 0.5,
|
|
143
|
-
cacheWritePerMillion: 6.25,
|
|
144
|
-
},
|
|
145
|
-
"claude-opus-4-7": {
|
|
146
|
-
inputPerMillion: 15.0,
|
|
147
|
-
outputPerMillion: 75.0,
|
|
148
|
-
cacheReadPerMillion: 1.5,
|
|
149
|
-
cacheWritePerMillion: 18.75,
|
|
150
|
-
},
|
|
151
|
-
"claude-opus-4-6": {
|
|
152
|
-
inputPerMillion: 5.0,
|
|
153
|
-
outputPerMillion: 25.0,
|
|
154
|
-
cacheReadPerMillion: 0.5,
|
|
155
|
-
cacheWritePerMillion: 6.25,
|
|
156
|
-
},
|
|
157
|
-
"claude-haiku-4-5": {
|
|
158
|
-
inputPerMillion: 1.0,
|
|
159
|
-
outputPerMillion: 5.0,
|
|
160
|
-
cacheReadPerMillion: 0.1,
|
|
161
|
-
cacheWritePerMillion: 1.25,
|
|
162
|
-
},
|
|
163
|
-
};
|
|
48
|
+
export function getClaudeManagedModelPricing(model: string): ClaudeManagedModelPricing | undefined {
|
|
49
|
+
const cost =
|
|
50
|
+
runtimeCatalogModel("anthropic", model)?.cost ??
|
|
51
|
+
runtimeCatalogModel("anthropic", model.replace(/-\d{8}$/, ""))?.cost;
|
|
52
|
+
if (typeof cost?.input !== "number" || typeof cost.output !== "number") return undefined;
|
|
53
|
+
return {
|
|
54
|
+
inputPerMillion: cost.input,
|
|
55
|
+
outputPerMillion: cost.output,
|
|
56
|
+
cacheReadPerMillion: typeof cost.cache_read === "number" ? cost.cache_read : cost.input * 0.1,
|
|
57
|
+
cacheWritePerMillion:
|
|
58
|
+
typeof cost.cache_write === "number" ? cost.cache_write : cost.input * 1.25,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
164
61
|
|
|
165
|
-
/**
|
|
166
|
-
* Models we've already warned about — keeps `console.warn` from spamming the
|
|
167
|
-
* worker logs when an old session keeps replaying through `span.model_request_end`
|
|
168
|
-
* events with an unrecognized model string.
|
|
169
|
-
*/
|
|
62
|
+
/** One warning per model per process for unpriced models. */
|
|
170
63
|
const warnedUnknownModels = new Set<string>();
|
|
171
64
|
|
|
172
65
|
/**
|
|
173
66
|
* Compute USD cost for one Claude managed-agents session, given the SDK's
|
|
174
67
|
* accumulated token counts.
|
|
175
68
|
*
|
|
176
|
-
* Returns `0` (with a deduplicated `console.warn`) for
|
|
177
|
-
* we'd rather under-report than make up a number on a typo.
|
|
69
|
+
* Returns `0` (with a deduplicated `console.warn`) for models the catalog does
|
|
70
|
+
* not price — we'd rather under-report than make up a number on a typo.
|
|
178
71
|
*
|
|
179
|
-
* Note: the runtime $0.08/session-hour fee is NOT folded in here
|
|
180
|
-
* computes
|
|
181
|
-
* `durationMs`, which is provider-state, not token-state.
|
|
72
|
+
* Note: the runtime $0.08/session-hour fee is NOT folded in here; the adapter
|
|
73
|
+
* computes it from the session's wallclock.
|
|
182
74
|
*/
|
|
183
75
|
export function computeClaudeManagedCostUsd(
|
|
184
76
|
model: string,
|
|
@@ -186,24 +78,18 @@ export function computeClaudeManagedCostUsd(
|
|
|
186
78
|
outputTokens: number,
|
|
187
79
|
cacheReadTokens: number,
|
|
188
80
|
cacheWriteTokens: number,
|
|
189
|
-
pricedAtMs: number = Date.now(),
|
|
190
81
|
): number {
|
|
191
|
-
const
|
|
192
|
-
if (!
|
|
82
|
+
const pricing = getClaudeManagedModelPricing(model);
|
|
83
|
+
if (!pricing) {
|
|
193
84
|
if (!warnedUnknownModels.has(model)) {
|
|
194
85
|
warnedUnknownModels.add(model);
|
|
195
86
|
console.warn(
|
|
196
|
-
`[claude-managed-models]
|
|
197
|
-
|
|
87
|
+
`[claude-managed-models] Unpriced model "${model}" — returning $0 cost. ` +
|
|
88
|
+
"Add it to the model catalog (refresh or overlay row).",
|
|
198
89
|
);
|
|
199
90
|
}
|
|
200
91
|
return 0;
|
|
201
92
|
}
|
|
202
|
-
const pricing =
|
|
203
|
-
configuredPricing.scheduledChange &&
|
|
204
|
-
pricedAtMs >= Date.parse(configuredPricing.scheduledChange.effectiveAt)
|
|
205
|
-
? configuredPricing.scheduledChange.pricing
|
|
206
|
-
: configuredPricing;
|
|
207
93
|
const inputCost = (inputTokens / 1_000_000) * pricing.inputPerMillion;
|
|
208
94
|
const outputCost = (outputTokens / 1_000_000) * pricing.outputPerMillion;
|
|
209
95
|
const cacheReadCost = (cacheReadTokens / 1_000_000) * pricing.cacheReadPerMillion;
|
|
@@ -558,16 +558,16 @@ export async function buildCodexConfig(
|
|
|
558
558
|
// at `~/.codex/config.toml` (Phase 6). Repeating them here makes local dev
|
|
559
559
|
// (no baseline file) behave identically to the Docker worker.
|
|
560
560
|
//
|
|
561
|
-
//
|
|
562
|
-
// the
|
|
563
|
-
//
|
|
561
|
+
// Keep ChatGPT apps/connectors disabled because their `codex_apps` tools use
|
|
562
|
+
// the worker's host OAuth identity. Hooks remain enabled for Codex steering
|
|
563
|
+
// and the installed context-mode plugin.
|
|
564
564
|
return {
|
|
565
565
|
model,
|
|
566
566
|
approval_policy: "never",
|
|
567
567
|
sandbox_mode: "danger-full-access",
|
|
568
568
|
skip_git_repo_check: true,
|
|
569
569
|
show_raw_agent_reasoning: false,
|
|
570
|
-
features: { hooks: true, plugin_hooks: true },
|
|
570
|
+
features: { apps: false, hooks: true, plugin_hooks: true },
|
|
571
571
|
mcp_servers: mcpServers as CodexConfig,
|
|
572
572
|
...reasoningConfig,
|
|
573
573
|
};
|