@desplega.ai/agent-swarm 1.131.0 → 1.133.1
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-w53mbns9.js → actions-cskpayd7.js} +11 -9
- package/dist/{anthropic-messages-rjmd2e7n.js → anthropic-messages-tpxtbx7b.js} +28 -12
- package/dist/{app-m9gwqsqv.js → app-ang77nbb.js} +8 -6
- package/dist/{assistant-bp65m6f3.js → assistant-b4exebdw.js} +16 -13
- package/dist/{azure-openai-responses-c0yjmbfd.js → azure-openai-responses-m3921t4y.js} +8 -8
- package/dist/{boot-reembed-62p0at2k.js → boot-reembed-ps2aftpb.js} +9 -7
- package/dist/{boot-reembed-xmfp6wdh.js → boot-reembed-znyk3nxb.js} +10 -8
- package/dist/{boot-scrub-logs-rr8q2dms.js → boot-scrub-logs-2ax3xgz1.js} +7 -5
- package/dist/{claude-adapter-2y47mrkd.js → claude-adapter-3ct8kgxw.js} +13 -9
- package/dist/{claude-managed-adapter-gv19tdew.js → claude-managed-adapter-akx4ntf2.js} +2 -2
- package/dist/{cli-t1xze5qh.js → cli-13w2hwkh.js} +1 -1
- package/dist/{cli-efxfnq6q.js → cli-1532szb1.js} +8 -6
- package/dist/{cli-d2tfkcga.js → cli-23d3rseb.js} +33 -17
- package/dist/{cli-nm5gtp1x.js → cli-2a75z9c5.js} +196 -7
- package/dist/{cli-fywms69x.js → cli-2t30rj0d.js} +1 -1
- package/dist/{cli-cvgjwnh1.js → cli-3c3tdgab.js} +10 -10
- package/dist/{cli-pm6xbh84.js → cli-3zzxa9jz.js} +46 -16
- package/dist/{cli-cdeg08wx.js → cli-4k6233gc.js} +1 -1
- package/dist/{cli-t55yw3a1.js → cli-5p2tz05r.js} +2 -2
- package/dist/{cli-0rcyq6d9.js → cli-5z2yhzvd.js} +125 -47
- package/dist/{cli-3kf51j15.js → cli-6zfq31nj.js} +9 -3
- package/dist/{cli-er3a4bb0.js → cli-8m9de10a.js} +6 -1
- package/dist/{cli-gm9cbhbq.js → cli-8t14vg9w.js} +27 -8
- package/dist/{cli-72q8m8gk.js → cli-9nfc2es8.js} +6 -6
- package/dist/{cli-5ze9rv97.js → cli-9ta3pwms.js} +11 -4
- package/dist/{cli-78xwvkhj.js → cli-avr0ns7z.js} +2 -2
- package/dist/{cli-n6h8qt8n.js → cli-c897wyhw.js} +12 -7
- package/dist/{cli-2q72qz2s.js → cli-dgk20ft7.js} +15 -6
- package/dist/cli-et1bbwqf.js +13 -0
- package/dist/{cli-bqw0mt1n.js → cli-f5w27pj3.js} +3 -3
- package/dist/{cli-2wadx7p2.js → cli-f8dre4bz.js} +2 -2
- package/dist/{cli-e7ckcg4v.js → cli-ftwpv451.js} +170 -387
- package/dist/{cli-g6b8x1h8.js → cli-g854s2dw.js} +1 -1
- package/dist/{cli-5kx36evn.js → cli-ggmdxeqa.js} +13 -8
- package/dist/cli-hkwfe3qj.js +530 -0
- package/dist/{cli-5dsbcjjw.js → cli-jqwnqx9m.js} +1 -1
- package/dist/{cli-9dr5qzc0.js → cli-ny122vh4.js} +21 -10
- package/dist/{cli-5v4rw6yd.js → cli-pvzqhbs9.js} +2 -2
- package/dist/cli-pzq5rjym.js +15 -0
- package/dist/{cli-xpxde7rm.js → cli-qes8ef67.js} +48 -30
- package/dist/{cli-sajgpkqg.js → cli-qs9hhsvb.js} +1723 -325
- package/dist/cli-qys3rhhz.js +27 -0
- package/dist/{cli-rzbpmxdr.js → cli-r6tpm37h.js} +2 -2
- package/dist/{cli-qv61hp37.js → cli-rch80c76.js} +2 -2
- package/dist/{cli-0258203w.js → cli-rpp0x4zy.js} +137 -17
- package/dist/{cli-5n6e5yfn.js → cli-s1k0wxhe.js} +12 -7
- package/dist/{cli-psh3c4va.js → cli-sfd9v7sj.js} +1 -1
- package/dist/{cli-70xqj0z3.js → cli-sh3ytsyj.js} +49 -39
- package/dist/{cli-zsspvvm2.js → cli-w1mp9jy7.js} +1 -1
- package/dist/{cli-d3x3x1c9.js → cli-xdb4mpnp.js} +2 -2
- package/dist/{cli-57khth04.js → cli-xmyqv00z.js} +120 -4
- package/dist/{cli-yw8vghx2.js → cli-xv8t8p3c.js} +65 -32
- package/dist/{cli-f1am9szv.js → cli-xxv5pn4f.js} +1 -1
- package/dist/{cli-t76vw5db.js → cli-y08jvxzx.js} +601 -140
- package/dist/{cli-a4jzdpa3.js → cli-zfbf3srj.js} +650 -245
- package/dist/{cli-a40rnf71.js → cli-zmq89k34.js} +6 -6
- package/dist/{cli-qmdnhpej.js → cli-zr9q011v.js} +23 -13
- package/dist/cli.js +22 -22
- package/dist/{codex-adapter-d24q75wk.js → codex-adapter-bef93pq4.js} +9 -7
- package/dist/{codex-hook-hq54t9ft.js → codex-hook-e8dba65p.js} +3 -2
- package/dist/{codex-session-runner-g50vcsex.js → codex-session-runner-5pkxys7x.js} +9 -7
- package/dist/{commands-c3nrc5hg.js → commands-e23s1bff.js} +9 -7
- package/dist/{db-nt7fg3tw.js → db-m3nabatn.js} +17 -5
- package/dist/{google-generative-ai-hysrd8qx.js → google-generative-ai-8maw55xh.js} +11 -8
- package/dist/{google-vertex-p5arrga0.js → google-vertex-8vjqmx8g.js} +11 -8
- package/dist/{handlers-fkr6swat.js → handlers-akazedvr.js} +16 -13
- package/dist/{hook-77wpvnjc.js → hook-ze4cpf0v.js} +55 -41
- package/dist/{hook-g019yehy.js → hook-zfqyyenw.js} +10 -7
- package/dist/{http-jewj0syk.js → http-sja0n6kw.js} +730 -150
- package/dist/index-0gr8vd6k.js +39 -0
- package/dist/{index-7n2xpbd4.js → index-354vkhdv.js} +154 -74
- package/dist/{index-070v4eyb.js → index-5qthek5t.js} +2 -3
- package/dist/{index-hfvggd0z.js → index-95t3cqq5.js} +16 -14
- package/dist/{index-9znhar3x.js → index-sea66619.js} +3 -4
- package/dist/{index-6gm5he8h.js → index-vpn36mma.js} +15 -13
- package/dist/{keepalive-j0fjvqfd.js → keepalive-3sp3meqj.js} +16 -10
- package/dist/{lead-1n8x30xe.js → lead-mefeewkf.js} +39 -36
- package/dist/{maintenance-gvev11sa.js → maintenance-8tbrbjfg.js} +10 -8
- package/dist/mistral-conversations-00zrp7g4.js +717 -0
- package/dist/{oauth-refresh-sweep-s9ecsvh0.js → oauth-refresh-sweep-srjwjz6m.js} +8 -6
- package/dist/{onboard-pvm5b38w.js → onboard-mt2tgyjg.js} +7 -7
- package/dist/{openai-codex-responses-5g27pd6f.js → openai-codex-responses-map32h2s.js} +18 -18
- package/dist/{openai-completions-3vkmfz2a.js → openai-completions-w871b1cq.js} +12 -11
- package/dist/{openai-responses-dg4t7j7a.js → openai-responses-b0j7xnw8.js} +15 -12
- package/dist/{opencode-adapter-1gm38aba.js → opencode-adapter-b39jefcj.js} +5 -3
- package/dist/{openrouter-images-g3gm8931.js → openrouter-images-srfkywy0.js} +4 -4
- package/dist/{otel-impl-p6jvgd9c.js → otel-impl-z6pxt3j9.js} +224 -9
- package/dist/{pi-mono-adapter-t091s27g.js → pi-mono-adapter-btvqmj58.js} +1138 -408
- package/dist/{pricing-refresh-k49rcyed.js → pricing-refresh-kyq8cezh.js} +9 -7
- package/dist/{rbac-roles-cr80g96t.js → rbac-roles-3ryfrfna.js} +8 -6
- package/dist/{rbac-roles-30pspvy7.js → rbac-roles-6qfvbee1.js} +9 -7
- package/dist/{render-v2-xm457ng1.js → render-v2-p61ppjey.js} +8 -6
- package/dist/{seed-pricing-yhpv35fr.js → seed-pricing-j56bbj4y.js} +8 -6
- package/dist/{setup-nytnmwwr.js → setup-tpr6c1kn.js} +2 -2
- package/dist/{worker-msytr2cw.js → worker-9w1v0mbb.js} +39 -36
- package/openapi.json +542 -16
- package/package.json +6 -6
- package/src/be/budget-refusal-notify.ts +14 -7
- package/src/be/db-queries/task-artifacts.ts +182 -0
- package/src/be/db.ts +783 -169
- package/src/be/events.ts +5 -0
- package/src/be/migrations/130_scratch_script_retention_grace.sql +6 -0
- package/src/be/migrations/131_session_logs_created_at_index.sql +2 -0
- package/src/be/migrations/132_multi_runtime_instances.sql +44 -0
- package/src/be/migrations/133_workflow_run_trigger_type.sql +12 -0
- package/src/be/migrations/135_backfill_task_pull_request_attachments.sql +228 -0
- package/src/be/migrations/136_task_requester_provenance.sql +37 -0
- package/src/be/migrations/137_memory_retrieval_composite_index.sql +1 -0
- package/src/be/multi-runtime.ts +430 -0
- package/src/be/scripts/db.ts +43 -1
- package/src/be/scripts/extract-schema.ts +3 -1
- package/src/be/scripts/retention.ts +164 -0
- package/src/be/scripts/run-saved.ts +16 -1
- package/src/be/scripts/typecheck.ts +3 -2
- package/src/be/seed-skills/index.ts +7 -0
- package/src/be/steering.ts +1 -1
- package/src/be/swarm-config-guard.ts +18 -0
- package/src/commands/credential-wait.ts +54 -0
- package/src/commands/onboard/steps/core-credentials.tsx +1 -1
- package/src/commands/onboard/steps/custom-templates.tsx +1 -1
- package/src/commands/onboard/steps/harness-credentials.tsx +1 -1
- package/src/commands/onboard/steps/health-check.tsx +1 -1
- package/src/commands/onboard/steps/start.tsx +1 -1
- package/src/commands/profile-sync-audit.ts +56 -0
- package/src/commands/profile-sync.ts +287 -15
- package/src/commands/provider-credentials.ts +46 -19
- package/src/commands/runner.ts +196 -33
- package/src/commands/templates.ts +22 -0
- package/src/github/handlers.ts +55 -9
- package/src/heartbeat/heartbeat.ts +71 -12
- package/src/hooks/hook.ts +49 -33
- package/src/http/active-sessions.ts +11 -1
- package/src/http/agents.ts +261 -30
- package/src/http/all-routes.ts +1 -0
- package/src/http/config.ts +13 -2
- package/src/http/core.ts +102 -4
- package/src/http/db-query-bounded.ts +313 -0
- package/src/http/db-query-shared.ts +249 -0
- package/src/http/db-query.ts +54 -42
- package/src/http/events.ts +2 -0
- package/src/http/index.ts +27 -2
- package/src/http/mcp-bridge.ts +37 -3
- package/src/http/mcp.ts +12 -0
- package/src/http/memory.ts +13 -2
- package/src/http/openapi.ts +1 -0
- package/src/http/poll.ts +70 -27
- package/src/http/route-def.ts +43 -9
- package/src/http/schedules.ts +2 -2
- package/src/http/scripts.ts +31 -4
- package/src/http/session-data.ts +44 -0
- package/src/http/tasks.ts +2 -2
- package/src/http/users.ts +74 -52
- package/src/http/webhooks.ts +5 -2
- package/src/http/workflows.ts +1 -4
- package/src/http/x.ts +14 -0
- package/src/integrations/kapso/inbound.ts +1 -1
- package/src/jira/outbound.ts +39 -8
- package/src/jira/webhook-lifecycle.ts +13 -2
- package/src/linear/outbound.ts +43 -10
- package/src/oauth/keepalive.ts +13 -2
- package/src/prompts/base-prompt.ts +1 -1
- package/src/prompts/session-templates.ts +45 -7
- package/src/providers/claude-adapter.ts +6 -0
- package/src/providers/claude-managed-models.ts +34 -10
- package/src/providers/codex-adapter.ts +6 -0
- package/src/providers/opencode-adapter.ts +6 -0
- package/src/providers/pi-mono-adapter.ts +8 -0
- package/src/providers/pricing-sources.md +24 -0
- package/src/queue-stall-alarm.ts +216 -0
- package/src/scheduler/scheduler.ts +7 -0
- package/src/script-workflows/executor.ts +2 -1
- package/src/scripts-runtime/executors/native.ts +2 -1
- package/src/scripts-runtime/executors/types.ts +5 -0
- package/src/scripts-runtime/loader.ts +5 -0
- package/src/scripts-runtime/swarm-config.ts +8 -0
- package/src/scripts-runtime/swarm-sdk.ts +7 -0
- package/src/scripts-runtime/types/stdlib.d.ts +1 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -0
- package/src/tests/budget-claim-gate.test.ts +20 -0
- package/src/tests/claude-adapter.test.ts +32 -0
- package/src/tests/claude-managed-adapter.test.ts +38 -7
- package/src/tests/codex-adapter.test.ts +30 -0
- package/src/tests/create-task-validation.test.ts +128 -0
- package/src/tests/credential-wait.test.ts +67 -1
- package/src/tests/db-query.test.ts +711 -2
- package/src/tests/http-api-integration.test.ts +81 -0
- package/src/tests/http-users.test.ts +166 -1
- package/src/tests/identity-field-budget.test.ts +176 -0
- package/src/tests/mcp-tools-user.test.ts +34 -0
- package/src/tests/mcp-user-route.test.ts +17 -0
- package/src/tests/metrics-http.test.ts +44 -0
- package/src/tests/multi-runtime-registration.test.ts +2703 -0
- package/src/tests/openapi-response-contract.test.ts +24 -0
- package/src/tests/openapi-route-headers.test.ts +83 -0
- package/src/tests/opencode-adapter.test.ts +40 -0
- package/src/tests/outbound-listener-rejection.test.ts +138 -0
- package/src/tests/pi-mono-adapter.test.ts +98 -0
- package/src/tests/profile-sync-warning.test.ts +277 -0
- package/src/tests/profile-sync.test.ts +232 -6
- package/src/tests/prompt-template-session.test.ts +32 -3
- package/src/tests/queue-stall-alarm.test.ts +226 -0
- package/src/tests/requester-comms.test.ts +32 -0
- package/src/tests/runner-requester-profile.test.ts +38 -0
- package/src/tests/sandboxed-process.test.ts +45 -0
- package/src/tests/schedule-target-type.test.ts +38 -0
- package/src/tests/script-connections.test.ts +16 -3
- package/src/tests/scripts-external-api.test.ts +8 -3
- package/src/tests/scripts-http.test.ts +12 -0
- package/src/tests/scripts-retention.test.ts +384 -0
- package/src/tests/scripts-runtime-identity.test.ts +375 -0
- package/src/tests/scripts-runtime.test.ts +4 -3
- package/src/tests/sdk-allowlist.test.ts +47 -0
- package/src/tests/send-task-requested-by.test.ts +9 -0
- package/src/tests/session-costs.test.ts +506 -1
- package/src/tests/shutdown-error-scrubbing.test.ts +92 -0
- package/src/tests/steering-core.test.ts +28 -0
- package/src/tests/task-artifacts.test.ts +386 -0
- package/src/tests/task-attachments-schema.test.ts +17 -1
- package/src/tests/task-completion-idempotency.test.ts +57 -0
- package/src/tests/task-pull-request-backfill-migration.test.ts +321 -0
- package/src/tests/update-profile-api.test.ts +67 -39
- package/src/tests/update-profile-auth.test.ts +48 -4
- package/src/tests/user-attribution-migration.test.ts +54 -0
- package/src/tests/user-identity.test.ts +72 -0
- package/src/tests/workflow-async-v2.test.ts +39 -1
- package/src/tests/workflow-http-v2.test.ts +3 -2
- package/src/tests/workflow-mcp-trigger-schema.test.ts +52 -3
- package/src/tests/workflow-retry-v2.test.ts +45 -1
- package/src/tests/workflow-swarm-script.test.ts +14 -5
- package/src/tools/db-query.ts +18 -8
- package/src/tools/get-task-details.ts +24 -3
- package/src/tools/manage-user.ts +36 -3
- package/src/tools/poll-task.ts +93 -14
- package/src/tools/script-common.ts +5 -0
- package/src/tools/send-task.ts +1 -4
- package/src/tools/store-progress.ts +13 -2
- package/src/tools/swarm-config/delete-config.ts +9 -0
- package/src/tools/swarm-config/set-config.ts +3 -2
- package/src/tools/task-action.ts +30 -0
- package/src/tools/task-tool-ctx.ts +8 -1
- package/src/tools/update-profile.ts +16 -21
- package/src/tools/utils.ts +5 -0
- package/src/tools/workflows/trigger-workflow.ts +7 -1
- package/src/types.ts +165 -1
- package/src/utils/github-pull-request.ts +76 -0
- package/src/utils/identity-field-budget.ts +73 -0
- package/src/utils/multi-runtime.ts +20 -0
- package/src/utils/requester-comms.ts +24 -0
- package/src/utils/sandboxed-process.ts +40 -14
- package/src/workflows/engine.ts +22 -2
- package/src/workflows/executors/swarm-script.ts +24 -1
- package/src/workflows/resume.ts +19 -11
- package/src/workflows/retry-poller.ts +1 -0
- package/src/workflows/triggers.ts +4 -0
- package/templates/schedules/daily-compounding-reflection/content.md +12 -3
- package/templates/skills/db-query-guidance/config.json +14 -0
- package/templates/skills/db-query-guidance/content.md +57 -0
- package/dist/cli-3te4jdkm.js +0 -225
- package/dist/cli-bmze986d.js +0 -7
- package/dist/cli-kh3ba2zf.js +0 -607
- package/dist/index-hp1kdbjj.js +0 -36
- package/dist/mistral-conversations-81fwav0j.js +0 -30578
- package/dist/otel-nqa12wf3.js +0 -3149
- package/dist/{pi-messages-tqj8q6b9.js → pi-messages-sssy32x4.js} +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@desplega.ai/agent-swarm",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.133.1",
|
|
4
4
|
"description": "agent-swarm.dev — an open-source operating system for AI work: a lead agent breaks goals into tasks, routes them to specialized workers such as Claude Code or Codex, runs each worker in an isolated container, and preserves shared memory, tools, schedules, and review gates so delegated work compounds across sessions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-swarm.dev",
|
|
@@ -169,14 +169,14 @@
|
|
|
169
169
|
"@aws-sdk/client-bedrock": "3.1048.0",
|
|
170
170
|
"@desplega.ai/business-use": "^0.4.2",
|
|
171
171
|
"@desplega.ai/localtunnel": "^2.2.0",
|
|
172
|
-
"@earendil-works/pi-agent-core": "^0.84.
|
|
173
|
-
"@earendil-works/pi-ai": "^0.84.
|
|
174
|
-
"@earendil-works/pi-coding-agent": "^0.84.
|
|
172
|
+
"@earendil-works/pi-agent-core": "^0.84.2",
|
|
173
|
+
"@earendil-works/pi-ai": "^0.84.2",
|
|
174
|
+
"@earendil-works/pi-coding-agent": "^0.84.2",
|
|
175
175
|
"@inkjs/ui": "^2.0.0",
|
|
176
176
|
"@linear/sdk": "^77.0.0",
|
|
177
177
|
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
178
|
-
"@openai/codex-sdk": "^0.
|
|
179
|
-
"@opencode-ai/sdk": "^1.18.
|
|
178
|
+
"@openai/codex-sdk": "^0.148.0",
|
|
179
|
+
"@opencode-ai/sdk": "^1.18.18",
|
|
180
180
|
"@openfort/openfort-node": "^0.9.1",
|
|
181
181
|
"@opentelemetry/api": "^1.9.1",
|
|
182
182
|
"@opentelemetry/exporter-metrics-otlp-http": "^0.218.0",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import { resolveTemplate } from "../prompts/resolver";
|
|
16
16
|
import type { AgentTask } from "../types";
|
|
17
|
+
import { scrubSecrets } from "../utils/secret-scrubber";
|
|
17
18
|
import {
|
|
18
19
|
createTaskExtended,
|
|
19
20
|
getAgentById,
|
|
@@ -139,8 +140,12 @@ export function emitBudgetRefusalSideEffects(ctx: BudgetRefusalContext, inserted
|
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
// 2. Workflow event bus emit — every refusal, not just the first per day.
|
|
142
|
-
|
|
143
|
-
|
|
143
|
+
// Mirrors the emit pattern in db.ts — any failure here (e.g. event bus module
|
|
144
|
+
// load error) must not break the refusal path. The rejection is caught on the
|
|
145
|
+
// promise rather than in a `try` block, because the callback runs after the
|
|
146
|
+
// surrounding frame has already returned.
|
|
147
|
+
import("../workflows/event-bus")
|
|
148
|
+
.then(({ workflowEventBus }) => {
|
|
144
149
|
workflowEventBus.emit("task.budget_refused", {
|
|
145
150
|
taskId: ctx.task.id,
|
|
146
151
|
agentId: ctx.agentId,
|
|
@@ -153,9 +158,11 @@ export function emitBudgetRefusalSideEffects(ctx: BudgetRefusalContext, inserted
|
|
|
153
158
|
userBudgetUsd: ctx.userBudgetUsd,
|
|
154
159
|
resetAt: ctx.resetAt,
|
|
155
160
|
});
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
+
})
|
|
162
|
+
.catch((err) =>
|
|
163
|
+
console.error(
|
|
164
|
+
"[budget-refusal-notify] task.budget_refused event not emitted:",
|
|
165
|
+
scrubSecrets(err instanceof Error ? err.message : String(err)),
|
|
166
|
+
),
|
|
167
|
+
);
|
|
161
168
|
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { extractGitHubPullRequestUrls } from "../../utils/github-pull-request";
|
|
2
|
+
import { getDb } from "../db";
|
|
3
|
+
|
|
4
|
+
export type TaskShippingEvidenceSource = "attachment" | "output-fallback" | "none";
|
|
5
|
+
|
|
6
|
+
export interface TaskShippingEvidence {
|
|
7
|
+
hasArtifact: boolean;
|
|
8
|
+
hasPullRequest: boolean;
|
|
9
|
+
pullRequestUrls: string[];
|
|
10
|
+
pullRequestSource: TaskShippingEvidenceSource;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function taskAlias(alias: string): string {
|
|
14
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(alias)) {
|
|
15
|
+
throw new Error(`Invalid task SQL alias: ${alias}`);
|
|
16
|
+
}
|
|
17
|
+
return alias;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ECMAScript whitespace plus prose wrappers that terminate URL-like tokens.
|
|
21
|
+
const githubTokenDelimiterCodePoints = [
|
|
22
|
+
9, 10, 11, 12, 13, 160, 5760, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202,
|
|
23
|
+
8232, 8233, 8239, 8287, 12288, 65279, 40, 41, 91, 93, 123, 125, 60, 62, 34, 39, 96,
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
function githubTokenDelimitersSql(): string {
|
|
27
|
+
return githubTokenDelimiterCodePoints.map((code, index) => `(${index + 1}, ${code})`).join(", ");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Keep aggregate SQL matching aligned with extractGitHubPullRequestUrls(). */
|
|
31
|
+
function githubPullRequestExistsSql(value: string): string {
|
|
32
|
+
return `EXISTS (
|
|
33
|
+
WITH RECURSIVE
|
|
34
|
+
token_delimiters(position, code_point) AS (
|
|
35
|
+
VALUES ${githubTokenDelimitersSql()}
|
|
36
|
+
),
|
|
37
|
+
normalized(value, position) AS (
|
|
38
|
+
SELECT coalesce(${value}, ''), 0
|
|
39
|
+
|
|
40
|
+
UNION ALL
|
|
41
|
+
|
|
42
|
+
SELECT replace(value, char(code_point), ' '), normalized.position + 1
|
|
43
|
+
FROM normalized
|
|
44
|
+
JOIN token_delimiters ON token_delimiters.position = normalized.position + 1
|
|
45
|
+
),
|
|
46
|
+
tokens(remaining, token) AS (
|
|
47
|
+
SELECT trim(value) || ' ', NULL
|
|
48
|
+
FROM normalized
|
|
49
|
+
WHERE position = (SELECT max(position) FROM token_delimiters)
|
|
50
|
+
|
|
51
|
+
UNION ALL
|
|
52
|
+
|
|
53
|
+
SELECT
|
|
54
|
+
ltrim(substr(remaining, instr(remaining, ' ') + 1)),
|
|
55
|
+
substr(remaining, 1, instr(remaining, ' ') - 1)
|
|
56
|
+
FROM tokens
|
|
57
|
+
WHERE remaining <> ''
|
|
58
|
+
),
|
|
59
|
+
github_paths(path) AS (
|
|
60
|
+
SELECT CASE
|
|
61
|
+
WHEN lower(token) GLOB 'https://github.com/*'
|
|
62
|
+
THEN substr(token, length('https://github.com/') + 1)
|
|
63
|
+
WHEN lower(token) GLOB 'http://github.com/*'
|
|
64
|
+
THEN substr(token, length('http://github.com/') + 1)
|
|
65
|
+
ELSE substr(token, length('github.com/') + 1)
|
|
66
|
+
END
|
|
67
|
+
FROM tokens
|
|
68
|
+
WHERE lower(token) GLOB 'https://github.com/*'
|
|
69
|
+
OR lower(token) GLOB 'http://github.com/*'
|
|
70
|
+
OR lower(token) GLOB 'github.com/*'
|
|
71
|
+
),
|
|
72
|
+
github_segments(owner, repo, remainder) AS (
|
|
73
|
+
SELECT
|
|
74
|
+
substr(path, 1, instr(path, '/') - 1),
|
|
75
|
+
substr(
|
|
76
|
+
substr(path, instr(path, '/') + 1),
|
|
77
|
+
1,
|
|
78
|
+
instr(substr(path, instr(path, '/') + 1), '/') - 1
|
|
79
|
+
),
|
|
80
|
+
substr(
|
|
81
|
+
substr(path, instr(path, '/') + 1),
|
|
82
|
+
instr(substr(path, instr(path, '/') + 1), '/') + 1
|
|
83
|
+
)
|
|
84
|
+
FROM github_paths
|
|
85
|
+
WHERE instr(path, '/') > 1
|
|
86
|
+
AND instr(substr(path, instr(path, '/') + 1), '/') > 1
|
|
87
|
+
),
|
|
88
|
+
github_pull_numbers(remainder, position) AS (
|
|
89
|
+
SELECT remainder, length('pull/') + 1
|
|
90
|
+
FROM github_segments
|
|
91
|
+
WHERE owner NOT GLOB '*[^A-Za-z0-9._-]*'
|
|
92
|
+
AND repo NOT GLOB '*[^A-Za-z0-9._-]*'
|
|
93
|
+
AND owner NOT IN ('.', '..')
|
|
94
|
+
AND repo NOT IN ('.', '..')
|
|
95
|
+
AND lower(remainder) GLOB 'pull/[0-9]*'
|
|
96
|
+
|
|
97
|
+
UNION ALL
|
|
98
|
+
|
|
99
|
+
SELECT remainder, position + 1
|
|
100
|
+
FROM github_pull_numbers
|
|
101
|
+
WHERE substr(remainder, position, 1) GLOB '[0-9]'
|
|
102
|
+
)
|
|
103
|
+
SELECT 1
|
|
104
|
+
FROM github_pull_numbers
|
|
105
|
+
WHERE substr(remainder, position, 1) NOT GLOB '[0-9]'
|
|
106
|
+
AND (
|
|
107
|
+
substr(remainder, position, 1) = ''
|
|
108
|
+
OR substr(remainder, position, 1) IN ('/', '?', '#')
|
|
109
|
+
OR trim(substr(remainder, position), ')]},.;:!') = ''
|
|
110
|
+
)
|
|
111
|
+
LIMIT 1
|
|
112
|
+
)`;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* SQL expressions for aggregate task-reporting queries. Attachment rows are
|
|
117
|
+
* authoritative; output matching remains a compatibility fallback while old
|
|
118
|
+
* databases are upgraded/backfilled.
|
|
119
|
+
*/
|
|
120
|
+
export function taskShippingEvidenceSql(alias = "t"): {
|
|
121
|
+
hasArtifact: string;
|
|
122
|
+
hasPullRequest: string;
|
|
123
|
+
} {
|
|
124
|
+
const t = taskAlias(alias);
|
|
125
|
+
const outputHasPullRequest = githubPullRequestExistsSql(`${t}.output`);
|
|
126
|
+
const hasAnyAttachment = `EXISTS (
|
|
127
|
+
SELECT 1 FROM task_attachments ta WHERE ta.task_id = ${t}.id
|
|
128
|
+
)`;
|
|
129
|
+
const hasPullRequestAttachment = `EXISTS (
|
|
130
|
+
SELECT 1 FROM task_attachments ta
|
|
131
|
+
WHERE ta.task_id = ${t}.id
|
|
132
|
+
AND ta.kind = 'url'
|
|
133
|
+
AND ${githubPullRequestExistsSql("ta.url")}
|
|
134
|
+
)`;
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
hasArtifact: `CASE WHEN ${hasAnyAttachment} THEN 1 WHEN ${outputHasPullRequest} THEN 1 ELSE 0 END`,
|
|
138
|
+
hasPullRequest: `CASE WHEN ${hasPullRequestAttachment} THEN 1 WHEN ${outputHasPullRequest} THEN 1 ELSE 0 END`,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Look up one task's attachment-first shipping evidence. */
|
|
143
|
+
export function getTaskShippingEvidence(taskId: string): TaskShippingEvidence | null {
|
|
144
|
+
const task = getDb()
|
|
145
|
+
.prepare<{ output: string | null }, [string]>("SELECT output FROM agent_tasks WHERE id = ?")
|
|
146
|
+
.get(taskId);
|
|
147
|
+
if (!task) return null;
|
|
148
|
+
|
|
149
|
+
const attachments = getDb()
|
|
150
|
+
.prepare<{ kind: string; url: string | null }, [string]>(
|
|
151
|
+
"SELECT kind, url FROM task_attachments WHERE task_id = ? ORDER BY created_at, rowid",
|
|
152
|
+
)
|
|
153
|
+
.all(taskId);
|
|
154
|
+
const attachmentPullRequests = Array.from(
|
|
155
|
+
new Set(
|
|
156
|
+
attachments.flatMap((attachment) =>
|
|
157
|
+
attachment.kind === "url"
|
|
158
|
+
? extractGitHubPullRequestUrls(attachment.url).map((pullRequest) => pullRequest.url)
|
|
159
|
+
: [],
|
|
160
|
+
),
|
|
161
|
+
),
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
if (attachmentPullRequests.length > 0) {
|
|
165
|
+
return {
|
|
166
|
+
hasArtifact: true,
|
|
167
|
+
hasPullRequest: true,
|
|
168
|
+
pullRequestUrls: attachmentPullRequests,
|
|
169
|
+
pullRequestSource: "attachment",
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const fallbackPullRequests = extractGitHubPullRequestUrls(task.output).map(
|
|
174
|
+
(pullRequest) => pullRequest.url,
|
|
175
|
+
);
|
|
176
|
+
return {
|
|
177
|
+
hasArtifact: attachments.length > 0 || fallbackPullRequests.length > 0,
|
|
178
|
+
hasPullRequest: fallbackPullRequests.length > 0,
|
|
179
|
+
pullRequestUrls: fallbackPullRequests,
|
|
180
|
+
pullRequestSource: fallbackPullRequests.length > 0 ? "output-fallback" : "none",
|
|
181
|
+
};
|
|
182
|
+
}
|