@desplega.ai/agent-swarm 1.129.0 → 1.131.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/README.md +2 -2
- package/dist/{actions-kfv2dawe.js → actions-w53mbns9.js} +11 -11
- package/dist/{anthropic-messages-3xgme8my.js → anthropic-messages-rjmd2e7n.js} +5 -5
- package/dist/{app-q8vjk6e8.js → app-m9gwqsqv.js} +8 -8
- package/dist/{artifact-hg4t1nx7.js → artifact-jysj3wrg.js} +2 -2
- package/dist/{assistant-g037r345.js → assistant-bp65m6f3.js} +13 -13
- package/dist/{azure-openai-responses-xa4sh9f6.js → azure-openai-responses-c0yjmbfd.js} +8 -5
- package/dist/{boot-reembed-18pzsrxa.js → boot-reembed-62p0at2k.js} +6 -6
- package/dist/{boot-reembed-wpks2cj8.js → boot-reembed-xmfp6wdh.js} +7 -7
- package/dist/{boot-scrub-logs-n7szd57r.js → boot-scrub-logs-rr8q2dms.js} +5 -5
- package/dist/{claude-adapter-qz4r0ajt.js → claude-adapter-2y47mrkd.js} +9 -9
- package/dist/{cli-mhjnbgb6.js → cli-0rcyq6d9.js} +450 -186
- package/dist/{cli-ttkmehy0.js → cli-2q72qz2s.js} +274 -25
- package/dist/{cli-gztgc3hz.js → cli-2wadx7p2.js} +2 -2
- package/dist/cli-3fj60etf.js +153 -0
- package/dist/{cli-7ecgm5v0.js → cli-3kf51j15.js} +1 -1
- package/dist/{cli-vgexpfsr.js → cli-57khth04.js} +6 -3
- package/dist/{cli-2mbe7vk0.js → cli-5dsbcjjw.js} +1 -1
- package/dist/{cli-etr62zy6.js → cli-5kx36evn.js} +2 -2
- package/dist/{cli-v2tr6amf.js → cli-5n6e5yfn.js} +30 -8
- package/dist/{cli-hx02s9zq.js → cli-5v4rw6yd.js} +2 -2
- package/dist/{cli-v37yr6mf.js → cli-5ze9rv97.js} +4 -4
- package/dist/{cli-ch7t5v7n.js → cli-6map995v.js} +9 -4
- package/dist/{cli-h0457a67.js → cli-70xqj0z3.js} +3 -3
- package/dist/{cli-kk4f9r17.js → cli-72q8m8gk.js} +8 -6
- package/dist/{cli-7padk69a.js → cli-78xwvkhj.js} +2 -2
- package/dist/{cli-dxtxacy7.js → cli-9dr5qzc0.js} +45 -8
- package/dist/{cli-17zxdgsq.js → cli-a40rnf71.js} +6 -6
- package/dist/{cli-t53vnnxz.js → cli-a4jzdpa3.js} +2514 -1055
- package/dist/{cli-w10fkrf1.js → cli-akdvwc9v.js} +354 -115
- package/dist/{cli-1qkk5er0.js → cli-bmze986d.js} +1 -1
- package/dist/{cli-ga12dc1d.js → cli-bqw0mt1n.js} +3 -3
- package/dist/{cli-0sf92efp.js → cli-cdeg08wx.js} +1 -1
- package/dist/{cli-a8ynhkyj.js → cli-cvgjwnh1.js} +17 -15
- package/dist/{cli-9fxg3v5m.js → cli-d2tfkcga.js} +4 -4
- package/dist/{cli-nhcd7x43.js → cli-d3x3x1c9.js} +2 -2
- package/dist/{cli-6nh2qxvh.js → cli-darcwax3.js} +1 -1
- package/dist/{cli-yjbgmysx.js → cli-e7ckcg4v.js} +12 -12
- package/dist/{cli-4n2gcjpd.js → cli-efxfnq6q.js} +4 -3
- package/dist/{cli-z9xqqhfk.js → cli-er3a4bb0.js} +1 -1
- package/dist/{cli-xg2eezyv.js → cli-f1am9szv.js} +1 -1
- package/dist/{cli-xy4cwsm9.js → cli-fywms69x.js} +1 -1
- package/dist/{cli-33jj76y8.js → cli-g6b8x1h8.js} +1 -1
- package/dist/{cli-epsvdckx.js → cli-gm9cbhbq.js} +20 -10
- package/dist/{cli-rkndnn90.js → cli-k9qkf1hw.js} +6 -4
- package/dist/{cli-zejvt395.js → cli-kh3ba2zf.js} +1 -1
- package/dist/{cli-gb25p1h2.js → cli-nm5gtp1x.js} +2 -2
- package/dist/{cli-akxnpx17.js → cli-pm6xbh84.js} +1829 -1629
- package/dist/{cli-2k0ztbfp.js → cli-psh3c4va.js} +1 -1
- package/dist/{cli-39vgrsep.js → cli-qv61hp37.js} +2 -2
- package/dist/{cli-hv2fndhm.js → cli-r6kqqbj0.js} +6 -4
- package/dist/{cli-1y1cm570.js → cli-rzbpmxdr.js} +1 -1
- package/dist/{cli-mmrk00vp.js → cli-t1xze5qh.js} +1 -1
- package/dist/{cli-g252a9ky.js → cli-t55yw3a1.js} +2 -2
- package/dist/{cli-7bz8dzqa.js → cli-t76vw5db.js} +1184 -1522
- package/dist/{cli-4n4mdv21.js → cli-xpxde7rm.js} +7 -3
- package/dist/{cli-fpaa5k2q.js → cli-yw8vghx2.js} +54 -18
- package/dist/cli-zsspvvm2.js +490 -0
- package/dist/cli.js +27 -25
- package/dist/{codex-adapter-7v6t7ff6.js → codex-adapter-d24q75wk.js} +7 -7
- package/dist/{codex-hook-amndawyb.js → codex-hook-hq54t9ft.js} +2 -2
- package/dist/{codex-session-runner-e7j4khe2.js → codex-session-runner-g50vcsex.js} +7 -7
- package/dist/{commands-ex0k5tbf.js → commands-c3nrc5hg.js} +5 -5
- package/dist/{db-df7jatfc.js → db-nt7fg3tw.js} +5 -5
- package/dist/{google-generative-ai-y42hnw9p.js → google-generative-ai-hysrd8qx.js} +7 -5
- package/dist/{google-vertex-4sg66gb6.js → google-vertex-p5arrga0.js} +7 -5
- package/dist/{handlers-1j2cfqt2.js → handlers-fkr6swat.js} +13 -13
- package/dist/{hook-nx9a0mj3.js → hook-77wpvnjc.js} +7 -7
- package/dist/{hook-w6yaf6sy.js → hook-g019yehy.js} +8 -8
- package/dist/{http-4tz5h8wg.js → http-jewj0syk.js} +2993 -716
- package/dist/{index-0bpkzb09.js → index-070v4eyb.js} +3 -3
- package/dist/{index-0s67qv7h.js → index-6gm5he8h.js} +11 -11
- package/dist/{index-35gtv6gj.js → index-7n2xpbd4.js} +310 -40
- package/dist/{index-ker3gccb.js → index-9znhar3x.js} +4 -4
- package/dist/{index-5n2c8yay.js → index-hase6zbe.js} +2 -2
- package/dist/{index-kcf3tm9h.js → index-hfvggd0z.js} +12 -12
- package/dist/{index-7c0jqna0.js → index-hp1kdbjj.js} +13 -13
- package/dist/{keepalive-3j4a9168.js → keepalive-j0fjvqfd.js} +7 -7
- package/dist/{lead-6kpevymb.js → lead-1n8x30xe.js} +33 -33
- package/dist/{maintenance-m1k82ean.js → maintenance-gvev11sa.js} +7 -7
- package/dist/{mistral-conversations-bjkdfb6z.js → mistral-conversations-81fwav0j.js} +6 -6
- package/dist/{oauth-refresh-sweep-881k8e4q.js → oauth-refresh-sweep-s9ecsvh0.js} +6 -6
- package/dist/{onboard-c0ykffjn.js → onboard-pvm5b38w.js} +2 -2
- package/dist/{openai-codex-responses-xetseqvt.js → openai-codex-responses-5g27pd6f.js} +43 -23
- package/dist/{openai-completions-5r2g5axa.js → openai-completions-3vkmfz2a.js} +55 -11
- package/dist/{openai-responses-ce67hd23.js → openai-responses-dg4t7j7a.js} +8 -5
- package/dist/{openrouter-images-pzfp22jb.js → openrouter-images-g3gm8931.js} +1 -1
- package/dist/{otel-impl-sqagjerv.js → otel-impl-p6jvgd9c.js} +6 -4
- package/dist/{otel-3mp81ppd.js → otel-nqa12wf3.js} +2 -2
- package/dist/{pi-mono-adapter-k584k16g.js → pi-mono-adapter-t091s27g.js} +17117 -7517
- package/dist/{pricing-refresh-y82whbf9.js → pricing-refresh-k49rcyed.js} +7 -7
- package/dist/{rbac-roles-nvkqmzyd.js → rbac-roles-30pspvy7.js} +7 -7
- package/dist/{rbac-roles-4ht8gegc.js → rbac-roles-cr80g96t.js} +6 -6
- package/dist/{render-v2-wvqdgvvp.js → render-v2-xm457ng1.js} +8 -8
- package/dist/{seed-pricing-fy3rxhde.js → seed-pricing-yhpv35fr.js} +6 -6
- package/dist/{setup-ak5cnc6f.js → setup-nytnmwwr.js} +2 -2
- package/dist/{worker-d8769q8a.js → worker-msytr2cw.js} +33 -33
- package/openapi.json +34039 -11036
- package/package.json +8 -6
- package/src/apps/definition.ts +368 -26
- package/src/apps/row-store.ts +66 -10
- package/src/apps/schema-migrate.ts +95 -1
- package/src/apps/store.ts +13 -4
- package/src/apps/sync-run-as.ts +18 -0
- package/src/apps/sync.ts +934 -0
- package/src/apps/version.ts +16 -2
- package/src/assets/key.ts +8 -1
- package/src/be/asset-key-audit.ts +3 -1
- package/src/be/db-queries/mcp-oauth.ts +297 -24
- package/src/be/db.ts +42 -1
- package/src/be/migrations/129_asset_keys_apps_scripts.sql +161 -0
- package/src/be/scripts/db.ts +5 -2
- package/src/be/scripts/typecheck.ts +1 -0
- package/src/be/seed-scripts/catalog/app-sync-run.ts +32 -0
- package/src/be/seed-scripts/catalog/github-issues-pull.ts +102 -0
- package/src/be/seed-scripts/index.ts +18 -0
- package/src/be/seed-skills/index.ts +7 -0
- package/src/http/active-sessions.ts +26 -18
- package/src/http/agents.ts +94 -27
- package/src/http/api-keys.ts +91 -17
- package/src/http/approval-requests.ts +87 -10
- package/src/http/apps.ts +361 -53
- package/src/http/assets.ts +165 -31
- package/src/http/budgets.ts +7 -5
- package/src/http/codex-oauth-keep-warm.ts +21 -3
- package/src/http/config.ts +46 -16
- package/src/http/context.ts +33 -6
- package/src/http/ecosystem.ts +20 -6
- package/src/http/events.ts +24 -9
- package/src/http/favorites.ts +20 -6
- package/src/http/fs.ts +60 -17
- package/src/http/heartbeat.ts +18 -4
- package/src/http/inbox-state.ts +12 -6
- package/src/http/integrations.ts +25 -5
- package/src/http/kv.ts +36 -15
- package/src/http/mcp-bridge.ts +5 -1
- package/src/http/mcp-oauth.ts +332 -17
- package/src/http/mcp-servers.ts +56 -18
- package/src/http/memory.ts +282 -29
- package/src/http/metrics.ts +80 -17
- package/src/http/oauth-callback.ts +10 -4
- package/src/http/oauth-generic.ts +5 -1
- package/src/http/oauth-locks.ts +6 -3
- package/src/http/openapi.ts +57 -9
- package/src/http/page-proxy.ts +25 -5
- package/src/http/pages-public.ts +37 -20
- package/src/http/pages.ts +93 -28
- package/src/http/poll.ts +89 -5
- package/src/http/pricing.ts +9 -6
- package/src/http/prompt-templates.ts +85 -21
- package/src/http/route-def.ts +67 -4
- package/src/http/schedules.ts +63 -14
- package/src/http/script-connection-proxy.ts +30 -4
- package/src/http/script-connections.ts +393 -43
- package/src/http/script-runs.ts +73 -19
- package/src/http/scripts.ts +257 -39
- package/src/http/session-data.ts +87 -14
- package/src/http/sessions.ts +80 -5
- package/src/http/skills.ts +115 -35
- package/src/http/stats.ts +94 -13
- package/src/http/task-templates.ts +6 -4
- package/src/http/tasks.ts +230 -61
- package/src/http/trackers/jira.ts +90 -30
- package/src/http/trackers/linear.ts +46 -12
- package/src/http/users.ts +162 -25
- package/src/http/utils.ts +12 -2
- package/src/http/webhooks.ts +30 -16
- package/src/http/workflow-events.ts +18 -5
- package/src/http/workflows.ts +128 -39
- package/src/http/x.ts +37 -6
- package/src/oauth/ensure-mcp-token.ts +16 -1
- package/src/oauth/mcp-wrapper.ts +281 -26
- package/src/providers/pi-mono-adapter.ts +1 -1
- package/src/scripts-runtime/credential-broker/README.md +1 -1
- package/src/scripts-runtime/credential-broker/fetch-patch.ts +12 -2
- package/src/scripts-runtime/sdk-allowlist.ts +1 -0
- package/src/scripts-runtime/stdlib/fetch.ts +6 -0
- package/src/scripts-runtime/types/stdlib.d.ts +1 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -0
- package/src/server.ts +2 -0
- package/src/tests/apps-rbac.test.ts +110 -0
- package/src/tests/apps-spike2.test.ts +4 -1
- package/src/tests/apps-sync-engine.test.ts +2540 -0
- package/src/tests/apps-sync.test.ts +1627 -0
- package/src/tests/asset-key-api.test.ts +48 -2
- package/src/tests/asset-key-invariants.test.ts +92 -0
- package/src/tests/asset-key-migration.test.ts +174 -8
- package/src/tests/asset-key-normalization.test.ts +2 -0
- package/src/tests/credential-broker.test.ts +27 -2
- package/src/tests/mcp-oauth-dcr-reuse.test.ts +743 -0
- package/src/tests/mcp-oauth-ensure-token.test.ts +45 -0
- package/src/tests/mcp-oauth-manual-client.test.ts +135 -2
- package/src/tests/mcp-oauth-queries.test.ts +153 -0
- package/src/tests/mcp-oauth-wrapper.test.ts +432 -0
- package/src/tests/memory-http-recall-gating.test.ts +2 -0
- package/src/tests/openapi-response-contract.test.ts +138 -0
- package/src/tests/rbac-admission-e2e.test.ts +68 -0
- package/src/tests/script-connections.test.ts +3 -0
- package/src/tests/scripts-runtime-fetch.test.ts +121 -0
- package/src/tests/scripts-runtime-secret-egress.test.ts +4 -2
- package/src/tests/seed-scripts.test.ts +2 -2
- package/src/tests/swarm-tool-result-gate.test.ts +32 -0
- package/src/tests/task-working-dir.test.ts +8 -4
- package/src/tests/whoami-route.test.ts +127 -0
- package/src/tests/workflow-engine-v2.test.ts +80 -7
- package/src/tests/workflow-swarm-script.test.ts +104 -0
- package/src/tools/app-get.ts +10 -2
- package/src/tools/app-rollback.ts +1 -0
- package/src/tools/app-sync.ts +112 -0
- package/src/tools/script-common.ts +20 -0
- package/src/tools/tool-config.ts +2 -1
- package/src/tools/utils.ts +11 -0
- package/src/tools/workflows/create-workflow.ts +4 -1
- package/src/types.ts +1394 -1206
- package/src/utils/template.ts +8 -1
- package/src/utils/zod-openapi.ts +11 -0
- package/src/workflows/engine.ts +27 -4
- package/src/workflows/executors/swarm-script.ts +28 -0
- package/src/workflows/retry-poller.ts +19 -2
- package/templates/skills/apps/content.md +94 -5
- package/templates/skills/asset-namespaces/content.md +2 -2
- package/templates/skills/scheduled-task-resilience/SKILL.md +102 -0
- package/templates/skills/scheduled-task-resilience/config.json +14 -0
- package/templates/skills/scheduled-task-resilience/content.md +97 -0
- package/dist/cli-7wmybrt5.js +0 -115
- package/dist/cli-d91pvmq1.js +0 -14
package/src/http/tasks.ts
CHANGED
|
@@ -44,7 +44,9 @@ import { createTaskWithSiblingAwareness } from "../tasks/sibling-awareness";
|
|
|
44
44
|
import { guardTerminalTaskResultWrite } from "../tasks/terminal-result-guard";
|
|
45
45
|
import { createResumeFollowUp, createWorkerTaskFollowUp } from "../tasks/worker-follow-up";
|
|
46
46
|
import {
|
|
47
|
+
AgentLogSchema,
|
|
47
48
|
type AgentTask,
|
|
49
|
+
AgentTaskSchema,
|
|
48
50
|
type AgentTaskSource,
|
|
49
51
|
AgentTaskSourceSchema,
|
|
50
52
|
type AgentTaskStatus,
|
|
@@ -56,14 +58,106 @@ import {
|
|
|
56
58
|
ProviderNameSchema,
|
|
57
59
|
ReasoningEffortSchema,
|
|
58
60
|
ResumeReasonSchema,
|
|
61
|
+
SteeringMessageSchema,
|
|
59
62
|
SteeringSourceSchema,
|
|
60
63
|
SteerModeSchema,
|
|
64
|
+
SteerResultSchema,
|
|
61
65
|
splitLegacyModelAlias,
|
|
66
|
+
TaskAttachmentSchema,
|
|
62
67
|
} from "../types";
|
|
63
68
|
import { getRequestAuth } from "../utils/request-auth-context";
|
|
64
69
|
import { scrubSecrets } from "../utils/secret-scrubber";
|
|
65
70
|
import { route } from "./route-def";
|
|
66
|
-
import {
|
|
71
|
+
import { jsonError, parseBody } from "./utils";
|
|
72
|
+
|
|
73
|
+
// ─── Response Schemas ────────────────────────────────────────────────────────
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* `/api/tasks` + `/api/sessions` list item shape — mirrors the `AgentTaskSummary`
|
|
77
|
+
* TS type in ../types (a strict field subset of `AgentTask`): the `task` text
|
|
78
|
+
* truncated to a bounded preview and completion/integration/context blobs
|
|
79
|
+
* dropped. Kept in lock-step with that type's `Pick<...>` field list.
|
|
80
|
+
*/
|
|
81
|
+
const AgentTaskSummarySchema = AgentTaskSchema.pick({
|
|
82
|
+
id: true,
|
|
83
|
+
key: true,
|
|
84
|
+
agentId: true,
|
|
85
|
+
creatorAgentId: true,
|
|
86
|
+
task: true,
|
|
87
|
+
title: true,
|
|
88
|
+
status: true,
|
|
89
|
+
source: true,
|
|
90
|
+
taskType: true,
|
|
91
|
+
tags: true,
|
|
92
|
+
priority: true,
|
|
93
|
+
dependsOn: true,
|
|
94
|
+
offeredTo: true,
|
|
95
|
+
acceptedAt: true,
|
|
96
|
+
parentTaskId: true,
|
|
97
|
+
scheduleId: true,
|
|
98
|
+
model: true,
|
|
99
|
+
modelTier: true,
|
|
100
|
+
effort: true,
|
|
101
|
+
provider: true,
|
|
102
|
+
requestedByUserId: true,
|
|
103
|
+
progress: true,
|
|
104
|
+
createdAt: true,
|
|
105
|
+
lastUpdatedAt: true,
|
|
106
|
+
finishedAt: true,
|
|
107
|
+
peakContextPercent: true,
|
|
108
|
+
totalCostUsd: true,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
/** Shared by cancel/pause/resume — each sends `{ success: true, task }` on success. */
|
|
112
|
+
const TaskActionResultSchema = z.object({
|
|
113
|
+
success: z.literal(true),
|
|
114
|
+
task: AgentTaskSchema,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
/** Shared by the steering-message delivered/handled callbacks — `{ message }`. */
|
|
118
|
+
const SteeringMessageEnvelopeSchema = z.object({ message: SteeringMessageSchema });
|
|
119
|
+
|
|
120
|
+
/** Shared by the steering-message list routes — `{ messages }`. */
|
|
121
|
+
const SteeringMessagesListSchema = z.object({ messages: z.array(SteeringMessageSchema) });
|
|
122
|
+
|
|
123
|
+
/** `POST /api/steering-messages/{id}/undeliverable` — promotion result. */
|
|
124
|
+
const SteeringUndeliverableResponseSchema = z.object({
|
|
125
|
+
message: SteeringMessageSchema,
|
|
126
|
+
promotedTaskId: z.string().optional(),
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
/** `GET /api/tasks/{id}` — full task decorated with steering + logs + attachments. */
|
|
130
|
+
const GetTaskResponseSchema = AgentTaskSchema.extend({
|
|
131
|
+
isLeadTask: z.boolean(),
|
|
132
|
+
supportedSteerModes: z.array(SteerModeSchema),
|
|
133
|
+
logs: z.array(AgentLogSchema),
|
|
134
|
+
attachments: z.array(TaskAttachmentSchema),
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const FinishTaskSuccessSchema = z.object({
|
|
138
|
+
success: z.literal(true),
|
|
139
|
+
alreadyFinished: z.boolean(),
|
|
140
|
+
task: AgentTaskSchema,
|
|
141
|
+
message: z.string().optional(),
|
|
142
|
+
wasNoOp: z.literal(true).optional(),
|
|
143
|
+
wasForcedOverwrite: z.literal(true).optional(),
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const FinishTaskConflictSchema = z.object({
|
|
147
|
+
success: z.literal(false),
|
|
148
|
+
message: z.string(),
|
|
149
|
+
task: AgentTaskSchema,
|
|
150
|
+
alreadyFinished: z.literal(true),
|
|
151
|
+
error: z.string(),
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const SupersedeTaskResponseSchema = z.object({
|
|
155
|
+
success: z.literal(true),
|
|
156
|
+
kind: z.enum(["alreadyFinished", "workflow-failed", "resumed"]),
|
|
157
|
+
task: AgentTaskSchema.nullable(),
|
|
158
|
+
resumeTaskId: z.string().nullable(),
|
|
159
|
+
resumeTaskStatus: AgentTaskStatusSchema.optional(),
|
|
160
|
+
});
|
|
67
161
|
|
|
68
162
|
// ─── Route Definitions ───────────────────────────────────────────────────────
|
|
69
163
|
|
|
@@ -104,7 +198,13 @@ const listTasks = route({
|
|
|
104
198
|
fields: z.enum(["full", "slim"]).optional(),
|
|
105
199
|
}),
|
|
106
200
|
responses: {
|
|
107
|
-
200: {
|
|
201
|
+
200: {
|
|
202
|
+
description: "Paginated task list",
|
|
203
|
+
schema: z.object({
|
|
204
|
+
tasks: z.union([z.array(AgentTaskSchema), z.array(AgentTaskSummarySchema)]),
|
|
205
|
+
total: z.number().int(),
|
|
206
|
+
}),
|
|
207
|
+
},
|
|
108
208
|
400: { description: "Validation error (e.g. unknown status token)" },
|
|
109
209
|
},
|
|
110
210
|
});
|
|
@@ -135,7 +235,7 @@ const createTask = route({
|
|
|
135
235
|
effort: ReasoningEffortSchema.optional(),
|
|
136
236
|
}),
|
|
137
237
|
responses: {
|
|
138
|
-
201: { description: "Task created" },
|
|
238
|
+
201: { description: "Task created", schema: AgentTaskSchema },
|
|
139
239
|
400: { description: "Validation error" },
|
|
140
240
|
},
|
|
141
241
|
});
|
|
@@ -168,7 +268,7 @@ const updateSession = route({
|
|
|
168
268
|
}),
|
|
169
269
|
]),
|
|
170
270
|
responses: {
|
|
171
|
-
200: { description: "Session ID updated" },
|
|
271
|
+
200: { description: "Session ID updated", schema: AgentTaskSchema },
|
|
172
272
|
404: { description: "Task not found" },
|
|
173
273
|
},
|
|
174
274
|
});
|
|
@@ -181,7 +281,7 @@ const cancelTaskRoute = route({
|
|
|
181
281
|
tags: ["Tasks"],
|
|
182
282
|
params: z.object({ id: z.string() }),
|
|
183
283
|
responses: {
|
|
184
|
-
200: { description: "Task cancelled" },
|
|
284
|
+
200: { description: "Task cancelled", schema: TaskActionResultSchema },
|
|
185
285
|
400: { description: "Cannot cancel terminal task" },
|
|
186
286
|
404: { description: "Task not found" },
|
|
187
287
|
},
|
|
@@ -206,7 +306,10 @@ const steerTaskRoute = route({
|
|
|
206
306
|
}),
|
|
207
307
|
rbac: { permission: "task.steer.own" },
|
|
208
308
|
responses: {
|
|
209
|
-
200: {
|
|
309
|
+
200: {
|
|
310
|
+
description: "Steering accepted (see `outcome` for what actually happened)",
|
|
311
|
+
schema: SteerResultSchema,
|
|
312
|
+
},
|
|
210
313
|
400: { description: "Validation error" },
|
|
211
314
|
403: { description: "Caller cannot steer this task" },
|
|
212
315
|
404: { description: "Task not found" },
|
|
@@ -224,7 +327,7 @@ const getTaskSteeringMessagesRoute = route({
|
|
|
224
327
|
tags: ["Tasks"],
|
|
225
328
|
params: z.object({ id: z.string() }),
|
|
226
329
|
responses: {
|
|
227
|
-
200: { description: "Steering messages" },
|
|
330
|
+
200: { description: "Steering messages", schema: SteeringMessagesListSchema },
|
|
228
331
|
404: { description: "Task not found" },
|
|
229
332
|
},
|
|
230
333
|
});
|
|
@@ -238,7 +341,7 @@ const getPendingSteeringMessagesRoute = route({
|
|
|
238
341
|
query: z.object({ taskId: z.string().optional() }),
|
|
239
342
|
auth: { apiKey: true, agentId: true },
|
|
240
343
|
responses: {
|
|
241
|
-
200: { description: "Pending steering messages" },
|
|
344
|
+
200: { description: "Pending steering messages", schema: SteeringMessagesListSchema },
|
|
242
345
|
400: { description: "Missing X-Agent-ID header" },
|
|
243
346
|
404: { description: "Agent not found" },
|
|
244
347
|
},
|
|
@@ -258,7 +361,10 @@ const markSteeringDeliveredRoute = route({
|
|
|
258
361
|
"worker callback scoped by required X-Agent-ID and verified against the steering message task assignee",
|
|
259
362
|
},
|
|
260
363
|
responses: {
|
|
261
|
-
200: {
|
|
364
|
+
200: {
|
|
365
|
+
description: "Steering message delivery recorded",
|
|
366
|
+
schema: SteeringMessageEnvelopeSchema,
|
|
367
|
+
},
|
|
262
368
|
400: { description: "Missing X-Agent-ID header or validation error" },
|
|
263
369
|
403: { description: "Steering message task is assigned to another agent" },
|
|
264
370
|
404: { description: "Agent or steering message not found" },
|
|
@@ -280,7 +386,10 @@ const markSteeringHandledRoute = route({
|
|
|
280
386
|
"worker acknowledgement scoped by required X-Agent-ID and verified against the steering message task assignee",
|
|
281
387
|
},
|
|
282
388
|
responses: {
|
|
283
|
-
200: {
|
|
389
|
+
200: {
|
|
390
|
+
description: "Steering message acknowledgement recorded",
|
|
391
|
+
schema: SteeringMessageEnvelopeSchema,
|
|
392
|
+
},
|
|
284
393
|
400: { description: "Missing X-Agent-ID header or validation error" },
|
|
285
394
|
403: { description: "Steering message task is assigned to another agent" },
|
|
286
395
|
404: { description: "Agent or steering message not found" },
|
|
@@ -301,7 +410,10 @@ const markSteeringUndeliverableRoute = route({
|
|
|
301
410
|
"worker callback scoped by required X-Agent-ID and verified against the steering message task assignee",
|
|
302
411
|
},
|
|
303
412
|
responses: {
|
|
304
|
-
200: {
|
|
413
|
+
200: {
|
|
414
|
+
description: "Steering message promoted to a follow-up task",
|
|
415
|
+
schema: SteeringUndeliverableResponseSchema,
|
|
416
|
+
},
|
|
305
417
|
400: { description: "Missing X-Agent-ID header or validation error" },
|
|
306
418
|
403: { description: "Steering message task is assigned to another agent" },
|
|
307
419
|
404: { description: "Agent or steering message not found" },
|
|
@@ -322,7 +434,7 @@ const getTask = route({
|
|
|
322
434
|
logsLimit: z.coerce.number().int().min(1).max(1000).optional(),
|
|
323
435
|
}),
|
|
324
436
|
responses: {
|
|
325
|
-
200: { description: "Task with logs and attachments" },
|
|
437
|
+
200: { description: "Task with logs and attachments", schema: GetTaskResponseSchema },
|
|
326
438
|
404: { description: "Task not found" },
|
|
327
439
|
},
|
|
328
440
|
});
|
|
@@ -336,7 +448,7 @@ const updateTaskProgressRoute = route({
|
|
|
336
448
|
params: z.object({ id: z.string() }),
|
|
337
449
|
body: z.object({ progress: z.string().min(1) }),
|
|
338
450
|
responses: {
|
|
339
|
-
200: { description: "Progress updated" },
|
|
451
|
+
200: { description: "Progress updated", schema: z.object({ success: z.literal(true) }) },
|
|
340
452
|
404: { description: "Task not found" },
|
|
341
453
|
},
|
|
342
454
|
});
|
|
@@ -356,11 +468,14 @@ const finishTask = route({
|
|
|
356
468
|
}),
|
|
357
469
|
auth: { apiKey: true, agentId: true },
|
|
358
470
|
responses: {
|
|
359
|
-
200: { description: "Task finished" },
|
|
471
|
+
200: { description: "Task finished", schema: FinishTaskSuccessSchema },
|
|
360
472
|
400: { description: "Invalid status" },
|
|
361
473
|
403: { description: "Not assigned to this agent" },
|
|
362
474
|
404: { description: "Task not found" },
|
|
363
|
-
409: {
|
|
475
|
+
409: {
|
|
476
|
+
description: "Differing terminal result text was discarded",
|
|
477
|
+
schema: FinishTaskConflictSchema,
|
|
478
|
+
},
|
|
364
479
|
},
|
|
365
480
|
});
|
|
366
481
|
|
|
@@ -372,7 +487,10 @@ const listPausedTasks = route({
|
|
|
372
487
|
tags: ["Tasks"],
|
|
373
488
|
auth: { apiKey: true, agentId: true },
|
|
374
489
|
responses: {
|
|
375
|
-
200: {
|
|
490
|
+
200: {
|
|
491
|
+
description: "Paused task list",
|
|
492
|
+
schema: z.object({ tasks: z.array(AgentTaskSchema) }),
|
|
493
|
+
},
|
|
376
494
|
},
|
|
377
495
|
});
|
|
378
496
|
|
|
@@ -384,7 +502,7 @@ const pauseTaskRoute = route({
|
|
|
384
502
|
tags: ["Tasks"],
|
|
385
503
|
params: z.object({ id: z.string() }),
|
|
386
504
|
responses: {
|
|
387
|
-
200: { description: "Task paused" },
|
|
505
|
+
200: { description: "Task paused", schema: TaskActionResultSchema },
|
|
388
506
|
400: { description: "Task not in_progress" },
|
|
389
507
|
403: { description: "Task belongs to another agent" },
|
|
390
508
|
404: { description: "Task not found" },
|
|
@@ -399,7 +517,7 @@ const resumeTaskRoute = route({
|
|
|
399
517
|
tags: ["Tasks"],
|
|
400
518
|
params: z.object({ id: z.string() }),
|
|
401
519
|
responses: {
|
|
402
|
-
200: { description: "Task resumed" },
|
|
520
|
+
200: { description: "Task resumed", schema: TaskActionResultSchema },
|
|
403
521
|
400: { description: "Task not paused" },
|
|
404
522
|
403: { description: "Task belongs to another agent" },
|
|
405
523
|
404: { description: "Task not found" },
|
|
@@ -418,7 +536,10 @@ const supersedeTaskRoute = route({
|
|
|
418
536
|
body: z.object({ reason: ResumeReasonSchema }),
|
|
419
537
|
auth: { apiKey: true, agentId: true },
|
|
420
538
|
responses: {
|
|
421
|
-
200: {
|
|
539
|
+
200: {
|
|
540
|
+
description: "Task superseded (or workflow-failed)",
|
|
541
|
+
schema: SupersedeTaskResponseSchema,
|
|
542
|
+
},
|
|
422
543
|
400: { description: "Task not in_progress" },
|
|
423
544
|
403: { description: "Task belongs to another agent" },
|
|
424
545
|
404: { description: "Task not found" },
|
|
@@ -439,7 +560,7 @@ const updateTaskVcsRoute = route({
|
|
|
439
560
|
vcsUrl: z.string().url(),
|
|
440
561
|
}),
|
|
441
562
|
responses: {
|
|
442
|
-
200: { description: "VCS info updated" },
|
|
563
|
+
200: { description: "VCS info updated", schema: AgentTaskSchema },
|
|
443
564
|
404: { description: "Task not found" },
|
|
444
565
|
},
|
|
445
566
|
auth: { apiKey: true },
|
|
@@ -458,7 +579,7 @@ const updateTaskTitleRoute = route({
|
|
|
458
579
|
title: z.string().trim().max(120).nullable(),
|
|
459
580
|
}),
|
|
460
581
|
responses: {
|
|
461
|
-
200: { description: "Title updated" },
|
|
582
|
+
200: { description: "Title updated", schema: z.object({ task: AgentTaskSchema }) },
|
|
462
583
|
404: { description: "Task not found" },
|
|
463
584
|
},
|
|
464
585
|
auth: { apiKey: true },
|
|
@@ -576,7 +697,7 @@ export async function handleTasks(
|
|
|
576
697
|
const tasks =
|
|
577
698
|
parsed.query.fields === "full" ? getAllTasks(filters) : getAllTasks(filters, { slim: true });
|
|
578
699
|
const total = getTasksCount(filters);
|
|
579
|
-
|
|
700
|
+
listTasks.respond(res, 200, { tasks, total });
|
|
580
701
|
return true;
|
|
581
702
|
}
|
|
582
703
|
|
|
@@ -671,7 +792,7 @@ export async function handleTasks(
|
|
|
671
792
|
},
|
|
672
793
|
});
|
|
673
794
|
|
|
674
|
-
|
|
795
|
+
createTask.respond(res, 201, task);
|
|
675
796
|
} catch (error) {
|
|
676
797
|
console.error("[HTTP] Failed to create task:", error);
|
|
677
798
|
jsonError(res, "Failed to create task", 500);
|
|
@@ -695,7 +816,7 @@ export async function handleTasks(
|
|
|
695
816
|
jsonError(res, "Task not found", 404);
|
|
696
817
|
return true;
|
|
697
818
|
}
|
|
698
|
-
|
|
819
|
+
updateSession.respond(res, 200, task);
|
|
699
820
|
return true;
|
|
700
821
|
}
|
|
701
822
|
|
|
@@ -783,7 +904,7 @@ export async function handleTasks(
|
|
|
783
904
|
updateAgentStatusFromCapacity(task.agentId);
|
|
784
905
|
}
|
|
785
906
|
|
|
786
|
-
|
|
907
|
+
cancelTaskRoute.respond(res, 200, { success: true, task: cancelledTask });
|
|
787
908
|
return true;
|
|
788
909
|
}
|
|
789
910
|
|
|
@@ -830,7 +951,7 @@ export async function handleTasks(
|
|
|
830
951
|
createdByAgentId,
|
|
831
952
|
createdByUserId: requestedByUserId,
|
|
832
953
|
});
|
|
833
|
-
|
|
954
|
+
steerTaskRoute.respond(res, 200, result);
|
|
834
955
|
} catch (error) {
|
|
835
956
|
if (error instanceof SteeringRequestError) {
|
|
836
957
|
jsonError(res, error.message, error.statusCode);
|
|
@@ -849,7 +970,9 @@ export async function handleTasks(
|
|
|
849
970
|
jsonError(res, "Task not found", 404);
|
|
850
971
|
return true;
|
|
851
972
|
}
|
|
852
|
-
|
|
973
|
+
getTaskSteeringMessagesRoute.respond(res, 200, {
|
|
974
|
+
messages: getSteeringMessagesForTask(parsed.params.id),
|
|
975
|
+
});
|
|
853
976
|
return true;
|
|
854
977
|
}
|
|
855
978
|
|
|
@@ -870,11 +993,13 @@ export async function handleTasks(
|
|
|
870
993
|
const task = getTaskById(parsed.query.taskId);
|
|
871
994
|
const messages =
|
|
872
995
|
task?.agentId === myAgentId ? getPendingSteeringForTask(parsed.query.taskId) : [];
|
|
873
|
-
|
|
996
|
+
getPendingSteeringMessagesRoute.respond(res, 200, { messages });
|
|
874
997
|
return true;
|
|
875
998
|
}
|
|
876
999
|
|
|
877
|
-
|
|
1000
|
+
getPendingSteeringMessagesRoute.respond(res, 200, {
|
|
1001
|
+
messages: getPendingSteeringForAgent(myAgentId),
|
|
1002
|
+
});
|
|
878
1003
|
return true;
|
|
879
1004
|
}
|
|
880
1005
|
|
|
@@ -902,7 +1027,7 @@ export async function handleTasks(
|
|
|
902
1027
|
return true;
|
|
903
1028
|
}
|
|
904
1029
|
if (message.status !== "pending") {
|
|
905
|
-
|
|
1030
|
+
markSteeringDeliveredRoute.respond(res, 200, { message });
|
|
906
1031
|
return true;
|
|
907
1032
|
}
|
|
908
1033
|
|
|
@@ -912,7 +1037,7 @@ export async function handleTasks(
|
|
|
912
1037
|
jsonError(res, "Failed to mark steering message delivered", 500);
|
|
913
1038
|
return true;
|
|
914
1039
|
}
|
|
915
|
-
|
|
1040
|
+
markSteeringDeliveredRoute.respond(res, 200, { message: delivered });
|
|
916
1041
|
return true;
|
|
917
1042
|
}
|
|
918
1043
|
|
|
@@ -940,7 +1065,7 @@ export async function handleTasks(
|
|
|
940
1065
|
return true;
|
|
941
1066
|
}
|
|
942
1067
|
if (message.status !== "delivered") {
|
|
943
|
-
|
|
1068
|
+
markSteeringHandledRoute.respond(res, 200, { message });
|
|
944
1069
|
return true;
|
|
945
1070
|
}
|
|
946
1071
|
|
|
@@ -961,7 +1086,7 @@ export async function handleTasks(
|
|
|
961
1086
|
jsonError(res, "Failed to mark steering message handled", 500);
|
|
962
1087
|
return true;
|
|
963
1088
|
}
|
|
964
|
-
|
|
1089
|
+
markSteeringHandledRoute.respond(res, 200, { message: handled });
|
|
965
1090
|
return true;
|
|
966
1091
|
}
|
|
967
1092
|
|
|
@@ -989,7 +1114,7 @@ export async function handleTasks(
|
|
|
989
1114
|
return true;
|
|
990
1115
|
}
|
|
991
1116
|
if (message.status !== "pending") {
|
|
992
|
-
|
|
1117
|
+
markSteeringUndeliverableRoute.respond(res, 200, {
|
|
993
1118
|
message,
|
|
994
1119
|
promotedTaskId: message.promotedTaskId,
|
|
995
1120
|
});
|
|
@@ -997,7 +1122,11 @@ export async function handleTasks(
|
|
|
997
1122
|
}
|
|
998
1123
|
|
|
999
1124
|
try {
|
|
1000
|
-
|
|
1125
|
+
markSteeringUndeliverableRoute.respond(
|
|
1126
|
+
res,
|
|
1127
|
+
200,
|
|
1128
|
+
markSteeringUndeliverable(message.id, parsed.body.reason),
|
|
1129
|
+
);
|
|
1001
1130
|
} catch (error) {
|
|
1002
1131
|
if (error instanceof SteeringRequestError) {
|
|
1003
1132
|
jsonError(res, error.message, error.statusCode);
|
|
@@ -1020,7 +1149,7 @@ export async function handleTasks(
|
|
|
1020
1149
|
|
|
1021
1150
|
const logs = getLogsByTaskId(parsed.params.id, parsed.query.logsLimit ?? 200);
|
|
1022
1151
|
const attachments = getTaskAttachments(parsed.params.id);
|
|
1023
|
-
|
|
1152
|
+
getTask.respond(res, 200, { ...task, ...getTaskSteeringFields(task), logs, attachments });
|
|
1024
1153
|
return true;
|
|
1025
1154
|
}
|
|
1026
1155
|
|
|
@@ -1035,7 +1164,7 @@ export async function handleTasks(
|
|
|
1035
1164
|
}
|
|
1036
1165
|
|
|
1037
1166
|
updateTaskProgress(parsed.params.id, parsed.body.progress);
|
|
1038
|
-
|
|
1167
|
+
updateTaskProgressRoute.respond(res, 200, { success: true });
|
|
1039
1168
|
return true;
|
|
1040
1169
|
}
|
|
1041
1170
|
|
|
@@ -1048,7 +1177,51 @@ export async function handleTasks(
|
|
|
1048
1177
|
const parsed = await finishTask.parse(req, res, pathSegments, queryParams);
|
|
1049
1178
|
if (!parsed) return true;
|
|
1050
1179
|
|
|
1051
|
-
|
|
1180
|
+
// Explicit (plain, non-derived) return type: without it TS infers a merged
|
|
1181
|
+
// shape across these branches and the `"success" in result` / `"error" in
|
|
1182
|
+
// result` narrowing below stops working. A `Pick`/`Extract`-derived alias
|
|
1183
|
+
// for the middle (guard-handled) variant was tried and also defeated
|
|
1184
|
+
// narrowing, so its fields are spelled out by hand here — keep in sync
|
|
1185
|
+
// with the `handled: true` branch of `TerminalResultGuardResult`
|
|
1186
|
+
// (../tasks/terminal-result-guard) minus the `handled` discriminant.
|
|
1187
|
+
type FinishTaskTransactionResult =
|
|
1188
|
+
| { error: string; status: number }
|
|
1189
|
+
| {
|
|
1190
|
+
success: boolean;
|
|
1191
|
+
message: string;
|
|
1192
|
+
task: AgentTask;
|
|
1193
|
+
wasNoOp?: boolean;
|
|
1194
|
+
wasForcedOverwrite?: boolean;
|
|
1195
|
+
alreadyFinished: true;
|
|
1196
|
+
}
|
|
1197
|
+
| { success: true; task: AgentTask; alreadyFinished: true }
|
|
1198
|
+
| { task: AgentTask; wasPaused: boolean };
|
|
1199
|
+
|
|
1200
|
+
// User-defined type guards (rather than inline `"x" in r && r.x` checks)
|
|
1201
|
+
// so TS narrows both branches of each condition — plain `&&`/`!(...)`
|
|
1202
|
+
// guards only narrow the true-branch (or don't narrow at all when negated),
|
|
1203
|
+
// leaving `result` unnarrowed (and e.g. `.task` inaccessible) for the rest
|
|
1204
|
+
// of this handler. Each predicate below evaluates the exact same runtime
|
|
1205
|
+
// condition the inline checks used to.
|
|
1206
|
+
const hasFinishError = (
|
|
1207
|
+
r: FinishTaskTransactionResult,
|
|
1208
|
+
): r is Extract<FinishTaskTransactionResult, { error: string }> => "error" in r && !!r.error;
|
|
1209
|
+
const isFinishConflict = (
|
|
1210
|
+
r: FinishTaskTransactionResult,
|
|
1211
|
+
): r is {
|
|
1212
|
+
success: false;
|
|
1213
|
+
message: string;
|
|
1214
|
+
task: AgentTask;
|
|
1215
|
+
wasNoOp?: boolean;
|
|
1216
|
+
wasForcedOverwrite?: boolean;
|
|
1217
|
+
alreadyFinished: true;
|
|
1218
|
+
} => "success" in r && r.success === false;
|
|
1219
|
+
const isFreshFinishResult = (
|
|
1220
|
+
r: FinishTaskTransactionResult,
|
|
1221
|
+
): r is Extract<FinishTaskTransactionResult, { task: AgentTask; wasPaused: boolean }> =>
|
|
1222
|
+
!("alreadyFinished" in r && r.alreadyFinished);
|
|
1223
|
+
|
|
1224
|
+
const result = getDb().transaction((): FinishTaskTransactionResult => {
|
|
1052
1225
|
const task = getTaskById(parsed.params.id);
|
|
1053
1226
|
|
|
1054
1227
|
if (!task) {
|
|
@@ -1099,24 +1272,20 @@ export async function handleTasks(
|
|
|
1099
1272
|
return { task: updatedTask, wasPaused };
|
|
1100
1273
|
})();
|
|
1101
1274
|
|
|
1102
|
-
if (
|
|
1103
|
-
jsonError(res, result.error,
|
|
1275
|
+
if (hasFinishError(result)) {
|
|
1276
|
+
jsonError(res, result.error, result.status ?? 500);
|
|
1104
1277
|
return true;
|
|
1105
1278
|
}
|
|
1106
1279
|
|
|
1107
|
-
if (
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
error: "message" in result ? result.message : "Terminal result write was discarded",
|
|
1113
|
-
},
|
|
1114
|
-
409,
|
|
1115
|
-
);
|
|
1280
|
+
if (isFinishConflict(result)) {
|
|
1281
|
+
finishTask.respond(res, 409, {
|
|
1282
|
+
...result,
|
|
1283
|
+
error: "message" in result ? result.message : "Terminal result write was discarded",
|
|
1284
|
+
});
|
|
1116
1285
|
return true;
|
|
1117
1286
|
}
|
|
1118
1287
|
|
|
1119
|
-
if (result.task &&
|
|
1288
|
+
if (result.task && isFreshFinishResult(result)) {
|
|
1120
1289
|
const finishEventId = parsed.body.status === "completed" ? "completed" : "failed";
|
|
1121
1290
|
|
|
1122
1291
|
ensure({
|
|
@@ -1155,7 +1324,7 @@ export async function handleTasks(
|
|
|
1155
1324
|
}
|
|
1156
1325
|
}
|
|
1157
1326
|
|
|
1158
|
-
|
|
1327
|
+
finishTask.respond(res, 200, {
|
|
1159
1328
|
success: true,
|
|
1160
1329
|
alreadyFinished: "alreadyFinished" in result ? result.alreadyFinished : false,
|
|
1161
1330
|
task: result.task,
|
|
@@ -1174,7 +1343,7 @@ export async function handleTasks(
|
|
|
1174
1343
|
return true;
|
|
1175
1344
|
}
|
|
1176
1345
|
const pausedTasks = getPausedTasksForAgent(myAgentId);
|
|
1177
|
-
|
|
1346
|
+
listPausedTasks.respond(res, 200, { tasks: pausedTasks });
|
|
1178
1347
|
return true;
|
|
1179
1348
|
}
|
|
1180
1349
|
|
|
@@ -1220,7 +1389,7 @@ export async function handleTasks(
|
|
|
1220
1389
|
conditions: [{ timeout_ms: 3_600_000 }], // 1 hour
|
|
1221
1390
|
});
|
|
1222
1391
|
|
|
1223
|
-
|
|
1392
|
+
pauseTaskRoute.respond(res, 200, { success: true, task: pausedTask });
|
|
1224
1393
|
return true;
|
|
1225
1394
|
}
|
|
1226
1395
|
|
|
@@ -1232,7 +1401,7 @@ export async function handleTasks(
|
|
|
1232
1401
|
jsonError(res, "Task not found", 404);
|
|
1233
1402
|
return true;
|
|
1234
1403
|
}
|
|
1235
|
-
|
|
1404
|
+
updateTaskVcsRoute.respond(res, 200, task);
|
|
1236
1405
|
return true;
|
|
1237
1406
|
}
|
|
1238
1407
|
|
|
@@ -1244,7 +1413,7 @@ export async function handleTasks(
|
|
|
1244
1413
|
jsonError(res, "Task not found", 404);
|
|
1245
1414
|
return true;
|
|
1246
1415
|
}
|
|
1247
|
-
|
|
1416
|
+
updateTaskTitleRoute.respond(res, 200, { task });
|
|
1248
1417
|
return true;
|
|
1249
1418
|
}
|
|
1250
1419
|
|
|
@@ -1290,7 +1459,7 @@ export async function handleTasks(
|
|
|
1290
1459
|
conditions: [{ timeout_ms: 86_400_000 }], // 1 day: tasks may stay paused for extended periods
|
|
1291
1460
|
});
|
|
1292
1461
|
|
|
1293
|
-
|
|
1462
|
+
resumeTaskRoute.respond(res, 200, { success: true, task: resumedTask });
|
|
1294
1463
|
return true;
|
|
1295
1464
|
}
|
|
1296
1465
|
|
|
@@ -1313,7 +1482,7 @@ export async function handleTasks(
|
|
|
1313
1482
|
// response (mirrors finishTask). Caller treats this as a successful
|
|
1314
1483
|
// supersede.
|
|
1315
1484
|
if (isTerminalTaskStatus(task.status)) {
|
|
1316
|
-
|
|
1485
|
+
supersedeTaskRoute.respond(res, 200, {
|
|
1317
1486
|
success: true,
|
|
1318
1487
|
kind: "alreadyFinished",
|
|
1319
1488
|
task,
|
|
@@ -1343,7 +1512,7 @@ export async function handleTasks(
|
|
|
1343
1512
|
reason: parsed.body.reason,
|
|
1344
1513
|
},
|
|
1345
1514
|
});
|
|
1346
|
-
|
|
1515
|
+
supersedeTaskRoute.respond(res, 200, {
|
|
1347
1516
|
success: true,
|
|
1348
1517
|
kind: "workflow-failed",
|
|
1349
1518
|
task: failed,
|
|
@@ -1365,7 +1534,7 @@ export async function handleTasks(
|
|
|
1365
1534
|
// Worker won the race (terminal transition between status check and
|
|
1366
1535
|
// this UPDATE). Treat as `alreadyFinished` — no resume child is created.
|
|
1367
1536
|
const fresh = getTaskById(parsed.params.id);
|
|
1368
|
-
|
|
1537
|
+
supersedeTaskRoute.respond(res, 200, {
|
|
1369
1538
|
success: true,
|
|
1370
1539
|
kind: "alreadyFinished",
|
|
1371
1540
|
task: fresh,
|
|
@@ -1389,7 +1558,7 @@ export async function handleTasks(
|
|
|
1389
1558
|
followUp.kind === "skipped" ? followUp.reason : followUp.kind
|
|
1390
1559
|
})`,
|
|
1391
1560
|
);
|
|
1392
|
-
|
|
1561
|
+
supersedeTaskRoute.respond(res, 200, {
|
|
1393
1562
|
success: true,
|
|
1394
1563
|
kind: "resumed",
|
|
1395
1564
|
task: superseded,
|
|
@@ -1413,7 +1582,7 @@ export async function handleTasks(
|
|
|
1413
1582
|
},
|
|
1414
1583
|
});
|
|
1415
1584
|
|
|
1416
|
-
|
|
1585
|
+
supersedeTaskRoute.respond(res, 200, {
|
|
1417
1586
|
success: true,
|
|
1418
1587
|
kind: "resumed",
|
|
1419
1588
|
task: superseded,
|