@desplega.ai/agent-swarm 1.136.0 → 1.138.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 +12 -3
- package/dist/acp-adapter-6nttxe2q.js +4787 -0
- package/dist/{actions-agcbc8nd.js → actions-z9dzgh3f.js} +7 -8
- package/dist/{app-g2s78xya.js → app-wb6bc7tt.js} +4 -5
- package/dist/{assistant-yd3jkb9d.js → assistant-08pd6pgy.js} +9 -10
- package/dist/{boot-reembed-6spqw4q0.js → boot-reembed-hstr4e2c.js} +4 -4
- package/dist/{boot-reembed-b22s9w5x.js → boot-reembed-y7p7qjbf.js} +5 -5
- package/dist/{boot-scrub-logs-6h3cqkc0.js → boot-scrub-logs-azbnxwhn.js} +3 -3
- package/dist/{claude-adapter-ng5y8zd7.js → claude-adapter-rwaq6eda.js} +10 -9
- package/dist/{claude-managed-adapter-5zr3n86v.js → claude-managed-adapter-vtseey1x.js} +3 -3
- package/dist/{cli-qckgdqmr.js → cli-005yr57a.js} +2 -2
- package/dist/{cli-54ht104h.js → cli-0cka8dnm.js} +3 -3
- package/dist/{cli-gpdtxzar.js → cli-23cpnqk9.js} +1 -1
- package/dist/{cli-qhfkxrpg.js → cli-2ypjdmqg.js} +223 -474
- package/dist/{cli-bnq8h7ea.js → cli-3719ggyf.js} +17 -10
- package/dist/cli-390sgxn5.js +257 -0
- package/dist/{cli-z6e8eqrm.js → cli-47esr8ht.js} +2 -2
- package/dist/{cli-jjhnma34.js → cli-4jaj24py.js} +248 -101
- package/dist/{cli-6gwgzdgw.js → cli-69377c2a.js} +5 -5
- package/dist/{cli-ads0hfw2.js → cli-6v4d8r8c.js} +205 -75
- package/dist/{cli-mgef08pc.js → cli-8rtyss6g.js} +1 -1
- package/dist/{cli-35jknh9e.js → cli-9w7vsmbm.js} +5 -5
- package/dist/{cli-m3z53bed.js → cli-b4zdc3x6.js} +1 -1
- package/dist/{cli-fpjmcbhz.js → cli-ba87cw29.js} +4 -4
- package/dist/{cli-4gzv54ss.js → cli-bzk75kdc.js} +43 -11
- package/dist/{cli-d5ygfv18.js → cli-cywkhzqs.js} +35 -11
- package/dist/{cli-0crn5kaz.js → cli-d62cd9qs.js} +16 -4
- package/dist/{cli-5bnz1t86.js → cli-f9skf1v7.js} +51 -7
- package/dist/{cli-06ghj6pe.js → cli-fytpjraz.js} +4 -4
- package/dist/{cli-j7qp8gtf.js → cli-h7c5dam1.js} +16 -11
- package/dist/{cli-4r4jkqep.js → cli-kkn46gfr.js} +9 -3
- package/dist/{cli-tmn19cdz.js → cli-kq9htgbr.js} +415 -62
- package/dist/{cli-8v57p983.js → cli-pkmqqxp8.js} +45 -69
- package/dist/{cli-84vrhesc.js → cli-qf34ej1d.js} +1 -1
- package/dist/{cli-v3qda694.js → cli-rnyttbh0.js} +0 -5
- package/dist/cli-rx5cxzn2.js +7 -0
- package/dist/{cli-cw70hymf.js → cli-s25avqg9.js} +2 -0
- package/dist/{cli-tee8w7tq.js → cli-s6t1qv67.js} +15 -10
- package/dist/{cli-68vayryq.js → cli-tb4csb08.js} +2 -2
- package/dist/{cli-y16cesaq.js → cli-vy48y9bx.js} +2 -2
- package/dist/{cli-3y553gws.js → cli-y294regh.js} +1 -1
- package/dist/{cli-spf767vc.js → cli-y43043ws.js} +1 -1
- package/dist/{cli-hz5hp6wn.js → cli-yh2eybyt.js} +1 -1
- package/dist/{cli-edwrx42s.js → cli-zmyxt25p.js} +5 -5
- package/dist/cli.js +40 -18
- package/dist/{codex-adapter-kw11ps3j.js → codex-adapter-yzep6mvb.js} +7 -6
- package/dist/{codex-session-runner-sffb69v7.js → codex-session-runner-25e8tn72.js} +7 -6
- package/dist/{commands-0xxp4tz8.js → commands-0vv72d6a.js} +3 -3
- package/dist/{db-0npp39zd.js → db-x61ncfa1.js} +19 -3
- package/dist/{google-generative-ai-6xxdj4t3.js → google-generative-ai-zyhy3dab.js} +1 -1
- package/dist/{google-vertex-zma18wb0.js → google-vertex-t25h65yd.js} +1 -1
- package/dist/{handlers-5p7a1jx6.js → handlers-fwdcaahf.js} +9 -10
- package/dist/{hook-jjpxn4se.js → hook-mpwfgynm.js} +6 -5
- package/dist/{hook-hpefr0a8.js → hook-x18504ja.js} +8 -7
- package/dist/{http-wfp33653.js → http-83m6qdds.js} +590 -192
- package/dist/{index-pe58mf1r.js → index-1nsdwvn5.js} +2 -1
- package/dist/{index-17h657rg.js → index-38f98ck3.js} +9 -9
- package/dist/{index-m2p7ctyh.js → index-7kxvtd38.js} +24 -12
- package/dist/{index-racb4wfq.js → index-a4naswjn.js} +23 -10
- package/dist/{index-p13cfsc2.js → index-agykc6k2.js} +2 -1
- package/dist/{index-zh66wm65.js → index-dawtzfhw.js} +22 -9
- package/dist/{keepalive-wxjd633a.js → keepalive-y0m8g5wn.js} +5 -5
- package/dist/{lead-359ec2z0.js → lead-ka18ef6a.js} +36 -36
- package/dist/{maintenance-rr03qjtb.js → maintenance-x585p56c.js} +5 -5
- package/dist/{oauth-refresh-sweep-jwj22yb8.js → oauth-refresh-sweep-kdm9vj7a.js} +4 -4
- package/dist/{onboard-asnhchcv.js → onboard-5v229nvt.js} +664 -248
- package/dist/{opencode-adapter-sx38y7f7.js → opencode-adapter-46nnmnvv.js} +3 -3
- package/dist/{otel-impl-54cra6mw.js → otel-impl-k47aj4sd.js} +73 -4
- package/dist/{pi-mono-adapter-29g7axgj.js → pi-mono-adapter-wawfj09v.js} +42 -40
- package/dist/{pricing-refresh-mkyy7c2y.js → pricing-refresh-ky2gjp05.js} +5 -5
- package/dist/{rbac-roles-kb3afm95.js → rbac-roles-0j0f7s8r.js} +4 -4
- package/dist/{rbac-roles-ak56tr75.js → rbac-roles-az4wc15e.js} +3 -3
- package/dist/{render-v2-434asg49.js → render-v2-seyxq61z.js} +4 -5
- package/dist/{seed-pricing-nbmd7ah8.js → seed-pricing-fev611hx.js} +4 -4
- package/dist/{setup-wh4qmjs4.js → setup-hy404zwh.js} +2 -2
- package/dist/{worker-j1d27tjv.js → worker-g1j5hn16.js} +36 -36
- package/openapi.json +197 -27
- package/package.json +9 -3
- package/src/be/db-client.ts +58 -5
- package/src/be/db-retention.ts +550 -121
- package/src/be/db.ts +367 -55
- package/src/be/memory/raters/retrieval.ts +40 -0
- package/src/be/migrations/140_approval_request_cancelled_status.sql +64 -0
- package/src/be/pricing-normalize.ts +3 -0
- package/src/be/script-connections.ts +26 -6
- package/src/be/seed-pricing.ts +18 -8
- package/src/be/swarm-config-guard.ts +33 -0
- package/src/cli.tsx +20 -1
- package/src/commands/onboard/compose-generator.ts +63 -7
- package/src/commands/onboard/env-generator.ts +32 -4
- package/src/commands/onboard/manifest.ts +4 -1
- package/src/commands/onboard/non-interactive.ts +159 -0
- package/src/commands/onboard/steps/generate.tsx +1 -34
- package/src/commands/onboard/steps/harness-credentials.tsx +181 -1
- package/src/commands/onboard/steps/harness.tsx +20 -6
- package/src/commands/onboard/steps/review.tsx +3 -2
- package/src/commands/onboard/types.ts +48 -1
- package/src/commands/onboard.tsx +18 -13
- package/src/commands/provider-credentials.ts +17 -3
- package/src/commands/runner.ts +1 -0
- package/src/heartbeat/heartbeat.ts +47 -7
- package/src/http/approval-requests.ts +53 -8
- package/src/http/index.ts +9 -1
- package/src/http/mcp-servers.ts +2 -0
- package/src/http/memory.ts +27 -1
- package/src/http/oauth-callback.ts +33 -0
- package/src/http/repos.ts +6 -0
- package/src/http/script-connections.ts +77 -0
- package/src/http/session-data.ts +5 -1
- package/src/http/stats.ts +21 -30
- package/src/http/tasks.ts +10 -0
- package/src/oauth/presets.ts +29 -0
- package/src/otel-impl.ts +96 -1
- package/src/otel.ts +34 -0
- package/src/prompts/memories.ts +2 -2
- package/src/providers/acp-adapter.ts +325 -0
- package/src/providers/acp-swarm-events.ts +113 -0
- package/src/providers/acp-targets.ts +103 -0
- package/src/providers/claude-managed-models.ts +17 -1
- package/src/providers/codex-adapter.ts +3 -3
- package/src/providers/codex-oauth/auth-json-fs.ts +2 -2
- package/src/providers/codex-oauth/home.ts +13 -0
- package/src/providers/index.ts +5 -1
- package/src/providers/types.ts +1 -1
- package/src/server-user.ts +1 -0
- package/src/slack/app.ts +5 -1
- package/src/tasks/worker-follow-up.ts +78 -7
- package/src/telemetry.ts +151 -0
- package/src/tests/acp-adapter.test.ts +192 -0
- package/src/tests/acp-swarm-events.test.ts +132 -0
- package/src/tests/agents-list-model-display.test.ts +20 -0
- package/src/tests/approval-cancellation-migration.test.ts +134 -0
- package/src/tests/approval-requests.test.ts +456 -2
- package/src/tests/apps-spike2.test.ts +4 -1
- package/src/tests/apps-sync-engine.test.ts +22 -18
- package/src/tests/claude-managed-adapter.test.ts +12 -0
- package/src/tests/codex-oauth-auth-json-fs.test.ts +19 -0
- package/src/tests/connection-embedded-auth.test.ts +4 -1
- package/src/tests/context-window.test.ts +2 -0
- package/src/tests/credential-check.test.ts +6 -0
- package/src/tests/db-client-busy-retry.test.ts +18 -0
- package/src/tests/db-client.test.ts +23 -0
- package/src/tests/db-retention-telemetry.test.ts +569 -0
- package/src/tests/db-retention.test.ts +456 -117
- package/src/tests/heartbeat.test.ts +140 -0
- package/src/tests/memory-http-recall-gating.test.ts +120 -13
- package/src/tests/memory-store.test.ts +41 -0
- package/src/tests/migration-046-budgets.test.ts +27 -5
- package/src/tests/oauth-presets.test.ts +17 -5
- package/src/tests/onboard-compose.test.ts +99 -0
- package/src/tests/onboard-env.test.ts +43 -0
- package/src/tests/onboard-manifest.test.ts +17 -1
- package/src/tests/onboard-non-interactive.test.ts +89 -0
- package/src/tests/pool-affinity.test.ts +100 -0
- package/src/tests/promote-draft-task-route.test.ts +32 -1
- package/src/tests/sandbox-spawn-test-helpers.ts +3 -0
- package/src/tests/sandboxed-process.test.ts +2 -2
- package/src/tests/schedule-target-type.test.ts +6 -3
- package/src/tests/script-connections-http.test.ts +4 -3
- package/src/tests/script-connections.test.ts +6 -1
- package/src/tests/script-workflows-runtime-e2e.test.ts +36 -28
- package/src/tests/scripts-external-api.test.ts +8 -5
- package/src/tests/scripts-http.test.ts +6 -3
- package/src/tests/scripts-mcp-e2e.test.ts +65 -60
- package/src/tests/scripts-retention.test.ts +6 -3
- package/src/tests/scripts-runtime-identity.test.ts +4 -2
- package/src/tests/scripts-runtime.test.ts +18 -16
- package/src/tests/session-costs-model-key-normalize.test.ts +2 -0
- package/src/tests/slack-read-boundaries.test.ts +3 -1
- package/src/tests/task-lifecycle-telemetry.test.ts +1 -0
- package/src/tests/task-tools-ctx.test.ts +88 -1
- package/src/tests/telemetry-init.test.ts +61 -0
- package/src/tests/tool-annotations.test.ts +4 -1
- package/src/tests/vendored-openapi.test.ts +15 -2
- package/src/tests/workflow-e2e.test.ts +4 -1
- package/src/tests/workflow-engine-v2.test.ts +5 -2
- package/src/tests/workflow-executors.test.ts +24 -19
- package/src/tests/workflow-http-v2.test.ts +17 -2
- package/src/tests/workflow-llm.test.ts +57 -0
- package/src/tests/workflow-retry-v2.test.ts +142 -1
- package/src/tests/workflow-swarm-script.test.ts +20 -17
- package/src/tools/get-task-details.ts +1 -0
- package/src/tools/mcp-servers/mcp-server-create.ts +7 -1
- package/src/tools/memory-search.ts +27 -2
- package/src/tools/send-task.ts +28 -10
- package/src/tools/task-action.ts +13 -5
- package/src/types.ts +31 -2
- package/src/utils/context-window.ts +2 -0
- package/src/workflows/approval-notifications.ts +72 -0
- package/src/workflows/checkpoint.ts +16 -9
- package/src/workflows/completed-step-routing.ts +31 -0
- package/src/workflows/engine.ts +59 -43
- package/src/workflows/executors/human-in-the-loop.ts +38 -4
- package/src/workflows/executors/raw-llm.ts +8 -6
- package/src/workflows/executors/validate.ts +6 -5
- package/src/workflows/executors/workflow-llm.ts +35 -0
- package/src/workflows/resume.ts +90 -13
- package/src/workflows/retry-poller.ts +8 -1
- package/vendored-openapi/README.md +4 -2
- package/vendored-openapi/manifest.json +33 -0
- package/vendored-openapi/microsoft-graph.json +781 -0
- package/dist/cli-5tnr64pm.js +0 -29
- package/dist/{anthropic-messages-pm7pp23c.js → anthropic-messages-tvgm75yc.js} +3 -3
- package/dist/{azure-openai-responses-cwesc845.js → azure-openai-responses-hed7waek.js} +4 -4
- package/dist/{cli-s9gpxh9q.js → cli-5kmzp1wx.js} +0 -0
- package/dist/{cli-s73zwwqn.js → cli-xjx3fbtn.js} +4 -4
- package/dist/{openai-codex-responses-xxca1qr1.js → openai-codex-responses-gv3n8rg0.js} +3 -3
- package/dist/{openai-completions-yzftqrft.js → openai-completions-dkrj9433.js} +8 -8
- package/dist/{openai-responses-e4dcwm9g.js → openai-responses-spk6t7kh.js} +11 -11
- package/dist/{openrouter-images-asqqnbvh.js → openrouter-images-71hthwh9.js} +3 -3
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_MODEL,
|
|
3
|
+
resolveCredential
|
|
4
|
+
} from "./cli-2ypjdmqg.js";
|
|
1
5
|
import {
|
|
2
6
|
getOpenRouterBaseUrl
|
|
3
7
|
} from "./cli-3dpj7atn.js";
|
|
@@ -18,15 +22,21 @@ import {
|
|
|
18
22
|
sandboxSpawnEnv,
|
|
19
23
|
snapshotCapped,
|
|
20
24
|
touchScratchScriptLastUsed
|
|
21
|
-
} from "./cli-
|
|
25
|
+
} from "./cli-3719ggyf.js";
|
|
22
26
|
import {
|
|
23
27
|
withSiblingAwareness
|
|
24
|
-
} from "./cli-
|
|
28
|
+
} from "./cli-23cpnqk9.js";
|
|
29
|
+
import {
|
|
30
|
+
getSlackApp
|
|
31
|
+
} from "./cli-cywkhzqs.js";
|
|
25
32
|
import {
|
|
26
33
|
FollowUpConfigSchema,
|
|
27
34
|
ModelTierSchema,
|
|
28
35
|
ReasoningEffortSchema,
|
|
36
|
+
cancelPendingApprovalRequestsForRun,
|
|
29
37
|
cancelTask,
|
|
38
|
+
claimApprovalCancellationNotification,
|
|
39
|
+
completeApprovalCancellationNotificationClaim,
|
|
30
40
|
createWorkflowRun,
|
|
31
41
|
createWorkflowRunStep,
|
|
32
42
|
createWorkflowVersion,
|
|
@@ -58,7 +68,9 @@ import {
|
|
|
58
68
|
init_db,
|
|
59
69
|
init_telemetry,
|
|
60
70
|
init_types,
|
|
71
|
+
listCancelledApprovalRequestsForRun,
|
|
61
72
|
listWorkflows,
|
|
73
|
+
releaseApprovalCancellationNotificationClaim,
|
|
62
74
|
resolveApprovalRequest,
|
|
63
75
|
resolveWaitState,
|
|
64
76
|
splitLegacyModelAlias,
|
|
@@ -67,7 +79,7 @@ import {
|
|
|
67
79
|
updateWorkflowRun,
|
|
68
80
|
updateWorkflowRunStep,
|
|
69
81
|
workflowContextKey
|
|
70
|
-
} from "./cli-
|
|
82
|
+
} from "./cli-kq9htgbr.js";
|
|
71
83
|
import {
|
|
72
84
|
deepInterpolate,
|
|
73
85
|
findInterpolationTokens,
|
|
@@ -81,14 +93,14 @@ import {
|
|
|
81
93
|
import {
|
|
82
94
|
init_zod
|
|
83
95
|
} from "./cli-s35981d0.js";
|
|
96
|
+
import {
|
|
97
|
+
exports_external
|
|
98
|
+
} from "./cli-pqv5gvyf.js";
|
|
84
99
|
import {
|
|
85
100
|
init_secret_scrubber,
|
|
86
101
|
isSensitiveKey,
|
|
87
102
|
scrubSecrets
|
|
88
103
|
} from "./cli-mkq1rk7b.js";
|
|
89
|
-
import {
|
|
90
|
-
exports_external
|
|
91
|
-
} from "./cli-pqv5gvyf.js";
|
|
92
104
|
import {
|
|
93
105
|
init_event_bus,
|
|
94
106
|
workflowEventBus
|
|
@@ -467,14 +479,19 @@ async function checkpointStepFailure(runId, stepId, error, retryCount, retryPoli
|
|
|
467
479
|
return { shouldRetry: false };
|
|
468
480
|
}
|
|
469
481
|
async function checkpointStepWaiting(runId, stepId, ctx) {
|
|
470
|
-
|
|
471
|
-
await
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
482
|
+
return getDbClient().transaction(async () => {
|
|
483
|
+
const step = await getDbClient().get(`UPDATE workflow_run_steps
|
|
484
|
+
SET status = 'waiting'
|
|
485
|
+
WHERE id = ? AND runId = ? AND status = 'running'
|
|
486
|
+
AND EXISTS (
|
|
487
|
+
SELECT 1 FROM workflow_runs
|
|
488
|
+
WHERE id = ? AND status IN ('running', 'waiting')
|
|
489
|
+
)
|
|
490
|
+
RETURNING id`, [stepId, runId, runId]);
|
|
491
|
+
if (!step)
|
|
492
|
+
return false;
|
|
493
|
+
await updateWorkflowRun(runId, { status: "waiting", context: ctx });
|
|
494
|
+
return true;
|
|
478
495
|
});
|
|
479
496
|
}
|
|
480
497
|
function calculateBackoff(policy, attempt) {
|
|
@@ -497,35 +514,8 @@ function calculateBackoff(policy, attempt) {
|
|
|
497
514
|
return Math.min(delay, policy.maxDelayMs);
|
|
498
515
|
}
|
|
499
516
|
|
|
500
|
-
// src/workflows/
|
|
517
|
+
// src/workflows/completed-step-routing.ts
|
|
501
518
|
init_db();
|
|
502
|
-
function cooldownToMs(cooldown) {
|
|
503
|
-
let ms = 0;
|
|
504
|
-
if (cooldown.hours)
|
|
505
|
-
ms += cooldown.hours * 60 * 60 * 1000;
|
|
506
|
-
if (cooldown.minutes)
|
|
507
|
-
ms += cooldown.minutes * 60 * 1000;
|
|
508
|
-
if (cooldown.seconds)
|
|
509
|
-
ms += cooldown.seconds * 1000;
|
|
510
|
-
return ms;
|
|
511
|
-
}
|
|
512
|
-
async function shouldSkipCooldown(workflowId, cooldown) {
|
|
513
|
-
const cooldownMs = cooldownToMs(cooldown);
|
|
514
|
-
const now = Date.now();
|
|
515
|
-
const lastSuccess = await getLastSuccessfulRun(workflowId);
|
|
516
|
-
if (lastSuccess?.finishedAt) {
|
|
517
|
-
const lastFinished = new Date(lastSuccess.finishedAt).getTime();
|
|
518
|
-
if (now - lastFinished < cooldownMs)
|
|
519
|
-
return true;
|
|
520
|
-
}
|
|
521
|
-
const lastAttempt = await getLastRunStart(workflowId);
|
|
522
|
-
if (lastAttempt?.startedAt) {
|
|
523
|
-
const lastStarted = new Date(lastAttempt.startedAt).getTime();
|
|
524
|
-
if (now - lastStarted < cooldownMs)
|
|
525
|
-
return true;
|
|
526
|
-
}
|
|
527
|
-
return false;
|
|
528
|
-
}
|
|
529
519
|
|
|
530
520
|
// src/workflows/foreach-join.ts
|
|
531
521
|
init_db();
|
|
@@ -606,6 +596,54 @@ function resultStatus(step) {
|
|
|
606
596
|
return step.error ? "failed" : "completed";
|
|
607
597
|
}
|
|
608
598
|
|
|
599
|
+
// src/workflows/completed-step-routing.ts
|
|
600
|
+
async function loadCompletedStepRouting(def, runId, completedNodeIds) {
|
|
601
|
+
const activeEdges = new Set;
|
|
602
|
+
const stepsByNodeId = new Map;
|
|
603
|
+
for (const nodeId of completedNodeIds) {
|
|
604
|
+
if (resolveForeachParent(def, nodeId))
|
|
605
|
+
continue;
|
|
606
|
+
const step = await getLatestStepForNode(runId, nodeId);
|
|
607
|
+
if (step)
|
|
608
|
+
stepsByNodeId.set(nodeId, step);
|
|
609
|
+
const successors = step?.nextPort ? getSuccessors(def, nodeId, step.nextPort) : getSuccessors(def, nodeId);
|
|
610
|
+
for (const successor of successors) {
|
|
611
|
+
activeEdges.add(`${nodeId}→${successor.id}`);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
return { activeEdges, stepsByNodeId };
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// src/workflows/cooldown.ts
|
|
618
|
+
init_db();
|
|
619
|
+
function cooldownToMs(cooldown) {
|
|
620
|
+
let ms = 0;
|
|
621
|
+
if (cooldown.hours)
|
|
622
|
+
ms += cooldown.hours * 60 * 60 * 1000;
|
|
623
|
+
if (cooldown.minutes)
|
|
624
|
+
ms += cooldown.minutes * 60 * 1000;
|
|
625
|
+
if (cooldown.seconds)
|
|
626
|
+
ms += cooldown.seconds * 1000;
|
|
627
|
+
return ms;
|
|
628
|
+
}
|
|
629
|
+
async function shouldSkipCooldown(workflowId, cooldown) {
|
|
630
|
+
const cooldownMs = cooldownToMs(cooldown);
|
|
631
|
+
const now = Date.now();
|
|
632
|
+
const lastSuccess = await getLastSuccessfulRun(workflowId);
|
|
633
|
+
if (lastSuccess?.finishedAt) {
|
|
634
|
+
const lastFinished = new Date(lastSuccess.finishedAt).getTime();
|
|
635
|
+
if (now - lastFinished < cooldownMs)
|
|
636
|
+
return true;
|
|
637
|
+
}
|
|
638
|
+
const lastAttempt = await getLastRunStart(workflowId);
|
|
639
|
+
if (lastAttempt?.startedAt) {
|
|
640
|
+
const lastStarted = new Date(lastAttempt.startedAt).getTime();
|
|
641
|
+
if (now - lastStarted < cooldownMs)
|
|
642
|
+
return true;
|
|
643
|
+
}
|
|
644
|
+
return false;
|
|
645
|
+
}
|
|
646
|
+
|
|
609
647
|
// src/workflows/input.ts
|
|
610
648
|
init_db();
|
|
611
649
|
init_secret_scrubber();
|
|
@@ -912,31 +950,8 @@ async function walkGraph(def, runId, ctx, startNodes, registry, workflowId, secr
|
|
|
912
950
|
if (!("run" in ctx)) {
|
|
913
951
|
ctx.run = { id: runId };
|
|
914
952
|
}
|
|
915
|
-
const completedNodeIds =
|
|
916
|
-
const activeEdges =
|
|
917
|
-
if (completedNodeIds.size > 0) {
|
|
918
|
-
for (const nodeId of completedNodeIds) {
|
|
919
|
-
if (resolveForeachParent(def, nodeId))
|
|
920
|
-
continue;
|
|
921
|
-
const step = await getLatestStepForNode(runId, nodeId);
|
|
922
|
-
if (step?.output !== undefined) {
|
|
923
|
-
const node = def.nodes.find((n) => n.id === nodeId);
|
|
924
|
-
if (node && registry.has(node.type)) {
|
|
925
|
-
const executor = registry.get(node.type);
|
|
926
|
-
const parseResult = executor.outputSchema.safeParse(step.output);
|
|
927
|
-
if (!parseResult.success) {
|
|
928
|
-
console.warn(`[workflow] Recovery: step ${nodeId} output failed validation: ${parseResult.error.message}`);
|
|
929
|
-
continue;
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
ctx[nodeId] = step.output;
|
|
933
|
-
}
|
|
934
|
-
const successors = step?.nextPort ? getSuccessors(def, nodeId, step.nextPort) : getSuccessors(def, nodeId);
|
|
935
|
-
for (const succ of successors) {
|
|
936
|
-
activeEdges.add(`${nodeId}→${succ.id}`);
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
}
|
|
953
|
+
const { completedNodeIds } = await rehydrateCompletedStepOutputs(def, runId, ctx, registry);
|
|
954
|
+
const { activeEdges } = await loadCompletedStepRouting(def, runId, completedNodeIds);
|
|
940
955
|
const allSteps = await getWorkflowRunStepsByRunId(runId);
|
|
941
956
|
if (allSteps.length >= getMaxWorkflowStepsPerRun()) {
|
|
942
957
|
await updateWorkflowRun(runId, {
|
|
@@ -1054,6 +1069,31 @@ async function walkGraph(def, runId, ctx, startNodes, registry, workflowId, secr
|
|
|
1054
1069
|
}
|
|
1055
1070
|
});
|
|
1056
1071
|
}
|
|
1072
|
+
async function rehydrateCompletedStepOutputs(def, runId, ctx, registry) {
|
|
1073
|
+
const completedNodeIds = new Set(await getCompletedStepNodeIds(runId));
|
|
1074
|
+
const latestSteps = new Map;
|
|
1075
|
+
for (const nodeId of completedNodeIds) {
|
|
1076
|
+
if (resolveForeachParent(def, nodeId))
|
|
1077
|
+
continue;
|
|
1078
|
+
const step = await getLatestStepForNode(runId, nodeId);
|
|
1079
|
+
if (!step)
|
|
1080
|
+
continue;
|
|
1081
|
+
if (step.output !== undefined) {
|
|
1082
|
+
const node = def.nodes.find((candidate) => candidate.id === nodeId);
|
|
1083
|
+
if (node && registry.has(node.type)) {
|
|
1084
|
+
const executor = registry.get(node.type);
|
|
1085
|
+
const parseResult = executor.outputSchema.safeParse(step.output);
|
|
1086
|
+
if (!parseResult.success) {
|
|
1087
|
+
console.warn(`[workflow] Recovery: step ${nodeId} output failed validation: ${parseResult.error.message}`);
|
|
1088
|
+
continue;
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
ctx[nodeId] = step.output;
|
|
1092
|
+
}
|
|
1093
|
+
latestSteps.set(nodeId, step);
|
|
1094
|
+
}
|
|
1095
|
+
return { completedNodeIds, latestSteps };
|
|
1096
|
+
}
|
|
1057
1097
|
function getAllPredecessors(def, nodeId) {
|
|
1058
1098
|
const preds = [];
|
|
1059
1099
|
for (const node of def.nodes) {
|
|
@@ -1067,6 +1107,10 @@ function getAllPredecessors(def, nodeId) {
|
|
|
1067
1107
|
}
|
|
1068
1108
|
async function executeStep(def, runId, ctx, node, registry, workflowId, secretKeys = new Set, options = {}) {
|
|
1069
1109
|
const dedup = await getDbClient().transaction(async () => {
|
|
1110
|
+
const run = await getWorkflowRun(runId);
|
|
1111
|
+
if (!run || run.status !== "running" && run.status !== "waiting") {
|
|
1112
|
+
return { halted: true };
|
|
1113
|
+
}
|
|
1070
1114
|
const iteration = await getStepCountForNode(runId, node.id);
|
|
1071
1115
|
const idempotencyKey = `${runId}:${node.id}:${iteration}`;
|
|
1072
1116
|
const existingStep2 = await getStepByIdempotencyKey(idempotencyKey);
|
|
@@ -1088,6 +1132,8 @@ async function executeStep(def, runId, ctx, node, registry, workflowId, secretKe
|
|
|
1088
1132
|
}
|
|
1089
1133
|
return { existingStep: existingStep2, stepId: stepId2, deduped: false };
|
|
1090
1134
|
});
|
|
1135
|
+
if ("halted" in dedup)
|
|
1136
|
+
return { outcome: "completed", successors: [] };
|
|
1091
1137
|
if (dedup.deduped && dedup.existingStep) {
|
|
1092
1138
|
if (dedup.existingStep.status === "completed") {
|
|
1093
1139
|
ctx[node.id] = dedup.existingStep.output;
|
|
@@ -1170,8 +1216,8 @@ async function executeStep(def, runId, ctx, node, registry, workflowId, secretKe
|
|
|
1170
1216
|
return { outcome: "completed", successors: [] };
|
|
1171
1217
|
}
|
|
1172
1218
|
if ("async" in result && result.async) {
|
|
1173
|
-
await checkpointStepWaiting(runId, stepId, ctx);
|
|
1174
|
-
return { outcome: "waiting", successors: [] };
|
|
1219
|
+
const waiting = await checkpointStepWaiting(runId, stepId, ctx);
|
|
1220
|
+
return { outcome: waiting ? "waiting" : "completed", successors: [] };
|
|
1175
1221
|
}
|
|
1176
1222
|
if (node.outputSchema && result.status === "success") {
|
|
1177
1223
|
const outputErrors = validateJsonSchema(node.outputSchema, result.output);
|
|
@@ -1347,6 +1393,44 @@ var FAILED_TASK_OUTPUT_PREFIX = "[FAILED:";
|
|
|
1347
1393
|
// src/workflows/resume.ts
|
|
1348
1394
|
init_db();
|
|
1349
1395
|
init_secret_scrubber();
|
|
1396
|
+
|
|
1397
|
+
// src/workflows/approval-notifications.ts
|
|
1398
|
+
init_db();
|
|
1399
|
+
init_secret_scrubber();
|
|
1400
|
+
async function postApprovalCancellationUpdates(approvals, reason, client = getSlackApp()?.client) {
|
|
1401
|
+
if (!client)
|
|
1402
|
+
return;
|
|
1403
|
+
const text = `This approval is no longer actionable: ${reason}`;
|
|
1404
|
+
for (const approval of approvals) {
|
|
1405
|
+
const channels = approval.notificationChannels;
|
|
1406
|
+
const slackThreads = (channels ?? []).filter((notification) => notification.channel === "slack" && notification.messageTs);
|
|
1407
|
+
if (slackThreads.length === 0)
|
|
1408
|
+
continue;
|
|
1409
|
+
for (const notification of slackThreads) {
|
|
1410
|
+
if (notification.channel !== "slack" || !notification.messageTs)
|
|
1411
|
+
continue;
|
|
1412
|
+
const notificationKey = `${notification.target}:${notification.messageTs}`;
|
|
1413
|
+
const claim = await claimApprovalCancellationNotification(approval.id, notificationKey);
|
|
1414
|
+
if (!claim)
|
|
1415
|
+
continue;
|
|
1416
|
+
try {
|
|
1417
|
+
await client.chat.postMessage({
|
|
1418
|
+
channel: notification.target,
|
|
1419
|
+
thread_ts: notification.messageTs,
|
|
1420
|
+
text,
|
|
1421
|
+
unfurl_links: false,
|
|
1422
|
+
unfurl_media: false
|
|
1423
|
+
});
|
|
1424
|
+
await completeApprovalCancellationNotificationClaim(approval.id, notificationKey, claim.leaseToken);
|
|
1425
|
+
} catch (error) {
|
|
1426
|
+
await releaseApprovalCancellationNotificationClaim(approval.id, notificationKey, claim.leaseToken);
|
|
1427
|
+
console.error(`[HITL] Failed to post cancellation update for approval ${approval.id}:`, scrubSecrets(error instanceof Error ? error.message : String(error)));
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
// src/workflows/resume.ts
|
|
1350
1434
|
init_event_bus();
|
|
1351
1435
|
|
|
1352
1436
|
// src/workflows/executors/wait.ts
|
|
@@ -1886,23 +1970,31 @@ async function retryFailedRun(runId, registry) {
|
|
|
1886
1970
|
const failedStep = steps.find((s) => s.status === "failed");
|
|
1887
1971
|
if (!failedStep)
|
|
1888
1972
|
throw new Error("No failed step found");
|
|
1973
|
+
const completedNodeIds = new Set(await getCompletedStepNodeIds(runId));
|
|
1974
|
+
const { activeEdges } = await loadCompletedStepRouting(workflow.definition, runId, completedNodeIds);
|
|
1975
|
+
const foreachParent = resolveForeachParent(workflow.definition, failedStep.nodeId);
|
|
1976
|
+
const failedNode = foreachParent ?? workflow.definition.nodes.find((n) => n.id === failedStep.nodeId);
|
|
1977
|
+
if (!failedNode)
|
|
1978
|
+
throw new Error(`Node ${failedStep.nodeId} not found in workflow definition`);
|
|
1979
|
+
const hasStructuralPredecessor = workflow.definition.nodes.some((node) => node.next && getNextTargets(node.next).includes(failedNode.id));
|
|
1980
|
+
const hasActivePredecessor = [...activeEdges].some((edge) => edge.endsWith(`→${failedNode.id}`));
|
|
1981
|
+
const shouldRetryFailedNode = foreachParent != null || !hasStructuralPredecessor || hasActivePredecessor;
|
|
1889
1982
|
const ctx = run.context ?? {};
|
|
1890
1983
|
const claimed = await getDbClient().transaction(async () => {
|
|
1891
1984
|
const current = await getWorkflowRun(runId);
|
|
1892
1985
|
if (!current || current.status !== "failed")
|
|
1893
1986
|
return false;
|
|
1894
|
-
await updateWorkflowRunStep(failedStep.id, {
|
|
1987
|
+
await updateWorkflowRunStep(failedStep.id, {
|
|
1988
|
+
status: shouldRetryFailedNode ? "pending" : "cancelled",
|
|
1989
|
+
error: shouldRetryFailedNode ? null : "Skipped on retry because its branch was not active"
|
|
1990
|
+
});
|
|
1895
1991
|
await updateWorkflowRun(runId, { status: "running", error: null, context: ctx });
|
|
1896
1992
|
return true;
|
|
1897
1993
|
});
|
|
1898
1994
|
if (!claimed)
|
|
1899
1995
|
throw new Error("Run is not in failed state");
|
|
1900
|
-
const
|
|
1901
|
-
const
|
|
1902
|
-
const failedNode = resolveForeachParent(workflow.definition, failedStep.nodeId) ?? workflow.definition.nodes.find((n) => n.id === failedStep.nodeId);
|
|
1903
|
-
if (!failedNode)
|
|
1904
|
-
throw new Error(`Node ${failedStep.nodeId} not found in workflow definition`);
|
|
1905
|
-
const nodesToRun = readyNodes.some((n) => n.id === failedNode.id) ? readyNodes : [failedNode, ...readyNodes];
|
|
1996
|
+
const readyNodes = findReadyNodes(workflow.definition, completedNodeIds, activeEdges);
|
|
1997
|
+
const nodesToRun = !shouldRetryFailedNode || readyNodes.some((n) => n.id === failedNode.id) ? readyNodes : [failedNode, ...readyNodes];
|
|
1906
1998
|
const secretKeys = getSecretInputKeys(workflow.input);
|
|
1907
1999
|
await walkGraph(workflow.definition, runId, ctx, nodesToRun, registry, workflow.id, secretKeys);
|
|
1908
2000
|
}
|
|
@@ -1911,15 +2003,17 @@ async function cancelWorkflowRun(runId, reason) {
|
|
|
1911
2003
|
if (!run)
|
|
1912
2004
|
throw new Error("Workflow run not found");
|
|
1913
2005
|
const terminalStatuses = ["completed", "failed", "cancelled", "skipped"];
|
|
1914
|
-
if (terminalStatuses.includes(run.status)) {
|
|
2006
|
+
if (terminalStatuses.includes(run.status) && run.status !== "cancelled") {
|
|
1915
2007
|
throw new Error(`Cannot cancel run in '${run.status}' state`);
|
|
1916
2008
|
}
|
|
1917
2009
|
const now = new Date().toISOString();
|
|
1918
2010
|
const cancelReason = reason ?? "Cancelled by user";
|
|
2011
|
+
let applied = false;
|
|
1919
2012
|
await getDbClient().transaction(async () => {
|
|
1920
2013
|
const current = await getWorkflowRun(runId);
|
|
1921
2014
|
if (!current || terminalStatuses.includes(current.status))
|
|
1922
2015
|
return;
|
|
2016
|
+
applied = true;
|
|
1923
2017
|
const steps = await getWorkflowRunStepsByRunId(runId);
|
|
1924
2018
|
for (const step of steps) {
|
|
1925
2019
|
if (terminalStatuses.includes(step.status))
|
|
@@ -1934,12 +2028,19 @@ async function cancelWorkflowRun(runId, reason) {
|
|
|
1934
2028
|
finishedAt: now
|
|
1935
2029
|
});
|
|
1936
2030
|
}
|
|
2031
|
+
await cancelPendingApprovalRequestsForRun(runId, cancelReason);
|
|
1937
2032
|
await updateWorkflowRun(runId, {
|
|
1938
2033
|
status: "cancelled",
|
|
1939
2034
|
error: cancelReason,
|
|
1940
2035
|
finishedAt: now
|
|
1941
2036
|
});
|
|
1942
2037
|
});
|
|
2038
|
+
const cancelledApprovals = await listCancelledApprovalRequestsForRun(runId);
|
|
2039
|
+
const latestRun = await getWorkflowRun(runId);
|
|
2040
|
+
if (!applied && latestRun?.status !== "cancelled") {
|
|
2041
|
+
throw new Error(`Cannot cancel run in '${latestRun?.status ?? "missing"}' state`);
|
|
2042
|
+
}
|
|
2043
|
+
await postApprovalCancellationUpdates(cancelledApprovals, applied ? cancelReason : latestRun?.error ?? cancelReason);
|
|
1943
2044
|
}
|
|
1944
2045
|
async function resumeFromApprovalResolution(event, registry) {
|
|
1945
2046
|
const run = await getWorkflowRun(event.workflowRunId);
|
|
@@ -2324,6 +2425,7 @@ function startRetryPoller(registry, intervalMs = 5000) {
|
|
|
2324
2425
|
const ctx = run.context ?? {};
|
|
2325
2426
|
if (!("run" in ctx))
|
|
2326
2427
|
ctx.run = { id: run.id };
|
|
2428
|
+
await rehydrateCompletedStepOutputs(workflow.definition, run.id, ctx, registry);
|
|
2327
2429
|
const inputCtx = buildNodeInterpolationCtx(node, ctx);
|
|
2328
2430
|
const { value: interpolatedValue, scriptBodyUnresolved } = interpolateNodeConfig(node, inputCtx);
|
|
2329
2431
|
if (scriptBodyUnresolved && scriptBodyUnresolved.length > 0) {
|
|
@@ -2351,7 +2453,9 @@ function startRetryPoller(registry, intervalMs = 5000) {
|
|
|
2351
2453
|
const retryPolicy = node.retry || executor.retryPolicy;
|
|
2352
2454
|
await checkpointStepFailure(run.id, step.id, result.error || "Retry failed", step.retryCount, retryPolicy);
|
|
2353
2455
|
} else if ("async" in result && result.async) {
|
|
2354
|
-
await checkpointStepWaiting(run.id, step.id, ctx);
|
|
2456
|
+
const waiting = await checkpointStepWaiting(run.id, step.id, ctx);
|
|
2457
|
+
if (!waiting)
|
|
2458
|
+
continue;
|
|
2355
2459
|
} else {
|
|
2356
2460
|
if (node.validation) {
|
|
2357
2461
|
const validationResult = await runStepValidation(registry, node, result.output, ctx, meta);
|
|
@@ -3054,6 +3158,7 @@ function normalizeExistingTaskOutput(output) {
|
|
|
3054
3158
|
// src/workflows/executors/human-in-the-loop.ts
|
|
3055
3159
|
init_zod();
|
|
3056
3160
|
init_constants();
|
|
3161
|
+
init_secret_scrubber();
|
|
3057
3162
|
var SelectOptionSchema = exports_external.object({
|
|
3058
3163
|
value: exports_external.string(),
|
|
3059
3164
|
label: exports_external.string(),
|
|
@@ -3138,6 +3243,12 @@ class HumanInTheLoopExecutor extends BaseExecutor {
|
|
|
3138
3243
|
const existing = await db.getApprovalRequestByStepId(meta.stepId);
|
|
3139
3244
|
if (existing) {
|
|
3140
3245
|
if (existing.status !== "pending") {
|
|
3246
|
+
if (existing.status === "cancelled") {
|
|
3247
|
+
return {
|
|
3248
|
+
status: "failed",
|
|
3249
|
+
error: `Approval request was cancelled: ${existing.resolutionReason ?? "workflow run cancelled"}`
|
|
3250
|
+
};
|
|
3251
|
+
}
|
|
3141
3252
|
const nextPort = existing.status === "timeout" ? "timeout" : existing.status === "rejected" ? "rejected" : "approved";
|
|
3142
3253
|
return {
|
|
3143
3254
|
status: "success",
|
|
@@ -3157,7 +3268,7 @@ class HumanInTheLoopExecutor extends BaseExecutor {
|
|
|
3157
3268
|
};
|
|
3158
3269
|
}
|
|
3159
3270
|
const requestId = crypto.randomUUID();
|
|
3160
|
-
await db.createApprovalRequest({
|
|
3271
|
+
const created = await db.createApprovalRequest({
|
|
3161
3272
|
id: requestId,
|
|
3162
3273
|
title: config.title,
|
|
3163
3274
|
questions: config.questions,
|
|
@@ -3166,11 +3277,20 @@ class HumanInTheLoopExecutor extends BaseExecutor {
|
|
|
3166
3277
|
workflowRunStepId: meta.stepId,
|
|
3167
3278
|
timeoutSeconds: config.timeout?.seconds,
|
|
3168
3279
|
notificationChannels: config.notifications,
|
|
3169
|
-
createdBy: meta.requestedByUserId
|
|
3280
|
+
createdBy: meta.requestedByUserId,
|
|
3281
|
+
requireActionableWorkflow: true
|
|
3170
3282
|
});
|
|
3283
|
+
if (created.status === "cancelled") {
|
|
3284
|
+
return {
|
|
3285
|
+
status: "success",
|
|
3286
|
+
async: true,
|
|
3287
|
+
waitFor: "approval.resolved",
|
|
3288
|
+
correlationId: requestId
|
|
3289
|
+
};
|
|
3290
|
+
}
|
|
3171
3291
|
if (config.notifications?.length) {
|
|
3172
3292
|
this.dispatchNotifications(requestId, config, db).catch((err) => {
|
|
3173
|
-
console.error("[HITL] Unexpected error dispatching notifications:", err);
|
|
3293
|
+
console.error("[HITL] Unexpected error dispatching notifications:", scrubSecrets(err instanceof Error ? err.message : String(err)));
|
|
3174
3294
|
});
|
|
3175
3295
|
}
|
|
3176
3296
|
return {
|
|
@@ -3194,8 +3314,8 @@ class HumanInTheLoopExecutor extends BaseExecutor {
|
|
|
3194
3314
|
}
|
|
3195
3315
|
if (notification.channel === "slack") {
|
|
3196
3316
|
try {
|
|
3197
|
-
const { getSlackApp } = await import("./app-
|
|
3198
|
-
const slackApp =
|
|
3317
|
+
const { getSlackApp: getSlackApp2 } = await import("./app-wb6bc7tt.js");
|
|
3318
|
+
const slackApp = getSlackApp2();
|
|
3199
3319
|
if (!slackApp) {
|
|
3200
3320
|
console.warn("[HITL] Slack not initialized — cannot send notification");
|
|
3201
3321
|
continue;
|
|
@@ -3245,15 +3365,19 @@ ${questionsSummary}${timeoutText}`
|
|
|
3245
3365
|
}
|
|
3246
3366
|
console.log(`[HITL] Slack notification sent to ${notification.target} for request ${requestId}`);
|
|
3247
3367
|
} catch (err) {
|
|
3248
|
-
console.error(`[HITL] Failed to send Slack notification to ${notification.target}:`, err);
|
|
3368
|
+
console.error(`[HITL] Failed to send Slack notification to ${notification.target}:`, scrubSecrets(err instanceof Error ? err.message : String(err)));
|
|
3249
3369
|
}
|
|
3250
3370
|
}
|
|
3251
3371
|
}
|
|
3252
3372
|
if (updated) {
|
|
3253
3373
|
try {
|
|
3254
3374
|
await db.updateApprovalRequestNotifications(requestId, updatedChannels);
|
|
3375
|
+
const latest = await db.getApprovalRequestById(requestId);
|
|
3376
|
+
if (latest?.status === "cancelled") {
|
|
3377
|
+
await postApprovalCancellationUpdates([latest], latest.resolutionReason ?? "Workflow run cancelled");
|
|
3378
|
+
}
|
|
3255
3379
|
} catch (err) {
|
|
3256
|
-
console.error("[HITL] Failed to update notification channels in DB:", err);
|
|
3380
|
+
console.error("[HITL] Failed to update notification channels in DB:", scrubSecrets(err instanceof Error ? err.message : String(err)));
|
|
3257
3381
|
}
|
|
3258
3382
|
}
|
|
3259
3383
|
}
|
|
@@ -3310,8 +3434,8 @@ class NotifyExecutor extends BaseExecutor {
|
|
|
3310
3434
|
}
|
|
3311
3435
|
}
|
|
3312
3436
|
case "slack": {
|
|
3313
|
-
const { getSlackApp } = await import("./app-
|
|
3314
|
-
const app =
|
|
3437
|
+
const { getSlackApp: getSlackApp2 } = await import("./app-wb6bc7tt.js");
|
|
3438
|
+
const app = getSlackApp2();
|
|
3315
3439
|
if (!app) {
|
|
3316
3440
|
return {
|
|
3317
3441
|
status: "success",
|
|
@@ -3422,6 +3546,26 @@ function evaluateCondition(op, actual, expected) {
|
|
|
3422
3546
|
|
|
3423
3547
|
// src/workflows/executors/raw-llm.ts
|
|
3424
3548
|
init_zod();
|
|
3549
|
+
|
|
3550
|
+
// src/workflows/executors/workflow-llm.ts
|
|
3551
|
+
async function resolveWorkflowLlmConfig(requestedModel, env = process.env) {
|
|
3552
|
+
const credential = await resolveCredential({ env });
|
|
3553
|
+
if (!credential) {
|
|
3554
|
+
throw new Error("No workflow LLM credential found. Set OPENROUTER_API_KEY or OPENAI_API_KEY.");
|
|
3555
|
+
}
|
|
3556
|
+
if (credential.kind !== "openrouter" && credential.kind !== "openai") {
|
|
3557
|
+
throw new Error(`Workflow LLM nodes do not support the resolved ${credential.kind} credential yet. Set OPENROUTER_API_KEY or OPENAI_API_KEY.`);
|
|
3558
|
+
}
|
|
3559
|
+
const providerPrefix = `${credential.kind}/`;
|
|
3560
|
+
const model = requestedModel ?? DEFAULT_MODEL[credential.kind];
|
|
3561
|
+
return {
|
|
3562
|
+
apiKey: credential.apiKey,
|
|
3563
|
+
baseURL: credential.kind === "openrouter" ? getOpenRouterBaseUrl(env) : undefined,
|
|
3564
|
+
model: model.startsWith(providerPrefix) ? model.slice(providerPrefix.length) : model
|
|
3565
|
+
};
|
|
3566
|
+
}
|
|
3567
|
+
|
|
3568
|
+
// src/workflows/executors/raw-llm.ts
|
|
3425
3569
|
var RawLlmConfigSchema = exports_external.object({
|
|
3426
3570
|
prompt: exports_external.string(),
|
|
3427
3571
|
model: exports_external.string().optional(),
|
|
@@ -3433,16 +3577,18 @@ var RawLlmOutputSchema = exports_external.object({
|
|
|
3433
3577
|
model: exports_external.string()
|
|
3434
3578
|
});
|
|
3435
3579
|
async function executeRawLlm(config) {
|
|
3436
|
-
|
|
3580
|
+
let modelName = config.model ?? "google/gemini-3-flash-preview";
|
|
3437
3581
|
try {
|
|
3438
|
-
const { createOpenAI } = await import("./index-
|
|
3439
|
-
const
|
|
3440
|
-
|
|
3441
|
-
|
|
3582
|
+
const { createOpenAI } = await import("./index-agykc6k2.js");
|
|
3583
|
+
const llmConfig = await resolveWorkflowLlmConfig(config.model);
|
|
3584
|
+
modelName = llmConfig.model;
|
|
3585
|
+
const provider = createOpenAI({
|
|
3586
|
+
baseURL: llmConfig.baseURL,
|
|
3587
|
+
apiKey: llmConfig.apiKey
|
|
3442
3588
|
});
|
|
3443
|
-
const model =
|
|
3589
|
+
const model = provider(llmConfig.model);
|
|
3444
3590
|
if (config.schema) {
|
|
3445
|
-
const { generateObject, jsonSchema } = await import("./index-
|
|
3591
|
+
const { generateObject, jsonSchema } = await import("./index-1nsdwvn5.js");
|
|
3446
3592
|
const { object } = await generateObject({
|
|
3447
3593
|
model,
|
|
3448
3594
|
schema: jsonSchema(config.schema),
|
|
@@ -3456,7 +3602,7 @@ async function executeRawLlm(config) {
|
|
|
3456
3602
|
output: { result: object, model: modelName }
|
|
3457
3603
|
};
|
|
3458
3604
|
}
|
|
3459
|
-
const { generateText } = await import("./index-
|
|
3605
|
+
const { generateText } = await import("./index-1nsdwvn5.js");
|
|
3460
3606
|
const { text } = await generateText({
|
|
3461
3607
|
model,
|
|
3462
3608
|
prompt: config.prompt
|
|
@@ -3889,14 +4035,15 @@ class ValidateExecutor extends BaseExecutor {
|
|
|
3889
4035
|
const interpolatedPrompt = this.deps.interpolate(prompt, context);
|
|
3890
4036
|
const outputStr = typeof targetOutput === "string" ? targetOutput : JSON.stringify(targetOutput);
|
|
3891
4037
|
try {
|
|
3892
|
-
const { createOpenAI } = await import("./index-
|
|
3893
|
-
const { generateObject, jsonSchema } = await import("./index-
|
|
3894
|
-
const
|
|
3895
|
-
|
|
3896
|
-
|
|
4038
|
+
const { createOpenAI } = await import("./index-agykc6k2.js");
|
|
4039
|
+
const { generateObject, jsonSchema } = await import("./index-1nsdwvn5.js");
|
|
4040
|
+
const llmConfig = await resolveWorkflowLlmConfig();
|
|
4041
|
+
const provider = createOpenAI({
|
|
4042
|
+
baseURL: llmConfig.baseURL,
|
|
4043
|
+
apiKey: llmConfig.apiKey
|
|
3897
4044
|
});
|
|
3898
4045
|
const { object } = await generateObject({
|
|
3899
|
-
model:
|
|
4046
|
+
model: provider(llmConfig.model),
|
|
3900
4047
|
schema: jsonSchema({
|
|
3901
4048
|
type: "object",
|
|
3902
4049
|
properties: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
summarizeSession
|
|
3
|
-
} from "./cli-
|
|
3
|
+
} from "./cli-390sgxn5.js";
|
|
4
4
|
import {
|
|
5
5
|
checkToolLoop,
|
|
6
6
|
clearToolHistory
|
|
@@ -27,14 +27,14 @@ import {
|
|
|
27
27
|
getMcpBaseUrl,
|
|
28
28
|
init_constants
|
|
29
29
|
} from "./cli-a1rrkrb4.js";
|
|
30
|
+
import {
|
|
31
|
+
init_package,
|
|
32
|
+
package_default
|
|
33
|
+
} from "./cli-kkn46gfr.js";
|
|
30
34
|
import {
|
|
31
35
|
init_secret_scrubber,
|
|
32
36
|
scrubSecrets
|
|
33
37
|
} from "./cli-mkq1rk7b.js";
|
|
34
|
-
import {
|
|
35
|
-
init_package,
|
|
36
|
-
package_default
|
|
37
|
-
} from "./cli-4r4jkqep.js";
|
|
38
38
|
|
|
39
39
|
// src/hooks/hook.ts
|
|
40
40
|
init_package();
|