openfox 2.0.114 → 2.0.116

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 (120) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/CHANGELOG.md +43 -0
  3. package/dist/{ask-ZYPCJKZD.js → ask-UBIRH3SO.js} +2 -2
  4. package/dist/{auth-YY5PJYSC.js → auth-GTGIGX5X.js} +2 -2
  5. package/dist/{auto-config-T5GR2N6X.js → auto-config-AAUO4PKW.js} +2 -2
  6. package/dist/{backend-LVYHLGQJ.js → backend-67OLCS5O.js} +2 -2
  7. package/dist/{branch.api-XVTYACSH.js → branch.api-UMKSQMSA.js} +2 -2
  8. package/dist/changelog-FZUE6OSG.js +63 -0
  9. package/dist/{chat-handler-KWXRSWXZ.js → chat-handler-Z6BEY66U.js} +31 -31
  10. package/dist/{chunk-2XD65L7M.js → chunk-27NABDXB.js} +2 -2
  11. package/dist/{chunk-YGJIK3CG.js → chunk-2FCLCUVR.js} +5 -5
  12. package/dist/{chunk-UTIQ7OO5.js → chunk-3KBRMBTP.js} +2 -2
  13. package/dist/{chunk-SFZGMB2G.js → chunk-3PG65AXG.js} +18 -3
  14. package/dist/{chunk-QD7MRMCH.js → chunk-4E52GUXJ.js} +231 -173
  15. package/dist/{chunk-I7FY2LTR.js → chunk-4GHLULHB.js} +18 -2
  16. package/dist/{chunk-K733B5T2.js → chunk-4HV3PDEK.js} +135 -134
  17. package/dist/{chunk-PBW3YC3G.js → chunk-5PT4UMRR.js} +5 -1
  18. package/dist/{chunk-NWJLWLKF.js → chunk-6XHDNSA3.js} +11 -11
  19. package/dist/{chunk-SA34STZ6.js → chunk-AESOGRFK.js} +2 -2
  20. package/dist/{chunk-4H427UBV.js → chunk-AGXJ5O63.js} +2 -2
  21. package/dist/{chunk-7GWARYQC.js → chunk-BH3BBUGB.js} +24 -22
  22. package/dist/{chunk-L63Q4JQJ.js → chunk-EQ5CGNOT.js} +3 -3
  23. package/dist/{chunk-NLO64UE3.js → chunk-EQ7DK2TG.js} +10 -6
  24. package/dist/{chunk-MUSPWEBB.js → chunk-GZTMCTUS.js} +4 -4
  25. package/dist/{chunk-HP5CIB66.js → chunk-HD6Y77RO.js} +2 -2
  26. package/dist/chunk-HNHSUQCN.js +7 -0
  27. package/dist/{chunk-W77NBJAZ.js → chunk-HYPXL7K5.js} +178 -33
  28. package/dist/{chunk-OTYAEEX3.js → chunk-HZSKKJHQ.js} +9 -8
  29. package/dist/{chunk-JP7NM545.js → chunk-JLAR2CMV.js} +2 -2
  30. package/dist/{chunk-3O77NT4T.js → chunk-KLQEL2DZ.js} +10 -4
  31. package/dist/{chunk-UPBWEHIL.js → chunk-LNNBLB6G.js} +20 -5
  32. package/dist/{chunk-OXSTNSCF.js → chunk-LTYL6ZGH.js} +2 -2
  33. package/dist/{chunk-P5UANBBX.js → chunk-M6X6AIEG.js} +2 -2
  34. package/dist/{chunk-LXYPMFTH.js → chunk-MKWS7TQH.js} +4 -4
  35. package/dist/{chunk-SBSUDHL4.js → chunk-O6DU226D.js} +2 -2
  36. package/dist/{chunk-HV6IALXF.js → chunk-QJWTBVJO.js} +14 -14
  37. package/dist/{chunk-BZVW77PI.js → chunk-QQVPUZQB.js} +157 -21
  38. package/dist/{chunk-GUHHUDNL.js → chunk-SQLJRO3J.js} +10 -10
  39. package/dist/{chunk-JXLRL5JR.js → chunk-TGVDUK4N.js} +7 -7
  40. package/dist/{chunk-L737Y63F.js → chunk-TOKQ2UVG.js} +2 -2
  41. package/dist/{chunk-FW4NDUBL.js → chunk-U4HMAYAD.js} +15 -14
  42. package/dist/{chunk-V4IE7HJY.js → chunk-W7VIYHPQ.js} +2 -2
  43. package/dist/{chunk-VPVLO436.js → chunk-X3XKYGUN.js} +4 -4
  44. package/dist/{chunk-5WRI5ZAA.js → chunk-YLJ4XMA6.js} +6 -2
  45. package/dist/{chunk-X25Q6RAV.js → chunk-ZKLE2Q3I.js} +1 -1
  46. package/dist/{chunk-TKKP56QK.js → chunk-ZTOG6LJD.js} +3 -3
  47. package/dist/cli/dev.js +3 -3
  48. package/dist/cli/index.js +3 -3
  49. package/dist/client-KCNTDTIR.js +16 -0
  50. package/dist/{client-pure-VFZIIK4S.js → client-pure-B5DHEKQJ.js} +3 -3
  51. package/dist/command-defaults/mark-done.command.md +14 -0
  52. package/dist/compactor-LAXZLPPA.js +32 -0
  53. package/dist/{config-EAB3V4QK.js → config-TUCHLIWD.js} +2 -2
  54. package/dist/{dynamic-context-MVGOF5V2.js → dynamic-context-YHWFFP53.js} +10 -10
  55. package/dist/{events-PI7IMPHT.js → events-IVPAMMR5.js} +9 -8
  56. package/dist/{folding-FO57K4JM.js → folding-RTGU63BW.js} +7 -6
  57. package/dist/http-client-IPUW2MSW.js +11 -0
  58. package/dist/inspect-proxy-WPEDMCG7.js +13 -0
  59. package/dist/{install-CPOPMCSE.js → install-VA2F6X6Z.js} +2 -2
  60. package/dist/launch-PAVQAWGP.js +52 -0
  61. package/dist/{manager-66YAEO7K.js → manager-EMLSLMMT.js} +6 -6
  62. package/dist/{model-overrides-L53PZNZA.js → model-overrides-7F2EOA4U.js} +5 -5
  63. package/dist/{oauth-provider-52YILVUJ.js → oauth-provider-DGBC2YM6.js} +2 -2
  64. package/dist/{oauth-store-XCFXV2VM.js → oauth-store-KECHUT54.js} +2 -2
  65. package/dist/{openFolder-HX7X356L.js → openFolder-XCMSU3OI.js} +2 -2
  66. package/dist/orchestrator-CS3KXLZE.js +63 -0
  67. package/dist/package.json +5 -2
  68. package/dist/{path-security-RSEI3YKB.js → path-security-JTCHWYG3.js} +13 -12
  69. package/dist/{paths-F27V3S4I.js → paths-BHR7CZ7I.js} +2 -2
  70. package/dist/{permissions-K6YEA2ZZ.js → permissions-UKR524ZB.js} +2 -2
  71. package/dist/{platform-WA4GK5BO.js → platform-ECDDYMAR.js} +5 -5
  72. package/dist/{processor-WDZSFBVO.js → processor-RZD4JRDX.js} +30 -30
  73. package/dist/profiles-GYHXBWPV.js +10 -0
  74. package/dist/{project-creator-676WQXVI.js → project-creator-PMQ65NKN.js} +4 -4
  75. package/dist/{projects-SSBWIYL4.js → projects-NDPNOV6D.js} +6 -4
  76. package/dist/{protocol-BzHs024-.d.ts → protocol-CfUkCYxF.d.ts} +12 -3
  77. package/dist/{protocol-RKSWKNXI.js → protocol-HYA5BYVN.js} +8 -4
  78. package/dist/provider/index.d.ts +4 -4
  79. package/dist/{provider-PLIWRBCF.js → provider-Q7J4UFTS.js} +11 -11
  80. package/dist/{provider-manager-2QSJTPWS.js → provider-manager-TMBO4DFG.js} +9 -9
  81. package/dist/{pwa-XPHP3PY2.js → pwa-2GRFSXD7.js} +3 -3
  82. package/dist/{registry-ZP4TN2IN.js → registry-5QL3BOWN.js} +6 -5
  83. package/dist/{serve-MZ3BCCWC.js → serve-KR22J37W.js} +36 -36
  84. package/dist/server/index.d.ts +26 -6
  85. package/dist/server/index.js +35 -35
  86. package/dist/server-ESKTIZL5.js +55 -0
  87. package/dist/service-M7XJHAK4.js +25 -0
  88. package/dist/{service-CXWJQFOZ.js → service-WKABQHKL.js} +2 -2
  89. package/dist/{session-overrides-LXN6W7SA.js → session-overrides-CWBKPHMF.js} +8 -7
  90. package/dist/{sessions-CHPVUG6H.js → sessions-I7ELDIIP.js} +9 -6
  91. package/dist/{settings-NEBM3GQX.js → settings-FGXQHKUH.js} +4 -4
  92. package/dist/shared/index.d.ts +3 -3
  93. package/dist/shared/index.js +2 -2
  94. package/dist/{store-SARB6V2N.js → store-JYPZ2RXB.js} +2 -2
  95. package/dist/{tasks-TJXG2V3U.js → tasks-X5H5HM4J.js} +12 -12
  96. package/dist/{tool-adapter-FEAHWU5C.js → tool-adapter-FJAFLDZA.js} +2 -2
  97. package/dist/{tools-CIM26IFB.js → tools-KBS6X3EN.js} +28 -28
  98. package/dist/{types-CbggXFvR.d.ts → types-CIVhQMvD.d.ts} +1 -1
  99. package/dist/{types-CMtHpDWT.d.ts → types-Df7NM9b5.d.ts} +2 -0
  100. package/dist/{update-UZBBO42X.js → update-TDS6LP5N.js} +4 -4
  101. package/dist/{update-server-LOOXIXDW.js → update-server-SVPV6ZJZ.js} +2 -2
  102. package/dist/{url-utils-SAJP7AEX.js → url-utils-C5BM7NF7.js} +2 -2
  103. package/dist/web/assets/index-ChtRS33s.js +324 -0
  104. package/dist/web/assets/{index-BmILAZrT.css → index-c43YT-4A.css} +1 -1
  105. package/dist/web/index.html +2 -2
  106. package/dist/web/sw.js +1 -1
  107. package/dist/workflow-defaults/default.workflow.json +2 -2
  108. package/dist/{workspace-2XODU4YJ.js → workspace-IQLLHMYR.js} +5 -5
  109. package/package.json +5 -2
  110. package/dist/chunk-NCZRWCJN.js +0 -7
  111. package/dist/client-EM7ISGUP.js +0 -16
  112. package/dist/compactor-V3LR7APW.js +0 -31
  113. package/dist/http-client-33EZ3BLR.js +0 -11
  114. package/dist/inspect-proxy-NHKQQ2CD.js +0 -13
  115. package/dist/launch-L5ROVNI3.js +0 -52
  116. package/dist/orchestrator-XK5K3RPL.js +0 -63
  117. package/dist/profiles-5J7F4BML.js +0 -10
  118. package/dist/server-EPXODFMB.js +0 -55
  119. package/dist/service-54PGIPDQ.js +0 -25
  120. package/dist/web/assets/index-rZHXkfMq.js +0 -324
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  runAgentTurn
3
- } from "./chunk-FW4NDUBL.js";
3
+ } from "./chunk-U4HMAYAD.js";
4
4
  import {
5
5
  executeSubAgent,
6
6
  getToolRegistryForAgent
7
- } from "./chunk-K733B5T2.js";
7
+ } from "./chunk-4HV3PDEK.js";
8
8
  import {
9
9
  TurnMetrics,
10
10
  createMessageStartEvent
11
- } from "./chunk-NLO64UE3.js";
11
+ } from "./chunk-EQ7DK2TG.js";
12
12
  import {
13
13
  checkAborted,
14
14
  decodeUtf8,
15
15
  spawnShellProcess
16
- } from "./chunk-TKKP56QK.js";
16
+ } from "./chunk-ZTOG6LJD.js";
17
17
  import {
18
18
  terminateProcessTree
19
19
  } from "./chunk-I72ACQ6R.js";
@@ -27,21 +27,24 @@ import {
27
27
  loadProjectWorkflows,
28
28
  loadUserWorkflows,
29
29
  normalizeWorkflowScope
30
- } from "./chunk-OTYAEEX3.js";
30
+ } from "./chunk-HZSKKJHQ.js";
31
31
  import {
32
32
  getCurrentContextWindowId,
33
33
  getEventStore
34
- } from "./chunk-JXLRL5JR.js";
34
+ } from "./chunk-TGVDUK4N.js";
35
35
  import {
36
36
  createChatMessageMessage,
37
37
  createSessionRunningMessage
38
- } from "./chunk-I7FY2LTR.js";
38
+ } from "./chunk-4GHLULHB.js";
39
39
  import {
40
40
  findAgentById,
41
41
  getRuntimeConfig,
42
42
  loadAllAgentsDefault,
43
43
  resolveDefaultAgentId
44
- } from "./chunk-UPBWEHIL.js";
44
+ } from "./chunk-LNNBLB6G.js";
45
+ import {
46
+ LLMError
47
+ } from "./chunk-LTYL6ZGH.js";
45
48
  import {
46
49
  logger
47
50
  } from "./chunk-K44MW7JJ.js";
@@ -50,11 +53,19 @@ import {
50
53
  } from "./chunk-VUQCQXXJ.js";
51
54
  import {
52
55
  createServerMessage
53
- } from "./chunk-X25Q6RAV.js";
56
+ } from "./chunk-ZKLE2Q3I.js";
54
57
  import {
55
58
  getGlobalConfigDir
56
59
  } from "./chunk-CQGTEGKL.js";
57
60
 
61
+ // src/server/runner/types.ts
62
+ var DEFAULT_LLM_RETRY_POLICY = {
63
+ backoffMs: [1e3, 5e3, 3e4],
64
+ minIntervalMs: 6e4,
65
+ maxDurationMs: 30 * 6e4,
66
+ maxAttempts: 40
67
+ };
68
+
58
69
  // src/server/workflows/types.ts
59
70
  var TERMINAL_DONE = "$done";
60
71
  var TERMINAL_BLOCKED = "$blocked";
@@ -336,6 +347,64 @@ function getCurrentWindowMessageOptions(sessionId) {
336
347
  const contextWindowId = getCurrentContextWindowId(sessionId);
337
348
  return contextWindowId ? { contextWindowId } : void 0;
338
349
  }
350
+ function sleepWithSignal(ms, signal) {
351
+ return new Promise((resolve, reject) => {
352
+ if (signal?.aborted) {
353
+ reject(new Error("Aborted"));
354
+ return;
355
+ }
356
+ const onAbort = () => {
357
+ clearTimeout(timer);
358
+ signal?.removeEventListener("abort", onAbort);
359
+ reject(new Error("Aborted"));
360
+ };
361
+ const timer = setTimeout(() => {
362
+ signal?.removeEventListener("abort", onAbort);
363
+ resolve();
364
+ }, ms);
365
+ signal?.addEventListener("abort", onAbort, { once: true });
366
+ });
367
+ }
368
+ function evaluateLLMRetry(failures, firstFailureAt, now, policy) {
369
+ if (now - firstFailureAt >= policy.maxDurationMs) return { retry: false };
370
+ if (failures >= policy.maxAttempts) return { retry: false };
371
+ const delayMs = failures <= policy.backoffMs.length ? policy.backoffMs[failures - 1] : policy.minIntervalMs;
372
+ return { retry: true, delayMs, attempt: failures + 1 };
373
+ }
374
+ function rollbackFailedAttempt(sessionId, turnStartSeq) {
375
+ const eventStore = getEventStore();
376
+ const fromSeq = Math.max(1, turnStartSeq);
377
+ const events = eventStore.getEvents(sessionId, fromSeq + 1);
378
+ const assistantIds = new Set(
379
+ events.filter((e) => e.type === "message.start" && e.data.role === "assistant").map((e) => e.data.messageId)
380
+ );
381
+ const tombstoneSeqs = events.filter((e) => {
382
+ switch (e.type) {
383
+ case "message.start":
384
+ return e.data.role === "assistant";
385
+ case "message.delta":
386
+ case "message.thinking":
387
+ case "message.done":
388
+ case "chat.done":
389
+ return assistantIds.has(e.data.messageId);
390
+ case "chat.error":
391
+ case "pattern.retry":
392
+ case "tool.preparing":
393
+ case "tool.call":
394
+ case "tool.output":
395
+ case "tool.result":
396
+ return true;
397
+ default:
398
+ return false;
399
+ }
400
+ }).map((e) => e.seq);
401
+ if (tombstoneSeqs.length > 0) {
402
+ eventStore.tombstoneEvents(sessionId, tombstoneSeqs);
403
+ }
404
+ if (assistantIds.size > 0) {
405
+ eventStore.append(sessionId, { type: "message.removed", data: { messageIds: [...assistantIds] } });
406
+ }
407
+ }
339
408
  function buildReason(metadataEntries) {
340
409
  const entries = metadataEntries?.["criteria"] ?? [];
341
410
  const remaining = entries.filter((e) => e.status !== "passed");
@@ -353,6 +422,8 @@ async function executeWorkflow(workflow, options, subGroup) {
353
422
  let currentStepId = isResume ? resumeFromStep : subGroup ? activeSteps[0]?.id ?? workflow.entryStep : workflow.entryStep;
354
423
  let lastStepOutput = options.initialStepOutput ?? {};
355
424
  const firstEntryForStep = /* @__PURE__ */ new Set();
425
+ const stepLLMFailures = /* @__PURE__ */ new Map();
426
+ const stepLLMDeadlines = /* @__PURE__ */ new Map();
356
427
  const messagesBeforeWorkflow = sessionManager.requireSession(sessionId).messages.length;
357
428
  const activeStepIds = new Set(activeSteps.map((s) => s.id));
358
429
  const activeSubGroups = /* @__PURE__ */ new Set();
@@ -497,9 +568,10 @@ async function executeWorkflow(workflow, options, subGroup) {
497
568
  const agentStep = step;
498
569
  const STEP_DONE_PROMPT = "\n\nOnce you're done, call step_done()";
499
570
  const STEP_DONE_NUDGE = "You haven't called step_done(). If you haven't finished the task, continue and when you're finished call step_done()";
571
+ const isResumingCurrentStep = isResume && step.id === resumeFromStep && !resumeConsumed;
572
+ const isLLMFailedRetry = firstEntryForStep.has(step.id) && (stepLLMFailures.get(step.id) ?? 0) > 0;
500
573
  let promptContent;
501
574
  let nudgeContent;
502
- const isResumingCurrentStep = isResume && step.id === resumeFromStep && !resumeConsumed;
503
575
  if (!firstEntryForStep.has(step.id) && agentStep.prompt && !isResumingCurrentStep) {
504
576
  const resolvedPrompt = resolveTemplate(agentStep.prompt, templateCtx);
505
577
  promptContent = resolvedPrompt + STEP_DONE_PROMPT;
@@ -528,7 +600,7 @@ async function executeWorkflow(workflow, options, subGroup) {
528
600
  })
529
601
  );
530
602
  }
531
- } else if (firstEntryForStep.has(step.id) && !isResumingCurrentStep) {
603
+ } else if (firstEntryForStep.has(step.id) && !isResumingCurrentStep && !isLLMFailedRetry) {
532
604
  const parts = [];
533
605
  if (agentStep.nudgePrompt) {
534
606
  const resolvedNudge = resolveTemplate(agentStep.nudgePrompt, templateCtx);
@@ -538,32 +610,105 @@ async function executeWorkflow(workflow, options, subGroup) {
538
610
  nudgeContent = parts.join("\n\n");
539
611
  emitWorkflowMessage(eventStore, sessionId, nudgeContent, currentWindowMessageOptions, onMessage);
540
612
  }
613
+ const turnStartSeq = eventStore.getLatestSeq(sessionId) ?? 0;
614
+ let retryBlocked = null;
615
+ let blockedReason = "";
616
+ const retryPolicy = { ...DEFAULT_LLM_RETRY_POLICY, ...options.llmRetryPolicy };
617
+ const handleLLMFailure = async (errorMessage) => {
618
+ const failures = (stepLLMFailures.get(step.id) ?? 0) + 1;
619
+ stepLLMFailures.set(step.id, failures);
620
+ const firstFailureAt = stepLLMDeadlines.get(step.id) ?? Date.now();
621
+ stepLLMDeadlines.set(step.id, firstFailureAt);
622
+ const decision = evaluateLLMRetry(failures, firstFailureAt, Date.now(), retryPolicy);
623
+ if (decision.retry) {
624
+ rollbackFailedAttempt(sessionId, turnStartSeq);
625
+ firstEntryForStep.add(step.id);
626
+ resumeConsumed = true;
627
+ eventStore.append(sessionId, {
628
+ type: "workflow.step_retry",
629
+ data: { stepName: step.name, attempt: decision.attempt, retryInMs: decision.delayMs }
630
+ });
631
+ retryBlocked = "retry";
632
+ await sleepWithSignal(decision.delayMs, signal);
633
+ return;
634
+ }
635
+ rollbackFailedAttempt(sessionId, turnStartSeq);
636
+ sessionManager.setPhase(sessionId, "blocked");
637
+ if (executionId) {
638
+ sessionManager.blockWorkflow(
639
+ sessionId,
640
+ executionId,
641
+ workflow.metadata.id,
642
+ workflow.metadata.name,
643
+ workflow.metadata.color
644
+ );
645
+ }
646
+ blockedReason = `Step "${step.name}" failed after ${failures} attempts: ${errorMessage}`;
647
+ eventStore.append(sessionId, { type: "chat.error", data: { error: blockedReason, recoverable: false } });
648
+ retryBlocked = "blocked";
649
+ };
541
650
  const turnMetrics = new TurnMetrics();
542
651
  const es = getEventStore();
543
652
  const append = (event) => es.append(sessionId, event);
544
653
  let stepDoneCalled = false;
545
- const agentResult = await runAgentTurn(
546
- {
547
- sessionManager,
548
- sessionId,
549
- llmClient,
550
- ...options.statsIdentity ? { statsIdentity: options.statsIdentity } : {},
551
- ...signal ? { signal } : {},
552
- ...onMessage ? { onMessage } : {}
553
- },
554
- turnMetrics,
555
- agentStep.agentId ?? resolveDefaultAgentId(),
556
- append,
557
- {
558
- ...!firstEntryForStep.has(step.id) && !agentStep.prompt && !isResumingCurrentStep ? { injectKickoff: () => injectGenericKickoff(sessionId) } : {},
559
- onToolExecuted: (toolCall, toolResult) => {
560
- if (toolCall.name === "step_done" && toolResult.success) {
561
- stepDoneCalled = true;
654
+ let agentResult;
655
+ try {
656
+ agentResult = await runAgentTurn(
657
+ {
658
+ sessionManager,
659
+ sessionId,
660
+ llmClient,
661
+ ...options.statsIdentity ? { statsIdentity: options.statsIdentity } : {},
662
+ ...signal ? { signal } : {},
663
+ ...onMessage ? { onMessage } : {},
664
+ suppressRecoverableErrors: true,
665
+ ...isLLMFailedRetry || isResumingCurrentStep ? { skipAgentReminder: true } : {}
666
+ },
667
+ turnMetrics,
668
+ agentStep.agentId ?? resolveDefaultAgentId(),
669
+ append,
670
+ {
671
+ ...!firstEntryForStep.has(step.id) && !agentStep.prompt && !isResumingCurrentStep ? { injectKickoff: () => injectGenericKickoff(sessionId) } : {},
672
+ onToolExecuted: (toolCall, toolResult) => {
673
+ if (toolCall.name === "step_done" && toolResult.success) {
674
+ stepDoneCalled = true;
675
+ }
562
676
  }
563
677
  }
678
+ );
679
+ } catch (error) {
680
+ if (error instanceof Error && error.message === "Aborted") {
681
+ throw error;
564
682
  }
565
- );
683
+ if (!(error instanceof LLMError)) {
684
+ throw error;
685
+ }
686
+ await handleLLMFailure(error.message);
687
+ if (retryBlocked === "retry") {
688
+ iterations -= 1;
689
+ continue;
690
+ }
691
+ return {
692
+ finalAction: { type: "BLOCKED", reason: blockedReason, blockedCriteria: [] },
693
+ iterations,
694
+ totalTime: (performance.now() - startTime) / 1e3
695
+ };
696
+ }
697
+ if (agentResult.failed) {
698
+ await handleLLMFailure(agentResult.failed.error);
699
+ if (retryBlocked === "retry") {
700
+ iterations -= 1;
701
+ continue;
702
+ }
703
+ return {
704
+ finalAction: { type: "BLOCKED", reason: blockedReason, blockedCriteria: [] },
705
+ iterations,
706
+ totalTime: (performance.now() - startTime) / 1e3
707
+ };
708
+ }
566
709
  firstEntryForStep.add(step.id);
710
+ stepLLMFailures.delete(step.id);
711
+ stepLLMDeadlines.delete(step.id);
567
712
  resumeConsumed = true;
568
713
  const agentReturnValue = agentResult.returnValueResult ?? "completed";
569
714
  lastStepOutput = {
@@ -587,7 +732,7 @@ async function executeWorkflow(workflow, options, subGroup) {
587
732
  const turnMetrics = new TurnMetrics();
588
733
  const promptTemplate = subStep.prompt ?? "Perform your task.";
589
734
  const resolvedPrompt = resolveTemplate(promptTemplate, templateCtx);
590
- const allAgents = await loadAllAgentsDefault();
735
+ const allAgents = await loadAllAgentsDefault(sessionManager.getProjectWorkdir(sessionId));
591
736
  const agentDef = findAgentById(subStep.subAgentType, allAgents);
592
737
  if (!agentDef) {
593
738
  logger.error("Sub-agent definition not found", { subAgentType: subStep.subAgentType });
@@ -894,9 +1039,9 @@ function launchWorkflowRun(deps, payload) {
894
1039
  ...payload.stepOutput ? { initialStepOutput: payload.stepOutput } : {},
895
1040
  ...payload.userChoice ? { userChoice: payload.userChoice } : {},
896
1041
  ...payload.resumeFrom ? (() => {
897
- const exec = sessionManager.getActiveWorkflowExecution(sessionId);
1042
+ const exec = sessionManager.getLatestWorkflowExecution(sessionId);
898
1043
  if (!exec) return {};
899
- if (exec.status === "waiting") {
1044
+ if (exec.status === "waiting" || exec.status === "blocked") {
900
1045
  const resumed = sessionManager.resumeWorkflow(
901
1046
  sessionId,
902
1047
  exec.id,
@@ -954,4 +1099,4 @@ export {
954
1099
  abortRunnerRun,
955
1100
  launchWorkflowRun
956
1101
  };
957
- //# sourceMappingURL=chunk-W77NBJAZ.js.map
1102
+ //# sourceMappingURL=chunk-HYPXL7K5.js.map
@@ -1,6 +1,3 @@
1
- import {
2
- getProject
3
- } from "./chunk-SFZGMB2G.js";
4
1
  import {
5
2
  deleteItemFromDir,
6
3
  getDefaultIds,
@@ -9,12 +6,15 @@ import {
9
6
  pathExists,
10
7
  saveItemToDir
11
8
  } from "./chunk-OSXPQSLW.js";
9
+ import {
10
+ getProject
11
+ } from "./chunk-3PG65AXG.js";
12
12
  import {
13
13
  parseDefaultModelSelection
14
- } from "./chunk-MUSPWEBB.js";
14
+ } from "./chunk-GZTMCTUS.js";
15
15
  import {
16
16
  getDatabase
17
- } from "./chunk-PBW3YC3G.js";
17
+ } from "./chunk-5PT4UMRR.js";
18
18
  import {
19
19
  logger
20
20
  } from "./chunk-K44MW7JJ.js";
@@ -342,10 +342,11 @@ async function resolveSlashLaunch(configDir, projectDir, prompt) {
342
342
  }
343
343
 
344
344
  // src/server/db/tasks.ts
345
+ import { randomBytes } from "crypto";
345
346
  function createTask(projectId, input) {
346
347
  const db = getDatabase();
347
348
  const now = (/* @__PURE__ */ new Date()).toISOString();
348
- const id = crypto.randomUUID();
349
+ const id = randomBytes(8).toString("hex");
349
350
  const position = db.prepare(`SELECT COALESCE(MAX(position), -1) + 1 AS pos FROM tasks WHERE project_id = ? AND status = 'todo'`).get(projectId);
350
351
  db.prepare(
351
352
  `INSERT INTO tasks (id, project_id, prompt, attachments, status, run_state, position, version, agent_id, provider_id, model, created_at, updated_at)
@@ -908,7 +909,7 @@ function createTasksService(deps) {
908
909
  const defaults = parseDefaultModelSelection(config.defaultModelSelection);
909
910
  const providerId = task.providerId ?? defaults.providerId ?? null;
910
911
  const model = task.model ?? defaults.model ?? null;
911
- const session = sessionManager.createSession(projectId, promptLabel(task.prompt), providerId, model);
912
+ const session = sessionManager.createSession(projectId, void 0, providerId, model);
912
913
  if (task.agentId) {
913
914
  try {
914
915
  sessionManager.setMode(session.id, task.agentId);
@@ -1078,4 +1079,4 @@ export {
1078
1079
  isTaskGateError,
1079
1080
  createTasksService
1080
1081
  };
1081
- //# sourceMappingURL=chunk-OTYAEEX3.js.map
1082
+ //# sourceMappingURL=chunk-HZSKKJHQ.js.map
@@ -2,7 +2,7 @@ import {
2
2
  SETTINGS_KEYS,
3
3
  getSetting,
4
4
  setSetting
5
- } from "./chunk-HP5CIB66.js";
5
+ } from "./chunk-HD6Y77RO.js";
6
6
 
7
7
  // src/server/agents/model-overrides.ts
8
8
  import { z } from "zod";
@@ -69,4 +69,4 @@ export {
69
69
  setAgentModelOverride,
70
70
  resolveLLMClientForAgent
71
71
  };
72
- //# sourceMappingURL=chunk-JP7NM545.js.map
72
+ //# sourceMappingURL=chunk-JLAR2CMV.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  resolveDefaultAgentId
3
- } from "./chunk-UPBWEHIL.js";
3
+ } from "./chunk-LNNBLB6G.js";
4
4
  import {
5
5
  getDatabase
6
- } from "./chunk-PBW3YC3G.js";
6
+ } from "./chunk-5PT4UMRR.js";
7
7
 
8
8
  // src/server/db/sessions.ts
9
9
  function getProjectDangerLevel(projectId) {
@@ -20,7 +20,7 @@ function createSession(projectId, workdir, title, providerId, providerModel, wor
20
20
  const now = (/* @__PURE__ */ new Date()).toISOString();
21
21
  const id = crypto.randomUUID();
22
22
  const dangerLevel = getProjectDangerLevel(projectId);
23
- const defaultAgent = resolveDefaultAgentId();
23
+ const defaultAgent = resolveDefaultAgentId(projectId);
24
24
  db.prepare(
25
25
  `
26
26
  INSERT INTO sessions (id, project_id, workdir, workspace, branch, phase, mode, workflow_phase, is_running, created_at, updated_at, title, provider_id, provider_model, danger_level)
@@ -396,6 +396,11 @@ function getActiveWorkflowExecution(sessionId) {
396
396
  ).get(sessionId);
397
397
  return row;
398
398
  }
399
+ function getLatestWorkflowExecution(sessionId) {
400
+ const db = getDatabase();
401
+ const row = db.prepare(`SELECT * FROM workflow_executions WHERE session_id = ? ORDER BY updated_at DESC LIMIT 1`).get(sessionId);
402
+ return row;
403
+ }
399
404
  function clearWorkflowExecution(executionId) {
400
405
  const db = getDatabase();
401
406
  const now = Date.now();
@@ -427,6 +432,7 @@ export {
427
432
  createWorkflowExecution,
428
433
  updateWorkflowExecutionStatus,
429
434
  getActiveWorkflowExecution,
435
+ getLatestWorkflowExecution,
430
436
  clearWorkflowExecution
431
437
  };
432
- //# sourceMappingURL=chunk-3O77NT4T.js.map
438
+ //# sourceMappingURL=chunk-KLQEL2DZ.js.map
@@ -1,10 +1,13 @@
1
1
  import {
2
2
  saveItemToDir
3
3
  } from "./chunk-OSXPQSLW.js";
4
+ import {
5
+ getProjectDefaultAgent
6
+ } from "./chunk-3PG65AXG.js";
4
7
  import {
5
8
  SETTINGS_KEYS,
6
9
  getSetting
7
- } from "./chunk-HP5CIB66.js";
10
+ } from "./chunk-HD6Y77RO.js";
8
11
  import {
9
12
  logger
10
13
  } from "./chunk-K44MW7JJ.js";
@@ -199,11 +202,11 @@ async function deleteProjectAgent(projectDir, agentId) {
199
202
  }
200
203
  return { success: false };
201
204
  }
202
- async function loadAllAgentsDefault() {
205
+ async function loadAllAgentsDefault(projectDir) {
203
206
  try {
204
207
  const config = getRuntimeConfig();
205
208
  const configDir = getGlobalConfigDir(config.mode ?? "production");
206
- return await loadAllAgents(configDir, config.workdir);
209
+ return await loadAllAgents(configDir, projectDir ?? config.workdir);
207
210
  } catch {
208
211
  return loadDefaultAgents();
209
212
  }
@@ -293,7 +296,19 @@ async function getOverrideAgentIds(configDir, projectDir) {
293
296
  const projectOverrides = projectAgents.map((agent) => agent.metadata.id).filter((id) => defaultIds.includes(id));
294
297
  return [...userOverrides, ...projectOverrides];
295
298
  }
296
- function resolveDefaultAgentId() {
299
+ function resolveDefaultAgentId(projectId) {
300
+ if (projectId) {
301
+ try {
302
+ const projectDefault = getProjectDefaultAgent(projectId);
303
+ if (projectDefault && projectDefault.trim().length > 0) {
304
+ return projectDefault.trim();
305
+ }
306
+ } catch (err) {
307
+ logger.debug("Failed to read project defaultAgent from DB", {
308
+ error: err instanceof Error ? err.message : String(err)
309
+ });
310
+ }
311
+ }
297
312
  try {
298
313
  const dbSetting = getSetting(SETTINGS_KEYS.DEFAULT_AGENT);
299
314
  if (dbSetting && dbSetting.trim().length > 0) {
@@ -337,4 +352,4 @@ export {
337
352
  getOverrideAgentIds,
338
353
  resolveDefaultAgentId
339
354
  };
340
- //# sourceMappingURL=chunk-UPBWEHIL.js.map
355
+ //# sourceMappingURL=chunk-LNNBLB6G.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SETTINGS_KEYS,
3
3
  getSetting
4
- } from "./chunk-HP5CIB66.js";
4
+ } from "./chunk-HD6Y77RO.js";
5
5
  import {
6
6
  logger
7
7
  } from "./chunk-K44MW7JJ.js";
@@ -164,4 +164,4 @@ export {
164
164
  WorkspaceInUseError,
165
165
  OpenAIHttpClient
166
166
  };
167
- //# sourceMappingURL=chunk-OXSTNSCF.js.map
167
+ //# sourceMappingURL=chunk-LTYL6ZGH.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getProjectByWorkdir
3
- } from "./chunk-SFZGMB2G.js";
3
+ } from "./chunk-3PG65AXG.js";
4
4
  import {
5
5
  logger
6
6
  } from "./chunk-K44MW7JJ.js";
@@ -345,4 +345,4 @@ export {
345
345
  startInspectProxy,
346
346
  stopAllInspectProxies
347
347
  };
348
- //# sourceMappingURL=chunk-P5UANBBX.js.map
348
+ //# sourceMappingURL=chunk-M6X6AIEG.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getModelProfile
3
- } from "./chunk-V4IE7HJY.js";
3
+ } from "./chunk-W7VIYHPQ.js";
4
4
  import {
5
5
  getBackendCapabilities
6
6
  } from "./chunk-AZHWLLPP.js";
@@ -13,11 +13,11 @@ import {
13
13
  getThinking,
14
14
  mapFinishReason,
15
15
  parseToolArguments
16
- } from "./chunk-L737Y63F.js";
16
+ } from "./chunk-TOKQ2UVG.js";
17
17
  import {
18
18
  LLMError,
19
19
  OpenAIHttpClient
20
- } from "./chunk-OXSTNSCF.js";
20
+ } from "./chunk-LTYL6ZGH.js";
21
21
  import {
22
22
  logger
23
23
  } from "./chunk-K44MW7JJ.js";
@@ -310,4 +310,4 @@ function createLLMClient(config, initialBackend = "unknown") {
310
310
  export {
311
311
  createLLMClient
312
312
  };
313
- //# sourceMappingURL=chunk-LXYPMFTH.js.map
313
+ //# sourceMappingURL=chunk-MKWS7TQH.js.map
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  getProjectByWorkdir,
6
6
  updateProject
7
- } from "./chunk-SFZGMB2G.js";
7
+ } from "./chunk-3PG65AXG.js";
8
8
  import {
9
9
  logger
10
10
  } from "./chunk-K44MW7JJ.js";
@@ -333,4 +333,4 @@ export {
333
333
  deleteWorkspace,
334
334
  isGitRepository
335
335
  };
336
- //# sourceMappingURL=chunk-SBSUDHL4.js.map
336
+ //# sourceMappingURL=chunk-O6DU226D.js.map
@@ -3,7 +3,7 @@ import {
3
3
  isCancel,
4
4
  password,
5
5
  select
6
- } from "./chunk-4H427UBV.js";
6
+ } from "./chunk-AGXJ5O63.js";
7
7
 
8
8
  // src/cli/main.ts
9
9
  import { parseArgs } from "util";
@@ -36,9 +36,9 @@ Options:
36
36
  `);
37
37
  }
38
38
  async function runNetworkSetup(mode) {
39
- const { loadAuthConfig, saveAuthConfig, encryptPassword } = await import("./auth-YY5PJYSC.js");
40
- const { saveGlobalConfig } = await import("./config-EAB3V4QK.js");
41
- const { getAuthKeyPath } = await import("./paths-F27V3S4I.js");
39
+ const { loadAuthConfig, saveAuthConfig, encryptPassword } = await import("./auth-GTGIGX5X.js");
40
+ const { saveGlobalConfig } = await import("./config-TUCHLIWD.js");
41
+ const { getAuthKeyPath } = await import("./paths-BHR7CZ7I.js");
42
42
  const existingAuth = await loadAuthConfig(mode);
43
43
  if (existingAuth) {
44
44
  return;
@@ -104,8 +104,8 @@ async function runNetworkSetup(mode) {
104
104
  console.log("\u2713 Configuration saved!\n");
105
105
  }
106
106
  async function runConfig(mode) {
107
- const { loadGlobalConfig, getActiveProvider, getDefaultModel } = await import("./config-EAB3V4QK.js");
108
- const { getGlobalConfigPath } = await import("./paths-F27V3S4I.js");
107
+ const { loadGlobalConfig, getActiveProvider, getDefaultModel } = await import("./config-TUCHLIWD.js");
108
+ const { getGlobalConfigPath } = await import("./paths-BHR7CZ7I.js");
109
109
  const config = await loadGlobalConfig(mode);
110
110
  const configPath = getGlobalConfigPath(mode);
111
111
  const activeProvider = getActiveProvider(config);
@@ -163,13 +163,13 @@ async function runCli(options) {
163
163
  break;
164
164
  }
165
165
  case "provider": {
166
- const { runProviderCommand } = await import("./provider-PLIWRBCF.js");
166
+ const { runProviderCommand } = await import("./provider-Q7J4UFTS.js");
167
167
  const [, subcommand] = positionals;
168
168
  await runProviderCommand(mode, subcommand);
169
169
  break;
170
170
  }
171
171
  case "service": {
172
- const { runServiceCommand } = await import("./service-CXWJQFOZ.js");
172
+ const { runServiceCommand } = await import("./service-WKABQHKL.js");
173
173
  const [, subcommand, ...serviceArgs] = positionals;
174
174
  if (values.follow) {
175
175
  serviceArgs.push("-f");
@@ -182,7 +182,7 @@ async function runCli(options) {
182
182
  break;
183
183
  }
184
184
  case "pwa": {
185
- const { runPwaCommand, printPwaHelp } = await import("./pwa-XPHP3PY2.js");
185
+ const { runPwaCommand, printPwaHelp } = await import("./pwa-2GRFSXD7.js");
186
186
  const [, subcommand] = positionals;
187
187
  if (subcommand === "--help" || subcommand === "-h" || values.help) {
188
188
  printPwaHelp();
@@ -192,7 +192,7 @@ async function runCli(options) {
192
192
  break;
193
193
  }
194
194
  case "install": {
195
- const { runInstall } = await import("./install-CPOPMCSE.js");
195
+ const { runInstall } = await import("./install-VA2F6X6Z.js");
196
196
  const code = await runInstall({ check: values.check === true });
197
197
  if (code !== 0) {
198
198
  process.exit(code);
@@ -200,7 +200,7 @@ async function runCli(options) {
200
200
  break;
201
201
  }
202
202
  case "update": {
203
- const { runUpdate } = await import("./update-UZBBO42X.js");
203
+ const { runUpdate } = await import("./update-TDS6LP5N.js");
204
204
  const code = await runUpdate();
205
205
  if (code !== 0) {
206
206
  process.exit(code);
@@ -208,12 +208,12 @@ async function runCli(options) {
208
208
  break;
209
209
  }
210
210
  default: {
211
- const { configFileExists } = await import("./config-EAB3V4QK.js");
211
+ const { configFileExists } = await import("./config-TUCHLIWD.js");
212
212
  const configExists = await configFileExists(mode);
213
213
  if (!configExists) {
214
214
  await runNetworkSetup(mode);
215
215
  }
216
- const { runServe } = await import("./serve-MZ3BCCWC.js");
216
+ const { runServe } = await import("./serve-KR22J37W.js");
217
217
  const serveOptions = { mode };
218
218
  if (values.port) serveOptions.port = parseInt(values.port);
219
219
  if (values["no-browser"] === true) serveOptions.openBrowser = false;
@@ -225,4 +225,4 @@ async function runCli(options) {
225
225
  export {
226
226
  runCli
227
227
  };
228
- //# sourceMappingURL=chunk-HV6IALXF.js.map
228
+ //# sourceMappingURL=chunk-QJWTBVJO.js.map