@desplega.ai/agent-swarm 1.157.0 → 1.158.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-qhqrk4q0.js → acp-adapter-xaq4n6pc.js} +1 -1
- package/dist/{actions-9rrg0zxm.js → actions-p9hz5yat.js} +15 -15
- package/dist/{app-enysy1zd.js → app-g26wdcz6.js} +4 -4
- package/dist/{artifact-td4q4dch.js → artifact-3v5t9jtg.js} +1 -1
- package/dist/{assistant-zegamy48.js → assistant-wydfqkb3.js} +16 -16
- package/dist/{boot-reembed-r6shx5qx.js → boot-reembed-g5ckg9yb.js} +6 -6
- package/dist/{boot-reembed-zfxb937k.js → boot-reembed-se8zmdcp.js} +5 -5
- package/dist/{boot-scrub-logs-k5y0se6r.js → boot-scrub-logs-wfxqan61.js} +3 -3
- package/dist/{seed-pricing-vqxa06qf.js → boot-seeds-s3q01xj3.js} +10 -10
- package/dist/{claude-adapter-5yc7hxwv.js → claude-adapter-tv2x4f36.js} +7 -7
- package/dist/{claude-managed-adapter-ea2aga6w.js → claude-managed-adapter-41b2s7fd.js} +2 -2
- package/dist/{claude-sdk-session-j4ywn3xf.js → claude-sdk-session-t442qz6f.js} +8 -8
- package/dist/{cli-e781c6f9.js → cli-0xjkj1j7.js} +1 -0
- package/dist/{cli-58rgvkt4.js → cli-1hkrch3k.js} +2 -2
- package/dist/{cli-yscm6cv8.js → cli-20cj37vt.js} +1866 -9
- package/dist/{cli-h0wdadsx.js → cli-4198qc9v.js} +7 -3
- package/dist/{cli-awwphhcs.js → cli-47m6dkd3.js} +362 -126
- package/dist/{cli-wb2zvbfg.js → cli-53sz8gkz.js} +1 -1
- package/dist/{cli-005pze6s.js → cli-5d10vd2m.js} +1 -1
- package/dist/{cli-v53rbqp3.js → cli-65hjmev5.js} +57 -17
- package/dist/{cli-scwq51gn.js → cli-68w09sjw.js} +7 -1
- package/dist/{cli-s98skd5r.js → cli-7gtvvpbh.js} +4 -4
- package/dist/{cli-y3nxwx0t.js → cli-7s3syk22.js} +18 -11
- package/dist/{cli-74h6f2bp.js → cli-8qmme6vd.js} +2 -2
- package/dist/{cli-wsed24mk.js → cli-987hg0aa.js} +2 -2
- package/dist/{cli-9n76jszt.js → cli-9httdpyq.js} +1 -1
- package/dist/{cli-f3va018d.js → cli-aky8tctm.js} +26 -93
- package/dist/{cli-sgyqyyxe.js → cli-c07r9a2m.js} +2 -1
- package/dist/{cli-c41wjx0r.js → cli-fgqxwrpv.js} +291 -12
- package/dist/{cli-01vfmq8c.js → cli-ftfvggzx.js} +607 -164
- package/dist/{cli-ytxs7mn1.js → cli-g8djp6qe.js} +17 -0
- package/dist/{cli-avkd6mqv.js → cli-h967nb6r.js} +551 -0
- package/dist/{cli-r9ee9c4w.js → cli-j55n64b6.js} +23 -22
- package/dist/{cli-9p33cz9h.js → cli-j57qkrpq.js} +86 -28
- package/dist/{cli-tjmghmm5.js → cli-q67y4wzm.js} +6 -3
- package/dist/{cli-n6zq3kbd.js → cli-rj19hc34.js} +1 -1
- package/dist/{cli-jytrw2na.js → cli-rjehvrts.js} +4 -4
- package/dist/{cli-tpv97m71.js → cli-rqz8qbw7.js} +245 -75
- package/dist/{cli-p37sg0a9.js → cli-s8eet254.js} +1 -1
- package/dist/cli-t1ze64h3.js +811 -0
- package/dist/{cli-6jjzxv3b.js → cli-ws6rqycm.js} +3 -2
- package/dist/{cli-xf5b7y1f.js → cli-wscdvcqz.js} +13 -5
- package/dist/{cli-5j7bm4tb.js → cli-x24pshtq.js} +5 -5
- package/dist/{cli-nbp6m6gp.js → cli-xberxa1r.js} +51 -26
- package/dist/{cli-vx9p3qdt.js → cli-xhaeg2nc.js} +1 -1
- package/dist/cli.js +29 -15
- package/dist/{codex-adapter-gns3s6c3.js → codex-adapter-cnm8wk11.js} +5 -5
- package/dist/{codex-session-runner-gqnxys5w.js → codex-session-runner-gfg547zj.js} +5 -5
- package/dist/{commands-hxy2y2sp.js → commands-e3bn0p75.js} +3 -3
- package/dist/{db-w8ghhsgf.js → db-03v9kzr2.js} +17 -3
- package/dist/{dispatcher-cp1rknjz.js → dispatcher-nrmg8yht.js} +14 -14
- package/dist/{dsh-adapter-1dwg97zv.js → dsh-adapter-k03nfqa6.js} +2 -2
- package/dist/{handlers-egfhr351.js → handlers-aqcedbyb.js} +17 -17
- package/dist/{hook-x4kftwzt.js → hook-7vkskkre.js} +19 -11
- package/dist/{hook-fbxjqfjz.js → hook-ybvmrmhq.js} +4 -4
- package/dist/{http-c7jfx990.js → http-2eqa8t24.js} +432 -195
- package/dist/{index-4k9hct21.js → index-1yks3qcr.js} +14 -14
- package/dist/{index-jtvpgb8f.js → index-a3vn96n8.js} +30 -27
- package/dist/{index-dc2ek6bw.js → index-c6zsv1bd.js} +5 -5
- package/dist/{index-yy07ef2s.js → index-chgdkq36.js} +14 -14
- package/dist/{index-r6bty6tb.js → index-x71bvq0p.js} +15 -15
- package/dist/{keepalive-f7ekefyc.js → keepalive-vtkf5n99.js} +5 -5
- package/dist/{lead-h053syts.js → lead-h3sp357x.js} +26 -26
- package/dist/{maintenance-a3w6zs54.js → maintenance-jzeqtk3q.js} +6 -6
- package/dist/{oauth-refresh-sweep-vra1dhkd.js → oauth-refresh-sweep-qp3dzmdp.js} +4 -4
- package/dist/{onboard-mfgzeqxs.js → onboard-tmsp0qbz.js} +278 -81
- package/dist/{opencode-adapter-z64xjzec.js → opencode-adapter-x6x2da1z.js} +3 -3
- package/dist/{otel-impl-2ez6xk57.js → otel-impl-9mz73q65.js} +416 -301
- package/dist/{pi-mono-adapter-2b7mw16r.js → pi-mono-adapter-m6dvv0dz.js} +2 -2
- package/dist/{pricing-refresh-6sw65tck.js → pricing-refresh-v1cbr9te.js} +5 -5
- package/dist/{rbac-roles-nm6924sy.js → rbac-roles-c9wqz83x.js} +4 -4
- package/dist/{render-v2-f026j6c4.js → render-v2-gryrh9h8.js} +4 -4
- package/dist/{setup-w606fr1q.js → setup-q9720bt6.js} +2 -2
- package/dist/{virtual-modules-8qheft18.js → virtual-modules-3htpgn8x.js} +1 -1
- package/dist/{work-objects-ezmggdne.js → work-objects-b76x7deb.js} +17 -17
- package/dist/{worker-1mbyv29k.js → worker-6vrxbv41.js} +26 -26
- package/openapi.json +1626 -629
- package/package.json +2 -1
- package/src/apps/catalog.generated.json +229 -0
- package/src/apps/page-validator.ts +71 -16
- package/src/apps/row-store.ts +66 -11
- package/src/apps/sync.ts +59 -17
- package/src/artifact-sdk/browser-sdk.ts +436 -2
- package/src/be/approval-sweeps.ts +109 -0
- package/src/be/boot-seeds.ts +40 -0
- package/src/be/chunking.ts +1 -1
- package/src/be/db/agents.ts +20 -0
- package/src/be/db/approvals.ts +78 -0
- package/src/be/db/tasks/read.ts +197 -39
- package/src/be/db/tasks/write.ts +41 -9
- package/src/be/db-client.ts +107 -48
- package/src/be/db.ts +219 -76
- package/src/be/events.ts +33 -1
- package/src/be/memory/graph-expansion.ts +10 -3
- package/src/be/memory/providers/sqlite-store.ts +55 -13
- package/src/be/memory/raters/retrieval.ts +5 -2
- package/src/be/memory/reranker.ts +26 -2
- package/src/be/memory/types.ts +2 -0
- package/src/be/migrations/166_approval_request_auto_cancellation.sql +9 -0
- package/src/be/migrations/171_memory_retrieval_relevance.sql +8 -0
- package/src/be/migrations/175_workflow_runs_list_index.sql +11 -0
- package/src/be/migrations/177_events_event_agent_created_index.sql +11 -0
- package/src/be/models-catalog.ts +2 -0
- package/src/be/modelsdev-cache.json +1857 -0
- package/src/be/modelsdev-cache.ts +14 -1
- package/src/be/pricing-normalize.ts +2 -0
- package/src/be/scripts/typecheck.ts +1 -0
- package/src/be/seed-pricing.ts +3 -1
- package/src/be/seed-skills/bundled-files.generated.json +1 -1
- package/src/be/steering.ts +53 -3
- package/src/be/swarm-config-guard.ts +3 -0
- package/src/be/task-citations.ts +29 -0
- package/src/cli.tsx +14 -1
- package/src/commands/onboard/compose-generator.ts +8 -3
- package/src/commands/onboard/container-engine.ts +220 -0
- package/src/commands/onboard/manifest.ts +1 -0
- package/src/commands/onboard/steps/health-check.tsx +4 -1
- package/src/commands/onboard/steps/prereq-check.tsx +50 -54
- package/src/commands/onboard/steps/start.tsx +31 -16
- package/src/commands/onboard/types.ts +7 -2
- package/src/commands/onboard.tsx +39 -4
- package/src/commands/profile-sync.ts +79 -26
- package/src/commands/runner.ts +8 -1
- package/src/extensions/catalog.generated.json +17 -0
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/heartbeat/heartbeat.ts +263 -103
- package/src/hooks/hook.ts +21 -12
- package/src/http/agents.ts +35 -0
- package/src/http/approval-requests.ts +136 -64
- package/src/http/apps.ts +14 -3
- package/src/http/config.ts +15 -1
- package/src/http/events.ts +62 -2
- package/src/http/index.ts +6 -4
- package/src/http/memory.ts +21 -7
- package/src/http/schedules.ts +1 -1
- package/src/http/session-data.ts +9 -4
- package/src/http/sessions.ts +25 -18
- package/src/http/stats.ts +19 -7
- package/src/http/status.ts +11 -1
- package/src/http/tasks.ts +40 -8
- package/src/http/webhooks.ts +67 -46
- package/src/http/workflows.ts +15 -20
- package/src/linear/outbound.ts +37 -15
- package/src/otel-impl.ts +151 -1
- package/src/otel.ts +14 -3
- package/src/prompts/memories.ts +19 -2
- package/src/providers/claude-managed-models.ts +8 -0
- package/src/providers/modelsdev-reasoning.json +551 -0
- package/src/rbac/legacy-policy.ts +16 -0
- package/src/rbac/permissions.ts +4 -0
- package/src/scheduler/schedule-task.ts +3 -0
- package/src/scripts-runtime/sdk-allowlist.ts +1 -0
- package/src/scripts-runtime/swarm-sdk.ts +9 -0
- package/src/scripts-runtime/types/stdlib.d.ts +1 -0
- package/src/scripts-runtime/types/swarm-extension.d.ts +1 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -0
- package/src/server.ts +12 -7
- package/src/slack/app.ts +35 -4
- package/src/slack/connection-state.ts +17 -0
- package/src/tasks/context-key.ts +1 -0
- package/src/tasks/worker-follow-up.ts +6 -2
- package/src/tests/agent-task-activity.test.ts +74 -0
- package/src/tests/agents-list-model-display.test.ts +6 -1
- package/src/tests/approval-auto-cancellation-migration.test.ts +104 -0
- package/src/tests/approval-requests.test.ts +395 -0
- package/src/tests/approval-sweeps-config.test.ts +47 -0
- package/src/tests/approval-sweeps.test.ts +508 -0
- package/src/tests/apps-kibo-blocks.test.ts +77 -0
- package/src/tests/apps-spike.test.ts +56 -1
- package/src/tests/apps-sync-engine.test.ts +20 -9
- package/src/tests/boot-seeds.test.ts +170 -0
- package/src/tests/cancel-approval-request-tool.test.ts +115 -0
- package/src/tests/claude-managed-adapter.test.ts +6 -0
- package/src/tests/config-key-filter.test.ts +80 -0
- package/src/tests/context-window.test.ts +1 -0
- package/src/tests/db-client-busy-retry.test.ts +96 -0
- package/src/tests/db-client.test.ts +60 -1
- package/src/tests/db-task-read-contract.test.ts +10 -0
- package/src/tests/db-task-write-contract.test.ts +9 -0
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/events-http.test.ts +103 -0
- package/src/tests/extensions-catalog.test.ts +22 -17
- package/src/tests/extensions-pre-task.test.ts +107 -0
- package/src/tests/fixtures/kibo-blocks-definition.json.txt +105 -0
- package/src/tests/follow-up-config-inheritance.test.ts +260 -0
- package/src/tests/heartbeat-orphan-resume.test.ts +84 -0
- package/src/tests/heartbeat-reboot-live.test.ts +95 -0
- package/src/tests/heartbeat-stall-cas.test.ts +80 -0
- package/src/tests/heartbeat.test.ts +99 -3
- package/src/tests/hook-mcp-config.test.ts +29 -0
- package/src/tests/http-api-integration.test.ts +16 -2
- package/src/tests/kv-storage.test.ts +62 -0
- package/src/tests/linear-outbound-sync.test.ts +120 -5
- package/src/tests/list-endpoint-slimming.test.ts +91 -0
- package/src/tests/memory-graph-organic-route.test.ts +155 -0
- package/src/tests/memory-http-recall-gating.test.ts +14 -4
- package/src/tests/memory-hybrid.test.ts +161 -1
- package/src/tests/memory-prompt-recall-crowdout.test.ts +297 -0
- package/src/tests/memory.test.ts +22 -0
- package/src/tests/onboard-container-engine.test.ts +240 -0
- package/src/tests/otel-event-loop-and-logs.test.ts +99 -0
- package/src/tests/pricing-routes.test.ts +14 -0
- package/src/tests/profile-sync-warning.test.ts +8 -4
- package/src/tests/promote-draft-task-route.test.ts +19 -0
- package/src/tests/provider-registration.test.ts +296 -42
- package/src/tests/rbac-engine.test.ts +30 -0
- package/src/tests/reasoning-effort.test.ts +8 -0
- package/src/tests/script-connections.test.ts +7 -0
- package/src/tests/sdk-allowlist.test.ts +39 -0
- package/src/tests/session-costs-model-key-normalize.test.ts +1 -0
- package/src/tests/sessions-detail-batch.test.ts +250 -0
- package/src/tests/sessions.test.ts +118 -0
- package/src/tests/slack-config.test.ts +22 -0
- package/src/tests/sonnet-5-5-registry.test.ts +44 -0
- package/src/tests/status.test.ts +36 -1
- package/src/tests/swarm-diff.test.ts +316 -10
- package/src/tests/task-completion-idempotency.test.ts +2 -1
- package/src/tests/tasks-requested-by-filter.test.ts +3 -1
- package/src/tests/tool-annotations.test.ts +1 -1
- package/src/tests/ui-list-slim-projections.test.ts +158 -0
- package/src/tests/webhooks-task-blocked.test.ts +127 -0
- package/src/tests/workflow-approval-recovery.test.ts +203 -0
- package/src/tests/workflow-hitl-routing.test.ts +22 -1
- package/src/tests/workflow-hitl-slack-card.test.ts +52 -0
- package/src/tests/workflow-http-v2.test.ts +99 -8
- package/src/tests/workflow-retry-validation.test.ts +56 -0
- package/src/tests/workflow-tla-races.test.ts +389 -0
- package/src/tests/workflow-validation-port-routing.test.ts +113 -1
- package/src/tools/cancel-approval-request.ts +57 -0
- package/src/tools/memory-search.ts +1 -0
- package/src/tools/request-human-input.ts +4 -2
- package/src/tools/send-task.ts +4 -0
- package/src/tools/templates.ts +19 -0
- package/src/tools/tool-config.ts +2 -1
- package/src/tools/workflows/list-workflow-runs.ts +1 -0
- package/src/types.ts +38 -0
- package/src/utils/context-window.ts +1 -0
- package/src/workflows/approval-cancel.ts +152 -0
- package/src/workflows/approval-notifications.ts +84 -0
- package/src/workflows/checkpoint.ts +10 -5
- package/src/workflows/definition.ts +21 -0
- package/src/workflows/engine.ts +152 -21
- package/src/workflows/executors/human-in-the-loop.ts +1 -1
- package/src/workflows/recovery.ts +100 -45
- package/src/workflows/resume.ts +49 -18
- package/src/workflows/retry-poller.ts +71 -21
- package/templates/extensions/README.md +1 -0
- package/templates/extensions/github-sender-allowlist/README.md +18 -0
- package/templates/extensions/github-sender-allowlist/hooks.ts +55 -0
- package/templates/extensions/github-sender-allowlist/manifest.json +8 -0
- package/templates/skills/apps/content.md +20 -1
- package/templates/skills/code-quality/content.md +26 -1
- package/templates/skills/pages/content.md +16 -4
- package/templates/skills/pages/files/examples/multiplayer-board.html +3 -12
- package/dist/cli-2daksqps.js +0 -378
- package/dist/rbac-roles-3gxmnb20.js +0 -37
|
@@ -41,6 +41,7 @@ const baseFacade = `type:AgentMailInboxMapping
|
|
|
41
41
|
type:ApiKeyStatus
|
|
42
42
|
type:AppVersion
|
|
43
43
|
type:ApprovalRequest
|
|
44
|
+
type:ApprovalRequestSummary
|
|
44
45
|
type:AssetSummaryFilters
|
|
45
46
|
type:AttributionByPersonRow
|
|
46
47
|
type:AvailableKeyIndicesResult
|
|
@@ -64,6 +65,7 @@ type:InboxSummary
|
|
|
64
65
|
type:InsertPricingRowInput
|
|
65
66
|
type:InsertTaskAttachmentInput
|
|
66
67
|
type:KeyCostSummary
|
|
68
|
+
type:KvJsonFieldEquals
|
|
67
69
|
type:McpServerFilters
|
|
68
70
|
type:McpServerInsert
|
|
69
71
|
type:MentionPreview
|
|
@@ -113,6 +115,7 @@ value:autoEncryptLegacyPlaintextSecrets
|
|
|
113
115
|
value:backfillSupersedeTaskResumeTaskId
|
|
114
116
|
value:bindSlackMessageTimestamp
|
|
115
117
|
value:buildRoutingAffinityFromAgent
|
|
118
|
+
value:cancelApprovalRequestById
|
|
116
119
|
value:cancelPendingApprovalRequestsForRun
|
|
117
120
|
value:cancelPendingSteeringForTask
|
|
118
121
|
value:cancelTask
|
|
@@ -223,6 +226,7 @@ value:getActiveSessions
|
|
|
223
226
|
value:getActiveTaskCount
|
|
224
227
|
value:getAgentById
|
|
225
228
|
value:getAgentCurrentTask
|
|
229
|
+
value:getAgentDailyTaskCounts
|
|
226
230
|
value:getAgentHarnessProviders
|
|
227
231
|
value:getAgentMailInboxMapping
|
|
228
232
|
value:getAgentMailInboxMappingsByAgent
|
|
@@ -265,6 +269,7 @@ value:getContextSnapshotsByTaskId
|
|
|
265
269
|
value:getContextSummaryByTaskId
|
|
266
270
|
value:getContextVersion
|
|
267
271
|
value:getContextVersionHistory
|
|
272
|
+
value:getCurrentStepForNode
|
|
268
273
|
value:getDailySpendForAgent
|
|
269
274
|
value:getDailySpendForUser
|
|
270
275
|
value:getDailySpendGlobal
|
|
@@ -370,6 +375,7 @@ value:getSlackTasksMissingTree
|
|
|
370
375
|
value:getSlackTreeMessage
|
|
371
376
|
value:getSlackTreeMessageByThread
|
|
372
377
|
value:getSlackTreeMessages
|
|
378
|
+
value:getStaleApprovalRequests
|
|
373
379
|
value:getStalePinnedResumes
|
|
374
380
|
value:getStaleUnassignedAffinityTasks
|
|
375
381
|
value:getStalledInProgressTasks
|
|
@@ -380,6 +386,7 @@ value:getStepCountForNode
|
|
|
380
386
|
value:getStuckApprovalRuns
|
|
381
387
|
value:getStuckWaitRuns
|
|
382
388
|
value:getStuckWorkflowRuns
|
|
389
|
+
value:getSupersededTasksWithoutResume
|
|
383
390
|
value:getSwarmConfigById
|
|
384
391
|
value:getSwarmConfigLookupById
|
|
385
392
|
value:getSwarmConfigs
|
|
@@ -436,9 +443,11 @@ value:isPendingSlackMessage
|
|
|
436
443
|
value:isPoolAffinityEnforcementEnabled
|
|
437
444
|
value:isSettledSlackMessage
|
|
438
445
|
value:isSqliteVecAvailable
|
|
446
|
+
value:kvPrefixUpperBound
|
|
439
447
|
value:listAgentsWithCredStatusByProvider
|
|
440
448
|
value:listAllMetrics
|
|
441
449
|
value:listAllPages
|
|
450
|
+
value:listApprovalRequestSummaries
|
|
442
451
|
value:listApprovalRequests
|
|
443
452
|
value:listAssetSummaries
|
|
444
453
|
value:listCancelledApprovalRequestsForRun
|
|
@@ -595,6 +604,7 @@ value:getMostRecentTaskInThread
|
|
|
595
604
|
value:getPendingSlackRelayTasks
|
|
596
605
|
value:getRecentlyFinishedWorkerTasks
|
|
597
606
|
value:getSlackTasksMissingTree
|
|
607
|
+
value:getSupersededTasksWithoutResume
|
|
598
608
|
value:getTaskById
|
|
599
609
|
value:getTaskStats
|
|
600
610
|
value:getTasksByAgentId
|
|
@@ -42,6 +42,7 @@ const baseFacade = `type:AgentMailInboxMapping
|
|
|
42
42
|
type:ApiKeyStatus
|
|
43
43
|
type:AppVersion
|
|
44
44
|
type:ApprovalRequest
|
|
45
|
+
type:ApprovalRequestSummary
|
|
45
46
|
type:AssetSummaryFilters
|
|
46
47
|
type:AttributionByPersonRow
|
|
47
48
|
type:AvailableKeyIndicesResult
|
|
@@ -65,6 +66,7 @@ type:InboxSummary
|
|
|
65
66
|
type:InsertPricingRowInput
|
|
66
67
|
type:InsertTaskAttachmentInput
|
|
67
68
|
type:KeyCostSummary
|
|
69
|
+
type:KvJsonFieldEquals
|
|
68
70
|
type:McpServerFilters
|
|
69
71
|
type:McpServerInsert
|
|
70
72
|
type:MentionPreview
|
|
@@ -114,6 +116,7 @@ value:autoEncryptLegacyPlaintextSecrets
|
|
|
114
116
|
value:backfillSupersedeTaskResumeTaskId
|
|
115
117
|
value:bindSlackMessageTimestamp
|
|
116
118
|
value:buildRoutingAffinityFromAgent
|
|
119
|
+
value:cancelApprovalRequestById
|
|
117
120
|
value:cancelPendingApprovalRequestsForRun
|
|
118
121
|
value:cancelPendingSteeringForTask
|
|
119
122
|
value:cancelTask
|
|
@@ -224,6 +227,7 @@ value:getActiveSessions
|
|
|
224
227
|
value:getActiveTaskCount
|
|
225
228
|
value:getAgentById
|
|
226
229
|
value:getAgentCurrentTask
|
|
230
|
+
value:getAgentDailyTaskCounts
|
|
227
231
|
value:getAgentHarnessProviders
|
|
228
232
|
value:getAgentMailInboxMapping
|
|
229
233
|
value:getAgentMailInboxMappingsByAgent
|
|
@@ -266,6 +270,7 @@ value:getContextSnapshotsByTaskId
|
|
|
266
270
|
value:getContextSummaryByTaskId
|
|
267
271
|
value:getContextVersion
|
|
268
272
|
value:getContextVersionHistory
|
|
273
|
+
value:getCurrentStepForNode
|
|
269
274
|
value:getDailySpendForAgent
|
|
270
275
|
value:getDailySpendForUser
|
|
271
276
|
value:getDailySpendGlobal
|
|
@@ -371,6 +376,7 @@ value:getSlackTasksMissingTree
|
|
|
371
376
|
value:getSlackTreeMessage
|
|
372
377
|
value:getSlackTreeMessageByThread
|
|
373
378
|
value:getSlackTreeMessages
|
|
379
|
+
value:getStaleApprovalRequests
|
|
374
380
|
value:getStalePinnedResumes
|
|
375
381
|
value:getStaleUnassignedAffinityTasks
|
|
376
382
|
value:getStalledInProgressTasks
|
|
@@ -381,6 +387,7 @@ value:getStepCountForNode
|
|
|
381
387
|
value:getStuckApprovalRuns
|
|
382
388
|
value:getStuckWaitRuns
|
|
383
389
|
value:getStuckWorkflowRuns
|
|
390
|
+
value:getSupersededTasksWithoutResume
|
|
384
391
|
value:getSwarmConfigById
|
|
385
392
|
value:getSwarmConfigLookupById
|
|
386
393
|
value:getSwarmConfigs
|
|
@@ -437,9 +444,11 @@ value:isPendingSlackMessage
|
|
|
437
444
|
value:isPoolAffinityEnforcementEnabled
|
|
438
445
|
value:isSettledSlackMessage
|
|
439
446
|
value:isSqliteVecAvailable
|
|
447
|
+
value:kvPrefixUpperBound
|
|
440
448
|
value:listAgentsWithCredStatusByProvider
|
|
441
449
|
value:listAllMetrics
|
|
442
450
|
value:listAllPages
|
|
451
|
+
value:listApprovalRequestSummaries
|
|
443
452
|
value:listApprovalRequests
|
|
444
453
|
value:listAssetSummaries
|
|
445
454
|
value:listCancelledApprovalRequestsForRun
|
|
@@ -78,7 +78,7 @@ describe("docs API index footprint", () => {
|
|
|
78
78
|
expect(tasks).toContain('"path":"/api/task-templates","method":"get"');
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
-
test("OpenAPI and generated pages keep all
|
|
81
|
+
test("OpenAPI and generated pages keep all 383 operations", async () => {
|
|
82
82
|
const spec = await Bun.file(resolve(repoRoot, "openapi.json")).json();
|
|
83
83
|
const operationKeys = [];
|
|
84
84
|
const tags = new Set();
|
|
@@ -103,8 +103,8 @@ describe("docs API index footprint", () => {
|
|
|
103
103
|
expect(spec.paths["/api/agents/{id}/runtime"]?.get).toBeDefined();
|
|
104
104
|
|
|
105
105
|
const generatedKeys = await generatedOperationKeys();
|
|
106
|
-
expect(operationKeys).toHaveLength(
|
|
107
|
-
expect(generatedKeys).toHaveLength(
|
|
106
|
+
expect(operationKeys).toHaveLength(383);
|
|
107
|
+
expect(generatedKeys).toHaveLength(383);
|
|
108
108
|
expect(new Set(generatedKeys)).toEqual(new Set(operationKeys));
|
|
109
109
|
});
|
|
110
110
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
|
2
2
|
import { unlink } from "node:fs/promises";
|
|
3
3
|
import type { Subprocess } from "bun";
|
|
4
|
+
import { fetchProfileSyncRejectionBanner } from "../commands/profile-sync";
|
|
4
5
|
import { getFreePort, SERVER_BOOT_HOOK_TIMEOUT_MS } from "./test-net";
|
|
5
6
|
|
|
6
7
|
let TEST_PORT = 0;
|
|
@@ -270,6 +271,108 @@ describe("GET /api/events", () => {
|
|
|
270
271
|
});
|
|
271
272
|
});
|
|
272
273
|
|
|
274
|
+
describe("GET /api/events — latestPerDataField", () => {
|
|
275
|
+
const AGENT = "profile-sync-latest-agent";
|
|
276
|
+
const ids: Record<string, string> = {};
|
|
277
|
+
|
|
278
|
+
beforeAll(async () => {
|
|
279
|
+
const seed: [string, string, string][] = [
|
|
280
|
+
["tools-old", "system.profile_sync_rejected", "toolsMd"],
|
|
281
|
+
["claude-rejected", "system.profile_sync_rejected", "claudeMd"],
|
|
282
|
+
["soul-reconciled", "system.profile_sync_reconciled", "soulMd"],
|
|
283
|
+
["tools-new", "system.profile_sync_rejected", "toolsMd"],
|
|
284
|
+
["claude-reconciled", "system.profile_sync_reconciled", "claudeMd"],
|
|
285
|
+
["soul-rejected", "system.profile_sync_rejected", "soulMd"],
|
|
286
|
+
];
|
|
287
|
+
for (const [key, event, field] of seed) {
|
|
288
|
+
const { body } = await post("/api/events", {
|
|
289
|
+
category: "system",
|
|
290
|
+
event,
|
|
291
|
+
status: event.endsWith("rejected") ? "error" : "ok",
|
|
292
|
+
source: "api",
|
|
293
|
+
agentId: AGENT,
|
|
294
|
+
data: { field, diskSize: 30_000, dbSize: 19_000, budget: 20_000, delta: 11_000 },
|
|
295
|
+
});
|
|
296
|
+
ids[key] = (body.event as { id: string }).id;
|
|
297
|
+
// createdAt has millisecond precision: keep the seed strictly ordered.
|
|
298
|
+
await Bun.sleep(5);
|
|
299
|
+
}
|
|
300
|
+
await post("/api/events", {
|
|
301
|
+
category: "system",
|
|
302
|
+
event: "system.profile_sync_conflict",
|
|
303
|
+
source: "api",
|
|
304
|
+
agentId: AGENT,
|
|
305
|
+
data: { field: "toolsMd" },
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
test("returns the newest event per (event, data.field) and confirms the mode", async () => {
|
|
310
|
+
const { status, body } = await get(
|
|
311
|
+
`/api/events?events=system.profile_sync_rejected,system.profile_sync_reconciled&dataFields=soulMd,claudeMd,toolsMd,identityMd&agentId=${AGENT}&latestPerDataField=true`,
|
|
312
|
+
);
|
|
313
|
+
expect(status).toBe(200);
|
|
314
|
+
expect(body.latestPerDataField).toBe(true);
|
|
315
|
+
const returned = (body.events as { id: string }[]).map((event) => event.id);
|
|
316
|
+
expect(returned).toEqual([
|
|
317
|
+
ids["soul-rejected"],
|
|
318
|
+
ids["claude-reconciled"],
|
|
319
|
+
ids["tools-new"],
|
|
320
|
+
ids["soul-reconciled"],
|
|
321
|
+
ids["claude-rejected"],
|
|
322
|
+
]);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
test("a single-event request keeps today's response shape", async () => {
|
|
326
|
+
const { status, body } = await get(
|
|
327
|
+
`/api/events?event=system.profile_sync_rejected&agentId=${AGENT}&dataField=toolsMd&limit=1`,
|
|
328
|
+
);
|
|
329
|
+
expect(status).toBe(200);
|
|
330
|
+
expect(Object.keys(body)).toEqual(["events"]);
|
|
331
|
+
expect((body.events as { id: string }[]).map((event) => event.id)).toEqual([ids["tools-new"]]);
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
test("rejects an unknown name in events", async () => {
|
|
335
|
+
const { status } = await get("/api/events?events=system.profile_sync_rejected,not.an.event");
|
|
336
|
+
expect(status).toBe(400);
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
test("rejects latestPerDataField without dataFields", async () => {
|
|
340
|
+
const { status } = await get(
|
|
341
|
+
"/api/events?events=system.profile_sync_rejected&latestPerDataField=true",
|
|
342
|
+
);
|
|
343
|
+
expect(status).toBe(400);
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
test("the profile-sync banner is identical through one batched call and 8 lookups", async () => {
|
|
347
|
+
const config = { apiUrl: BASE, apiKey: TEST_API_KEY, agentId: AGENT };
|
|
348
|
+
const eventRequests: string[] = [];
|
|
349
|
+
const recording = (async (input: string | URL | Request, init?: RequestInit) => {
|
|
350
|
+
const url = new URL(String(input));
|
|
351
|
+
if (url.pathname === "/api/events") eventRequests.push(url.search);
|
|
352
|
+
return fetch(input, init);
|
|
353
|
+
}) as typeof fetch;
|
|
354
|
+
// Simulates an API that predates latestPerDataField: drop the confirmation.
|
|
355
|
+
const legacy = (async (input: string | URL | Request, init?: RequestInit) => {
|
|
356
|
+
const response = await recording(input, init);
|
|
357
|
+
if (!new URL(String(input)).searchParams.has("latestPerDataField")) return response;
|
|
358
|
+
const { latestPerDataField: _dropped, ...rest } = await response.json();
|
|
359
|
+
return new Response(JSON.stringify(rest), { status: response.status });
|
|
360
|
+
}) as typeof fetch;
|
|
361
|
+
|
|
362
|
+
const batched = await fetchProfileSyncRejectionBanner(config, recording);
|
|
363
|
+
const batchedCalls = eventRequests.length;
|
|
364
|
+
eventRequests.length = 0;
|
|
365
|
+
const perField = await fetchProfileSyncRejectionBanner(config, legacy);
|
|
366
|
+
|
|
367
|
+
expect(batchedCalls).toBe(1);
|
|
368
|
+
expect(eventRequests).toHaveLength(9);
|
|
369
|
+
expect(batched).toContain(ids["tools-new"] ?? "missing");
|
|
370
|
+
expect(batched).toContain(ids["soul-rejected"] ?? "missing");
|
|
371
|
+
expect(batched).not.toContain(ids["claude-rejected"] ?? "missing");
|
|
372
|
+
expect(batched).toBe(perField);
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
|
|
273
376
|
describe("GET /api/events/counts", () => {
|
|
274
377
|
test("returns counts grouped by event name", async () => {
|
|
275
378
|
const { status, body } = await get("/api/events/counts");
|
|
@@ -32,23 +32,28 @@ afterEach(async () => {
|
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
describe("predefined extension catalog", () => {
|
|
35
|
-
test(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
35
|
+
test(
|
|
36
|
+
"every bundled entry passes the manifest schema and bundle validation",
|
|
37
|
+
async () => {
|
|
38
|
+
const catalog = getExtensionCatalog();
|
|
39
|
+
expect(Object.keys(catalog).sort()).toEqual([
|
|
40
|
+
"github-sender-allowlist",
|
|
41
|
+
"notify-on-complete",
|
|
42
|
+
"require-ticket-ref",
|
|
43
|
+
"require-verification-note",
|
|
44
|
+
"task-digest",
|
|
45
|
+
]);
|
|
46
|
+
for (const [name, entry] of Object.entries(catalog)) {
|
|
47
|
+
expect(entry.manifest.name).toBe(name);
|
|
48
|
+
expect(ExtensionManifestSchema.safeParse(entry.manifest).success).toBe(true);
|
|
49
|
+
const result = await validateBundle({ manifest: entry.manifest, files: entry.files });
|
|
50
|
+
expect(result).toMatchObject({ ok: true });
|
|
51
|
+
}
|
|
52
|
+
expect(getCatalogEntry("task-digest")?.manifestFile).toBe("manifest.yaml");
|
|
53
|
+
expect(getCatalogEntry("toString")).toBeNull();
|
|
54
|
+
},
|
|
55
|
+
{ timeout: 15_000 },
|
|
56
|
+
);
|
|
52
57
|
|
|
53
58
|
test("the generator reads YAML and JSON templates and their referenced files", async () => {
|
|
54
59
|
const dir = await templatesDir({
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
import * as dbClient from "../be/db-client";
|
|
21
21
|
import type { InstallExtensionArgs as ExtensionInstallBody } from "../be/extensions/db";
|
|
22
22
|
import { installExtension, listExtensionRuns } from "../be/extensions/db";
|
|
23
|
+
import { getCatalogEntry } from "../extensions/catalog";
|
|
23
24
|
import { disableExtension, enableExtension, stopExtensionRuntime } from "../extensions/lifecycle";
|
|
24
25
|
import { handleTasks } from "../http/tasks";
|
|
25
26
|
import { dispatchScheduleTarget } from "../scheduler/scheduler";
|
|
@@ -168,6 +169,112 @@ describe("extension task boundaries", () => {
|
|
|
168
169
|
expect(retried.status).toBe(201);
|
|
169
170
|
});
|
|
170
171
|
|
|
172
|
+
test("GitHub sender allowlist separates internal and external senders", async () => {
|
|
173
|
+
const template = getCatalogEntry("github-sender-allowlist");
|
|
174
|
+
if (!template) throw new Error("github-sender-allowlist is missing from the catalog");
|
|
175
|
+
const installed = await installExtension({
|
|
176
|
+
manifest: template.manifest,
|
|
177
|
+
files: template.files,
|
|
178
|
+
config: {
|
|
179
|
+
internal: ["tarasyarema", "harlequinetcie"],
|
|
180
|
+
external: ["fuvidani", "capchase-bot"],
|
|
181
|
+
reviewBots: ["review-bot"],
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
await enableExtension(installed.extension.id);
|
|
185
|
+
|
|
186
|
+
const createFromGitHub = (
|
|
187
|
+
description: string,
|
|
188
|
+
vcsAuthor: string,
|
|
189
|
+
taskType: string,
|
|
190
|
+
vcsUrl: string,
|
|
191
|
+
source: "github" | "api" = "github",
|
|
192
|
+
) =>
|
|
193
|
+
createTaskWithSiblingAwareness(
|
|
194
|
+
description,
|
|
195
|
+
{ source, vcsAuthor, taskType, vcsUrl },
|
|
196
|
+
{ origin: "webhook" },
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
await createFromGitHub(
|
|
200
|
+
"internal sender issue",
|
|
201
|
+
"HARLEQUINETCIE",
|
|
202
|
+
"github-issue",
|
|
203
|
+
"https://github.com/acme/project/issues/1",
|
|
204
|
+
);
|
|
205
|
+
await createFromGitHub(
|
|
206
|
+
"internal sender review",
|
|
207
|
+
"tarasyarema",
|
|
208
|
+
"github-review",
|
|
209
|
+
"https://github.com/acme/project/pull/2",
|
|
210
|
+
);
|
|
211
|
+
await createFromGitHub(
|
|
212
|
+
"external sender PR comment",
|
|
213
|
+
"FuViDaNi",
|
|
214
|
+
"github-comment",
|
|
215
|
+
"https://github.com/acme/project/pull/2",
|
|
216
|
+
);
|
|
217
|
+
await createFromGitHub(
|
|
218
|
+
"external sender PR assignment",
|
|
219
|
+
"capchase-bot",
|
|
220
|
+
"github-pr",
|
|
221
|
+
"https://github.com/acme/project/pull/3",
|
|
222
|
+
);
|
|
223
|
+
await createFromGitHub(
|
|
224
|
+
"external sender PR review",
|
|
225
|
+
"fuvidani",
|
|
226
|
+
"github-review",
|
|
227
|
+
"https://github.com/acme/project/pull/4",
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
await expect(
|
|
231
|
+
createFromGitHub(
|
|
232
|
+
"external sender issue comment",
|
|
233
|
+
"fuvidani",
|
|
234
|
+
"github-comment",
|
|
235
|
+
"https://github.com/acme/project/issues/5",
|
|
236
|
+
),
|
|
237
|
+
).rejects.toThrow('GitHub sender "fuvidani" is blocked: external senders are allowed only');
|
|
238
|
+
await expect(
|
|
239
|
+
createFromGitHub(
|
|
240
|
+
"unknown sender issue",
|
|
241
|
+
"unknown-user",
|
|
242
|
+
"github-issue",
|
|
243
|
+
"https://github.com/acme/project/issues/6",
|
|
244
|
+
),
|
|
245
|
+
).rejects.toThrow('GitHub sender "unknown-user" is blocked: sender is not on the internal');
|
|
246
|
+
|
|
247
|
+
await expect(
|
|
248
|
+
createFromGitHub(
|
|
249
|
+
"unknown sender review",
|
|
250
|
+
"unknown-user",
|
|
251
|
+
"github-review",
|
|
252
|
+
"https://github.com/acme/project/pull/7",
|
|
253
|
+
),
|
|
254
|
+
).rejects.toThrow('GitHub sender "unknown-user" is blocked: sender is not on the internal');
|
|
255
|
+
await createFromGitHub(
|
|
256
|
+
"review bot review",
|
|
257
|
+
"REVIEW-BOT",
|
|
258
|
+
"github-review",
|
|
259
|
+
"https://github.com/acme/project/pull/8",
|
|
260
|
+
);
|
|
261
|
+
await expect(
|
|
262
|
+
createFromGitHub(
|
|
263
|
+
"review bot PR comment",
|
|
264
|
+
"review-bot",
|
|
265
|
+
"github-comment",
|
|
266
|
+
"https://github.com/acme/project/pull/9",
|
|
267
|
+
),
|
|
268
|
+
).rejects.toThrow('GitHub sender "review-bot" is blocked: review bots are allowed only');
|
|
269
|
+
await createFromGitHub(
|
|
270
|
+
"non-GitHub source",
|
|
271
|
+
"unknown-user",
|
|
272
|
+
"github-issue",
|
|
273
|
+
"https://github.com/acme/project/issues/10",
|
|
274
|
+
"api",
|
|
275
|
+
);
|
|
276
|
+
});
|
|
277
|
+
|
|
171
278
|
test("scheduler and workflow executor provide their task creation origins", async () => {
|
|
172
279
|
const extension = await installSource(
|
|
173
280
|
"record-task-origin",
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
{
|
|
2
|
+
"models": {
|
|
3
|
+
"deal": {
|
|
4
|
+
"columns": {
|
|
5
|
+
"title": { "kind": "string", "required": true },
|
|
6
|
+
"stage": { "kind": "enum", "enum": ["lead", "qualified", "won", "lost"], "default": "lead" },
|
|
7
|
+
"owner": { "kind": "string" },
|
|
8
|
+
"value": { "kind": "number" },
|
|
9
|
+
"closeDate": { "kind": "date" }
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"queries": {
|
|
14
|
+
"deals": { "model": "deal", "sort": { "column": "createdAt", "dir": "desc" } },
|
|
15
|
+
"dealById": { "model": "deal", "filter": { "id": { "$param": "deal" } } }
|
|
16
|
+
},
|
|
17
|
+
"pages": {
|
|
18
|
+
"main": {
|
|
19
|
+
"params": { "deal": { "kind": "string" } },
|
|
20
|
+
"root": "root",
|
|
21
|
+
"elements": {
|
|
22
|
+
"root": {
|
|
23
|
+
"type": "Stack",
|
|
24
|
+
"props": { "gap": "lg" },
|
|
25
|
+
"children": ["board", "calendars", "activity", "dealDrawer"]
|
|
26
|
+
},
|
|
27
|
+
"board": {
|
|
28
|
+
"type": "Kanban",
|
|
29
|
+
"props": {
|
|
30
|
+
"data": { "$state": "/queries/deals/data" },
|
|
31
|
+
"loading": { "$state": "/queries/deals/loading" },
|
|
32
|
+
"columnField": "stage",
|
|
33
|
+
"columns": ["lead", "qualified", { "id": "won", "label": "Won" }, { "id": "lost", "label": "Lost" }],
|
|
34
|
+
"titleField": "title",
|
|
35
|
+
"cardFields": [
|
|
36
|
+
{ "key": "owner", "label": "Owner" },
|
|
37
|
+
{ "key": "value", "label": "Value", "kind": "number" }
|
|
38
|
+
],
|
|
39
|
+
"onMove": [
|
|
40
|
+
{
|
|
41
|
+
"action": "app.mutate",
|
|
42
|
+
"params": {
|
|
43
|
+
"model": "deal",
|
|
44
|
+
"op": "update",
|
|
45
|
+
"rowId": { "$row": "id" },
|
|
46
|
+
"values": { "stage": { "$row": "stage" } }
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"onCardClick": [
|
|
51
|
+
{ "action": "app.navigate", "params": { "page": "main", "params": { "deal": { "$row": "id" } } } }
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"calendars": { "type": "Grid", "props": { "columns": 2 }, "children": ["closeCalendar", "createdCalendar"] },
|
|
56
|
+
"closeCalendar": {
|
|
57
|
+
"type": "Calendar",
|
|
58
|
+
"props": {
|
|
59
|
+
"data": { "$state": "/queries/deals/data" },
|
|
60
|
+
"startField": "closeDate",
|
|
61
|
+
"titleField": "title",
|
|
62
|
+
"onSelect": [
|
|
63
|
+
{ "action": "app.navigate", "params": { "page": "main", "params": { "deal": { "$row": "id" } } } }
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"createdCalendar": {
|
|
68
|
+
"type": "Calendar",
|
|
69
|
+
"props": {
|
|
70
|
+
"data": { "$state": "/queries/deals/data" },
|
|
71
|
+
"startField": "createdAt",
|
|
72
|
+
"endField": "closeDate",
|
|
73
|
+
"titleField": "title"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"activity": {
|
|
77
|
+
"type": "ContributionGraph",
|
|
78
|
+
"props": {
|
|
79
|
+
"data": { "$state": "/queries/deals/data" },
|
|
80
|
+
"dateField": "createdAt",
|
|
81
|
+
"countField": "value",
|
|
82
|
+
"days": 180
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"dealDrawer": {
|
|
86
|
+
"type": "Drawer",
|
|
87
|
+
"props": { "param": "deal", "title": "Deal" },
|
|
88
|
+
"children": ["dealDetail"]
|
|
89
|
+
},
|
|
90
|
+
"dealDetail": {
|
|
91
|
+
"type": "DetailList",
|
|
92
|
+
"props": {
|
|
93
|
+
"data": { "$state": "/queries/dealById/data/0" },
|
|
94
|
+
"fields": [
|
|
95
|
+
{ "key": "title" },
|
|
96
|
+
{ "key": "stage", "kind": "badge" },
|
|
97
|
+
{ "key": "closeDate", "kind": "date" }
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"defaultPage": "main"
|
|
105
|
+
}
|