@desplega.ai/agent-swarm 1.167.0 → 1.169.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.
Files changed (184) hide show
  1. package/dist/{acp-adapter-zpvy6321.js → acp-adapter-m47zfx4a.js} +2 -2
  2. package/dist/{actions-fq2zrwtf.js → actions-ws7k3tvq.js} +25 -19
  3. package/dist/{amp-adapter-5gbk7501.js → amp-adapter-nvv8k8j5.js} +1 -1
  4. package/dist/{app-nctetn1e.js → app-80w6qspx.js} +5 -5
  5. package/dist/{assistant-0aq8gjvj.js → assistant-jtq439kw.js} +29 -20
  6. package/dist/{boot-reembed-1ze5853n.js → boot-reembed-3nc0aaed.js} +4 -4
  7. package/dist/{boot-reembed-fmp5ww69.js → boot-reembed-feda8wn8.js} +4 -4
  8. package/dist/{boot-scrub-sweep-cbp8xd4e.js → boot-scrub-sweep-grsa2er0.js} +5 -5
  9. package/dist/{boot-seeds-22tx8a53.js → boot-seeds-gcfgq44f.js} +7 -7
  10. package/dist/{claude-adapter-0jhgeh1d.js → claude-adapter-pjv2q7t8.js} +7 -7
  11. package/dist/{claude-managed-adapter-tzwxy803.js → claude-managed-adapter-0wa8se82.js} +2 -2
  12. package/dist/{claude-managed-setup-nrhfx5b0.js → claude-managed-setup-zxa9p9tx.js} +1 -1
  13. package/dist/{claude-sdk-session-wh77rh83.js → claude-sdk-session-c9j6k9kx.js} +8772 -8663
  14. package/dist/{cli-c2tpw9ck.js → cli-3ry5gx4f.js} +1 -1
  15. package/dist/{cli-wydz3feg.js → cli-61tbnjpf.js} +214 -2472
  16. package/dist/{cli-cexctgn5.js → cli-7vz49g7h.js} +101 -34
  17. package/dist/{cli-6qxmjpem.js → cli-8xjst8q2.js} +34 -22
  18. package/dist/{cli-tx2zvn23.js → cli-91r17hb1.js} +3 -3
  19. package/dist/{cli-577bxkf6.js → cli-a8vps458.js} +182 -2208
  20. package/dist/{cli-tc5zec7v.js → cli-b7y8113e.js} +1 -1
  21. package/dist/{cli-69egj654.js → cli-bqrs5ycj.js} +1 -1
  22. package/dist/{cli-cf2vgn9d.js → cli-dv76vq5d.js} +30 -28
  23. package/dist/{cli-g5erf0zt.js → cli-e2prcx5m.js} +31 -0
  24. package/dist/{cli-c8r99akr.js → cli-e5qk3m2a.js} +209 -31
  25. package/dist/{cli-z1dqhc9y.js → cli-eqfbsxsn.js} +3 -3
  26. package/dist/{cli-kw0jcfje.js → cli-fyeft04q.js} +1 -1
  27. package/dist/{cli-5qkcdv8c.js → cli-gmdajfw5.js} +3 -3
  28. package/dist/{cli-ypgba1a8.js → cli-jkfxpg1b.js} +1 -1
  29. package/dist/{cli-mxvnnv5q.js → cli-jv36y8wz.js} +1 -1
  30. package/dist/{cli-m7vmeepg.js → cli-km8559dm.js} +6 -6
  31. package/dist/{cli-ykt8f7va.js → cli-kp3vfknv.js} +1 -1
  32. package/dist/{cli-ymmc1zxg.js → cli-m23r88re.js} +8 -5
  33. package/dist/{cli-v1pwxreq.js → cli-n4z21pt8.js} +1 -1
  34. package/dist/{cli-mxry91sa.js → cli-qg2zhjfc.js} +73 -4
  35. package/dist/{cli-1yrcfa5s.js → cli-rbr91whd.js} +4 -4
  36. package/dist/{cli-mkdsy1nq.js → cli-rg1c8ccw.js} +93 -7
  37. package/dist/cli-rh44xx46.js +2659 -0
  38. package/dist/cli-s0k2j7q9.js +2084 -0
  39. package/dist/{cli-ty4bzkqr.js → cli-sajr098b.js} +1 -1
  40. package/dist/{cli-6vfz44sr.js → cli-swrz3mj8.js} +1 -1
  41. package/dist/{cli-p8rt8spp.js → cli-vejds37t.js} +2 -2
  42. package/dist/{cli-jbzbr36n.js → cli-w6xa5nf5.js} +1 -1
  43. package/dist/{cli-9q3wt23f.js → cli-x6z90nq9.js} +1 -1
  44. package/dist/{cli-qzmzwegq.js → cli-ysnkvdx6.js} +102 -9
  45. package/dist/{cli-y0kjpfm9.js → cli-yvxfaem2.js} +2 -2
  46. package/dist/{cli-pkj1w46r.js → cli-z48ggfyq.js} +1 -1
  47. package/dist/{cli-6bpvv8h4.js → cli-zzev32jw.js} +1 -1
  48. package/dist/cli.js +20 -17
  49. package/dist/{codex-adapter-cgesnjkr.js → codex-adapter-0kpg09ca.js} +3 -3
  50. package/dist/{codex-hook-15dgc4cb.js → codex-hook-295jpbfa.js} +2 -2
  51. package/dist/{codex-session-runner-8kd7ddhr.js → codex-session-runner-8n672hxh.js} +3 -3
  52. package/dist/{commands-h6zaaxym.js → commands-mhmg5n0x.js} +4 -4
  53. package/dist/{cursor-adapter-v8mm6bp5.js → cursor-adapter-wn8n5zzk.js} +2 -2
  54. package/dist/{db-qg3myn53.js → db-wa6s1mwv.js} +4 -4
  55. package/dist/{dispatcher-7vnwj9qw.js → dispatcher-nhs2pkr8.js} +16 -14
  56. package/dist/{dsh-adapter-tz6hfp5r.js → dsh-adapter-5423p70m.js} +1 -1
  57. package/dist/{grok-adapter-jdt2dz2s.js → grok-adapter-28pkdt80.js} +3 -3
  58. package/dist/{handlers-2qtkpncr.js → handlers-5rtf9nng.js} +19 -17
  59. package/dist/{hook-51yfcgsv.js → hook-krjfkpzy.js} +4 -4
  60. package/dist/{hook-qnbdgwvd.js → hook-qkm73zk6.js} +5 -5
  61. package/dist/{http-jsmtag08.js → http-a397xcn4.js} +4845 -3484
  62. package/dist/{index-2t9kesn1.js → index-ac0v8v9d.js} +4 -4
  63. package/dist/{index-ekywyv2v.js → index-kqre45fr.js} +16 -14
  64. package/dist/{index-bt8wkv1w.js → index-rtxg15ah.js} +17 -15
  65. package/dist/{index-t4g06w93.js → index-vvsq7v45.js} +26 -23
  66. package/dist/{index-cx1sb9bq.js → index-ytdhtdry.js} +50 -11
  67. package/dist/{keepalive-4aezx4bj.js → keepalive-psfh8ysx.js} +6 -6
  68. package/dist/{lead-r44bkpm5.js → lead-m6rppjn7.js} +29 -27
  69. package/dist/{maintenance-grz5jrzh.js → maintenance-41f837ke.js} +4 -4
  70. package/dist/{node-qm9eb6z0.js → node-fkajaq96.js} +1 -1
  71. package/dist/{oauth-refresh-sweep-wm4ctjfj.js → oauth-refresh-sweep-6hr55hm8.js} +5 -5
  72. package/dist/{onboard-v60zgqf0.js → onboard-ktrtd7cz.js} +2 -2
  73. package/dist/{otel-impl-ghh4dyf8.js → otel-impl-dq4f2k3m.js} +1 -1
  74. package/dist/{pi-mono-adapter-0eg8kw2c.js → pi-mono-adapter-e5v9w0hv.js} +3 -2
  75. package/dist/{pricing-refresh-mjrqvnvw.js → pricing-refresh-kmk7j1ra.js} +6 -6
  76. package/dist/{rbac-roles-fd5tskj9.js → rbac-roles-9w1dkkxd.js} +4 -4
  77. package/dist/{rbac-roles-axv4d74x.js → rbac-roles-9ykx9tc5.js} +5 -5
  78. package/dist/{render-v2-k50j33qd.js → render-v2-ycqm53np.js} +5 -5
  79. package/dist/resume-cq2pkp8q.js +70 -0
  80. package/dist/{setup-4syh0pd2.js → setup-0dcmdvbn.js} +2 -2
  81. package/dist/{virtual-modules-ftr9kwe8.js → virtual-modules-1x9k4jcs.js} +1 -1
  82. package/dist/{work-objects-jcdbg8rr.js → work-objects-x01x2fh8.js} +19 -17
  83. package/dist/{worker-x8j8c9sx.js → worker-py1ssb1h.js} +29 -27
  84. package/openapi.json +15622 -15042
  85. package/package.json +8 -5
  86. package/src/apps/store.ts +1 -0
  87. package/src/artifact-sdk/feedback-overlay.ts +528 -0
  88. package/src/be/db/workflow-runs.ts +95 -0
  89. package/src/be/db-queries/slack-inbound.ts +489 -0
  90. package/src/be/db.ts +9 -2
  91. package/src/be/extensions/assets.ts +1 -1
  92. package/src/be/migrations/203_workflow_run_parent_step.sql +10 -0
  93. package/src/be/migrations/204_slack_inbound_receipts.sql +51 -0
  94. package/src/be/script-connections.ts +41 -7
  95. package/src/be/scripts/run-saved.ts +40 -20
  96. package/src/be/swarm-config-guard.ts +4 -0
  97. package/src/extensions/catalog.generated.json +17 -0
  98. package/src/extensions/catalog.ts +1 -1
  99. package/src/extensions/dispatcher.ts +3 -3
  100. package/src/heartbeat/heartbeat.ts +152 -2
  101. package/src/heartbeat/templates.ts +16 -0
  102. package/src/http/all-routes.ts +1 -0
  103. package/src/http/index.ts +2 -0
  104. package/src/http/integrations.ts +3 -1
  105. package/src/http/mcp-bridge.ts +1 -0
  106. package/src/http/pages-public.ts +7 -2
  107. package/src/http/pages.ts +178 -0
  108. package/src/http/script-connections.ts +35 -0
  109. package/src/http/slack-inbound.ts +107 -0
  110. package/src/http/tasks.ts +45 -27
  111. package/src/http/users.ts +1 -1
  112. package/src/http/webhooks.ts +20 -20
  113. package/src/prompts/session-templates.ts +32 -0
  114. package/src/providers/acp-targets.ts +1 -1
  115. package/src/providers/amp-adapter.ts +2 -2
  116. package/src/providers/claude-adapter.ts +6 -0
  117. package/src/providers/claude-background-keepalive.ts +100 -0
  118. package/src/providers/claude-managed-adapter.ts +2 -11
  119. package/src/providers/claude-sdk-session.ts +7 -1
  120. package/src/providers/dsh-adapter.ts +1 -1
  121. package/src/providers/opencode-adapter.ts +1 -2
  122. package/src/providers/pi-mono-adapter.ts +3 -3
  123. package/src/realtime/browser.generated.txt +8 -8
  124. package/src/realtime/browser.ts +3 -3
  125. package/src/scheduler/scheduler.ts +82 -13
  126. package/src/scripts-runtime/executors/quickjs-pool-config.ts +26 -0
  127. package/src/scripts-runtime/executors/quickjs.ts +9 -2
  128. package/src/scripts-runtime/executors/registry.ts +1 -1
  129. package/src/server.ts +1 -0
  130. package/src/slack/actions.ts +6 -2
  131. package/src/slack/app.ts +5 -0
  132. package/src/slack/assistant.ts +15 -5
  133. package/src/slack/egress-scrub.ts +3 -2
  134. package/src/slack/handlers.ts +36 -18
  135. package/src/slack/inbound-dispatch.ts +549 -0
  136. package/src/slack/inbound-files.ts +2 -0
  137. package/src/telemetry-context.ts +1 -0
  138. package/src/tests/claude-background-keepalive-wiring.test.ts +220 -0
  139. package/src/tests/claude-background-keepalive.fixture.ts +162 -0
  140. package/src/tests/claude-background-keepalive.test.ts +139 -0
  141. package/src/tests/codex-oauth-device.test.ts +1 -1
  142. package/src/tests/connection-embedded-auth.test.ts +51 -0
  143. package/src/tests/docs-index-footprint.test.js +3 -3
  144. package/src/tests/dsh-adapter.test.ts +1 -1
  145. package/src/tests/extensions-catalog.test.ts +1 -0
  146. package/src/tests/extensions-example-slack-reply-gate.test.ts +756 -0
  147. package/src/tests/heartbeat-checklist.test.ts +243 -0
  148. package/src/tests/pages-feedback.test.ts +218 -0
  149. package/src/tests/schedule-target-type.test.ts +136 -0
  150. package/src/tests/script-connections-http.test.ts +45 -0
  151. package/src/tests/script-connections-mcp.test.ts +41 -0
  152. package/src/tests/script-connections.test.ts +2 -0
  153. package/src/tests/script-executor-quickjs-pool.test.ts +106 -0
  154. package/src/tests/script-executor-registry.test.ts +56 -0
  155. package/src/tests/send-task-self-send.test.ts +107 -0
  156. package/src/tests/slack-inbound-diagnostics-auth.test.ts +93 -0
  157. package/src/tests/slack-inbound-receipts.test.ts +684 -0
  158. package/src/tests/slack-session-status.test.ts +4 -2
  159. package/src/tests/ui-e2e-ingest-payload.test.ts +5 -1
  160. package/src/tests/user-token-routes.test.ts +1 -1
  161. package/src/tests/workflow-executors.test.ts +3 -2
  162. package/src/tests/workflow-sub-workflow.test.ts +363 -0
  163. package/src/tools/script-connections/tool.ts +35 -3
  164. package/src/tools/send-task.ts +9 -1
  165. package/src/utils/internal-ai/complete-structured.ts +6 -3
  166. package/src/utils/runtime-model-catalog.ts +1 -1
  167. package/src/workflows/engine.ts +17 -1
  168. package/src/workflows/executors/agent-task.ts +2 -2
  169. package/src/workflows/executors/human-in-the-loop.ts +3 -3
  170. package/src/workflows/executors/registry.ts +2 -0
  171. package/src/workflows/executors/script.ts +1 -1
  172. package/src/workflows/executors/sub-workflow.ts +135 -0
  173. package/src/workflows/executors/wait.ts +3 -3
  174. package/src/workflows/recovery.ts +11 -1
  175. package/src/workflows/resume.ts +77 -0
  176. package/src/workflows/wait-filter.ts +5 -7
  177. package/templates/extensions/README.md +1 -0
  178. package/templates/extensions/slack-reply-gate/README.md +98 -0
  179. package/templates/extensions/slack-reply-gate/hooks.ts +582 -0
  180. package/templates/extensions/slack-reply-gate/manifest.json +8 -0
  181. package/templates/skills/heartbeat-runbook/content.md +3 -1
  182. package/templates/skills/pages/content.md +25 -0
  183. package/templates/skills/swarm-scripts/SKILL.md +10 -0
  184. package/templates/skills/swarm-scripts/content.md +10 -0
@@ -4,10 +4,6 @@ import {
4
4
  import {
5
5
  getApiKey
6
6
  } from "./cli-f14fvzag.js";
7
- import {
8
- DEFAULT_MODEL,
9
- resolveCredential
10
- } from "./cli-7mhy3ths.js";
11
7
  import {
12
8
  detachedProcessGroup,
13
9
  registerProcessGroup,
@@ -19,16 +15,10 @@ import {
19
15
  generateRandomCodeVerifier,
20
16
  generateRandomState,
21
17
  oauthAppRowToProviderConfig
22
- } from "./cli-kw0jcfje.js";
23
- import {
24
- getSlackApp
25
- } from "./cli-c8r99akr.js";
18
+ } from "./cli-fyeft04q.js";
26
19
  import {
27
20
  CredentialBroker,
28
21
  DEFAULT_CREDENTIAL_BINDINGS,
29
- claimApprovalCancellationNotification,
30
- completeApprovalCancellationNotificationClaim,
31
- createTaskExtended,
32
22
  decryptSecret,
33
23
  encryptSecret,
34
24
  getAuthorizationById,
@@ -41,45 +31,29 @@ import {
41
31
  getOAuthAppById,
42
32
  getResolvedConfig,
43
33
  getScriptById,
44
- getTaskById,
45
34
  init_credential_broker,
46
35
  init_crypto,
47
36
  init_date_utils,
48
37
  init_db,
49
38
  init_db1 as init_db2,
50
39
  init_oauth,
40
+ init_quickjs_pool_config,
51
41
  init_secret_registry,
52
42
  normalizeDateRequired,
53
43
  oauthSecretName,
54
44
  placeholderForConfigKey,
55
45
  registerStoredSecret,
56
- releaseApprovalCancellationNotificationClaim,
46
+ resolveQuickJSPoolSize,
57
47
  restoreScratchScriptLastUsedIfUnchanged,
58
48
  touchScratchScriptLastUsed,
59
49
  updateAuthorizationTokens,
60
50
  upsertAuthorization,
61
51
  upsertSwarmConfig
62
- } from "./cli-mkdsy1nq.js";
52
+ } from "./cli-rg1c8ccw.js";
63
53
  import {
64
- TERMINAL_TASK_STATUSES,
65
54
  defaultAssetKey,
66
- init_key,
67
- init_types
55
+ init_key
68
56
  } from "./cli-xvdgasgy.js";
69
- import {
70
- init_resolver,
71
- resolveTemplate
72
- } from "./cli-5c2j5yvx.js";
73
- import {
74
- DEFAULT_OPENROUTER_BASE_URL,
75
- getOpenRouterAttributionHeaders,
76
- getOpenRouterBaseUrl,
77
- init_openrouter_base_url
78
- } from "./cli-a35hzdve.js";
79
- import {
80
- getAppUrl,
81
- init_constants
82
- } from "./cli-gd4favx9.js";
83
57
  import {
84
58
  init_env_flag,
85
59
  isEnvFlagEnabled
@@ -383,8 +357,8 @@ var require_luxon = __commonJS(function(exports) {
383
357
  }
384
358
 
385
359
  class InvalidUnitError extends LuxonError {
386
- constructor(unit2) {
387
- super(`Invalid unit ${unit2}`);
360
+ constructor(unit) {
361
+ super(`Invalid unit ${unit}`);
388
362
  }
389
363
  }
390
364
 
@@ -1013,16 +987,16 @@ var require_luxon = __commonJS(function(exports) {
1013
987
  this.rtf = getCachedRTF(intl, opts);
1014
988
  }
1015
989
  }
1016
- format(count, unit2) {
990
+ format(count, unit) {
1017
991
  if (this.rtf) {
1018
- return this.rtf.format(count, unit2);
992
+ return this.rtf.format(count, unit);
1019
993
  } else {
1020
- return formatRelativeTime(unit2, count, this.opts.numeric, this.opts.style !== "long");
994
+ return formatRelativeTime(unit, count, this.opts.numeric, this.opts.style !== "long");
1021
995
  }
1022
996
  }
1023
- formatToParts(count, unit2) {
997
+ formatToParts(count, unit) {
1024
998
  if (this.rtf) {
1025
- return this.rtf.formatToParts(count, unit2);
999
+ return this.rtf.formatToParts(count, unit);
1026
1000
  } else {
1027
1001
  return [];
1028
1002
  }
@@ -1491,8 +1465,8 @@ var require_luxon = __commonJS(function(exports) {
1491
1465
  }
1492
1466
  var nonLeapLadder = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
1493
1467
  var leapLadder = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335];
1494
- function unitOutOfRange(unit2, value) {
1495
- return new Invalid("unit out of range", `you specified ${value} (of type ${typeof value}) as a ${unit2}, which is invalid`);
1468
+ function unitOutOfRange(unit, value) {
1469
+ return new Invalid("unit out of range", `you specified ${value} (of type ${typeof value}) as a ${unit}, which is invalid`);
1496
1470
  }
1497
1471
  function dayOfWeek(year, month, day) {
1498
1472
  const d = new Date(Date.UTC(year, month - 1, day));
@@ -1960,7 +1934,7 @@ var require_luxon = __commonJS(function(exports) {
1960
1934
  function eraForDateTime(dt, length) {
1961
1935
  return eras(length)[dt.year < 0 ? 0 : 1];
1962
1936
  }
1963
- function formatRelativeTime(unit2, count, numeric = "always", narrow = false) {
1937
+ function formatRelativeTime(unit, count, numeric = "always", narrow = false) {
1964
1938
  const units = {
1965
1939
  years: ["year", "yr."],
1966
1940
  quarters: ["quarter", "qtr."],
@@ -1971,19 +1945,19 @@ var require_luxon = __commonJS(function(exports) {
1971
1945
  minutes: ["minute", "min."],
1972
1946
  seconds: ["second", "sec."]
1973
1947
  };
1974
- const lastable = ["hours", "minutes", "seconds"].indexOf(unit2) === -1;
1948
+ const lastable = ["hours", "minutes", "seconds"].indexOf(unit) === -1;
1975
1949
  if (numeric === "auto" && lastable) {
1976
- const isDay = unit2 === "days";
1950
+ const isDay = unit === "days";
1977
1951
  switch (count) {
1978
1952
  case 1:
1979
- return isDay ? "tomorrow" : `next ${units[unit2][0]}`;
1953
+ return isDay ? "tomorrow" : `next ${units[unit][0]}`;
1980
1954
  case -1:
1981
- return isDay ? "yesterday" : `last ${units[unit2][0]}`;
1955
+ return isDay ? "yesterday" : `last ${units[unit][0]}`;
1982
1956
  case 0:
1983
- return isDay ? "today" : `this ${units[unit2][0]}`;
1957
+ return isDay ? "today" : `this ${units[unit][0]}`;
1984
1958
  }
1985
1959
  }
1986
- const isInPast = Object.is(count, -0) || count < 0, fmtValue = Math.abs(count), singular = fmtValue === 1, lilUnits = units[unit2], fmtUnit = narrow ? singular ? lilUnits[1] : lilUnits[2] || lilUnits[1] : singular ? units[unit2][0] : unit2;
1960
+ const isInPast = Object.is(count, -0) || count < 0, fmtValue = Math.abs(count), singular = fmtValue === 1, lilUnits = units[unit], fmtUnit = narrow ? singular ? lilUnits[1] : lilUnits[2] || lilUnits[1] : singular ? units[unit][0] : unit;
1987
1961
  return isInPast ? `${fmtValue} ${fmtUnit} ago` : `in ${fmtValue} ${fmtUnit}`;
1988
1962
  }
1989
1963
  function stringifyTokens(splits, tokenToString) {
@@ -2644,9 +2618,9 @@ var require_luxon = __commonJS(function(exports) {
2644
2618
  function durationToMillis(matrix, vals) {
2645
2619
  var _vals$milliseconds;
2646
2620
  let sum = (_vals$milliseconds = vals.milliseconds) != null ? _vals$milliseconds : 0;
2647
- for (const unit2 of reverseUnits.slice(1)) {
2648
- if (vals[unit2]) {
2649
- sum += vals[unit2] * matrix[unit2]["milliseconds"];
2621
+ for (const unit of reverseUnits.slice(1)) {
2622
+ if (vals[unit]) {
2623
+ sum += vals[unit] * matrix[unit]["milliseconds"];
2650
2624
  }
2651
2625
  }
2652
2626
  return sum;
@@ -2760,7 +2734,7 @@ var require_luxon = __commonJS(function(exports) {
2760
2734
  });
2761
2735
  }
2762
2736
  }
2763
- static normalizeUnit(unit2) {
2737
+ static normalizeUnit(unit) {
2764
2738
  const normalized = {
2765
2739
  year: "years",
2766
2740
  years: "years",
@@ -2780,9 +2754,9 @@ var require_luxon = __commonJS(function(exports) {
2780
2754
  seconds: "seconds",
2781
2755
  millisecond: "milliseconds",
2782
2756
  milliseconds: "milliseconds"
2783
- }[unit2 ? unit2.toLowerCase() : unit2];
2757
+ }[unit ? unit.toLowerCase() : unit];
2784
2758
  if (!normalized)
2785
- throw new InvalidUnitError(unit2);
2759
+ throw new InvalidUnitError(unit);
2786
2760
  return normalized;
2787
2761
  }
2788
2762
  static isDuration(o) {
@@ -2805,8 +2779,8 @@ var require_luxon = __commonJS(function(exports) {
2805
2779
  if (!this.isValid)
2806
2780
  return INVALID$2;
2807
2781
  const showZeros = opts.showZeros !== false;
2808
- const l2 = orderedUnits$1.map((unit2) => {
2809
- const val = this.values[unit2];
2782
+ const l2 = orderedUnits$1.map((unit) => {
2783
+ const val = this.values[unit];
2810
2784
  if (isUndefined(val) || val === 0 && !showZeros) {
2811
2785
  return null;
2812
2786
  }
@@ -2814,7 +2788,7 @@ var require_luxon = __commonJS(function(exports) {
2814
2788
  style: "unit",
2815
2789
  unitDisplay: "long",
2816
2790
  ...opts,
2817
- unit: unit2.slice(0, -1)
2791
+ unit: unit.slice(0, -1)
2818
2792
  }).format(val);
2819
2793
  }).filter((n2) => n2);
2820
2794
  return this.loc.listFormatter({
@@ -2924,8 +2898,8 @@ var require_luxon = __commonJS(function(exports) {
2924
2898
  values: result
2925
2899
  }, true);
2926
2900
  }
2927
- get(unit2) {
2928
- return this[Duration.normalizeUnit(unit2)];
2901
+ get(unit) {
2902
+ return this[Duration.normalizeUnit(unit)];
2929
2903
  }
2930
2904
  set(values) {
2931
2905
  if (!this.isValid)
@@ -2955,8 +2929,8 @@ var require_luxon = __commonJS(function(exports) {
2955
2929
  };
2956
2930
  return clone$1(this, opts);
2957
2931
  }
2958
- as(unit2) {
2959
- return this.isValid ? this.shiftTo(unit2).get(unit2) : NaN;
2932
+ as(unit) {
2933
+ return this.isValid ? this.shiftTo(unit).get(unit) : NaN;
2960
2934
  }
2961
2935
  normalize() {
2962
2936
  if (!this.isValid)
@@ -3200,13 +3174,13 @@ var require_luxon = __commonJS(function(exports) {
3200
3174
  get invalidExplanation() {
3201
3175
  return this.invalid ? this.invalid.explanation : null;
3202
3176
  }
3203
- length(unit2 = "milliseconds") {
3204
- return this.isValid ? this.toDuration(...[unit2]).get(unit2) : NaN;
3177
+ length(unit = "milliseconds") {
3178
+ return this.isValid ? this.toDuration(...[unit]).get(unit) : NaN;
3205
3179
  }
3206
- count(unit2 = "milliseconds", opts) {
3180
+ count(unit = "milliseconds", opts) {
3207
3181
  if (!this.isValid)
3208
3182
  return NaN;
3209
- const start = this.start.startOf(unit2, opts);
3183
+ const start = this.start.startOf(unit, opts);
3210
3184
  let end;
3211
3185
  if (opts != null && opts.useLocaleWeeks) {
3212
3186
  end = this.end.reconfigure({
@@ -3215,11 +3189,11 @@ var require_luxon = __commonJS(function(exports) {
3215
3189
  } else {
3216
3190
  end = this.end;
3217
3191
  }
3218
- end = end.startOf(unit2, opts);
3219
- return Math.floor(end.diff(start, unit2).get(unit2)) + (end.valueOf() !== this.end.valueOf());
3192
+ end = end.startOf(unit, opts);
3193
+ return Math.floor(end.diff(start, unit).get(unit)) + (end.valueOf() !== this.end.valueOf());
3220
3194
  }
3221
- hasSame(unit2) {
3222
- return this.isValid ? this.isEmpty() || this.e.minus(1).hasSame(this.s, unit2) : false;
3195
+ hasSame(unit) {
3196
+ return this.isValid ? this.isEmpty() || this.e.minus(1).hasSame(this.s, unit) : false;
3223
3197
  }
3224
3198
  isEmpty() {
3225
3199
  return this.s.valueOf() === this.e.valueOf();
@@ -3402,11 +3376,11 @@ var require_luxon = __commonJS(function(exports) {
3402
3376
  return INVALID$1;
3403
3377
  return `${this.s.toFormat(dateFormat)}${separator}${this.e.toFormat(dateFormat)}`;
3404
3378
  }
3405
- toDuration(unit2, opts) {
3379
+ toDuration(unit, opts) {
3406
3380
  if (!this.isValid) {
3407
3381
  return Duration.invalid(this.invalidReason);
3408
3382
  }
3409
- return this.e.diff(this.s, unit2, opts);
3383
+ return this.e.diff(this.s, unit, opts);
3410
3384
  }
3411
3385
  mapEndpoints(mapFn) {
3412
3386
  return Interval.fromDateTimes(mapFn(this.s), mapFn(this.e));
@@ -3507,17 +3481,17 @@ var require_luxon = __commonJS(function(exports) {
3507
3481
  const results = {};
3508
3482
  const earlier = cursor;
3509
3483
  let lowestOrder, highWater;
3510
- for (const [unit2, differ] of differs) {
3511
- if (units.indexOf(unit2) >= 0) {
3512
- lowestOrder = unit2;
3513
- results[unit2] = differ(cursor, later);
3484
+ for (const [unit, differ] of differs) {
3485
+ if (units.indexOf(unit) >= 0) {
3486
+ lowestOrder = unit;
3487
+ results[unit] = differ(cursor, later);
3514
3488
  highWater = earlier.plus(results);
3515
3489
  if (highWater > later) {
3516
- results[unit2]--;
3490
+ results[unit]--;
3517
3491
  cursor = earlier.plus(results);
3518
3492
  if (cursor > later) {
3519
3493
  highWater = cursor;
3520
- results[unit2]--;
3494
+ results[unit]--;
3521
3495
  cursor = earlier.plus(results);
3522
3496
  }
3523
3497
  } else {
@@ -3702,11 +3676,11 @@ var require_luxon = __commonJS(function(exports) {
3702
3676
  return literal2(t);
3703
3677
  }
3704
3678
  };
3705
- const unit2 = unitate(token) || {
3679
+ const unit = unitate(token) || {
3706
3680
  invalidReason: MISSING_FTP
3707
3681
  };
3708
- unit2.token = token;
3709
- return unit2;
3682
+ unit.token = token;
3683
+ return unit;
3710
3684
  }
3711
3685
  var partTypeStyleToTokenVal = {
3712
3686
  year: {
@@ -4184,7 +4158,7 @@ var require_luxon = __commonJS(function(exports) {
4184
4158
  var orderedUnits = ["year", "month", "day", "hour", "minute", "second", "millisecond"];
4185
4159
  var orderedWeekUnits = ["weekYear", "weekNumber", "weekday", "hour", "minute", "second", "millisecond"];
4186
4160
  var orderedOrdinalUnits = ["year", "ordinal", "hour", "minute", "second", "millisecond"];
4187
- function normalizeUnit(unit2) {
4161
+ function normalizeUnit(unit) {
4188
4162
  const normalized = {
4189
4163
  year: "year",
4190
4164
  years: "year",
@@ -4210,13 +4184,13 @@ var require_luxon = __commonJS(function(exports) {
4210
4184
  weekyear: "weekYear",
4211
4185
  weekyears: "weekYear",
4212
4186
  ordinal: "ordinal"
4213
- }[unit2.toLowerCase()];
4187
+ }[unit.toLowerCase()];
4214
4188
  if (!normalized)
4215
- throw new InvalidUnitError(unit2);
4189
+ throw new InvalidUnitError(unit);
4216
4190
  return normalized;
4217
4191
  }
4218
- function normalizeUnitWithLocalWeeks(unit2) {
4219
- switch (unit2.toLowerCase()) {
4192
+ function normalizeUnitWithLocalWeeks(unit) {
4193
+ switch (unit.toLowerCase()) {
4220
4194
  case "localweekday":
4221
4195
  case "localweekdays":
4222
4196
  return "localWeekday";
@@ -4227,7 +4201,7 @@ var require_luxon = __commonJS(function(exports) {
4227
4201
  case "localweekyears":
4228
4202
  return "localWeekYear";
4229
4203
  default:
4230
- return normalizeUnit(unit2);
4204
+ return normalizeUnit(unit);
4231
4205
  }
4232
4206
  }
4233
4207
  function guessOffsetForZone(zone) {
@@ -4275,27 +4249,27 @@ var require_luxon = __commonJS(function(exports) {
4275
4249
  });
4276
4250
  }
4277
4251
  function diffRelative(start, end, opts) {
4278
- const round = isUndefined(opts.round) ? true : opts.round, rounding = isUndefined(opts.rounding) ? "trunc" : opts.rounding, format = (c, unit2) => {
4252
+ const round = isUndefined(opts.round) ? true : opts.round, rounding = isUndefined(opts.rounding) ? "trunc" : opts.rounding, format = (c, unit) => {
4279
4253
  c = roundTo(c, round || opts.calendary ? 0 : 2, opts.calendary ? "round" : rounding);
4280
4254
  const formatter = end.loc.clone(opts).relFormatter(opts);
4281
- return formatter.format(c, unit2);
4282
- }, differ = (unit2) => {
4255
+ return formatter.format(c, unit);
4256
+ }, differ = (unit) => {
4283
4257
  if (opts.calendary) {
4284
- if (!end.hasSame(start, unit2)) {
4285
- return end.startOf(unit2).diff(start.startOf(unit2), unit2).get(unit2);
4258
+ if (!end.hasSame(start, unit)) {
4259
+ return end.startOf(unit).diff(start.startOf(unit), unit).get(unit);
4286
4260
  } else
4287
4261
  return 0;
4288
4262
  } else {
4289
- return end.diff(start, unit2).get(unit2);
4263
+ return end.diff(start, unit).get(unit);
4290
4264
  }
4291
4265
  };
4292
4266
  if (opts.unit) {
4293
4267
  return format(differ(opts.unit), opts.unit);
4294
4268
  }
4295
- for (const unit2 of opts.units) {
4296
- const count = differ(unit2);
4269
+ for (const unit of opts.units) {
4270
+ const count = differ(unit);
4297
4271
  if (Math.abs(count) >= 1) {
4298
- return format(count, unit2);
4272
+ return format(count, unit);
4299
4273
  }
4300
4274
  }
4301
4275
  return format(start > end ? -0 : 0, opts.units[opts.units.length - 1]);
@@ -4534,8 +4508,8 @@ var require_luxon = __commonJS(function(exports) {
4534
4508
  zoneOffsetTs = undefined;
4535
4509
  zoneOffsetGuessCache.clear();
4536
4510
  }
4537
- get(unit2) {
4538
- return this[unit2];
4511
+ get(unit) {
4512
+ return this[unit];
4539
4513
  }
4540
4514
  get isValid() {
4541
4515
  return this.invalid === null;
@@ -4821,12 +4795,12 @@ var require_luxon = __commonJS(function(exports) {
4821
4795
  const dur = Duration.fromDurationLike(duration).negate();
4822
4796
  return clone(this, adjustTime(this, dur));
4823
4797
  }
4824
- startOf(unit2, {
4798
+ startOf(unit, {
4825
4799
  useLocaleWeeks = false
4826
4800
  } = {}) {
4827
4801
  if (!this.isValid)
4828
4802
  return this;
4829
- const o = {}, normalizedUnit = Duration.normalizeUnit(unit2);
4803
+ const o = {}, normalizedUnit = Duration.normalizeUnit(unit);
4830
4804
  switch (normalizedUnit) {
4831
4805
  case "years":
4832
4806
  o.month = 1;
@@ -4864,10 +4838,10 @@ var require_luxon = __commonJS(function(exports) {
4864
4838
  }
4865
4839
  return this.set(o);
4866
4840
  }
4867
- endOf(unit2, opts) {
4841
+ endOf(unit, opts) {
4868
4842
  return this.isValid ? this.plus({
4869
- [unit2]: 1
4870
- }).startOf(unit2, opts).minus(1) : this;
4843
+ [unit]: 1
4844
+ }).startOf(unit, opts).minus(1) : this;
4871
4845
  }
4872
4846
  toFormat(fmt, opts = {}) {
4873
4847
  return this.isValid ? Formatter.create(this.loc.redefaultToEN(opts)).formatDateTimeFromString(this, fmt) : INVALID;
@@ -5005,7 +4979,7 @@ var require_luxon = __commonJS(function(exports) {
5005
4979
  toJSDate() {
5006
4980
  return new Date(this.isValid ? this.ts : NaN);
5007
4981
  }
5008
- diff(otherDateTime, unit2 = "milliseconds", opts = {}) {
4982
+ diff(otherDateTime, unit = "milliseconds", opts = {}) {
5009
4983
  if (!this.isValid || !otherDateTime.isValid) {
5010
4984
  return Duration.invalid("created by diffing an invalid DateTime");
5011
4985
  }
@@ -5014,23 +4988,23 @@ var require_luxon = __commonJS(function(exports) {
5014
4988
  numberingSystem: this.numberingSystem,
5015
4989
  ...opts
5016
4990
  };
5017
- const units = maybeArray(unit2).map(Duration.normalizeUnit), otherIsLater = otherDateTime.valueOf() > this.valueOf(), earlier = otherIsLater ? this : otherDateTime, later = otherIsLater ? otherDateTime : this, diffed = diff(earlier, later, units, durOpts);
4991
+ const units = maybeArray(unit).map(Duration.normalizeUnit), otherIsLater = otherDateTime.valueOf() > this.valueOf(), earlier = otherIsLater ? this : otherDateTime, later = otherIsLater ? otherDateTime : this, diffed = diff(earlier, later, units, durOpts);
5018
4992
  return otherIsLater ? diffed.negate() : diffed;
5019
4993
  }
5020
- diffNow(unit2 = "milliseconds", opts = {}) {
5021
- return this.diff(DateTime.now(), unit2, opts);
4994
+ diffNow(unit = "milliseconds", opts = {}) {
4995
+ return this.diff(DateTime.now(), unit, opts);
5022
4996
  }
5023
4997
  until(otherDateTime) {
5024
4998
  return this.isValid ? Interval.fromDateTimes(this, otherDateTime) : this;
5025
4999
  }
5026
- hasSame(otherDateTime, unit2, opts) {
5000
+ hasSame(otherDateTime, unit, opts) {
5027
5001
  if (!this.isValid)
5028
5002
  return false;
5029
5003
  const inputMs = otherDateTime.valueOf();
5030
5004
  const adjustedToZone = this.setZone(otherDateTime.zone, {
5031
5005
  keepLocalTime: true
5032
5006
  });
5033
- return adjustedToZone.startOf(unit2, opts) <= inputMs && inputMs <= adjustedToZone.endOf(unit2, opts);
5007
+ return adjustedToZone.startOf(unit, opts) <= inputMs && inputMs <= adjustedToZone.endOf(unit, opts);
5034
5008
  }
5035
5009
  equals(other) {
5036
5010
  return this.isValid && other.isValid && this.valueOf() === other.valueOf() && this.zone.equals(other.zone) && this.loc.equals(other.loc);
@@ -5042,16 +5016,16 @@ var require_luxon = __commonJS(function(exports) {
5042
5016
  zone: this.zone
5043
5017
  }), padding = options.padding ? this < base ? -options.padding : options.padding : 0;
5044
5018
  let units = ["years", "months", "days", "hours", "minutes", "seconds"];
5045
- let unit2 = options.unit;
5019
+ let unit = options.unit;
5046
5020
  if (Array.isArray(options.unit)) {
5047
5021
  units = options.unit;
5048
- unit2 = undefined;
5022
+ unit = undefined;
5049
5023
  }
5050
5024
  return diffRelative(base, this.plus(padding), {
5051
5025
  ...options,
5052
5026
  numeric: "always",
5053
5027
  units,
5054
- unit: unit2
5028
+ unit
5055
5029
  });
5056
5030
  }
5057
5031
  toRelativeCalendar(options = {}) {
@@ -5341,19 +5315,19 @@ var require_CronDate = __commonJS(function(exports) {
5341
5315
  subtractSecond() {
5342
5316
  this.#date = this.#date.minus({ seconds: 1 });
5343
5317
  }
5344
- addUnit(unit2) {
5345
- this.#verbMap.add[unit2]();
5318
+ addUnit(unit) {
5319
+ this.#verbMap.add[unit]();
5346
5320
  }
5347
- subtractUnit(unit2) {
5348
- this.#verbMap.subtract[unit2]();
5321
+ subtractUnit(unit) {
5322
+ this.#verbMap.subtract[unit]();
5349
5323
  }
5350
- invokeDateOperation(verb, unit2) {
5324
+ invokeDateOperation(verb, unit) {
5351
5325
  if (verb === DateMathOp.Add) {
5352
- this.addUnit(unit2);
5326
+ this.addUnit(unit);
5353
5327
  return;
5354
5328
  }
5355
5329
  if (verb === DateMathOp.Subtract) {
5356
- this.subtractUnit(unit2);
5330
+ this.subtractUnit(unit);
5357
5331
  return;
5358
5332
  }
5359
5333
  throw new Error(`Invalid verb: ${verb}`);
@@ -5462,13 +5436,13 @@ var require_CronDate = __commonJS(function(exports) {
5462
5436
  }
5463
5437
  return day > lastDay - 7;
5464
5438
  }
5465
- applyDateOperation(op, unit2, hoursLength) {
5466
- if (unit2 === TimeUnit.Month || unit2 === TimeUnit.Day) {
5467
- this.invokeDateOperation(op, unit2);
5439
+ applyDateOperation(op, unit, hoursLength) {
5440
+ if (unit === TimeUnit.Month || unit === TimeUnit.Day) {
5441
+ this.invokeDateOperation(op, unit);
5468
5442
  return;
5469
5443
  }
5470
5444
  const previousHour = this.getHours();
5471
- this.invokeDateOperation(op, unit2);
5445
+ this.invokeDateOperation(op, unit);
5472
5446
  const currentHour = this.getHours();
5473
5447
  const diff = currentHour - previousHour;
5474
5448
  if (diff === 2) {
@@ -10344,17 +10318,17 @@ var require_typescript = __commonJS(function(exports, module) {
10344
10318
  }
10345
10319
  return true;
10346
10320
  }
10347
- function fail2(message, stackCrawlMark) {
10321
+ function fail(message, stackCrawlMark) {
10348
10322
  debugger;
10349
10323
  const e = new Error(message ? `Debug Failure. ${message}` : "Debug Failure.");
10350
10324
  if (Error.captureStackTrace) {
10351
- Error.captureStackTrace(e, stackCrawlMark || fail2);
10325
+ Error.captureStackTrace(e, stackCrawlMark || fail);
10352
10326
  }
10353
10327
  throw e;
10354
10328
  }
10355
- Debug2.fail = fail2;
10329
+ Debug2.fail = fail;
10356
10330
  function failBadSyntaxKind(node, message, stackCrawlMark) {
10357
- return fail2(`${message || "Unexpected node."}\r
10331
+ return fail(`${message || "Unexpected node."}\r
10358
10332
  Node ${formatSyntaxKind(node.kind)} was unexpected.`, stackCrawlMark || failBadSyntaxKind);
10359
10333
  }
10360
10334
  Debug2.failBadSyntaxKind = failBadSyntaxKind;
@@ -10365,38 +10339,38 @@ Node ${formatSyntaxKind(node.kind)} was unexpected.`, stackCrawlMark || failBadS
10365
10339
  message += `\r
10366
10340
  Verbose Debug Information: ` + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo());
10367
10341
  }
10368
- fail2(message, stackCrawlMark || assert);
10342
+ fail(message, stackCrawlMark || assert);
10369
10343
  }
10370
10344
  }
10371
10345
  Debug2.assert = assert;
10372
10346
  function assertEqual(a, b, msg, msg2, stackCrawlMark) {
10373
10347
  if (a !== b) {
10374
10348
  const message = msg ? msg2 ? `${msg} ${msg2}` : msg : "";
10375
- fail2(`Expected ${a} === ${b}. ${message}`, stackCrawlMark || assertEqual);
10349
+ fail(`Expected ${a} === ${b}. ${message}`, stackCrawlMark || assertEqual);
10376
10350
  }
10377
10351
  }
10378
10352
  Debug2.assertEqual = assertEqual;
10379
10353
  function assertLessThan(a, b, msg, stackCrawlMark) {
10380
10354
  if (a >= b) {
10381
- fail2(`Expected ${a} < ${b}. ${msg || ""}`, stackCrawlMark || assertLessThan);
10355
+ fail(`Expected ${a} < ${b}. ${msg || ""}`, stackCrawlMark || assertLessThan);
10382
10356
  }
10383
10357
  }
10384
10358
  Debug2.assertLessThan = assertLessThan;
10385
10359
  function assertLessThanOrEqual(a, b, stackCrawlMark) {
10386
10360
  if (a > b) {
10387
- fail2(`Expected ${a} <= ${b}`, stackCrawlMark || assertLessThanOrEqual);
10361
+ fail(`Expected ${a} <= ${b}`, stackCrawlMark || assertLessThanOrEqual);
10388
10362
  }
10389
10363
  }
10390
10364
  Debug2.assertLessThanOrEqual = assertLessThanOrEqual;
10391
10365
  function assertGreaterThanOrEqual(a, b, stackCrawlMark) {
10392
10366
  if (a < b) {
10393
- fail2(`Expected ${a} >= ${b}`, stackCrawlMark || assertGreaterThanOrEqual);
10367
+ fail(`Expected ${a} >= ${b}`, stackCrawlMark || assertGreaterThanOrEqual);
10394
10368
  }
10395
10369
  }
10396
10370
  Debug2.assertGreaterThanOrEqual = assertGreaterThanOrEqual;
10397
10371
  function assertIsDefined(value, message, stackCrawlMark) {
10398
10372
  if (value === undefined || value === null) {
10399
- fail2(message, stackCrawlMark || assertIsDefined);
10373
+ fail(message, stackCrawlMark || assertIsDefined);
10400
10374
  }
10401
10375
  }
10402
10376
  Debug2.assertIsDefined = assertIsDefined;
@@ -10418,7 +10392,7 @@ Verbose Debug Information: ` + (typeof verboseDebugInfo === "string" ? verboseDe
10418
10392
  Debug2.checkEachDefined = checkEachDefined;
10419
10393
  function assertNever(member, message = "Illegal value:", stackCrawlMark) {
10420
10394
  const detail = typeof member === "object" && hasProperty(member, "kind") && hasProperty(member, "pos") ? "SyntaxKind: " + formatSyntaxKind(member.kind) : JSON.stringify(member);
10421
- return fail2(`${message} ${detail}`, stackCrawlMark || assertNever);
10395
+ return fail(`${message} ${detail}`, stackCrawlMark || assertNever);
10422
10396
  }
10423
10397
  Debug2.assertNever = assertNever;
10424
10398
  function assertEachNode(nodes, test, message, stackCrawlMark) {
@@ -115349,30 +115323,30 @@ ${lanes.join(`
115349
115323
  function getSourceFileFromReference(referencingFile, ref) {
115350
115324
  return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), getSourceFile);
115351
115325
  }
115352
- function getSourceFileFromReferenceWorker(fileName, getSourceFile2, fail2, reason) {
115326
+ function getSourceFileFromReferenceWorker(fileName, getSourceFile2, fail, reason) {
115353
115327
  if (hasExtension(fileName)) {
115354
115328
  const canonicalFileName = host.getCanonicalFileName(fileName);
115355
115329
  if (!options.allowNonTsExtensions && !forEach(flatten(supportedExtensionsWithJsonIfResolveJsonModule), (extension) => fileExtensionIs(canonicalFileName, extension))) {
115356
- if (fail2) {
115330
+ if (fail) {
115357
115331
  if (hasJSFileExtension(canonicalFileName)) {
115358
- fail2(Diagnostics.File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option, fileName);
115332
+ fail(Diagnostics.File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option, fileName);
115359
115333
  } else {
115360
- fail2(Diagnostics.File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + flatten(supportedExtensions).join("', '") + "'");
115334
+ fail(Diagnostics.File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + flatten(supportedExtensions).join("', '") + "'");
115361
115335
  }
115362
115336
  }
115363
115337
  return;
115364
115338
  }
115365
115339
  const sourceFile = getSourceFile2(fileName);
115366
- if (fail2) {
115340
+ if (fail) {
115367
115341
  if (!sourceFile) {
115368
115342
  const redirect = getRedirectFromSourceFile(fileName);
115369
115343
  if (redirect == null ? undefined : redirect.outputDts) {
115370
- fail2(Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect.outputDts, fileName);
115344
+ fail(Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect.outputDts, fileName);
115371
115345
  } else {
115372
- fail2(Diagnostics.File_0_not_found, fileName);
115346
+ fail(Diagnostics.File_0_not_found, fileName);
115373
115347
  }
115374
115348
  } else if (isReferencedFile(reason) && canonicalFileName === host.getCanonicalFileName(getSourceFileByPath(reason.file).fileName)) {
115375
- fail2(Diagnostics.A_file_cannot_have_a_reference_to_itself);
115349
+ fail(Diagnostics.A_file_cannot_have_a_reference_to_itself);
115376
115350
  }
115377
115351
  }
115378
115352
  return sourceFile;
@@ -115380,13 +115354,13 @@ ${lanes.join(`
115380
115354
  const sourceFileNoExtension = options.allowNonTsExtensions && getSourceFile2(fileName);
115381
115355
  if (sourceFileNoExtension)
115382
115356
  return sourceFileNoExtension;
115383
- if (fail2 && options.allowNonTsExtensions) {
115384
- fail2(Diagnostics.File_0_not_found, fileName);
115357
+ if (fail && options.allowNonTsExtensions) {
115358
+ fail(Diagnostics.File_0_not_found, fileName);
115385
115359
  return;
115386
115360
  }
115387
115361
  const sourceFileWithAddedExtension = forEach(supportedExtensions[0], (extension) => getSourceFile2(fileName + extension));
115388
- if (fail2 && !sourceFileWithAddedExtension)
115389
- fail2(Diagnostics.Could_not_resolve_the_path_0_with_the_extensions_Colon_1, fileName, "'" + flatten(supportedExtensions).join("', '") + "'");
115362
+ if (fail && !sourceFileWithAddedExtension)
115363
+ fail(Diagnostics.Could_not_resolve_the_path_0_with_the_extensions_Colon_1, fileName, "'" + flatten(supportedExtensions).join("', '") + "'");
115390
115364
  return sourceFileWithAddedExtension;
115391
115365
  }
115392
115366
  }
@@ -175207,2044 +175181,6 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
175207
175181
  } });
175208
175182
  });
175209
175183
 
175210
- // src/workflows/executors/system-one-decision.ts
175211
- init_zod();
175212
- init_openrouter_base_url();
175213
- init_secret_scrubber();
175214
-
175215
- // src/workflows/executors/base.ts
175216
- class BaseExecutor {
175217
- deps;
175218
- retryPolicy;
175219
- constructor(deps) {
175220
- this.deps = deps;
175221
- }
175222
- async checkReadiness(_nodes) {
175223
- return [];
175224
- }
175225
- resolveApproval(_parkedOutput, _approval) {
175226
- return null;
175227
- }
175228
- async run(input) {
175229
- const configResult = this.configSchema.safeParse(input.config);
175230
- if (!configResult.success) {
175231
- return {
175232
- status: "failed",
175233
- error: `Input validation failed: ${configResult.error.message}`
175234
- };
175235
- }
175236
- let result;
175237
- try {
175238
- result = await this.execute(configResult.data, input.context, input.meta);
175239
- } catch (err) {
175240
- return {
175241
- status: "failed",
175242
- error: `Executor threw: ${err instanceof Error ? err.message : String(err)}`
175243
- };
175244
- }
175245
- if (result.status === "success" && result.output !== undefined) {
175246
- const outputResult = this.outputSchema.safeParse(result.output);
175247
- if (!outputResult.success) {
175248
- return {
175249
- status: "failed",
175250
- error: `Output validation failed: ${outputResult.error.message}`
175251
- };
175252
- }
175253
- }
175254
- return result;
175255
- }
175256
- }
175257
-
175258
- // src/workflows/executors/human-in-the-loop.ts
175259
- init_zod();
175260
- init_constants();
175261
- init_secret_scrubber();
175262
-
175263
- // src/workflows/approval-notifications.ts
175264
- init_db2();
175265
- init_resolver();
175266
- init_types();
175267
- init_secret_scrubber();
175268
- async function postApprovalCancellationUpdates(approvals, reason, client = getSlackApp()?.client) {
175269
- if (!client)
175270
- return;
175271
- const text = `This approval is no longer actionable: ${reason}`;
175272
- for (const approval of approvals) {
175273
- const channels = approval.notificationChannels;
175274
- const slackThreads = (channels ?? []).filter((notification) => notification.channel === "slack" && notification.messageTs);
175275
- if (slackThreads.length === 0)
175276
- continue;
175277
- for (const notification of slackThreads) {
175278
- if (notification.channel !== "slack" || !notification.messageTs)
175279
- continue;
175280
- const notificationKey = `${notification.target}:${notification.messageTs}`;
175281
- const claim = await claimApprovalCancellationNotification(approval.id, notificationKey);
175282
- if (!claim)
175283
- continue;
175284
- try {
175285
- await client.chat.postMessage({
175286
- channel: notification.target,
175287
- thread_ts: notification.messageTs,
175288
- text,
175289
- unfurl_links: false,
175290
- unfurl_media: false
175291
- });
175292
- await completeApprovalCancellationNotificationClaim(approval.id, notificationKey, claim.leaseToken);
175293
- } catch (error) {
175294
- await releaseApprovalCancellationNotificationClaim(approval.id, notificationKey, claim.leaseToken);
175295
- console.error(`[HITL] Failed to post cancellation update for approval ${approval.id}:`, scrubSecrets(error instanceof Error ? error.message : String(error)));
175296
- }
175297
- }
175298
- }
175299
- }
175300
- async function createApprovalFollowUpTask(request, templateEventType) {
175301
- if (request.workflowRunId || !request.sourceTaskId)
175302
- return false;
175303
- const sourceTask = await getTaskById(request.sourceTaskId);
175304
- if (!sourceTask)
175305
- return false;
175306
- if (templateEventType === "hitl.timeout" && TERMINAL_TASK_STATUSES.includes(sourceTask.status)) {
175307
- return false;
175308
- }
175309
- const { text: taskText } = templateEventType === "hitl.follow_up" ? resolveTemplate("hitl.follow_up", {
175310
- request_id: request.id,
175311
- title: request.title,
175312
- status: request.status,
175313
- responses: formatResponses(request.questions, request.responses ?? {})
175314
- }) : resolveTemplate("hitl.timeout", {
175315
- request_id: request.id,
175316
- title: request.title,
175317
- expires_at: request.expiresAt ?? "",
175318
- reason: request.resolutionReason ?? ""
175319
- });
175320
- await createTaskExtended(taskText, {
175321
- agentId: sourceTask.agentId,
175322
- routingReason: sourceTask.agentId ? "continuity" : undefined,
175323
- routingSource: sourceTask.agentId ? "engine_default" : undefined,
175324
- parentTaskId: request.sourceTaskId,
175325
- source: "system",
175326
- taskType: "hitl-follow-up",
175327
- tags: ["hitl", "follow-up"],
175328
- slackChannelId: sourceTask.slackChannelId ?? undefined,
175329
- slackThreadTs: sourceTask.slackThreadTs ?? undefined,
175330
- slackUserId: sourceTask.slackUserId ?? undefined
175331
- });
175332
- return true;
175333
- }
175334
- function formatResponses(questions, responses) {
175335
- return questions.map((q) => {
175336
- const answer = responses[q.id];
175337
- let answerText;
175338
- if (answer == null) {
175339
- answerText = "(no answer)";
175340
- } else if (q.type === "approval") {
175341
- const a = answer;
175342
- answerText = a.approved ? "Approved" : "Rejected";
175343
- if (a.comment)
175344
- answerText += ` — ${a.comment}`;
175345
- } else if (typeof answer === "object") {
175346
- answerText = JSON.stringify(answer);
175347
- } else {
175348
- answerText = String(answer);
175349
- }
175350
- return `- ${q.label}: ${answerText}`;
175351
- }).join(`
175352
- `);
175353
- }
175354
-
175355
- // src/workflows/executors/human-in-the-loop.ts
175356
- var SelectOptionSchema = exports_external.object({
175357
- value: exports_external.string(),
175358
- label: exports_external.string(),
175359
- description: exports_external.string().optional()
175360
- });
175361
- var QuestionSchema = exports_external.discriminatedUnion("type", [
175362
- exports_external.object({
175363
- id: exports_external.string(),
175364
- type: exports_external.literal("approval"),
175365
- label: exports_external.string(),
175366
- required: exports_external.boolean().default(true),
175367
- description: exports_external.string().optional()
175368
- }),
175369
- exports_external.object({
175370
- id: exports_external.string(),
175371
- type: exports_external.literal("text"),
175372
- label: exports_external.string(),
175373
- required: exports_external.boolean().default(true),
175374
- description: exports_external.string().optional(),
175375
- placeholder: exports_external.string().optional(),
175376
- multiline: exports_external.boolean().optional()
175377
- }),
175378
- exports_external.object({
175379
- id: exports_external.string(),
175380
- type: exports_external.literal("single-select"),
175381
- label: exports_external.string(),
175382
- required: exports_external.boolean().default(true),
175383
- description: exports_external.string().optional(),
175384
- options: exports_external.array(SelectOptionSchema)
175385
- }),
175386
- exports_external.object({
175387
- id: exports_external.string(),
175388
- type: exports_external.literal("multi-select"),
175389
- label: exports_external.string(),
175390
- required: exports_external.boolean().default(true),
175391
- description: exports_external.string().optional(),
175392
- options: exports_external.array(SelectOptionSchema),
175393
- minSelections: exports_external.number().int().min(0).optional(),
175394
- maxSelections: exports_external.number().int().min(1).optional()
175395
- }),
175396
- exports_external.object({
175397
- id: exports_external.string(),
175398
- type: exports_external.literal("boolean"),
175399
- label: exports_external.string(),
175400
- required: exports_external.boolean().default(true),
175401
- description: exports_external.string().optional(),
175402
- defaultValue: exports_external.boolean().optional()
175403
- })
175404
- ]);
175405
- var ApproverConfigSchema = exports_external.object({
175406
- users: exports_external.array(exports_external.string()).optional(),
175407
- roles: exports_external.array(exports_external.string()).optional(),
175408
- policy: exports_external.union([exports_external.literal("any"), exports_external.literal("all"), exports_external.object({ min: exports_external.number().int().min(1) })])
175409
- });
175410
- var NotificationConfigSchema = exports_external.object({
175411
- channel: exports_external.enum(["slack", "email"]),
175412
- target: exports_external.string()
175413
- });
175414
- var HITLTimeoutSchema = exports_external.object({
175415
- seconds: exports_external.number().int().min(1),
175416
- action: exports_external.literal("reject")
175417
- });
175418
- var DYNAMIC_QUESTIONS_TOKEN_RE = /^\{\{[^}]+\}\}$/;
175419
- var MAX_HITL_QUESTIONS = 100;
175420
- var SLACK_SECTION_TEXT_LIMIT = 3000;
175421
- var MAX_REPORTED_ISSUES = 5;
175422
- var HITLConfigSchema = exports_external.object({
175423
- title: exports_external.string(),
175424
- questions: exports_external.union([
175425
- exports_external.array(QuestionSchema).min(1),
175426
- exports_external.string().regex(DYNAMIC_QUESTIONS_TOKEN_RE, "questions must be an array or one exact {{interpolation}} token")
175427
- ]),
175428
- approvers: ApproverConfigSchema,
175429
- timeout: HITLTimeoutSchema.optional(),
175430
- notifications: exports_external.array(NotificationConfigSchema).optional()
175431
- });
175432
- var HITLOutputSchema = exports_external.object({
175433
- requestId: exports_external.string().uuid(),
175434
- status: exports_external.string(),
175435
- responses: exports_external.record(exports_external.string(), exports_external.unknown()).nullable()
175436
- });
175437
- function resolveHitlQuestions(value) {
175438
- const fail = (reason) => ({
175439
- ok: false,
175440
- error: `human-in-the-loop questions ${reason}`
175441
- });
175442
- if (typeof value === "string") {
175443
- return fail(value.trim() === "" ? "resolved to an empty value: the {{token}} did not resolve (check the node's inputs mapping and the upstream output)" : "resolved to a string; they must resolve to an array of question objects (use one exact {{token}} pointing at an array)");
175444
- }
175445
- if (!Array.isArray(value)) {
175446
- return fail(`must resolve to an array of question objects, got ${value === null ? "null" : typeof value}`);
175447
- }
175448
- if (value.length === 0) {
175449
- return fail("resolved to an empty array; refusing to create an approval card with no questions");
175450
- }
175451
- if (value.length > MAX_HITL_QUESTIONS) {
175452
- return fail(`resolved to ${value.length} questions, over the limit of ${MAX_HITL_QUESTIONS} per card; split or group them upstream`);
175453
- }
175454
- const issues = [];
175455
- const questions = [];
175456
- const seenIds = new Set;
175457
- value.forEach((raw, index) => {
175458
- const parsed = QuestionSchema.safeParse(raw);
175459
- if (!parsed.success) {
175460
- for (const issue of parsed.error.issues) {
175461
- const path = issue.path.length > 0 ? `.${issue.path.map(String).join(".")}` : "";
175462
- issues.push(`[${index}]${path}: ${issue.message}`);
175463
- }
175464
- return;
175465
- }
175466
- const question = parsed.data;
175467
- if (question.id.trim() === "") {
175468
- issues.push(`[${index}].id: must be a non-empty string`);
175469
- } else if (seenIds.has(question.id)) {
175470
- issues.push(`[${index}].id: duplicate id "${question.id}" (responses are keyed by id)`);
175471
- }
175472
- seenIds.add(question.id);
175473
- if ((question.type === "single-select" || question.type === "multi-select") && question.options.length === 0) {
175474
- issues.push(`[${index}].options: a ${question.type} question needs at least one option`);
175475
- }
175476
- questions.push(question);
175477
- });
175478
- if (issues.length > 0) {
175479
- const shown = issues.slice(0, MAX_REPORTED_ISSUES).join("; ");
175480
- const more = issues.length > MAX_REPORTED_ISSUES ? `; and ${issues.length - MAX_REPORTED_ISSUES} more issue(s)` : "";
175481
- return fail(`are invalid: ${shown}${more}`);
175482
- }
175483
- return { ok: true, questions };
175484
- }
175485
- function escapeSlackMrkdwn(text) {
175486
- return text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
175487
- }
175488
- function buildSlackQuestionsSummary(questions, timeoutText = "") {
175489
- const header = `*Questions:*
175490
- `;
175491
- const lines = questions.map((q) => `• ${escapeSlackMrkdwn(q.label.replace(/\s+/g, " ").trim())}`);
175492
- const fits = (shown, omitted) => {
175493
- const tail = omitted > 0 ? `
175494
- _…and ${omitted} more. Answer all of them on the dashboard._` : "";
175495
- const text = `${header}${shown.join(`
175496
- `)}${tail}${timeoutText}`;
175497
- return text.length <= SLACK_SECTION_TEXT_LIMIT ? text : null;
175498
- };
175499
- const full = fits(lines, 0);
175500
- if (full)
175501
- return full;
175502
- for (let count = lines.length - 1;count >= 0; count--) {
175503
- const text = fits(lines.slice(0, count), lines.length - count);
175504
- if (text)
175505
- return text;
175506
- }
175507
- return `${header}_${questions.length} questions. Answer them on the dashboard._`;
175508
- }
175509
-
175510
- class HumanInTheLoopExecutor extends BaseExecutor {
175511
- type = "human-in-the-loop";
175512
- mode = "async";
175513
- configSchema = HITLConfigSchema;
175514
- outputSchema = HITLOutputSchema;
175515
- async run(input) {
175516
- const resolved = resolveHitlQuestions(input.config?.questions);
175517
- if (!resolved.ok)
175518
- return { status: "failed", error: resolved.error };
175519
- return super.run({ ...input, config: { ...input.config, questions: resolved.questions } });
175520
- }
175521
- async execute(config, _context, meta) {
175522
- const { db } = this.deps;
175523
- const existing = await db.getApprovalRequestByStepId(meta.stepId);
175524
- if (existing) {
175525
- if (existing.status !== "pending") {
175526
- if (existing.status === "cancelled") {
175527
- return {
175528
- status: "failed",
175529
- error: `Approval request was cancelled: ${existing.resolutionReason ?? "workflow run cancelled"}`
175530
- };
175531
- }
175532
- const nextPort = existing.status === "timeout" ? "timeout" : existing.status === "rejected" ? "rejected" : "approved";
175533
- return {
175534
- status: "success",
175535
- output: {
175536
- requestId: existing.id,
175537
- status: existing.status,
175538
- responses: existing.responses
175539
- },
175540
- nextPort
175541
- };
175542
- }
175543
- return {
175544
- status: "success",
175545
- async: true,
175546
- waitFor: "approval.resolved",
175547
- correlationId: existing.id
175548
- };
175549
- }
175550
- if (!Array.isArray(config.questions)) {
175551
- return { status: "failed", error: "human-in-the-loop questions did not resolve to an array" };
175552
- }
175553
- const requestId = crypto.randomUUID();
175554
- const created = await db.createApprovalRequest({
175555
- id: requestId,
175556
- title: config.title,
175557
- questions: config.questions,
175558
- approvers: config.approvers,
175559
- workflowRunId: meta.runId,
175560
- workflowRunStepId: meta.stepId,
175561
- timeoutSeconds: config.timeout?.seconds,
175562
- notificationChannels: config.notifications,
175563
- createdBy: meta.requestedByUserId,
175564
- requireActionableWorkflow: true
175565
- });
175566
- if (created.status === "cancelled") {
175567
- return {
175568
- status: "success",
175569
- async: true,
175570
- waitFor: "approval.resolved",
175571
- correlationId: requestId
175572
- };
175573
- }
175574
- if (config.notifications?.length) {
175575
- this.dispatchNotifications(requestId, config, db).catch((err) => {
175576
- console.error("[HITL] Unexpected error dispatching notifications:", scrubSecrets(err instanceof Error ? err.message : String(err)));
175577
- });
175578
- }
175579
- return {
175580
- status: "success",
175581
- async: true,
175582
- waitFor: "approval.resolved",
175583
- correlationId: requestId
175584
- };
175585
- }
175586
- async dispatchNotifications(requestId, config, db) {
175587
- if (!config.notifications?.length)
175588
- return;
175589
- const approvalUrl = `${getAppUrl()}/approval-requests/${requestId}`;
175590
- const updatedChannels = [...config.notifications];
175591
- let updated = false;
175592
- for (let i = 0;i < config.notifications.length; i++) {
175593
- const notification = config.notifications[i];
175594
- if (notification.channel === "email") {
175595
- console.warn(`[HITL] Email notifications not yet supported (target: ${notification.target})`);
175596
- continue;
175597
- }
175598
- if (notification.channel === "slack") {
175599
- try {
175600
- const { getSlackApp: getSlackApp2 } = await import("./app-nctetn1e.js");
175601
- const slackApp = getSlackApp2();
175602
- if (!slackApp) {
175603
- console.warn("[HITL] Slack not initialized — cannot send notification");
175604
- continue;
175605
- }
175606
- const questions = Array.isArray(config.questions) ? config.questions : [];
175607
- const questionsText = buildSlackQuestionsSummary(questions);
175608
- const timeoutCaption = config.timeout ? [
175609
- {
175610
- type: "context",
175611
- elements: [
175612
- {
175613
- type: "mrkdwn",
175614
- text: `⏱ Timeout: ${formatTimeout(config.timeout.seconds)} — times out if not responded`
175615
- }
175616
- ]
175617
- }
175618
- ] : [];
175619
- const blocks = [
175620
- {
175621
- type: "section",
175622
- text: {
175623
- type: "mrkdwn",
175624
- text: `\uD83D\uDD14 *Approval Required: ${config.title}*`
175625
- }
175626
- },
175627
- {
175628
- type: "section",
175629
- text: {
175630
- type: "mrkdwn",
175631
- text: questionsText
175632
- }
175633
- },
175634
- {
175635
- type: "actions",
175636
- elements: [
175637
- {
175638
- type: "button",
175639
- text: { type: "plain_text", text: "Review & Respond" },
175640
- url: approvalUrl,
175641
- style: "primary"
175642
- }
175643
- ]
175644
- },
175645
- ...timeoutCaption
175646
- ];
175647
- const result = await slackApp.client.chat.postMessage({
175648
- channel: notification.target,
175649
- text: `Approval Required: ${config.title} — ${approvalUrl}`,
175650
- unfurl_links: false,
175651
- unfurl_media: false,
175652
- blocks
175653
- });
175654
- if (result.ts) {
175655
- updatedChannels[i] = { ...notification, messageTs: result.ts };
175656
- updated = true;
175657
- }
175658
- console.log(`[HITL] Slack notification sent to ${notification.target} for request ${requestId}`);
175659
- } catch (err) {
175660
- console.error(`[HITL] Failed to send Slack notification to ${notification.target}:`, scrubSecrets(err instanceof Error ? err.message : String(err)));
175661
- }
175662
- }
175663
- }
175664
- if (updated) {
175665
- try {
175666
- await db.updateApprovalRequestNotifications(requestId, updatedChannels);
175667
- const latest = await db.getApprovalRequestById(requestId);
175668
- if (latest?.status === "cancelled") {
175669
- await postApprovalCancellationUpdates([latest], latest.resolutionReason ?? "Workflow run cancelled");
175670
- }
175671
- } catch (err) {
175672
- console.error("[HITL] Failed to update notification channels in DB:", scrubSecrets(err instanceof Error ? err.message : String(err)));
175673
- }
175674
- }
175675
- }
175676
- }
175677
- function formatTimeout(seconds) {
175678
- if (seconds < 60)
175679
- return `${seconds}s`;
175680
- if (seconds < 3600)
175681
- return `${Math.round(seconds / 60)}m`;
175682
- const hours = Math.floor(seconds / 3600);
175683
- const mins = Math.round(seconds % 3600 / 60);
175684
- return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
175685
- }
175686
-
175687
- // src/workflows/executors/system-one-providers.ts
175688
- init_openrouter_base_url();
175689
-
175690
- // src/workflows/executors/system-one-wire.ts
175691
- class SystemOneWireError extends Error {
175692
- }
175693
- var VALIDATION_PREFIX = "SystemOne response failed validation: ";
175694
- function wireContractError(message) {
175695
- throw new SystemOneWireError(`${VALIDATION_PREFIX}${message}`);
175696
- }
175697
- function isRecord(value) {
175698
- return typeof value === "object" && value !== null && !Array.isArray(value);
175699
- }
175700
- var SYSTEM_ONE_WIRE = {
175701
- buildRequest: (config, model) => ({
175702
- state: config.state,
175703
- ...model === undefined ? {} : { model },
175704
- questions: config.questions
175705
- }),
175706
- toSystemOne: (body) => body
175707
- };
175708
- var CLOUDFLARE_WIRE = {
175709
- buildRequest: SYSTEM_ONE_WIRE.buildRequest,
175710
- toSystemOne(body) {
175711
- if (!isRecord(body))
175712
- wireContractError("response body must be a JSON object");
175713
- if (body.success !== true) {
175714
- const code = cloudflareErrorCode(body);
175715
- throw new SystemOneWireError(`Cloudflare Workers AI reported a failed run${code ? ` (${code})` : ""}. No decision was made.`);
175716
- }
175717
- if (!isRecord(body.result))
175718
- wireContractError("Cloudflare response is missing its result");
175719
- return body.result;
175720
- }
175721
- };
175722
- var ERROR_CODE_RE = /^[A-Za-z0-9._:-]{1,64}$/;
175723
- function cloudflareErrorCode(body) {
175724
- const first = Array.isArray(body.errors) ? body.errors[0] : undefined;
175725
- const code = isRecord(first) ? first.code : undefined;
175726
- if (typeof code === "number" && Number.isSafeInteger(code))
175727
- return String(code);
175728
- return typeof code === "string" && ERROR_CODE_RE.test(code) ? code : undefined;
175729
- }
175730
-
175731
- // src/workflows/executors/system-one-openai-wire.ts
175732
- function entryText(entry) {
175733
- if (entry === undefined || entry === null)
175734
- return;
175735
- return typeof entry === "string" ? entry : JSON.stringify(entry);
175736
- }
175737
- function openaiInput(state) {
175738
- if (typeof state === "string")
175739
- return state;
175740
- if (Array.isArray(state)) {
175741
- return [
175742
- {
175743
- role: "user",
175744
- content: state.map((text) => ({ type: "input_text", text: String(text) }))
175745
- }
175746
- ];
175747
- }
175748
- return JSON.stringify(state);
175749
- }
175750
- function openaiQuestion(name, question) {
175751
- const instructions = entryText(question.instructions) ?? "";
175752
- switch (question.type) {
175753
- case "noul": {
175754
- const whenTrue = entryText(question.criteria?.true);
175755
- const whenFalse = entryText(question.criteria?.false);
175756
- const parts = [instructions];
175757
- if (whenTrue)
175758
- parts.push(`True when: ${whenTrue}`);
175759
- if (whenFalse)
175760
- parts.push(`False when: ${whenFalse}`);
175761
- return { type: "predicate", name, instructions: parts.join(`
175762
-
175763
- `) };
175764
- }
175765
- case "choice":
175766
- return {
175767
- type: "choice",
175768
- name,
175769
- instructions,
175770
- choices: Object.entries(question.criteria).map(([value, entry]) => {
175771
- const description = entryText(entry);
175772
- return description === undefined ? { value } : { value, description };
175773
- })
175774
- };
175775
- case "score":
175776
- return {
175777
- type: "score",
175778
- name,
175779
- instructions,
175780
- levels: question.criteria.map((entry, index) => ({
175781
- label: entryText(entry) ?? String(index)
175782
- }))
175783
- };
175784
- }
175785
- }
175786
- function probabilityMap(value, at) {
175787
- if (!Array.isArray(value))
175788
- return value;
175789
- const out = {};
175790
- for (const item of value) {
175791
- if (!isRecord(item) || typeof item.value !== "string" && typeof item.value !== "number") {
175792
- wireContractError(`${at} entries must carry a string or number value`);
175793
- }
175794
- const key = String(item.value);
175795
- if (Object.hasOwn(out, key))
175796
- wireContractError(`${at} lists an option twice`);
175797
- out[key] = item.probability;
175798
- }
175799
- return out;
175800
- }
175801
- function toSystemOneAnswer(id, question, raw) {
175802
- const at = `answer "${id}".probabilities`;
175803
- switch (raw.type) {
175804
- case "predicate":
175805
- return { type: "noul", noul: raw.probability };
175806
- case "choice":
175807
- return {
175808
- type: "choice",
175809
- choice: raw.choice,
175810
- probabilities: probabilityMap(raw.probabilities, at),
175811
- confidence: raw.confidence
175812
- };
175813
- case "score":
175814
- return {
175815
- type: "score",
175816
- score: raw.score,
175817
- probabilities: probabilityMap(raw.probabilities, at),
175818
- legend: question.type === "score" ? Object.fromEntries(question.criteria.map((entry, index) => [String(index), entry])) : undefined,
175819
- confidence: raw.confidence
175820
- };
175821
- default:
175822
- return raw;
175823
- }
175824
- }
175825
- var OPENAI_DECISIONS_WIRE = {
175826
- buildRequest: (config, model) => ({
175827
- ...model === undefined ? {} : { model },
175828
- input: openaiInput(config.state),
175829
- questions: Object.entries(config.questions).map(([name, question]) => openaiQuestion(name, question))
175830
- }),
175831
- toSystemOne(body, { questions }) {
175832
- if (!isRecord(body))
175833
- wireContractError("response body must be a JSON object");
175834
- if (!Array.isArray(body.answers))
175835
- wireContractError("response is missing the answers array");
175836
- const byName = new Map;
175837
- for (const answer of body.answers) {
175838
- if (!isRecord(answer) || typeof answer.name !== "string") {
175839
- wireContractError("every answer must be an object naming its question");
175840
- }
175841
- if (!Object.hasOwn(questions, answer.name)) {
175842
- wireContractError("response contains an answer for an undeclared question");
175843
- }
175844
- if (byName.has(answer.name)) {
175845
- wireContractError(`response answers question "${answer.name}" twice`);
175846
- }
175847
- byName.set(answer.name, answer);
175848
- }
175849
- const refused = [...byName.values()].filter((answer) => answer.type === "refusal").map((answer) => `"${answer.name}"`);
175850
- if (refused.length > 0) {
175851
- throw new SystemOneWireError(`OpenAI refused question${refused.length > 1 ? "s" : ""} ${refused.join(", ")}; no decision was made`);
175852
- }
175853
- const answers = {};
175854
- for (const [id, answer] of byName) {
175855
- const question = questions[id];
175856
- if (question)
175857
- answers[id] = toSystemOneAnswer(id, question, answer);
175858
- }
175859
- const usage = isRecord(body.usage) ? { input_tokens: body.usage.input_tokens, output_tokens: body.usage.output_tokens } : body.usage;
175860
- return { model: body.model, answers, usage };
175861
- }
175862
- };
175863
-
175864
- // src/workflows/executors/workflow-llm.ts
175865
- init_openrouter_base_url();
175866
- async function resolveWorkflowLlmConfig(requestedModel, env = process.env, options = {}) {
175867
- const credential = await resolveCredential({ env });
175868
- if (!credential) {
175869
- throw new Error("No workflow LLM credential found. Set OPENROUTER_API_KEY or OPENAI_API_KEY.");
175870
- }
175871
- if (options.requireKind && credential.kind !== options.requireKind) {
175872
- throw new Error(`No ${options.requireKind} credential found for this workflow LLM call.`);
175873
- }
175874
- if (credential.kind !== "openrouter" && credential.kind !== "openai") {
175875
- throw new Error(`Workflow LLM nodes do not support the resolved ${credential.kind} credential yet. Set OPENROUTER_API_KEY or OPENAI_API_KEY.`);
175876
- }
175877
- const providerPrefix = `${credential.kind}/`;
175878
- const model = requestedModel ?? DEFAULT_MODEL[credential.kind];
175879
- const baseURL = credential.kind === "openrouter" ? getOpenRouterBaseUrl(env) : undefined;
175880
- return {
175881
- apiKey: credential.apiKey,
175882
- baseURL,
175883
- headers: baseURL ? getOpenRouterAttributionHeaders(baseURL, env) : {},
175884
- model: model.startsWith(providerPrefix) ? model.slice(providerPrefix.length) : model
175885
- };
175886
- }
175887
-
175888
- // src/workflows/executors/system-one-providers.ts
175889
- var TYPESAFE_KEY = "TYPESAFE_API_KEY";
175890
- var OPENROUTER_KEY = "OPENROUTER_API_KEY";
175891
- var LAYA_KEY = "LAYA_API_KEY";
175892
- var LAYA_URL_KEY = "LAYA_URL";
175893
- var OPENAI_DECISIONS_KEY = "OPENAI_DECISIONS_API_KEY";
175894
- var CLOUDFLARE_TOKEN_KEY = "CLOUDFLARE_API_TOKEN";
175895
- var CLOUDFLARE_ACCOUNT_KEY = "CLOUDFLARE_ACCOUNT_ID";
175896
- var CLOUDFLARE_ACCOUNT_RE = /^[0-9a-f]{32}$/;
175897
- async function readGlobalConfig(db, key) {
175898
- const rows = await db.getSwarmConfigs({ scope: "global", key });
175899
- return rows.find((row) => row.scope === "global" && row.key === key)?.value;
175900
- }
175901
- var SYSTEM_ONE_PROVIDERS = {
175902
- typesafe: {
175903
- label: "TypeSafe",
175904
- keyName: TYPESAFE_KEY,
175905
- endpoint: "https://api.typesafe.ai/v1/systemone",
175906
- defaultModel: "jev-latest",
175907
- confidenceField: "confidence",
175908
- readKey: ({ db }) => readGlobalConfig(db, TYPESAFE_KEY)
175909
- },
175910
- openrouter: {
175911
- label: "OpenRouter",
175912
- keyName: OPENROUTER_KEY,
175913
- endpoint: "https://openrouter.ai/api/alpha/decisions",
175914
- defaultModel: "~typesafe/jev-latest",
175915
- confidenceField: "confidence",
175916
- deploymentProblem(env) {
175917
- return getOpenRouterBaseUrl(env) === DEFAULT_OPENROUTER_BASE_URL ? null : 'OPENROUTER_BASE_URL points at a gateway. SystemOne provider "openrouter" calls openrouter.ai directly and is not supported through a gateway; unset OPENROUTER_BASE_URL or use provider "typesafe".';
175918
- },
175919
- async readKey({ env }) {
175920
- try {
175921
- return (await resolveWorkflowLlmConfig(undefined, env, { requireKind: "openrouter" })).apiKey;
175922
- } catch {
175923
- return null;
175924
- }
175925
- }
175926
- },
175927
- laya: {
175928
- label: "laya",
175929
- keyName: LAYA_KEY,
175930
- endpoint: { configKey: LAYA_URL_KEY, path: "/v1/systemone" },
175931
- confidenceField: "answer_confidence",
175932
- readKey: ({ db }) => readGlobalConfig(db, LAYA_KEY)
175933
- },
175934
- openai: {
175935
- label: "OpenAI",
175936
- keyName: OPENAI_DECISIONS_KEY,
175937
- endpoint: "https://api.openai.com/v1/decisions",
175938
- defaultModel: "gpt-6-luna",
175939
- confidenceField: "confidence",
175940
- wire: OPENAI_DECISIONS_WIRE,
175941
- readKey: ({ db }) => readGlobalConfig(db, OPENAI_DECISIONS_KEY)
175942
- },
175943
- cloudflare: {
175944
- label: "Cloudflare Workers AI",
175945
- keyName: CLOUDFLARE_TOKEN_KEY,
175946
- endpoint: {
175947
- configKey: CLOUDFLARE_ACCOUNT_KEY,
175948
- describe: "the 32-character id of a Cloudflare account",
175949
- build: (accountId, model) => {
175950
- const id = accountId.trim();
175951
- return CLOUDFLARE_ACCOUNT_RE.test(id) ? `https://api.cloudflare.com/client/v4/accounts/${id}/ai/run/@cf/cloudflare/${model}` : null;
175952
- }
175953
- },
175954
- defaultModel: "clef",
175955
- allowedModels: ["clef", "clef-flash"],
175956
- limits: { maxQuestions: 64 },
175957
- confidenceField: "confidence",
175958
- wire: CLOUDFLARE_WIRE,
175959
- readKey: ({ db }) => readGlobalConfig(db, CLOUDFLARE_TOKEN_KEY)
175960
- }
175961
- };
175962
- var SYSTEM_ONE_PROVIDER_IDS = Object.keys(SYSTEM_ONE_PROVIDERS);
175963
- var SYSTEM_ONE_DEFAULT_PROVIDER = "typesafe";
175964
- function isSystemOneProviderId(value) {
175965
- return typeof value === "string" && Object.hasOwn(SYSTEM_ONE_PROVIDERS, value);
175966
- }
175967
- function systemOneProviderOf(config) {
175968
- if (config.provider === undefined)
175969
- return SYSTEM_ONE_DEFAULT_PROVIDER;
175970
- return isSystemOneProviderId(config.provider) ? config.provider : undefined;
175971
- }
175972
- var SET_IT = (keyName) => `Set ${keyName} as a global secret on the Secrets page (Settings > Secrets).`;
175973
- var SET_URL = (configKey) => `Set ${configKey} as a global config value (set-config with scope global).`;
175974
- function systemOneKeyMissingMessage(id) {
175975
- const { label, keyName } = SYSTEM_ONE_PROVIDERS[id];
175976
- return `${keyName} is not configured. SystemOne provider "${id}" needs a working ${label} API key. ${SET_IT(keyName)}`;
175977
- }
175978
- function systemOneKeyUnreadableMessage(id) {
175979
- return `Could not read ${SYSTEM_ONE_PROVIDERS[id].keyName} from swarm config`;
175980
- }
175981
- function systemOneKeyMalformedMessage(id) {
175982
- return `${SYSTEM_ONE_PROVIDERS[id].keyName} is not a valid bearer token value. ${SET_IT(SYSTEM_ONE_PROVIDERS[id].keyName)}`;
175983
- }
175984
- function systemOneKeyRejectedMessage(id, status, code) {
175985
- const { label, keyName } = SYSTEM_ONE_PROVIDERS[id];
175986
- const detail = code ? ` (${code})` : "";
175987
- return `${keyName} was rejected by ${label} (HTTP ${status}${detail}). ` + `The key is invalid, revoked, or lacks access to the model. Replace it on the Secrets page (Settings > Secrets). No decision was made.`;
175988
- }
175989
- function urlKeyOf(provider) {
175990
- return typeof provider.endpoint === "string" ? null : provider.endpoint.configKey;
175991
- }
175992
- function isBuiltEndpoint(endpoint) {
175993
- return typeof endpoint !== "string" && "build" in endpoint;
175994
- }
175995
- function urlDescriptionOf(provider) {
175996
- return isBuiltEndpoint(provider.endpoint) ? provider.endpoint.describe : `the URL of a ${provider.label} server`;
175997
- }
175998
- function systemOneUrlMissingMessage(id) {
175999
- const provider = SYSTEM_ONE_PROVIDERS[id];
176000
- const configKey = urlKeyOf(provider) ?? "";
176001
- return `${configKey} is not configured. SystemOne provider "${id}" needs ${urlDescriptionOf(provider)}. ${SET_URL(configKey)}`;
176002
- }
176003
- function systemOneUrlUnreadableMessage(id) {
176004
- return `Could not read ${urlKeyOf(SYSTEM_ONE_PROVIDERS[id]) ?? ""} from swarm config`;
176005
- }
176006
- function systemOneUrlInvalidMessage(id) {
176007
- const provider = SYSTEM_ONE_PROVIDERS[id];
176008
- const configKey = urlKeyOf(provider) ?? "";
176009
- if (isBuiltEndpoint(provider.endpoint)) {
176010
- return `${configKey} is not ${provider.endpoint.describe}. ${SET_URL(configKey)}`;
176011
- }
176012
- return `${configKey} is not a usable ${provider.label} server URL. It must be an https URL (http only for localhost) with no credentials, query, or fragment. ${SET_URL(configKey)}`;
176013
- }
176014
- function systemOneModelProblem(id, model) {
176015
- const { allowedModels } = SYSTEM_ONE_PROVIDERS[id];
176016
- if (!allowedModels || model !== undefined && allowedModels.includes(model))
176017
- return null;
176018
- return `SystemOne provider "${id}" serves only the models ${allowedModels.join(", ")}; set model to one of them or leave it unset.`;
176019
- }
176020
- function systemOneQuestionLimitProblem(id, count) {
176021
- const max = SYSTEM_ONE_PROVIDERS[id].limits?.maxQuestions;
176022
- return max !== undefined && count > max ? `SystemOne provider "${id}" takes at most ${max} questions per node; this node has ${count}.` : null;
176023
- }
176024
- function hasWhitespaceOrControl(value) {
176025
- for (const char of value) {
176026
- const code = char.charCodeAt(0);
176027
- if (code <= 32 || code === 127)
176028
- return true;
176029
- }
176030
- return false;
176031
- }
176032
- var LOOPBACK_HOSTS = new Set(["localhost", "127.0.0.1", "[::1]"]);
176033
- function systemOneEndpointFromBase(base, path) {
176034
- let url;
176035
- try {
176036
- url = new URL(base.trim());
176037
- } catch {
176038
- return null;
176039
- }
176040
- const secure = url.protocol === "https:";
176041
- const loopback = url.protocol === "http:" && LOOPBACK_HOSTS.has(url.hostname);
176042
- if (!secure && !loopback)
176043
- return null;
176044
- if (url.username || url.password || url.search || url.hash)
176045
- return null;
176046
- return `${url.origin}${url.pathname.replace(/\/+$/, "")}${path}`;
176047
- }
176048
- async function resolveSystemOneTarget(id, ctx, overrides = {}) {
176049
- const provider = SYSTEM_ONE_PROVIDERS[id];
176050
- const deploymentProblem = provider.deploymentProblem?.(ctx.env);
176051
- if (deploymentProblem)
176052
- return { ok: false, error: deploymentProblem };
176053
- const errors = [];
176054
- let endpoint;
176055
- if (typeof provider.endpoint === "string") {
176056
- endpoint = provider.endpoint;
176057
- } else {
176058
- const { configKey } = provider.endpoint;
176059
- let base;
176060
- let readable = true;
176061
- try {
176062
- base = await (overrides.serverUrl ? overrides.serverUrl(id) : readGlobalConfig(ctx.db, configKey));
176063
- } catch {
176064
- readable = false;
176065
- errors.push(systemOneUrlUnreadableMessage(id));
176066
- }
176067
- if (readable) {
176068
- if (!base || base.trim() === "") {
176069
- errors.push(systemOneUrlMissingMessage(id));
176070
- } else {
176071
- const resolved = isBuiltEndpoint(provider.endpoint) ? provider.endpoint.build(base, overrides.model ?? provider.defaultModel ?? "") : systemOneEndpointFromBase(base, provider.endpoint.path);
176072
- if (resolved)
176073
- endpoint = resolved;
176074
- else
176075
- errors.push(systemOneUrlInvalidMessage(id));
176076
- }
176077
- }
176078
- }
176079
- let apiKey;
176080
- let keyProblem;
176081
- try {
176082
- apiKey = await (overrides.apiKey ? overrides.apiKey(id) : provider.readKey(ctx));
176083
- } catch {
176084
- keyProblem = systemOneKeyUnreadableMessage(id);
176085
- }
176086
- if (!keyProblem) {
176087
- if (!apiKey || apiKey.trim() === "")
176088
- keyProblem = systemOneKeyMissingMessage(id);
176089
- else if (hasWhitespaceOrControl(apiKey))
176090
- keyProblem = systemOneKeyMalformedMessage(id);
176091
- }
176092
- if (keyProblem)
176093
- errors.push(keyProblem);
176094
- if (errors.length > 0 || !endpoint || !apiKey)
176095
- return { ok: false, error: errors.join(" ") };
176096
- return { ok: true, apiKey, endpoint };
176097
- }
176098
-
176099
- // src/workflows/executors/system-one-decision.ts
176100
- var SYSTEM_ONE_DECISION_NODE_TYPE = "system-one-decision";
176101
- var SYSTEM_ONE_ENDPOINT = SYSTEM_ONE_PROVIDERS.typesafe.endpoint;
176102
- var SYSTEM_ONE_API_KEY_CONFIG_KEY = SYSTEM_ONE_PROVIDERS.typesafe.keyName;
176103
- var SYSTEM_ONE_DEFAULT_TIMEOUT_MS = 30000;
176104
- var SYSTEM_ONE_MIN_TIMEOUT_MS = 1000;
176105
- var SYSTEM_ONE_MAX_TIMEOUT_MS = 300000;
176106
- var SYSTEM_ONE_DEFAULT_MAX_RETRIES = 2;
176107
- var SYSTEM_ONE_MAX_RETRIES_LIMIT = 3;
176108
- var CHOICE_MIN_OPTIONS = 2;
176109
- var CHOICE_MAX_OPTIONS = 255;
176110
- var SCORE_MIN_LEVELS = 2;
176111
- var SCORE_MAX_LEVELS = 10;
176112
- var DEADLINE_MARGIN_MS = 250;
176113
- var BACKOFF_BASE_MS = 500;
176114
- var BACKOFF_CAP_MS = 8000;
176115
- var DISTRIBUTION_TOLERANCE = 0.02;
176116
- var MAX_RESPONSE_CHARS = 1048576;
176117
- var MAX_ERROR_BODY_CHARS = 65536;
176118
- var REVIEW_PORTS = ["approved", "rejected", "timeout"];
176119
- var ENGINE_RETRY_DEFAULT = 3;
176120
- var SystemOneEntrySchema = exports_external.union([
176121
- exports_external.string(),
176122
- exports_external.null(),
176123
- exports_external.array(exports_external.unknown()),
176124
- exports_external.record(exports_external.string(), exports_external.unknown())
176125
- ]);
176126
- var SystemOneInstructionsSchema = SystemOneEntrySchema.refine((value) => value !== null && !(typeof value === "string" && value.trim() === ""), { message: "instructions must not be null or blank" });
176127
- var SystemOneStateSchema = exports_external.union([
176128
- exports_external.string().min(1, "state must not be empty"),
176129
- exports_external.array(exports_external.string()).min(1, "state must not be an empty array"),
176130
- exports_external.record(exports_external.string(), exports_external.unknown())
176131
- ]);
176132
- var NoulQuestionSchema = exports_external.strictObject({
176133
- type: exports_external.literal("noul"),
176134
- instructions: SystemOneInstructionsSchema,
176135
- criteria: exports_external.strictObject({ true: SystemOneEntrySchema.optional(), false: SystemOneEntrySchema.optional() }).refine((criteria) => criteria.true !== undefined || criteria.false !== undefined, {
176136
- message: "noul criteria must describe at least one of true / false"
176137
- }).optional()
176138
- });
176139
- var ChoiceQuestionSchema = exports_external.strictObject({
176140
- type: exports_external.literal("choice"),
176141
- instructions: SystemOneInstructionsSchema,
176142
- criteria: exports_external.record(exports_external.string().min(1), SystemOneEntrySchema).refine((criteria) => {
176143
- const count = Object.keys(criteria).length;
176144
- return count >= CHOICE_MIN_OPTIONS && count <= CHOICE_MAX_OPTIONS;
176145
- }, {
176146
- message: `choice criteria must define ${CHOICE_MIN_OPTIONS}-${CHOICE_MAX_OPTIONS} options`
176147
- })
176148
- });
176149
- var ScoreQuestionSchema = exports_external.strictObject({
176150
- type: exports_external.literal("score"),
176151
- instructions: SystemOneInstructionsSchema,
176152
- criteria: exports_external.array(SystemOneEntrySchema).min(SCORE_MIN_LEVELS).max(SCORE_MAX_LEVELS)
176153
- });
176154
- var SystemOneQuestionSchema = exports_external.discriminatedUnion("type", [
176155
- NoulQuestionSchema,
176156
- ChoiceQuestionSchema,
176157
- ScoreQuestionSchema
176158
- ]);
176159
- var Unit = exports_external.number().min(0).max(1);
176160
- var QUESTION_ID_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
176161
- var RESERVED_QUESTION_IDS = new Set([
176162
- ...Object.getOwnPropertyNames(Object.prototype),
176163
- "prototype"
176164
- ]);
176165
- var SystemOnePrimitiveTypeSchema = exports_external.enum(["noul", "choice", "score"]);
176166
- var HumanReviewSchema = exports_external.strictObject({
176167
- band: exports_external.strictObject({ min: Unit, max: Unit }).refine((band) => band.min <= band.max, { message: "band.min must not exceed band.max" }),
176168
- approvers: ApproverConfigSchema,
176169
- title: exports_external.string().min(1).optional(),
176170
- timeout: HITLTimeoutSchema.optional(),
176171
- notifications: exports_external.array(NotificationConfigSchema).optional()
176172
- });
176173
- var SystemOneDecisionConfigSchema = exports_external.strictObject({
176174
- provider: exports_external.enum(SYSTEM_ONE_PROVIDER_IDS).default(SYSTEM_ONE_DEFAULT_PROVIDER),
176175
- model: exports_external.string().min(1).optional(),
176176
- state: SystemOneStateSchema,
176177
- timeoutMs: exports_external.number().int().min(SYSTEM_ONE_MIN_TIMEOUT_MS).max(SYSTEM_ONE_MAX_TIMEOUT_MS).default(SYSTEM_ONE_DEFAULT_TIMEOUT_MS),
176178
- maxRetries: exports_external.number().int().min(0).max(SYSTEM_ONE_MAX_RETRIES_LIMIT).default(SYSTEM_ONE_DEFAULT_MAX_RETRIES),
176179
- questions: exports_external.record(exports_external.string().regex(QUESTION_ID_RE, "question ids must start with a letter or underscore and use only letters, digits, _ or -"), SystemOneQuestionSchema),
176180
- returns: exports_external.record(exports_external.string(), exports_external.strictObject({ type: SystemOnePrimitiveTypeSchema })),
176181
- humanReview: HumanReviewSchema.optional()
176182
- }).superRefine((config, ctx) => {
176183
- const questionIds = Object.keys(config.questions);
176184
- if (questionIds.length === 0) {
176185
- ctx.addIssue({
176186
- code: "custom",
176187
- path: ["questions"],
176188
- message: "system-one-decision needs at least one question"
176189
- });
176190
- }
176191
- for (const id of questionIds) {
176192
- if (RESERVED_QUESTION_IDS.has(id)) {
176193
- ctx.addIssue({
176194
- code: "custom",
176195
- path: ["questions", id],
176196
- message: `"${id}" is reserved and cannot be a question id`
176197
- });
176198
- }
176199
- const declared = Object.hasOwn(config.returns, id) ? config.returns[id] : undefined;
176200
- if (!declared) {
176201
- ctx.addIssue({
176202
- code: "custom",
176203
- path: ["returns"],
176204
- message: `returns must declare question "${id}"`
176205
- });
176206
- } else if (declared.type !== config.questions[id]?.type) {
176207
- ctx.addIssue({
176208
- code: "custom",
176209
- path: ["returns", id, "type"],
176210
- message: `returns.${id}.type is "${declared.type}" but question "${id}" is "${config.questions[id]?.type}"`
176211
- });
176212
- }
176213
- }
176214
- for (const id of Object.keys(config.returns)) {
176215
- if (!Object.hasOwn(config.questions, id)) {
176216
- ctx.addIssue({
176217
- code: "custom",
176218
- path: ["returns", id],
176219
- message: `returns declares "${id}" but no question has that id`
176220
- });
176221
- }
176222
- }
176223
- const modelProblem = systemOneModelProblem(config.provider, config.model ?? SYSTEM_ONE_PROVIDERS[config.provider].defaultModel);
176224
- if (modelProblem)
176225
- ctx.addIssue({ code: "custom", path: ["model"], message: modelProblem });
176226
- const limitProblem = systemOneQuestionLimitProblem(config.provider, questionIds.length);
176227
- if (limitProblem)
176228
- ctx.addIssue({ code: "custom", path: ["questions"], message: limitProblem });
176229
- });
176230
- var NoulAnswerSchema = exports_external.strictObject({ type: exports_external.literal("noul"), noul: Unit });
176231
- var ChoiceAnswerSchema = exports_external.strictObject({
176232
- type: exports_external.literal("choice"),
176233
- choice: exports_external.string(),
176234
- probabilities: exports_external.record(exports_external.string(), Unit),
176235
- confidence: Unit
176236
- });
176237
- var ScoreAnswerSchema = exports_external.strictObject({
176238
- type: exports_external.literal("score"),
176239
- score: exports_external.number(),
176240
- legend: exports_external.record(exports_external.string(), SystemOneEntrySchema),
176241
- probabilities: exports_external.record(exports_external.string(), Unit),
176242
- confidence: Unit
176243
- });
176244
- var SystemOneAnswerSchema = exports_external.discriminatedUnion("type", [
176245
- NoulAnswerSchema,
176246
- ChoiceAnswerSchema,
176247
- ScoreAnswerSchema
176248
- ]);
176249
- var ReviewQuestionSchema = exports_external.strictObject({
176250
- confidence: Unit,
176251
- inBand: exports_external.boolean(),
176252
- decidedBy: exports_external.enum(["model", "human"]),
176253
- modelAnswer: exports_external.union([exports_external.string(), exports_external.number()]).optional()
176254
- });
176255
- var ReviewSchema = exports_external.strictObject({
176256
- status: exports_external.enum(["not_required", "pending", "approved", "rejected", "timeout"]),
176257
- approvalRequestId: exports_external.string().optional(),
176258
- reason: exports_external.string().optional(),
176259
- questions: exports_external.record(exports_external.string(), ReviewQuestionSchema)
176260
- });
176261
- var SystemOneDecisionOutputSchema = exports_external.object({
176262
- model: exports_external.string().min(1),
176263
- answers: exports_external.record(exports_external.string(), SystemOneAnswerSchema),
176264
- usage: exports_external.object({
176265
- input_tokens: exports_external.number().int().min(0),
176266
- output_tokens: exports_external.number().int().min(0)
176267
- }),
176268
- requestId: exports_external.string().optional(),
176269
- routing: exports_external.strictObject({ model: exports_external.string().min(1) }).optional(),
176270
- review: ReviewSchema.optional()
176271
- });
176272
- function systemOneRetryViolations(node) {
176273
- if (node.type !== SYSTEM_ONE_DECISION_NODE_TYPE)
176274
- return [];
176275
- const violations = [];
176276
- const attempts = (retry) => retry ? retry.maxRetries ?? ENGINE_RETRY_DEFAULT : 0;
176277
- if (attempts(node.retry) > 0) {
176278
- violations.push(`Node "${node.id}" (system-one-decision) must not set retry.maxRetries > 0: the system-one-decision executor retries transient transport errors itself (config.maxRetries), and engine retries would re-send rejected requests`);
176279
- }
176280
- if (attempts(node.validation?.retry) > 0) {
176281
- violations.push(`Node "${node.id}" (system-one-decision) must not set validation.retry.maxRetries > 0: a validation-driven retry would send another paid request`);
176282
- }
176283
- return violations;
176284
- }
176285
- function systemOneStaticShapeViolations(node) {
176286
- if (node.type !== SYSTEM_ONE_DECISION_NODE_TYPE)
176287
- return [];
176288
- const violations = [];
176289
- for (const field of ["questions", "returns"]) {
176290
- const value = node.config[field];
176291
- if (value !== undefined && (typeof value !== "object" || value === null || Array.isArray(value))) {
176292
- violations.push(`Node "${node.id}" (system-one-decision) config.${field} must be an object: question ids and return types are static, only state and descriptions may use {{tokens}}`);
176293
- }
176294
- }
176295
- const provider = node.config.provider;
176296
- if (typeof provider === "string" && provider.includes("{{")) {
176297
- violations.push(`Node "${node.id}" (system-one-decision) config.provider must be a literal (${SYSTEM_ONE_PROVIDER_IDS.join(", ")}), not a {{token}}: the provider decides which credential is checked before the run starts`);
176298
- }
176299
- if (isRecord2(node.config.humanReview) && node.next != null) {
176300
- if (typeof node.next === "string" || Array.isArray(node.next)) {
176301
- violations.push(`Node "${node.id}" (system-one-decision) sets humanReview, so next must map output ports (${REVIEW_PORTS.join(", ")}): a single or list next would run the same successors after a rejection or a timeout`);
176302
- } else {
176303
- const ports = Object.keys(node.next);
176304
- const unknown2 = ports.filter((port) => !REVIEW_PORTS.includes(port));
176305
- if (unknown2.length > 0) {
176306
- violations.push(`Node "${node.id}" (system-one-decision) sets humanReview, so next ports must be ${REVIEW_PORTS.join(", ")}; got ${unknown2.map((port) => `"${port}"`).join(", ")}`);
176307
- }
176308
- if (!ports.includes("approved")) {
176309
- violations.push(`Node "${node.id}" (system-one-decision) sets humanReview, so next must define the "approved" port: it carries every answer that is accepted, by the model or by a person`);
176310
- }
176311
- }
176312
- }
176313
- return violations;
176314
- }
176315
- function systemOneUnresolvedError(nodeId, tokens) {
176316
- const rendered = [...new Set(tokens)].map((token) => `{{${token}}}`).join(", ");
176317
- return `SystemOne Decision node "${nodeId}" has unresolved interpolation token(s): ${rendered}. ` + "No request was sent. Declare the value in the node's inputs mapping or fix the path.";
176318
- }
176319
-
176320
- class SystemOneContractError extends Error {
176321
- }
176322
- function fail(message) {
176323
- throw new SystemOneContractError(message);
176324
- }
176325
- function isRecord2(value) {
176326
- return typeof value === "object" && value !== null && !Array.isArray(value);
176327
- }
176328
- function unit(value, what) {
176329
- if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > 1) {
176330
- fail(`${what} must be a finite number between 0 and 1`);
176331
- }
176332
- return value;
176333
- }
176334
- function distribution(value, keys, what) {
176335
- if (!isRecord2(value))
176336
- fail(`${what} must be an object`);
176337
- const actual = Object.keys(value);
176338
- const missing = keys.filter((key) => !Object.hasOwn(value, key));
176339
- const extra = actual.filter((key) => !keys.includes(key));
176340
- if (missing.length > 0 || extra.length > 0) {
176341
- fail(`${what} keys must be exactly the declared ${keys.length} option(s)` + (missing.length > 0 ? `; missing ${missing.length}` : "") + (extra.length > 0 ? `; ${extra.length} unexpected` : ""));
176342
- }
176343
- const out = {};
176344
- let sum = 0;
176345
- for (const key of keys) {
176346
- const p = unit(value[key], `${what}["${key}"]`);
176347
- out[key] = p;
176348
- sum += p;
176349
- }
176350
- if (Math.abs(sum - 1) > DISTRIBUTION_TOLERANCE) {
176351
- fail(`${what} must sum to 1 (within ${DISTRIBUTION_TOLERANCE})`);
176352
- }
176353
- return out;
176354
- }
176355
- function validateAnswer(id, question, raw, confidenceField) {
176356
- const at = `answer "${id}"`;
176357
- if (!isRecord2(raw))
176358
- fail(`${at} must be an object`);
176359
- if (raw.type !== question.type) {
176360
- fail(`${at} has type ${JSON.stringify(raw.type)} but the question declares "${question.type}"`);
176361
- }
176362
- switch (question.type) {
176363
- case "noul":
176364
- return { type: "noul", noul: unit(raw.noul, `${at}.noul`) };
176365
- case "choice": {
176366
- const options = Object.keys(question.criteria);
176367
- if (typeof raw.choice !== "string" || !Object.hasOwn(question.criteria, raw.choice)) {
176368
- fail(`${at}.choice is not one of the declared options`);
176369
- }
176370
- return {
176371
- type: "choice",
176372
- choice: raw.choice,
176373
- probabilities: distribution(raw.probabilities, options, `${at}.probabilities`),
176374
- confidence: unit(raw[confidenceField], `${at}.${confidenceField}`)
176375
- };
176376
- }
176377
- case "score": {
176378
- const indices = question.criteria.map((_, index) => String(index));
176379
- const top = indices.length - 1;
176380
- if (typeof raw.score !== "number" || !Number.isFinite(raw.score) || raw.score < 0 || raw.score > top) {
176381
- fail(`${at}.score must be a finite number between 0 and ${top}`);
176382
- }
176383
- if (!isRecord2(raw.legend))
176384
- fail(`${at}.legend must be an object`);
176385
- const legend = {};
176386
- for (const key of indices) {
176387
- if (!Object.hasOwn(raw.legend, key))
176388
- fail(`${at}.legend is missing level ${key}`);
176389
- const entry = SystemOneEntrySchema.safeParse(raw.legend[key]);
176390
- if (!entry.success)
176391
- fail(`${at}.legend["${key}"] must be a string, object, array, or null`);
176392
- legend[key] = entry.data;
176393
- }
176394
- return {
176395
- type: "score",
176396
- score: raw.score,
176397
- legend,
176398
- probabilities: distribution(raw.probabilities, indices, `${at}.probabilities`),
176399
- confidence: unit(raw[confidenceField], `${at}.${confidenceField}`)
176400
- };
176401
- }
176402
- }
176403
- }
176404
- var MAX_ROUTING_MODEL_CHARS = 128;
176405
- function readRoutingModel(routing) {
176406
- if (!isRecord2(routing))
176407
- return;
176408
- const { model } = routing;
176409
- return typeof model === "string" && model !== "" && model.length <= MAX_ROUTING_MODEL_CHARS ? model : undefined;
176410
- }
176411
- function validateSystemOneResponse(questions, body, requestId, confidenceField = "confidence") {
176412
- if (!isRecord2(body))
176413
- fail("response body must be a JSON object");
176414
- if (typeof body.model !== "string" || body.model === "") {
176415
- fail("response is missing the model that produced the answers");
176416
- }
176417
- if (!isRecord2(body.answers))
176418
- fail("response is missing the answers object");
176419
- const usage = exports_external.object({ input_tokens: exports_external.number().int().min(0), output_tokens: exports_external.number().int().min(0) }).safeParse(body.usage);
176420
- if (!usage.success)
176421
- fail("response usage must report non-negative integer input_tokens and output_tokens");
176422
- const declared = Object.keys(questions);
176423
- const unexpected = Object.keys(body.answers).filter((id) => !Object.hasOwn(questions, id));
176424
- if (unexpected.length > 0)
176425
- fail(`response contains ${unexpected.length} answer(s) for undeclared questions`);
176426
- const answers = {};
176427
- for (const id of declared) {
176428
- if (!Object.hasOwn(body.answers, id))
176429
- fail(`response is missing the answer for question "${id}"`);
176430
- const question = questions[id];
176431
- if (!question)
176432
- fail(`question "${id}" is not defined`);
176433
- answers[id] = validateAnswer(id, question, body.answers[id], confidenceField);
176434
- }
176435
- if (declared.length === 0)
176436
- fail("a system-one-decision call needs at least one question");
176437
- const routingModel = readRoutingModel(body.routing);
176438
- return {
176439
- model: body.model,
176440
- answers,
176441
- usage: usage.data,
176442
- ...requestId ? { requestId } : {},
176443
- ...routingModel ? { routing: { model: routingModel } } : {}
176444
- };
176445
- }
176446
- var REVIEW_CONFIRM_ID = "$confirm";
176447
- var REVIEW_STATE_CHARS = 2000;
176448
- var REVIEW_LABEL_CHARS = 160;
176449
- var REVIEW_OPTION_CHARS = 200;
176450
- var round6 = (value) => Math.round(value * 1e6) / 1e6;
176451
- function answerConfidence(answer) {
176452
- return answer.type === "noul" ? round6(Math.max(answer.noul, 1 - answer.noul)) : answer.confidence;
176453
- }
176454
- function clip(text, max) {
176455
- return text.length > max ? `${text.slice(0, max - 1)}…` : text;
176456
- }
176457
- function showEntry(entry, max) {
176458
- return clip(typeof entry === "string" ? entry : JSON.stringify(entry) ?? "", max);
176459
- }
176460
- function modelAnswerOf(answer) {
176461
- return answer.type === "choice" ? answer.choice : answer.type === "score" ? answer.score : answer.noul;
176462
- }
176463
- function buildReviewCard(nodeId, config, review, parked) {
176464
- const state = scrubSecrets(typeof config.state === "string" ? config.state : JSON.stringify(config.state) ?? "");
176465
- const questions = [
176466
- {
176467
- id: REVIEW_CONFIRM_ID,
176468
- type: "approval",
176469
- label: "Accept these answers and continue?",
176470
- required: true,
176471
- description: `Model ${parked.model}. Input: ${clip(state, REVIEW_STATE_CHARS)}`
176472
- }
176473
- ];
176474
- for (const [id, info] of Object.entries(parked.review?.questions ?? {})) {
176475
- if (!info.inBand)
176476
- continue;
176477
- const question = config.questions[id];
176478
- const answer = parked.answers[id];
176479
- if (!question || !answer)
176480
- continue;
176481
- const label = `${id}: ${showEntry(question.instructions, REVIEW_LABEL_CHARS)}`;
176482
- const said = `The model answered ${JSON.stringify(modelAnswerOf(answer))} at confidence ${info.confidence}.`;
176483
- if (question.type === "choice" && answer.type === "choice") {
176484
- questions.push({
176485
- id,
176486
- type: "single-select",
176487
- label,
176488
- required: false,
176489
- description: `${said} Leave empty to confirm it, or pick another option.`,
176490
- options: Object.entries(question.criteria).map(([value, entry]) => ({
176491
- value,
176492
- label: value,
176493
- ...typeof entry === "string" && entry ? { description: clip(entry, REVIEW_OPTION_CHARS) } : {}
176494
- }))
176495
- });
176496
- } else if (question.type === "score" && answer.type === "score") {
176497
- questions.push({
176498
- id,
176499
- type: "single-select",
176500
- label,
176501
- required: false,
176502
- description: `${said} Leave empty to confirm it, or pick a level.`,
176503
- options: question.criteria.map((entry, level) => ({
176504
- value: String(level),
176505
- label: `${level}: ${showEntry(entry, REVIEW_OPTION_CHARS)}`
176506
- }))
176507
- });
176508
- } else if (question.type === "noul" && answer.type === "noul") {
176509
- questions.push({
176510
- id,
176511
- type: "boolean",
176512
- label,
176513
- required: false,
176514
- defaultValue: answer.noul >= 0.5,
176515
- description: `${said} The switch starts on the side the model took.`
176516
- });
176517
- }
176518
- }
176519
- return {
176520
- title: review.title ?? `Review decision: ${nodeId}`,
176521
- questions,
176522
- approvers: review.approvers,
176523
- ...review.timeout ? { timeout: review.timeout } : {},
176524
- ...review.notifications ? { notifications: review.notifications } : {}
176525
- };
176526
- }
176527
- function readHumanAnswer(answer, response) {
176528
- if (response === undefined || response === null || response === "")
176529
- return { kind: "confirm" };
176530
- switch (answer.type) {
176531
- case "choice":
176532
- if (typeof response !== "string" || !Object.hasOwn(answer.probabilities, response)) {
176533
- return { kind: "invalid" };
176534
- }
176535
- return response === answer.choice ? { kind: "confirm" } : { kind: "override", answer: { ...answer, choice: response } };
176536
- case "score": {
176537
- if (typeof response !== "string" || !Object.hasOwn(answer.legend, response)) {
176538
- return { kind: "invalid" };
176539
- }
176540
- const level = Number(response);
176541
- return level === answer.score ? { kind: "confirm" } : { kind: "override", answer: { ...answer, score: level } };
176542
- }
176543
- case "noul":
176544
- if (typeof response !== "boolean")
176545
- return { kind: "invalid" };
176546
- return response === answer.noul >= 0.5 ? { kind: "confirm" } : { kind: "override", answer: { ...answer, noul: response ? 1 : 0 } };
176547
- }
176548
- }
176549
- function resolveReviewedDecision(parkedOutput, approval) {
176550
- const parked = SystemOneDecisionOutputSchema.safeParse(parkedOutput);
176551
- if (!parked.success || parked.data.review?.status !== "pending")
176552
- return null;
176553
- const decision = parked.data;
176554
- const parkedQuestions = decision.review?.questions ?? {};
176555
- const finish = (status, answers2, questions2, reason) => ({
176556
- output: {
176557
- ...decision,
176558
- answers: answers2,
176559
- review: {
176560
- status,
176561
- approvalRequestId: approval.requestId,
176562
- ...reason ? { reason } : {},
176563
- questions: questions2
176564
- }
176565
- },
176566
- nextPort: status
176567
- });
176568
- if (approval.status !== "approved") {
176569
- return finish(approval.status, decision.answers, parkedQuestions);
176570
- }
176571
- const answers = { ...decision.answers };
176572
- const questions = { ...parkedQuestions };
176573
- for (const [id, info] of Object.entries(parkedQuestions)) {
176574
- const modelAnswer = decision.answers[id];
176575
- if (!info.inBand || !modelAnswer)
176576
- continue;
176577
- const human = readHumanAnswer(modelAnswer, approval.responses?.[id]);
176578
- if (human.kind === "invalid") {
176579
- return finish("rejected", decision.answers, parkedQuestions, `The response for "${id}" is not one of its options`);
176580
- }
176581
- if (human.kind === "override")
176582
- answers[id] = human.answer;
176583
- questions[id] = { ...info, decidedBy: "human", modelAnswer: modelAnswerOf(modelAnswer) };
176584
- }
176585
- return finish("approved", answers, questions);
176586
- }
176587
- var REQUEST_ID_RE = /^[A-Za-z0-9._:-]{1,128}$/;
176588
- var ERROR_CODE_RE2 = /^[A-Za-z0-9._:-]{1,64}$/;
176589
- function readRequestId(headers) {
176590
- const value = headers.get("x-request-id") ?? headers.get("request-id") ?? headers.get("cf-ray");
176591
- return value && REQUEST_ID_RE.test(value) ? value : undefined;
176592
- }
176593
- function parseRetryAfter(value, now) {
176594
- if (!value)
176595
- return;
176596
- const trimmed = value.trim();
176597
- if (/^\d+(\.\d+)?$/.test(trimmed))
176598
- return Math.round(Number(trimmed) * 1000);
176599
- const at = Date.parse(trimmed);
176600
- return Number.isNaN(at) ? undefined : Math.max(0, at - now);
176601
- }
176602
- function readErrorCode(text) {
176603
- if (text.length === 0 || text.length > MAX_ERROR_BODY_CHARS)
176604
- return;
176605
- let parsed;
176606
- try {
176607
- parsed = JSON.parse(text);
176608
- } catch {
176609
- return;
176610
- }
176611
- if (!isRecord2(parsed))
176612
- return;
176613
- const nested = isRecord2(parsed.error) ? parsed.error : undefined;
176614
- const detail = isRecord2(parsed.detail) ? parsed.detail : undefined;
176615
- for (const candidate of [
176616
- nested?.code,
176617
- nested?.type,
176618
- detail?.error_type,
176619
- parsed.code,
176620
- parsed.type
176621
- ]) {
176622
- if (typeof candidate === "string" && ERROR_CODE_RE2.test(candidate))
176623
- return candidate;
176624
- }
176625
- return cloudflareErrorCode(parsed);
176626
- }
176627
- function defaultSleep(ms, signal) {
176628
- return new Promise((resolve) => {
176629
- if (signal.aborted)
176630
- return resolve();
176631
- const timer = setTimeout(done, ms);
176632
- function done() {
176633
- clearTimeout(timer);
176634
- signal.removeEventListener("abort", done);
176635
- resolve();
176636
- }
176637
- signal.addEventListener("abort", done, { once: true });
176638
- });
176639
- }
176640
-
176641
- class SystemOneDecisionExecutor extends BaseExecutor {
176642
- options;
176643
- type = SYSTEM_ONE_DECISION_NODE_TYPE;
176644
- mode = "async";
176645
- configSchema = SystemOneDecisionConfigSchema;
176646
- outputSchema = SystemOneDecisionOutputSchema;
176647
- constructor(deps, options = {}) {
176648
- super(deps);
176649
- this.options = options;
176650
- }
176651
- providerContext() {
176652
- return { db: this.deps.db, env: this.options.env ?? process.env };
176653
- }
176654
- resolveTarget(id, model) {
176655
- return resolveSystemOneTarget(id, this.providerContext(), {
176656
- apiKey: this.options.getApiKey,
176657
- serverUrl: this.options.getServerUrl,
176658
- model
176659
- });
176660
- }
176661
- async checkReadiness(nodes) {
176662
- const nodeIdsByProvider = new Map;
176663
- for (const node of nodes) {
176664
- const id = systemOneProviderOf(node.config);
176665
- if (id)
176666
- nodeIdsByProvider.set(id, [...nodeIdsByProvider.get(id) ?? [], node.id]);
176667
- }
176668
- const problems = [];
176669
- for (const [id, nodeIds] of nodeIdsByProvider) {
176670
- const target = await this.resolveTarget(id);
176671
- if (!target.ok)
176672
- problems.push({ nodeIds, message: target.error });
176673
- }
176674
- return problems;
176675
- }
176676
- async execute(config, context, meta) {
176677
- if (config.humanReview) {
176678
- const existing = await this.deps.db.getApprovalRequestByStepId(meta.stepId);
176679
- if (existing) {
176680
- return this.handOffToReviewer(config, await this.readParked(meta.stepId), context, meta);
176681
- }
176682
- }
176683
- const providerId = config.provider;
176684
- const provider = SYSTEM_ONE_PROVIDERS[providerId];
176685
- const model = config.model ?? provider.defaultModel;
176686
- const modelProblem = systemOneModelProblem(providerId, model);
176687
- if (modelProblem)
176688
- return { status: "failed", error: modelProblem };
176689
- const target = await this.resolveTarget(providerId, model);
176690
- if (!target.ok)
176691
- return { status: "failed", error: target.error };
176692
- const { apiKey, endpoint } = target;
176693
- const wire = provider.wire ?? SYSTEM_ONE_WIRE;
176694
- const body = JSON.stringify(wire.buildRequest(config, model));
176695
- const scrub = (message) => message.split(apiKey).join("[REDACTED]");
176696
- const sent = await this.send(providerId, endpoint, apiKey, body, config.timeoutMs, config.maxRetries);
176697
- if (!sent.ok)
176698
- return { status: "failed", error: scrub(sent.error) };
176699
- let parsed;
176700
- try {
176701
- parsed = JSON.parse(sent.text);
176702
- } catch {
176703
- return { status: "failed", error: "SystemOne response was not valid JSON" };
176704
- }
176705
- let decision;
176706
- try {
176707
- decision = validateSystemOneResponse(config.questions, wire.toSystemOne(parsed, { questions: config.questions, model }), sent.requestId, provider.confidenceField);
176708
- } catch (err) {
176709
- if (err instanceof SystemOneWireError) {
176710
- const withId = sent.requestId ? `${err.message} [request ${sent.requestId}]` : err.message;
176711
- return { status: "failed", error: scrub(withId) };
176712
- }
176713
- if (err instanceof SystemOneContractError) {
176714
- return {
176715
- status: "failed",
176716
- error: scrub(`SystemOne response failed validation: ${err.message}`)
176717
- };
176718
- }
176719
- throw err;
176720
- }
176721
- if (!config.humanReview)
176722
- return { status: "success", output: decision };
176723
- return this.reviewDecision(config, config.humanReview, decision, context, meta);
176724
- }
176725
- async reviewDecision(config, review, decision, context, meta) {
176726
- const questions = {};
176727
- for (const [id, answer] of Object.entries(decision.answers)) {
176728
- const confidence = answerConfidence(answer);
176729
- questions[id] = {
176730
- confidence,
176731
- inBand: confidence >= review.band.min && confidence <= review.band.max,
176732
- decidedBy: "model"
176733
- };
176734
- }
176735
- if (!Object.values(questions).some((question) => question.inBand)) {
176736
- return {
176737
- status: "success",
176738
- output: { ...decision, review: { status: "not_required", questions } },
176739
- nextPort: "approved"
176740
- };
176741
- }
176742
- const parked = {
176743
- ...decision,
176744
- review: { status: "pending", questions }
176745
- };
176746
- await this.deps.db.updateWorkflowRunStep(meta.stepId, { output: parked });
176747
- return this.handOffToReviewer(config, parked, context, meta);
176748
- }
176749
- async readParked(stepId) {
176750
- const step = await this.deps.db.getWorkflowRunStep(stepId);
176751
- const parked = SystemOneDecisionOutputSchema.safeParse(step?.output);
176752
- return parked.success && parked.data.review?.status === "pending" ? parked.data : null;
176753
- }
176754
- async handOffToReviewer(config, parked, context, meta) {
176755
- if (!parked || !config.humanReview) {
176756
- return {
176757
- status: "failed",
176758
- error: "The decision this step parked with is missing, so its approval cannot be resumed. Run the node again."
176759
- };
176760
- }
176761
- const result = await new HumanInTheLoopExecutor(this.deps).run({
176762
- config: buildReviewCard(meta.nodeId, config, config.humanReview, parked),
176763
- context,
176764
- meta
176765
- });
176766
- if (result.status === "failed")
176767
- return { status: "failed", error: result.error };
176768
- if ("async" in result)
176769
- return result;
176770
- const answered = result.output;
176771
- const outcome = answered ? this.resolveApproval(parked, {
176772
- requestId: answered.requestId,
176773
- status: answered.status,
176774
- responses: answered.responses
176775
- }) : null;
176776
- if (!outcome) {
176777
- return {
176778
- status: "failed",
176779
- error: "The approval was answered but its result could not be applied"
176780
- };
176781
- }
176782
- return {
176783
- status: "success",
176784
- output: outcome.output,
176785
- nextPort: outcome.nextPort
176786
- };
176787
- }
176788
- resolveApproval(parkedOutput, approval) {
176789
- return resolveReviewedDecision(parkedOutput, approval);
176790
- }
176791
- async send(providerId, endpoint, apiKey, body, timeoutMs, maxRetries) {
176792
- const doFetch = this.options.fetch ?? fetch;
176793
- const sleep = this.options.sleep ?? defaultSleep;
176794
- const now = this.options.now ?? Date.now;
176795
- const random = this.options.random ?? Math.random;
176796
- const deadlineAt = now() + timeoutMs - DEADLINE_MARGIN_MS;
176797
- const controller = new AbortController;
176798
- const timer = setTimeout(() => controller.abort(), Math.max(0, deadlineAt - now()));
176799
- const timedOut = () => ({
176800
- ok: false,
176801
- error: `SystemOne request exceeded its ${timeoutMs}ms time budget`
176802
- });
176803
- try {
176804
- for (let attempt = 0;; attempt++) {
176805
- const result = await this.attemptOnce(doFetch, providerId, endpoint, apiKey, body, controller.signal, now);
176806
- if (result.kind === "ok") {
176807
- return { ok: true, text: result.text, requestId: result.requestId };
176808
- }
176809
- if (result.kind === "timeout" || controller.signal.aborted)
176810
- return timedOut();
176811
- const attempts = attempt + 1;
176812
- const suffix = attempts > 1 ? ` after ${attempts} attempts` : "";
176813
- if (!result.retryable || attempt >= maxRetries) {
176814
- return { ok: false, error: `${result.message}${suffix}` };
176815
- }
176816
- const backoff = Math.min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * 2 ** attempt);
176817
- const delay = result.retryAfterMs ?? Math.round(backoff * (0.5 + random() * 0.5));
176818
- if (delay >= deadlineAt - now()) {
176819
- return {
176820
- ok: false,
176821
- error: `${result.message}${suffix}; the ${delay}ms retry delay does not fit the ${timeoutMs}ms time budget`
176822
- };
176823
- }
176824
- await sleep(delay, controller.signal);
176825
- if (controller.signal.aborted)
176826
- return timedOut();
176827
- }
176828
- } finally {
176829
- clearTimeout(timer);
176830
- }
176831
- }
176832
- async attemptOnce(doFetch, providerId, endpoint, apiKey, body, signal, now) {
176833
- let res;
176834
- try {
176835
- res = await doFetch(endpoint, {
176836
- method: "POST",
176837
- headers: {
176838
- ...getOpenRouterAttributionHeaders(endpoint, this.providerContext().env),
176839
- "content-type": "application/json",
176840
- accept: "application/json",
176841
- authorization: `Bearer ${apiKey}`
176842
- },
176843
- body,
176844
- redirect: "manual",
176845
- signal
176846
- });
176847
- } catch (err) {
176848
- if (signal.aborted)
176849
- return { kind: "timeout" };
176850
- const code2 = err?.code;
176851
- const detail2 = typeof code2 === "string" && /^[A-Z0-9_]{3,40}$/.test(code2) ? ` (${code2})` : "";
176852
- return {
176853
- kind: "fail",
176854
- message: `SystemOne request failed: network error${detail2}`,
176855
- retryable: true
176856
- };
176857
- }
176858
- const requestId = readRequestId(res.headers);
176859
- const withId = (message) => requestId ? `${message} [request ${requestId}]` : message;
176860
- if (res.status >= 200 && res.status < 300) {
176861
- let text;
176862
- try {
176863
- text = await res.text();
176864
- } catch {
176865
- if (signal.aborted)
176866
- return { kind: "timeout" };
176867
- return {
176868
- kind: "fail",
176869
- message: withId("SystemOne response body could not be read"),
176870
- retryable: true
176871
- };
176872
- }
176873
- if (text.length > MAX_RESPONSE_CHARS) {
176874
- return {
176875
- kind: "fail",
176876
- message: withId("SystemOne response exceeded the size limit"),
176877
- retryable: false
176878
- };
176879
- }
176880
- return { kind: "ok", text, requestId };
176881
- }
176882
- if (res.status >= 300 && res.status < 400) {
176883
- return {
176884
- kind: "fail",
176885
- message: withId(`SystemOne request was redirected (HTTP ${res.status}); redirects are refused`),
176886
- retryable: false
176887
- };
176888
- }
176889
- let errorText = "";
176890
- try {
176891
- errorText = await res.text();
176892
- } catch {
176893
- if (signal.aborted)
176894
- return { kind: "timeout" };
176895
- }
176896
- const code = readErrorCode(errorText);
176897
- if (res.status === 401 || res.status === 403) {
176898
- return {
176899
- kind: "fail",
176900
- message: withId(systemOneKeyRejectedMessage(providerId, res.status, code)),
176901
- retryable: false
176902
- };
176903
- }
176904
- const detail = code ? ` (${code})` : "";
176905
- const retryable = res.status === 408 || res.status === 429 || res.status >= 500;
176906
- return {
176907
- kind: "fail",
176908
- message: withId(`SystemOne API returned HTTP ${res.status}${detail}`),
176909
- retryable,
176910
- retryAfterMs: retryable ? parseRetryAfter(res.headers.get("retry-after"), now()) : undefined
176911
- };
176912
- }
176913
- }
176914
-
176915
- // src/workflows/definition.ts
176916
- function getNextTargets(next) {
176917
- if (typeof next === "string")
176918
- return [next];
176919
- if (Array.isArray(next))
176920
- return next;
176921
- return Object.values(next);
176922
- }
176923
- function generateEdges(def) {
176924
- const edges = [];
176925
- for (const node of def.nodes) {
176926
- if (!node.next)
176927
- continue;
176928
- if (typeof node.next === "string") {
176929
- edges.push({
176930
- id: `${node.id}→${node.next}`,
176931
- source: node.id,
176932
- target: node.next,
176933
- sourcePort: "default"
176934
- });
176935
- } else if (Array.isArray(node.next)) {
176936
- for (const targetId of node.next) {
176937
- edges.push({
176938
- id: `${node.id}→${targetId}`,
176939
- source: node.id,
176940
- target: targetId,
176941
- sourcePort: "default"
176942
- });
176943
- }
176944
- } else {
176945
- for (const [port, targetId] of Object.entries(node.next)) {
176946
- edges.push({
176947
- id: `${node.id}→${targetId}:${port}`,
176948
- source: node.id,
176949
- target: targetId,
176950
- sourcePort: port
176951
- });
176952
- }
176953
- }
176954
- }
176955
- return edges;
176956
- }
176957
- function findEntryNodes(def) {
176958
- const targets = new Set;
176959
- for (const node of def.nodes) {
176960
- if (!node.next)
176961
- continue;
176962
- for (const targetId of getNextTargets(node.next)) {
176963
- targets.add(targetId);
176964
- }
176965
- }
176966
- return def.nodes.filter((n) => !targets.has(n.id));
176967
- }
176968
- function resolveValidationPort(next, executorPort, validationPassed) {
176969
- if (validationPassed === undefined)
176970
- return executorPort;
176971
- if (!next || typeof next !== "object" || Array.isArray(next))
176972
- return executorPort;
176973
- if (executorPort && Object.hasOwn(next, executorPort))
176974
- return executorPort;
176975
- return validationPassed ? "pass" : "fail";
176976
- }
176977
- function getSuccessors(def, nodeId, port) {
176978
- const node = def.nodes.find((n) => n.id === nodeId);
176979
- if (!node?.next)
176980
- return [];
176981
- const targetIds = [];
176982
- if (typeof node.next === "string") {
176983
- targetIds.push(node.next);
176984
- } else if (Array.isArray(node.next)) {
176985
- targetIds.push(...node.next);
176986
- } else {
176987
- if (port) {
176988
- const targetId = node.next[port];
176989
- if (targetId)
176990
- targetIds.push(targetId);
176991
- } else {
176992
- targetIds.push(...Object.values(node.next));
176993
- }
176994
- }
176995
- return targetIds.map((id) => def.nodes.find((n) => n.id === id)).filter((n) => n != null);
176996
- }
176997
- function isUpstream(def, sourceId, targetId) {
176998
- const reverseDeps = new Map;
176999
- for (const node of def.nodes) {
177000
- if (!node.next)
177001
- continue;
177002
- for (const target of getNextTargets(node.next)) {
177003
- if (!reverseDeps.has(target))
177004
- reverseDeps.set(target, []);
177005
- reverseDeps.get(target).push(node.id);
177006
- }
177007
- }
177008
- const visited = new Set;
177009
- const queue = [targetId];
177010
- while (queue.length > 0) {
177011
- const current = queue.shift();
177012
- const preds = reverseDeps.get(current) || [];
177013
- for (const pred of preds) {
177014
- if (visited.has(pred))
177015
- continue;
177016
- visited.add(pred);
177017
- if (pred === sourceId)
177018
- return true;
177019
- queue.push(pred);
177020
- }
177021
- }
177022
- return false;
177023
- }
177024
- function containsInterpolationToken(value) {
177025
- if (typeof value === "string")
177026
- return value.includes("{{") && value.includes("}}");
177027
- if (Array.isArray(value))
177028
- return value.some(containsInterpolationToken);
177029
- if (value && typeof value === "object") {
177030
- return Object.values(value).some(containsInterpolationToken);
177031
- }
177032
- return false;
177033
- }
177034
- function definitionNodeIds(def) {
177035
- return new Set(def.nodes.map((node) => node.id));
177036
- }
177037
- function validateDefinition(def, registry, options = {}) {
177038
- const errors = [];
177039
- const nodeIds = new Set(def.nodes.map((n) => n.id));
177040
- for (const node of def.nodes) {
177041
- if (node.id.includes("#") && !options.legacyNodeIds?.has(node.id)) {
177042
- errors.push(`Node "${node.id}" contains reserved character "#"`);
177043
- }
177044
- if (node.type === "human-in-the-loop" && typeof node.config.questions === "string" && !/^\{\{[^}]+\}\}$/.test(node.config.questions.trim())) {
177045
- errors.push(`Node "${node.id}" human-in-the-loop config.questions must be an array or one exact {{interpolation}} token`);
177046
- }
177047
- errors.push(...systemOneStaticShapeViolations(node), ...systemOneRetryViolations(node));
177048
- if (node.type === "foreach") {
177049
- validateForeachNode(node, errors);
177050
- if (node.id.includes("#")) {
177051
- errors.push(`Node "${node.id}" cannot be a foreach: its id contains "#", which is reserved for synthetic child ids`);
177052
- }
177053
- if (isUpstream(def, node.id, node.id)) {
177054
- errors.push("foreach inside a loop is not supported in v1");
177055
- }
177056
- const collidingSibling = def.nodes.find((other) => other.id !== node.id && other.id.startsWith(`${node.id}#`));
177057
- if (collidingSibling) {
177058
- errors.push(`Node "${node.id}" cannot be a foreach: node "${collidingSibling.id}" collides with its synthetic child id space ("${node.id}#…")`);
177059
- }
177060
- }
177061
- }
177062
- for (const node of def.nodes) {
177063
- if (!node.next)
177064
- continue;
177065
- if (typeof node.next === "string") {
177066
- if (!nodeIds.has(node.next)) {
177067
- errors.push(`Node "${node.id}" references non-existent next target "${node.next}"`);
177068
- }
177069
- } else if (Array.isArray(node.next)) {
177070
- for (const targetId of node.next) {
177071
- if (!nodeIds.has(targetId)) {
177072
- errors.push(`Node "${node.id}" fan-out references non-existent target "${targetId}"`);
177073
- }
177074
- }
177075
- } else {
177076
- for (const [port, targetId] of Object.entries(node.next)) {
177077
- if (!nodeIds.has(targetId)) {
177078
- errors.push(`Node "${node.id}" port "${port}" references non-existent target "${targetId}"`);
177079
- }
177080
- }
177081
- }
177082
- }
177083
- const entryNodes = findEntryNodes(def);
177084
- if (entryNodes.length === 0) {
177085
- errors.push("No entry node found (every node is a target of some other node)");
177086
- } else if (entryNodes.length > 1) {
177087
- const ids = entryNodes.map((n) => `"${n.id}"`).join(", ");
177088
- errors.push(`Multiple entry nodes found: ${ids} (expected exactly one)`);
177089
- }
177090
- if (entryNodes.length === 1) {
177091
- const reachable = new Set;
177092
- const queue = [entryNodes[0].id];
177093
- while (queue.length > 0) {
177094
- const current = queue.shift();
177095
- if (reachable.has(current))
177096
- continue;
177097
- reachable.add(current);
177098
- const node = def.nodes.find((n) => n.id === current);
177099
- if (!node?.next)
177100
- continue;
177101
- for (const targetId of getNextTargets(node.next)) {
177102
- queue.push(targetId);
177103
- }
177104
- }
177105
- for (const node of def.nodes) {
177106
- if (!reachable.has(node.id)) {
177107
- errors.push(`Node "${node.id}" is unreachable from the entry node`);
177108
- }
177109
- }
177110
- }
177111
- if (registry) {
177112
- for (const node of def.nodes) {
177113
- if (!registry.has(node.type)) {
177114
- errors.push(`Node "${node.id}" uses unregistered executor type "${node.type}"`);
177115
- continue;
177116
- }
177117
- reportStaticConfigIssues(node, registry.get(node.type).configSchema, node.config, errors);
177118
- if (node.type === "foreach" && registry.has("agent-task")) {
177119
- const body = node.config.body;
177120
- const bodyConfig = typeof body === "object" && body !== null && !Array.isArray(body) ? body.config : undefined;
177121
- if (typeof bodyConfig === "object" && bodyConfig !== null && !Array.isArray(bodyConfig)) {
177122
- reportStaticConfigIssues(node, registry.get("agent-task").configSchema, bodyConfig, errors, "config.body.config");
177123
- }
177124
- }
177125
- }
177126
- }
177127
- for (const node of def.nodes) {
177128
- if (!node.inputs)
177129
- continue;
177130
- for (const [localName, sourcePath] of Object.entries(node.inputs)) {
177131
- const [sourceNodeId] = sourcePath.split(".");
177132
- if (!sourceNodeId)
177133
- continue;
177134
- if (sourceNodeId === "trigger" || sourceNodeId === "input" || sourceNodeId === "run") {
177135
- continue;
177136
- }
177137
- if (!nodeIds.has(sourceNodeId)) {
177138
- errors.push(`Node "${node.id}" input "${localName}" references non-existent node "${sourceNodeId}"`);
177139
- continue;
177140
- }
177141
- if (!isUpstream(def, sourceNodeId, node.id)) {
177142
- errors.push(`Node "${node.id}" input "${localName}" references "${sourceNodeId}" which is not upstream`);
177143
- }
177144
- }
177145
- }
177146
- return { valid: errors.length === 0, errors };
177147
- }
177148
- function reportStaticConfigIssues(node, schema, config, errors, pathPrefix = "config") {
177149
- const result = schema.safeParse(config);
177150
- if (result.success)
177151
- return;
177152
- for (const rawIssue of result.error?.issues ?? []) {
177153
- const issue = rawIssue;
177154
- const issuePath = issue.path.map(String);
177155
- const path = [pathPrefix, ...issuePath].join(".");
177156
- let value = config;
177157
- for (const segment of issue.path) {
177158
- if (value === null || typeof value !== "object") {
177159
- value = undefined;
177160
- break;
177161
- }
177162
- value = value[segment];
177163
- }
177164
- if (containsInterpolationToken(value))
177165
- continue;
177166
- const renderedValue = value === undefined ? "undefined" : JSON.stringify(value);
177167
- errors.push(`Node "${node.id}" (${node.type}) ${path} has invalid value ${renderedValue}: ${issue.message}`);
177168
- }
177169
- }
177170
- function validateForeachNode(node, errors) {
177171
- const config = node.config;
177172
- if (Object.hasOwn(config, "concurrency")) {
177173
- errors.push(`Node "${node.id}" foreach concurrency is not supported in v1`);
177174
- }
177175
- if (node.outputSchema !== undefined || node.validation !== undefined) {
177176
- errors.push(`Node "${node.id}" foreach node-level outputSchema/validation is not supported in v1`);
177177
- }
177178
- const over = config.over;
177179
- const isInterpolatedArray = typeof over === "string" && /^\{\{[^}]+\}\}$/.test(over.trim());
177180
- if (!Array.isArray(over) && !isInterpolatedArray) {
177181
- errors.push(`Node "${node.id}" foreach config.over must be an array or one exact {{interpolation}} token`);
177182
- }
177183
- if (typeof config.itemKey !== "string" || config.itemKey.length === 0) {
177184
- errors.push(`Node "${node.id}" foreach config.itemKey must be a non-empty string`);
177185
- }
177186
- const body = config.body;
177187
- if (typeof body !== "object" || body === null || Array.isArray(body)) {
177188
- errors.push(`Node "${node.id}" foreach config.body must be an object`);
177189
- return;
177190
- }
177191
- const bodyRecord = body;
177192
- if (bodyRecord.type !== "agent-task") {
177193
- errors.push(`Node "${node.id}" foreach config.body.type must be "agent-task" in v1`);
177194
- }
177195
- if (typeof bodyRecord.config !== "object" || bodyRecord.config === null || Array.isArray(bodyRecord.config)) {
177196
- errors.push(`Node "${node.id}" foreach config.body.config must be an object`);
177197
- return;
177198
- }
177199
- const bodyConfig = bodyRecord.config;
177200
- if (typeof bodyConfig.template !== "string") {
177201
- errors.push(`Node "${node.id}" foreach agent-task body.config.template must be a string`);
177202
- }
177203
- }
177204
- function applyDefinitionPatch(def, patch) {
177205
- const errors = [];
177206
- let nodes = [...def.nodes];
177207
- if (patch.delete?.length) {
177208
- const missing = patch.delete.filter((id) => !nodes.some((n) => n.id === id));
177209
- if (missing.length > 0) {
177210
- errors.push(`Cannot delete non-existent nodes: ${missing.join(", ")}`);
177211
- }
177212
- const toDelete = new Set(patch.delete);
177213
- nodes = nodes.filter((n) => !toDelete.has(n.id));
177214
- }
177215
- if (patch.create?.length) {
177216
- const existingIds = new Set(nodes.map((n) => n.id));
177217
- for (const newNode of patch.create) {
177218
- if (existingIds.has(newNode.id)) {
177219
- errors.push(`Cannot create node with duplicate ID: "${newNode.id}"`);
177220
- continue;
177221
- }
177222
- nodes.push(newNode);
177223
- existingIds.add(newNode.id);
177224
- }
177225
- }
177226
- if (patch.update?.length) {
177227
- for (const { nodeId, node: partial } of patch.update) {
177228
- const idx = nodes.findIndex((n) => n.id === nodeId);
177229
- if (idx === -1) {
177230
- errors.push(`Cannot update non-existent node: "${nodeId}"`);
177231
- continue;
177232
- }
177233
- const defined = {};
177234
- for (const [k, v] of Object.entries(partial)) {
177235
- if (v !== undefined)
177236
- defined[k] = v;
177237
- }
177238
- nodes[idx] = { ...nodes[idx], ...defined, id: nodeId };
177239
- }
177240
- }
177241
- const patchedDef = { ...def, nodes };
177242
- if (patch.onNodeFailure !== undefined) {
177243
- patchedDef.onNodeFailure = patch.onNodeFailure;
177244
- }
177245
- return { definition: patchedDef, errors };
177246
- }
177247
-
177248
175184
  // src/be/script-connections.ts
177249
175185
  init_zod();
177250
175186
  init_db2();
@@ -179515,6 +177451,31 @@ async function setScriptConnectionEnabled(id, enabled, userId) {
179515
177451
  WHERE id = ? RETURNING *`, [enabled ? 1 : 0, new Date().toISOString(), userId ?? null, id]);
179516
177452
  return row ? connectionFromRow(row) : null;
179517
177453
  }
177454
+ async function deleteScriptConnection(id) {
177455
+ const deleted = await getDbClient().transaction(async (tx) => {
177456
+ await tx.run("PRAGMA defer_foreign_keys = ON");
177457
+ const row = await tx.get("SELECT * FROM script_connections WHERE id = ?", [
177458
+ id
177459
+ ]);
177460
+ if (!row)
177461
+ return null;
177462
+ const connection = connectionFromRow(row);
177463
+ await deleteManagedBindingForConnection(id);
177464
+ await tx.run("DELETE FROM script_connections WHERE id = ?", [id]);
177465
+ const secretKey = derivedInlineSecretKey(connection);
177466
+ if (secretKey) {
177467
+ await deleteManagedConnectionSecret({
177468
+ scope: connection.scope,
177469
+ scopeId: connection.scopeId,
177470
+ key: secretKey
177471
+ });
177472
+ }
177473
+ return connection;
177474
+ });
177475
+ if (deleted && derivedInlineSecretKey(deleted))
177476
+ refreshSecretScrubberCache();
177477
+ return deleted;
177478
+ }
179518
177479
  function getScriptApiConnectionDescriptors(context = {}) {
179519
177480
  return listScriptConnections(context).filter((connection) => connection.kind === "openapi" || connection.kind === "graphql").map((connection) => {
179520
177481
  if (!connection.generatedRuntimeJson)
@@ -180043,7 +178004,7 @@ class NativeScriptExecutor {
180043
178004
  }
180044
178005
 
180045
178006
  // src/scripts-runtime/executors/quickjs.ts
180046
- var POOL_SIZE = 4;
178007
+ init_quickjs_pool_config();
180047
178008
  var UNRESPONSIVE_GRACE_MS = 5000;
180048
178009
  var RECYCLE_WASM_HEAP_BYTES = 64 * 1024 * 1024;
180049
178010
  function workerSpecifier() {
@@ -180132,7 +178093,11 @@ class QuickJSScriptExecutor {
180132
178093
  }
180133
178094
  if (input.signal?.aborted)
180134
178095
  return emptyOutput("killed");
180135
- sharedPool ??= new QuickJSWorkerPool(POOL_SIZE);
178096
+ try {
178097
+ sharedPool ??= new QuickJSWorkerPool(resolveQuickJSPoolSize(process.env.SCRIPT_QUICKJS_POOL_SIZE));
178098
+ } catch (error) {
178099
+ return emptyOutput("executor_error", error instanceof Error ? error.message : String(error));
178100
+ }
180136
178101
  const pool = sharedPool;
180137
178102
  const slot = await pool.acquire();
180138
178103
  if (input.signal?.aborted) {
@@ -180200,7 +178165,7 @@ var EXECUTORS = {
180200
178165
  quickjs: () => new QuickJSScriptExecutor
180201
178166
  };
180202
178167
  function getScriptExecutor(name = process.env.SCRIPT_EXECUTOR ?? "native") {
180203
- const factory = EXECUTORS[name];
178168
+ const factory = EXECUTORS[name.trim()];
180204
178169
  if (!factory) {
180205
178170
  throw new Error(`Unknown SCRIPT_EXECUTOR: ${name}. Available: ${Object.keys(EXECUTORS).join(", ")}`);
180206
178171
  }
@@ -180399,25 +178364,24 @@ async function extractArgsJsonSchema(source) {
180399
178364
  }
180400
178365
  }
180401
178366
 
180402
- // src/be/scripts/typecheck.ts
180403
- var import_typescript3 = __toESM(require_typescript(), 1);
180404
- import { fileURLToPath as fileURLToPath3 } from "node:url";
180405
-
180406
- // src/apps/definition.ts
180407
- init_zod();
180408
- init_db();
180409
-
180410
178367
  // src/be/scripts/run-saved.ts
180411
178368
  init_db();
180412
178369
  function getSavedScriptOwnerAgentId(script) {
180413
178370
  return script.scopeId ?? script.createdByAgentId;
180414
178371
  }
180415
- async function runSavedScriptAsAgent(args) {
178372
+ async function runSavedScriptAsAgent(args, deps = {}) {
180416
178373
  const runStartTouch = args.script.isScratch ? await touchScratchScriptLastUsed(args.script.id) : null;
180417
- const credentials = await buildScriptCredentialBindingsWithFailures({
180418
- agentId: args.agentId
180419
- });
180420
- const output = await runScript({
178374
+ const buildCredentials = deps.buildCredentials ?? buildScriptCredentialBindingsWithFailures;
178375
+ const credentials = await buildCredentials({ agentId: args.agentId });
178376
+ const output = args.signal?.aborted ? {
178377
+ result: undefined,
178378
+ stdout: "",
178379
+ stderr: "aborted before execution started",
178380
+ truncated: { stdout: false, stderr: false },
178381
+ durationMs: 0,
178382
+ exitCode: 1,
178383
+ error: "killed"
178384
+ } : await runScript({
180421
178385
  source: args.script.source,
180422
178386
  args: args.input,
180423
178387
  fsMode: args.script.fsMode,
@@ -180425,7 +178389,9 @@ async function runSavedScriptAsAgent(args) {
180425
178389
  egressSecrets: credentials.egressSecrets,
180426
178390
  failedBindings: credentials.failedBindings,
180427
178391
  apiConnections: getScriptApiConnectionDescriptors({ agentId: args.agentId }),
180428
- mcpConnections: getScriptMcpConnectionDescriptors({ agentId: args.agentId })
178392
+ mcpConnections: getScriptMcpConnectionDescriptors({ agentId: args.agentId }),
178393
+ ...args.timeoutMs ? { timeoutMs: args.timeoutMs } : {},
178394
+ ...args.signal ? { signal: args.signal } : {}
180429
178395
  });
180430
178396
  if (output.exitCode === 0 && !output.error && !output.runtimeError) {
180431
178397
  await touchScratchScriptLastUsed(args.script.id);
@@ -180434,6 +178400,14 @@ async function runSavedScriptAsAgent(args) {
180434
178400
  }
180435
178401
  return output;
180436
178402
  }
178403
+
178404
+ // src/be/scripts/typecheck.ts
178405
+ var import_typescript3 = __toESM(require_typescript(), 1);
178406
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
178407
+
178408
+ // src/apps/definition.ts
178409
+ init_zod();
178410
+ init_db();
180437
178411
  // src/apps/catalog.generated.json
180438
178412
  var catalog_generated_default = {
180439
178413
  $comment: "GENERATED by apps/ui/scripts/generate-catalog-schema.ts — do not hand-edit. Regenerate with `cd apps/ui && bun run generate:catalog-schema`.",
@@ -183529,25 +181503,25 @@ init_db2();
183529
181503
 
183530
181504
  // src/apps/format-upgrades.ts
183531
181505
  var CURRENT_APP_SCHEMA_VERSION = 1;
183532
- function isRecord3(value) {
181506
+ function isRecord(value) {
183533
181507
  return typeof value === "object" && value !== null && !Array.isArray(value);
183534
181508
  }
183535
181509
  function upgradeFrom0(raw) {
183536
181510
  const upgraded = { ...raw };
183537
- if (isRecord3(upgraded.page) && !Object.hasOwn(upgraded, "pages")) {
181511
+ if (isRecord(upgraded.page) && !Object.hasOwn(upgraded, "pages")) {
183538
181512
  upgraded.pages = { main: upgraded.page };
183539
181513
  upgraded.defaultPage = "main";
183540
181514
  }
183541
181515
  delete upgraded.page;
183542
- if (isRecord3(upgraded.models)) {
181516
+ if (isRecord(upgraded.models)) {
183543
181517
  upgraded.models = Object.fromEntries(Object.entries(upgraded.models).map(([modelName, model]) => {
183544
- if (!isRecord3(model))
181518
+ if (!isRecord(model))
183545
181519
  return [modelName, model];
183546
181520
  const upgradedModel = { ...model };
183547
181521
  delete upgradedModel.sources;
183548
- if (isRecord3(upgradedModel.columns)) {
181522
+ if (isRecord(upgradedModel.columns)) {
183549
181523
  upgradedModel.columns = Object.fromEntries(Object.entries(upgradedModel.columns).map(([columnName, column]) => {
183550
- if (!isRecord3(column))
181524
+ if (!isRecord(column))
183551
181525
  return [columnName, column];
183552
181526
  const upgradedColumn = { ...column };
183553
181527
  delete upgradedColumn.source;
@@ -183562,13 +181536,13 @@ function upgradeFrom0(raw) {
183562
181536
  }
183563
181537
  var APP_FORMAT_UPGRADES = [{ from: 0, to: 1, upgrade: upgradeFrom0 }];
183564
181538
  function schemaVersionOf(raw) {
183565
- if (!isRecord3(raw) || typeof raw.schemaVersion !== "number" || !Number.isInteger(raw.schemaVersion)) {
181539
+ if (!isRecord(raw) || typeof raw.schemaVersion !== "number" || !Number.isInteger(raw.schemaVersion)) {
183566
181540
  return 0;
183567
181541
  }
183568
181542
  return raw.schemaVersion;
183569
181543
  }
183570
181544
  function upgradeAppDefinition(raw) {
183571
- if (!isRecord3(raw))
181545
+ if (!isRecord(raw))
183572
181546
  return raw;
183573
181547
  let upgraded = raw;
183574
181548
  let version = schemaVersionOf(upgraded);
@@ -184927,4 +182901,4 @@ void _scriptMain;
184927
182901
  });
184928
182902
  }
184929
182903
 
184930
- export { require_dist, isInvalidClientError, assertUrlSafe, publicEndpointSsrfOptions, discoverProtectedResourceMetadata, discoverAuthorizationServerMetadata, normalizeTokenEndpointAuthMethod, resolveAdvertisedTokenEndpointAuthMethod, authMethodForStoredClient, selectDcrTokenEndpointAuthMethod, registerClient, buildAuthorizeUrl, exchangeCodeForTokens, refreshMcpToken, revokeMcpToken, computeExpiresAt, getMcpOAuthToken, findReusableMcpOAuthClient, invalidateMcpOAuthClient, upsertMcpOAuthToken, applyMcpOAuthRefresh, markMcpOAuthTokenStatus, deleteMcpOAuthToken, insertMcpOAuthPending, consumeMcpOAuthPending, gcMcpOAuthPending, setMcpServerAuthMethod, ensureMcpToken, callMcpServerTool, listVendoredOpenapiEntries, ConnectionAuthInputSchema, connectionAuthSummary, listRelationalCredentialBindings, getCredentialBindingById, findCredentialBindingByIdentity, upsertCredentialBinding, disableCredentialBinding, listScriptConnections, listScriptConnectionsAsync, getScriptConnectionById, ScriptConnectionConflictError, connectionAuthInputFromFlat, upsertScriptConnection, refreshScriptConnection, setScriptConnectionEnabled, getScriptApiConnectionDescriptors, getScriptMcpConnectionDescriptors, getScriptApiTypes, getScriptMcpTypes, oauthAppToProviderConfig, getOAuthProviderConfig, getOAuthBindingTokenStatus, buildScriptCredentialBindingsWithFailures, buildScriptCredentialBindings, buildSandboxedCommand, sandboxSpawnEnv, createCappedStreamState, snapshotCapped, readStreamCapped, writeBareImportShim, MIN_SCRIPT_WALL_CLOCK_MS, SCRIPT_LONG_TIMEOUT_HINT_MS, MAX_SCRIPT_WALL_CLOCK_MS, DEFAULT_SCRIPT_RESOURCES, require_typescript, checkImportAllowlist, validateScriptImports, runScript, BaseExecutor, postApprovalCancellationUpdates, createApprovalFollowUpTask, HumanInTheLoopExecutor, resolveWorkflowLlmConfig, SYSTEM_ONE_DECISION_NODE_TYPE, systemOneRetryViolations, systemOneUnresolvedError, SystemOneDecisionExecutor, getNextTargets, generateEdges, findEntryNodes, resolveValidationPort, getSuccessors, definitionNodeIds, validateDefinition, applyDefinitionPatch, extractScriptSignature, extractArgsJsonSchema, getSavedScriptOwnerAgentId, runSavedScriptAsAgent, resolveSyncRunAs, AppNameSchema, ColumnKindSchema, isIso8601Date, SYSTEM_COLUMN_KINDS, SORTABLE_SYSTEM_DATE_COLUMNS, AppElementsSchema, AppDefinitionSchema, collectScriptReferences, parseAppDefinition, applyAppDefinitionPatch, upgradeAppDefinition, decodeAppDefinition, appDefinitionNeedsRepair, createApp, getApp, listApps, listAppRecords, updateApp, deleteApp, getScriptAppTypes, SCRIPT_SDK_TYPES, scriptSdkTypesWithGeneratedApis, SCRIPT_STDLIB_MODULE_TYPES, scriptStdlibTypesWithGeneratedApis, typecheckWithAmbient, typecheckScript };
182904
+ export { require_dist, isInvalidClientError, assertUrlSafe, publicEndpointSsrfOptions, discoverProtectedResourceMetadata, discoverAuthorizationServerMetadata, normalizeTokenEndpointAuthMethod, resolveAdvertisedTokenEndpointAuthMethod, authMethodForStoredClient, selectDcrTokenEndpointAuthMethod, registerClient, buildAuthorizeUrl, exchangeCodeForTokens, refreshMcpToken, revokeMcpToken, computeExpiresAt, getMcpOAuthToken, findReusableMcpOAuthClient, invalidateMcpOAuthClient, upsertMcpOAuthToken, applyMcpOAuthRefresh, markMcpOAuthTokenStatus, deleteMcpOAuthToken, insertMcpOAuthPending, consumeMcpOAuthPending, gcMcpOAuthPending, setMcpServerAuthMethod, ensureMcpToken, callMcpServerTool, listVendoredOpenapiEntries, ConnectionAuthInputSchema, connectionAuthSummary, listRelationalCredentialBindings, getCredentialBindingById, findCredentialBindingByIdentity, upsertCredentialBinding, disableCredentialBinding, listScriptConnections, listScriptConnectionsAsync, getScriptConnectionById, ScriptConnectionConflictError, connectionAuthInputFromFlat, upsertScriptConnection, refreshScriptConnection, setScriptConnectionEnabled, deleteScriptConnection, getScriptApiConnectionDescriptors, getScriptMcpConnectionDescriptors, getScriptApiTypes, getScriptMcpTypes, oauthAppToProviderConfig, getOAuthProviderConfig, getOAuthBindingTokenStatus, buildScriptCredentialBindingsWithFailures, buildScriptCredentialBindings, buildSandboxedCommand, sandboxSpawnEnv, createCappedStreamState, snapshotCapped, readStreamCapped, writeBareImportShim, MIN_SCRIPT_WALL_CLOCK_MS, SCRIPT_LONG_TIMEOUT_HINT_MS, MAX_SCRIPT_WALL_CLOCK_MS, DEFAULT_SCRIPT_RESOURCES, require_typescript, checkImportAllowlist, validateScriptImports, runScript, extractScriptSignature, extractArgsJsonSchema, getSavedScriptOwnerAgentId, runSavedScriptAsAgent, resolveSyncRunAs, AppNameSchema, ColumnKindSchema, isIso8601Date, SYSTEM_COLUMN_KINDS, SORTABLE_SYSTEM_DATE_COLUMNS, AppElementsSchema, AppDefinitionSchema, collectScriptReferences, parseAppDefinition, applyAppDefinitionPatch, upgradeAppDefinition, decodeAppDefinition, appDefinitionNeedsRepair, createApp, getApp, listApps, listAppRecords, updateApp, deleteApp, getScriptAppTypes, SCRIPT_SDK_TYPES, scriptSdkTypesWithGeneratedApis, SCRIPT_STDLIB_MODULE_TYPES, scriptStdlibTypesWithGeneratedApis, typecheckWithAmbient, typecheckScript };