nolo-cli 0.96.0-alpha.1 → 0.97.0-alpha.2

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 (63) hide show
  1. package/{_executeModel-AUQRMRWL.js → _executeModel-G2MRKK2K.js} +15 -15
  2. package/{agentDeleteCommand-4BAHJRU3.js → agentDeleteCommand-4427YKQF.js} +6 -6
  3. package/{agentEmailCommands-QISOY7Y6.js → agentEmailCommands-RNBKKO7Q.js} +18 -18
  4. package/{agentListCommands-U46ODMQU.js → agentListCommands-O4AEMQVV.js} +8 -8
  5. package/{agentMachineCommands-EHV2KM2C.js → agentMachineCommands-FOFX5S2Q.js} +7 -7
  6. package/{agentRecordCommands-SIPURU2S.js → agentRecordCommands-6QK7AMXQ.js} +18 -18
  7. package/{agentRunCommand-K4CLMA6B.js → agentRunCommand-2W3Q3A7M.js} +18 -18
  8. package/{agentRunControl-XLGD3UZ5.js → agentRunControl-WCTKX5VL.js} +2 -2
  9. package/{agentRuntimeLocal-O4HPUJA4.js → agentRuntimeLocal-IW3IM5P6.js} +6 -6
  10. package/{agentSlice-ZYT2OUR3.js → agentSlice-SK47GTN7.js} +1 -1
  11. package/{appDeleteCommands-R5BBTKQK.js → appDeleteCommands-ZXLXNRHF.js} +6 -6
  12. package/{appDeployCommands-ZJIXOJWD.js → appDeployCommands-PWB4YERK.js} +6 -6
  13. package/{appDeployStatusCommands-B3R2ZTBF.js → appDeployStatusCommands-2EZKZP7Y.js} +6 -6
  14. package/{appGetCommands-2AQSOV2A.js → appGetCommands-JNUKOWHO.js} +6 -6
  15. package/{appListCommands-HCIJGZFY.js → appListCommands-6X3H67SS.js} +6 -6
  16. package/{chatQueueReduxAdapter-Q5V4YJVI.js → chatQueueReduxAdapter-ZJ555AT2.js} +4 -4
  17. package/{chunk-OF7AQZUG.js → chunk-2YMRWISD.js} +1 -1
  18. package/{chunk-JOHSKZQX.js → chunk-3SK4LEIH.js} +27 -13
  19. package/{chunk-NTW5GWDM.js → chunk-3VNWWVKB.js} +2 -0
  20. package/{chunk-3IIEFNGY.js → chunk-4EZHSKTB.js} +1 -1
  21. package/{chunk-BGSLKVCP.js → chunk-7D6Z6AA4.js} +2 -2
  22. package/{chunk-LLT642J4.js → chunk-ADTY7BWR.js} +1 -1
  23. package/{chunk-WADCY6G6.js → chunk-ASQYTZTR.js} +43 -6
  24. package/{chunk-ZXKVPF4K.js → chunk-B4ZH7KVO.js} +1 -1
  25. package/{chunk-EGSKXKR5.js → chunk-EHKBVWKL.js} +1 -1
  26. package/{chunk-OA6Q2A4I.js → chunk-L7I247DF.js} +79 -19
  27. package/{chunk-JAXOVNM4.js → chunk-NEDZDG3M.js} +1 -1
  28. package/{chunk-3SJQXXGY.js → chunk-NUVMWYJM.js} +92 -13
  29. package/{chunk-BZWBEHGD.js → chunk-O35EJJVP.js} +14 -8
  30. package/{chunk-XRWZB6CF.js → chunk-OIMN34NA.js} +6 -6
  31. package/{chunk-AFDS2CVM.js → chunk-OZPMVBJI.js} +2 -2
  32. package/{chunk-XOVEWFLK.js → chunk-QLNJRTKI.js} +2 -2
  33. package/{chunk-A6G32FNX.js → chunk-R7N5TMTV.js} +3 -3
  34. package/{chunk-IAO6JBYW.js → chunk-RG6JBBX5.js} +5 -1
  35. package/{chunk-ZLR5JN3E.js → chunk-RSJECD7I.js} +3 -3
  36. package/{chunk-4MY4GLIW.js → chunk-SDTTBMBU.js} +115 -37
  37. package/{chunk-DEUUPHOO.js → chunk-TDRTS7QW.js} +1 -1
  38. package/{chunk-CPH3W5A7.js → chunk-WGR3J4Q6.js} +86 -1
  39. package/{chunk-FOWEGIMF.js → chunk-WRFW73PB.js} +10 -10
  40. package/{chunk-MMPXJXHT.js → chunk-X4QAVDFE.js} +99 -13
  41. package/{contentThunks-PT23JWJX.js → contentThunks-YLWTUILV.js} +5 -5
  42. package/{createAgentAutomationAction-N27SYTLU.js → createAgentAutomationAction-HFLPOBWQ.js} +5 -5
  43. package/{createDialogAction-XZPLHD5G.js → createDialogAction-4H52MURR.js} +6 -6
  44. package/{createPageAction-KHVJQ3CS.js → createPageAction-5YDRMJOS.js} +5 -5
  45. package/{dialogCommands-ZUWW5UT6.js → dialogCommands-KFK2FF5B.js} +6 -6
  46. package/{dialogSlice-3YH242HS.js → dialogSlice-TMSHUGEM.js} +4 -4
  47. package/{docCreateCommands-Q6FADDSJ.js → docCreateCommands-V777WOZ7.js} +6 -6
  48. package/{docDeleteCommands-ZKIH54PZ.js → docDeleteCommands-5KHT7Z5Q.js} +6 -6
  49. package/{docReadCommands-7BZT2QTW.js → docReadCommands-BLROGWP3.js} +6 -6
  50. package/{docStore-YSZRNUUD.js → docStore-OBC5QOW7.js} +1 -1
  51. package/{docUpdateCommands-WJXWTRL7.js → docUpdateCommands-QXOZHQ5H.js} +6 -6
  52. package/{handleSendMessageAction-KJO2QDBM.js → handleSendMessageAction-4LGNXH6T.js} +4 -4
  53. package/index.js +47 -47
  54. package/{machineCommands-QC4TD7GJ.js → machineCommands-SNLCRHQK.js} +18 -18
  55. package/{machineWsRunDispatch-XUOIAXO7.js → machineWsRunDispatch-ZGZVDQSO.js} +18 -18
  56. package/package.json +1 -1
  57. package/{readlineWorkspace-74TXXSLO.js → readlineWorkspace-OUL7ZN7D.js} +22 -19
  58. package/{runAgentClientLoop-37BXJD62.js → runAgentClientLoop-GD3APV7V.js} +13 -13
  59. package/{spaceCommands-P3ONT6LL.js → spaceCommands-TIDVUPDV.js} +6 -6
  60. package/{streamAgentChatTurn-FGXQXALU.js → streamAgentChatTurn-M73KWCCU.js} +15 -15
  61. package/{tools-R5UF2KZO.js → tools-DXXDQ2CP.js} +10 -10
  62. package/{tuiSummaryLlmCaller-T2SHYMDZ.js → tuiSummaryLlmCaller-VJY3YD2Q.js} +2 -2
  63. package/{updateDialogTitleAction-RTADGV7A.js → updateDialogTitleAction-XI73NQMU.js} +5 -5
@@ -8,7 +8,7 @@ import {
8
8
  readSseFrames,
9
9
  streamSseDataValues,
10
10
  throwIfChatCompletionStreamFailed
11
- } from "./chunk-OF7AQZUG.js";
11
+ } from "./chunk-2YMRWISD.js";
12
12
  import {
13
13
  DEVIN_CONNECT_URL
14
14
  } from "./chunk-Q5FJJ6XI.js";
@@ -20,7 +20,7 @@ import {
20
20
  resolveHistoricalToolContentCap,
21
21
  resolveToolOutputProfile,
22
22
  stripImagePartsFromMessages
23
- } from "./chunk-3IIEFNGY.js";
23
+ } from "./chunk-4EZHSKTB.js";
24
24
  import {
25
25
  downgradeUnparsableToolCalls,
26
26
  hasParsableObjectArguments,
@@ -38,13 +38,15 @@ import {
38
38
  TOOL_GUIDED_SECTION_ORDER,
39
39
  buildIdentityBlock,
40
40
  buildRuntimeGuidanceBlocks,
41
+ detectDispatchIntent,
42
+ detectDispatchIntentFromMessages,
41
43
  estimateContextTokens,
42
44
  hashStablePrefixContent,
43
45
  normalizeChatCompletionsBodyForProvider,
44
46
  requiresBareImageUrl,
45
47
  resolveToolGuidedSections,
46
48
  toBareImageUrlMessages
47
- } from "./chunk-OA6Q2A4I.js";
49
+ } from "./chunk-L7I247DF.js";
48
50
  import {
49
51
  convertMessagesToResponsesInput,
50
52
  extractReasoningFromResponseOutput,
@@ -91,7 +93,7 @@ import {
91
93
  resolveEmptyAssistantFallbackMessage,
92
94
  resolveEmptyAssistantOutcome,
93
95
  resolveTruncatedReasoningTailLog
94
- } from "./chunk-JAXOVNM4.js";
96
+ } from "./chunk-NEDZDG3M.js";
95
97
  import {
96
98
  COMPACTION_SUMMARY_SCHEMA_VERSION,
97
99
  COMPACTION_SUMMARY_SYSTEM_PROMPT,
@@ -110,7 +112,7 @@ import {
110
112
  resolveCompressionTriggerRatio,
111
113
  truncateToolOutputForContext,
112
114
  withProviderCallTimingFields
113
- } from "./chunk-WADCY6G6.js";
115
+ } from "./chunk-ASQYTZTR.js";
114
116
  import {
115
117
  estimateTokenCount
116
118
  } from "./chunk-PSCNXBYA.js";
@@ -12625,20 +12627,33 @@ function isColdResume(history, nowMs) {
12625
12627
  }
12626
12628
  async function maybeAutoCompactLocalHistory(args2) {
12627
12629
  const { adapter, dialogId, history } = args2;
12628
- const unchanged = () => ({
12630
+ const unchanged = (decision) => ({
12629
12631
  history,
12630
12632
  compressed: false,
12631
- summaryGenerated: false
12633
+ summaryGenerated: false,
12634
+ decision
12632
12635
  });
12633
- if (!dialogId || history.length === 0 || typeof adapter.loadDialogSummary !== "function" || typeof adapter.saveDialogSummary !== "function") {
12634
- return unchanged();
12636
+ if (!dialogId) {
12637
+ return unchanged({ outcome: "skipped", skipReason: "no-dialog-id" });
12638
+ }
12639
+ if (history.length === 0) {
12640
+ return unchanged({ outcome: "skipped", skipReason: "empty-history" });
12641
+ }
12642
+ if (typeof adapter.loadDialogSummary !== "function" || typeof adapter.saveDialogSummary !== "function") {
12643
+ return unchanged({
12644
+ outcome: "skipped",
12645
+ skipReason: "adapter-missing-summary-methods"
12646
+ });
12635
12647
  }
12636
12648
  let stored = null;
12637
12649
  try {
12638
12650
  stored = await adapter.loadDialogSummary(dialogId);
12639
12651
  } catch (error) {
12640
12652
  console.warn("[localLoop] loadDialogSummary failed:", error);
12641
- return unchanged();
12653
+ return unchanged({
12654
+ outcome: "skipped",
12655
+ skipReason: "load-summary-failed"
12656
+ });
12642
12657
  }
12643
12658
  const bridged = toPlanCompressionMessages(history);
12644
12659
  const validation = validateStoredSummary({ history, stored: stored ?? {} });
@@ -12674,7 +12689,21 @@ async function maybeAutoCompactLocalHistory(args2) {
12674
12689
  ...args2.realContextUsagePercent !== void 0 ? { realContextUsagePercent: args2.realContextUsagePercent } : {}
12675
12690
  });
12676
12691
  const projectExisting = () => {
12677
- if (!existingSummary.trim()) return unchanged();
12692
+ const diag = plan.diagnostics;
12693
+ const diagSnapshot = diag ? {
12694
+ estimatedTokens: diag.totalUsed,
12695
+ historyBudget: diag.historyBudget,
12696
+ triggerRatio: diag.triggerRatio,
12697
+ ...diag.realUsageRatio !== void 0 ? { realUsageRatio: diag.realUsageRatio } : {}
12698
+ } : {};
12699
+ const skippedDecision = {
12700
+ outcome: "skipped",
12701
+ skipReason: diag?.emptyReason === "no-pending" ? "no-pending" : diag?.emptyReason === "below-min-compress-count" ? "below-min-compress-count" : "below-trigger",
12702
+ ...diagSnapshot,
12703
+ ...diag ? { pendingMsgCount: diag.pendingMsgCount } : {},
12704
+ ...diag?.compressCount !== void 0 ? { compressCount: diag.compressCount } : {}
12705
+ };
12706
+ if (!existingSummary.trim()) return unchanged(skippedDecision);
12678
12707
  return {
12679
12708
  history: projectHistoryWithSummary({
12680
12709
  history,
@@ -12682,7 +12711,12 @@ async function maybeAutoCompactLocalHistory(args2) {
12682
12711
  summarizedBeforeId
12683
12712
  }),
12684
12713
  compressed: true,
12685
- summaryGenerated: false
12714
+ summaryGenerated: false,
12715
+ decision: {
12716
+ outcome: "compressed",
12717
+ trigger: "existing-summary",
12718
+ ...diagSnapshot
12719
+ }
12686
12720
  };
12687
12721
  };
12688
12722
  if (!plan.shouldCompress) {
@@ -12712,7 +12746,11 @@ async function maybeAutoCompactLocalHistory(args2) {
12712
12746
  );
12713
12747
  return {
12714
12748
  ...projectExisting(),
12715
- failureMessage: "summary model returned empty content"
12749
+ failureMessage: "summary model returned empty content",
12750
+ decision: {
12751
+ outcome: "failed",
12752
+ detail: "summary model returned empty content"
12753
+ }
12716
12754
  };
12717
12755
  }
12718
12756
  await adapter.saveDialogSummary({
@@ -12749,12 +12787,26 @@ async function maybeAutoCompactLocalHistory(args2) {
12749
12787
  beforeTokens: metrics.previousSummaryTokens + metrics.compressedTokens,
12750
12788
  afterTokens: metrics.newSummaryTokens + metrics.retainedTokens,
12751
12789
  ...result4.usage ? { usage: result4.usage } : {},
12752
- metrics
12790
+ metrics,
12791
+ decision: {
12792
+ outcome: "compressed",
12793
+ trigger: invalidSummary ? "invalid-summary" : coldResume ? "cold-resume" : plan.diagnostics?.triggeredByRealUsage ? "real-usage" : "estimate",
12794
+ ...plan.diagnostics ? {
12795
+ estimatedTokens: plan.diagnostics.totalUsed,
12796
+ historyBudget: plan.diagnostics.historyBudget,
12797
+ triggerRatio: plan.diagnostics.triggerRatio,
12798
+ ...plan.diagnostics.realUsageRatio !== void 0 ? { realUsageRatio: plan.diagnostics.realUsageRatio } : {}
12799
+ } : {}
12800
+ }
12753
12801
  };
12754
12802
  } catch (error) {
12755
12803
  console.warn("[localLoop] auto-compaction failed:", error);
12756
12804
  const failureMessage = error instanceof Error && error.message ? error.message.slice(0, 200) : String(error).slice(0, 200);
12757
- return { ...projectExisting(), failureMessage };
12805
+ return {
12806
+ ...projectExisting(),
12807
+ failureMessage,
12808
+ decision: { outcome: "failed", detail: failureMessage }
12809
+ };
12758
12810
  }
12759
12811
  }
12760
12812
 
@@ -13529,7 +13581,14 @@ async function runLocalAgentTurn(input) {
13529
13581
  agentConfig.exposedToolNames ?? agentConfig.toolNames ?? []
13530
13582
  );
13531
13583
  const guidanceBlocks = buildRuntimeGuidanceBlocks(agentTools);
13532
- const toolGuidedSections = resolveToolGuidedSections(agentTools);
13584
+ const toolGuidedSections = resolveToolGuidedSections(agentTools, {
13585
+ // 单调锁定:历史里任一 user 消息命中派发关键词、或已出现过
13586
+ // startAgentRun/controlAgentRun 的 tool_calls,后续每轮都保持 true,
13587
+ // 防止 session-scope 的 agentCollaboration 段逐轮翻转击穿前缀缓存。
13588
+ dispatchIntent: detectDispatchIntentFromMessages(history) || detectDispatchIntent(
13589
+ typeof input.input === "string" ? input.input : void 0
13590
+ )
13591
+ });
13533
13592
  const guidanceScopes = [
13534
13593
  ...input.userLanguage?.trim() ? [buildUserResponseLanguageContext({ language: input.userLanguage })] : [],
13535
13594
  guidanceBlocks.startupProtocol,
@@ -13578,19 +13637,29 @@ async function runLocalAgentTurn(input) {
13578
13637
  }
13579
13638
  let compactionUsage;
13580
13639
  const emitCompactionObservation = (compacted) => {
13581
- if (compacted.compressed || compacted.summaryGenerated || compacted.failureMessage) {
13582
- emitLoopEvent(observationBoundary, {
13583
- kind: "compaction",
13584
- atMs: Date.now(),
13585
- reason: compacted.reason ?? "context_budget",
13586
- summaryGenerated: compacted.summaryGenerated,
13587
- compressed: compacted.compressed,
13588
- ...compacted.failureMessage ? { failed: true, detail: compacted.failureMessage } : {},
13589
- ...compacted.beforeTokens !== void 0 ? { beforeTokens: compacted.beforeTokens } : {},
13590
- ...compacted.afterTokens !== void 0 ? { afterTokens: compacted.afterTokens } : {},
13591
- ...compacted.savedTokens !== void 0 ? { savedTokens: compacted.savedTokens } : {}
13592
- });
13640
+ const decision = compacted.decision;
13641
+ if (decision?.outcome === "skipped") {
13642
+ const isProtectionGap = decision.skipReason === "adapter-missing-summary-methods" || decision.skipReason === "load-summary-failed";
13643
+ const approachingBudget = decision.skipReason === "below-trigger" && typeof decision.estimatedTokens === "number" && typeof decision.historyBudget === "number" && decision.historyBudget > 0 && decision.estimatedTokens >= decision.historyBudget * 0.5;
13644
+ if (!isProtectionGap && !approachingBudget) return;
13593
13645
  }
13646
+ emitLoopEvent(observationBoundary, {
13647
+ kind: "compaction",
13648
+ atMs: Date.now(),
13649
+ ...compacted.reason ? { reason: compacted.reason } : {},
13650
+ summaryGenerated: compacted.summaryGenerated,
13651
+ compressed: compacted.compressed,
13652
+ ...compacted.failureMessage ? { failed: true, detail: compacted.failureMessage } : {},
13653
+ ...decision?.outcome === "skipped" ? { skipped: true, skipReason: decision.skipReason } : {},
13654
+ ...decision && "trigger" in decision && decision.trigger ? { trigger: decision.trigger } : {},
13655
+ ...decision && "estimatedTokens" in decision && decision.estimatedTokens !== void 0 ? { estimatedTokens: decision.estimatedTokens } : {},
13656
+ ...decision && "historyBudget" in decision && decision.historyBudget !== void 0 ? { historyBudget: decision.historyBudget } : {},
13657
+ ...decision && "realUsageRatio" in decision && decision.realUsageRatio !== void 0 ? { realUsageRatio: decision.realUsageRatio } : {},
13658
+ ...decision && "triggerRatio" in decision && decision.triggerRatio !== void 0 ? { triggerRatio: decision.triggerRatio } : {},
13659
+ ...compacted.beforeTokens !== void 0 ? { beforeTokens: compacted.beforeTokens } : {},
13660
+ ...compacted.afterTokens !== void 0 ? { afterTokens: compacted.afterTokens } : {},
13661
+ ...compacted.savedTokens !== void 0 ? { savedTokens: compacted.savedTokens } : {}
13662
+ });
13594
13663
  };
13595
13664
  try {
13596
13665
  const compacted = await maybeAutoCompactLocalHistory({
@@ -13671,17 +13740,26 @@ async function runLocalAgentTurn(input) {
13671
13740
  let skipFinalAppend = false;
13672
13741
  let partialContent = "";
13673
13742
  const progressGuard = createLocalLoopProgressGuard(input.progressGuardConfig);
13743
+ let ephemeralSummary = null;
13744
+ const ephemeralDialogId = `ephemeral-${crypto.randomUUID()}`;
13745
+ const compactionAdapter = input.continueDialogId ? input.adapter : {
13746
+ ...input.adapter,
13747
+ loadDialogSummary: async () => ephemeralSummary,
13748
+ saveDialogSummary: async (summaryInput) => {
13749
+ ephemeralSummary = summaryInput;
13750
+ }
13751
+ };
13752
+ const compactionDialogId = input.continueDialogId ?? ephemeralDialogId;
13674
13753
  const maybeCompactInLoop = async () => {
13675
- if (!input.continueDialogId) return;
13676
- if (!contextUsage) return;
13677
- const inputTokens = normalizeUsage(contextUsage).input_tokens;
13678
- if (!inputTokens || inputTokens <= 0) return;
13679
- const ratio = Math.min(1, inputTokens / contextWindow);
13680
- if (ratio < compressionTriggerRatio) return;
13754
+ const inputTokens = contextUsage ? normalizeUsage(contextUsage).input_tokens : 0;
13755
+ const ratio = inputTokens > 0 ? Math.min(1, inputTokens / contextWindow) : void 0;
13756
+ if (ratio !== void 0 && ratio < compressionTriggerRatio * 0.85) {
13757
+ return;
13758
+ }
13681
13759
  try {
13682
13760
  const compacted = await maybeAutoCompactLocalHistory({
13683
- adapter: input.adapter,
13684
- dialogId: input.continueDialogId,
13761
+ adapter: compactionAdapter,
13762
+ dialogId: compactionDialogId,
13685
13763
  // canonical 坐标:store 全量历史 + 本轮消息的「持久化形态」
13686
13764
  // (applyPersistedTurnInput 会把首条 user 消息换成 paste 展开形态)。
13687
13765
  // 锚点与 sourceHash 都必须按持久化形态计算——否则下轮从 store
@@ -13697,7 +13775,7 @@ async function runLocalAgentTurn(input) {
13697
13775
  model: agentConfig.model,
13698
13776
  resolveProvider: resolveProviderOnce,
13699
13777
  contextWindow,
13700
- realContextUsagePercent: ratio
13778
+ ...ratio !== void 0 ? { realContextUsagePercent: ratio } : {}
13701
13779
  });
13702
13780
  if (compacted.usage) {
13703
13781
  compactionUsage = addOutOfBandUsage(compactionUsage, compacted.usage);
@@ -8,7 +8,7 @@ import {
8
8
  import {
9
9
  deriveCredentialGroup,
10
10
  toSafeAgentSummary
11
- } from "./chunk-IAO6JBYW.js";
11
+ } from "./chunk-RG6JBBX5.js";
12
12
  import {
13
13
  PUBLIC_AGENT_KEY_PREFIX,
14
14
  isOwnedAgentKey,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isAgentRunTerminalStatus
3
- } from "./chunk-NTW5GWDM.js";
3
+ } from "./chunk-3VNWWVKB.js";
4
4
  import {
5
5
  isCompiledBinary,
6
6
  resolveCliEntrypointPath
@@ -11,6 +11,60 @@ import { homedir as nodeHomedir } from "node:os";
11
11
  import { dirname, isAbsolute, join, resolve } from "node:path";
12
12
  import * as nodeFs from "node:fs";
13
13
  import { execFileSync as nodeExecFileSync, spawn as nodeSpawn } from "node:child_process";
14
+
15
+ // packages/ai/tools/agent/runFailureClass.ts
16
+ var RATE_LIMIT_PATTERN = /429|rate.?limit|quota|insufficient.?balance|UPSTREAM_402|cooling|冷却/i;
17
+ var PROVIDER_ERROR_PATTERN = /provider|upstream|5\d\d|bad.?gateway|service.?unavailable|overloaded/i;
18
+ var MALFORMED_PATTERN = /MALFORMED_FUNCTION_CALL|malformed|invalid.?function.?call|invalid.?tool.?call/i;
19
+ var STALLED_PATTERN = /stall|no.?progress|repetition|stagnant|无进展|卡死/i;
20
+ var TOOL_ERROR_PATTERN = /tool.?error|tool.?fail|工具/i;
21
+ function classifyRunFailure(input) {
22
+ const status = typeof input.status === "string" ? input.status : "";
23
+ if (status === "done" || status === "killed" || status === "cancelled") {
24
+ return void 0;
25
+ }
26
+ const reason = typeof input.failureReason === "string" ? input.failureReason : "";
27
+ const message = typeof input.errorMessage === "string" ? input.errorMessage : "";
28
+ switch (reason) {
29
+ case "provider_rate_limited":
30
+ return { failureClass: "rate_limited", retryable: true };
31
+ case "provider_error":
32
+ return MALFORMED_PATTERN.test(message) ? { failureClass: "provider_error", retryable: false } : { failureClass: "provider_error", retryable: true };
33
+ case "stalled":
34
+ return { failureClass: "stalled", retryable: false };
35
+ case "tool_error":
36
+ return { failureClass: "tool_error", retryable: false };
37
+ case "config_unresolved":
38
+ return { failureClass: "unknown", retryable: false };
39
+ case "cancelled":
40
+ return void 0;
41
+ default:
42
+ break;
43
+ }
44
+ if (message) {
45
+ if (RATE_LIMIT_PATTERN.test(message)) {
46
+ return { failureClass: "rate_limited", retryable: true };
47
+ }
48
+ if (MALFORMED_PATTERN.test(message)) {
49
+ return { failureClass: "provider_error", retryable: false };
50
+ }
51
+ if (STALLED_PATTERN.test(message)) {
52
+ return { failureClass: "stalled", retryable: false };
53
+ }
54
+ if (TOOL_ERROR_PATTERN.test(message)) {
55
+ return { failureClass: "tool_error", retryable: false };
56
+ }
57
+ if (PROVIDER_ERROR_PATTERN.test(message)) {
58
+ return { failureClass: "provider_error", retryable: true };
59
+ }
60
+ }
61
+ if (status === "failed" || status === "timeout" || status === "orphaned") {
62
+ return { failureClass: "unknown", retryable: false };
63
+ }
64
+ return void 0;
65
+ }
66
+
67
+ // packages/cli/agentRunControl.ts
14
68
  var RUN_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
15
69
  "done",
16
70
  "failed",
@@ -794,6 +848,7 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
794
848
  logPath,
795
849
  queuePath,
796
850
  batchId,
851
+ ...typeof input.credentialGroup === "string" && input.credentialGroup.trim() ? { credentialGroup: input.credentialGroup.trim() } : {},
797
852
  ...typeof input.parentDialogId === "string" && input.parentDialogId.trim() ? { parentDialogId: input.parentDialogId.trim() } : {},
798
853
  ...dodCommands && dodCommands.length > 0 ? { dodCommands } : {},
799
854
  ...spawnHead ? { spawnHead } : {},
@@ -925,6 +980,15 @@ function transitionRunToTerminal(runId, update, deps = {}, options = {}) {
925
980
  } else if (update.status === "killed") {
926
981
  record2.failureReason = "cancelled";
927
982
  }
983
+ const classification = classifyRunFailure({
984
+ status: update.status,
985
+ failureReason: record2.failureReason,
986
+ errorMessage: update.note ?? record2.note
987
+ });
988
+ if (classification) {
989
+ record2.failureClass = classification.failureClass;
990
+ record2.retryable = classification.retryable;
991
+ }
928
992
  const resolvedToolCount = typeof update.toolCallCount === "number" ? update.toolCallCount : record2.activity?.counters?.toolCalls;
929
993
  if (typeof resolvedToolCount === "number") {
930
994
  record2.toolCallCount = resolvedToolCount;
@@ -1044,6 +1108,15 @@ function checkStaleRun(runId, deps = {}) {
1044
1108
  const at = now().toISOString();
1045
1109
  latest.status = "orphaned";
1046
1110
  latest.note = pidReused ? "orphaned: process gone (pid reused by another process)" : "orphaned: process gone without writing terminal status";
1111
+ const orphanClassification = classifyRunFailure({
1112
+ status: "orphaned",
1113
+ failureReason: latest.failureReason,
1114
+ errorMessage: latest.note
1115
+ });
1116
+ if (orphanClassification) {
1117
+ latest.failureClass = orphanClassification.failureClass;
1118
+ latest.retryable = orphanClassification.retryable;
1119
+ }
1047
1120
  latest.endedAt = at;
1048
1121
  latest.reconciledAt = at;
1049
1122
  latest.pid = void 0;
@@ -1259,6 +1332,18 @@ function printStatusOnce(record, deps) {
1259
1332
  }
1260
1333
  if (record.note) deps.output.write(`note: ${record.note}
1261
1334
  `);
1335
+ if (record.failureReason) deps.output.write(`failure: ${record.failureReason}
1336
+ `);
1337
+ if (record.failureClass) {
1338
+ deps.output.write(
1339
+ `class: ${record.failureClass}${typeof record.retryable === "boolean" ? ` (retryable=${record.retryable})` : ""}
1340
+ `
1341
+ );
1342
+ }
1343
+ if (record.credentialGroup) {
1344
+ deps.output.write(`credGroup: ${record.credentialGroup}
1345
+ `);
1346
+ }
1262
1347
  const activitySummary = formatActivitySummary(record.activity);
1263
1348
  if (activitySummary) deps.output.write(`${activitySummary}
1264
1349
  `);
@@ -14,7 +14,7 @@ import {
14
14
  } from "./chunk-AGGIDPCZ.js";
15
15
  import {
16
16
  runLlm
17
- } from "./chunk-ZLR5JN3E.js";
17
+ } from "./chunk-RSJECD7I.js";
18
18
  import {
19
19
  cleanupCliSessionForDialog
20
20
  } from "./chunk-TOP2VXOR.js";
@@ -55,7 +55,7 @@ import {
55
55
  getModelInfo,
56
56
  normalizeUsage,
57
57
  resolveAutoExecutionProfile
58
- } from "./chunk-JAXOVNM4.js";
58
+ } from "./chunk-NEDZDG3M.js";
59
59
  import {
60
60
  COMPACTION_SUMMARY_SYSTEM_PROMPT,
61
61
  buildCompactionMetricsFromPlan,
@@ -66,7 +66,7 @@ import {
66
66
  normalizeAssistantContentBuffer,
67
67
  planCompression,
68
68
  serializeMessageContent
69
- } from "./chunk-WADCY6G6.js";
69
+ } from "./chunk-ASQYTZTR.js";
70
70
  import {
71
71
  findModelConfig,
72
72
  getModelConfig
@@ -17470,7 +17470,7 @@ var messageSlice = createSliceWithThunks({
17470
17470
  runtimeOptions: args.runtimeOptions
17471
17471
  });
17472
17472
  if (agentKeyToUse) {
17473
- const { streamAgentChatTurn } = await import("./agentSlice-ZYT2OUR3.js");
17473
+ const { streamAgentChatTurn } = await import("./agentSlice-SK47GTN7.js");
17474
17474
  await dispatch(
17475
17475
  streamAgentChatTurn({
17476
17476
  agentKey: agentKeyToUse,
@@ -18606,7 +18606,7 @@ var deleteDialogThunk = async (payload, thunkApi) => {
18606
18606
  }
18607
18607
  if (isCurrentDialog) {
18608
18608
  await thunkApi.dispatch(resetMsgs());
18609
- const { clearPendingAttachments: clearPendingAttachments2 } = await import("./dialogSlice-3YH242HS.js");
18609
+ const { clearPendingAttachments: clearPendingAttachments2 } = await import("./dialogSlice-TMSHUGEM.js");
18610
18610
  dispatch(clearPendingAttachments2());
18611
18611
  }
18612
18612
  return { dialogKey, isCurrentDialog, attachmentPlan };
@@ -18614,15 +18614,15 @@ var deleteDialogThunk = async (payload, thunkApi) => {
18614
18614
 
18615
18615
  // packages/chat/dialog/dialogSlice.ts
18616
18616
  var runCreateDialogAction = async (args, thunkApi) => {
18617
- const { createDialogAction } = await import("./createDialogAction-XZPLHD5G.js");
18617
+ const { createDialogAction } = await import("./createDialogAction-4H52MURR.js");
18618
18618
  return createDialogAction(args, thunkApi);
18619
18619
  };
18620
18620
  var runCreateAgentAutomationAction = async (args, thunkApi) => {
18621
- const { createAgentAutomationAction } = await import("./createAgentAutomationAction-N27SYTLU.js");
18621
+ const { createAgentAutomationAction } = await import("./createAgentAutomationAction-HFLPOBWQ.js");
18622
18622
  return createAgentAutomationAction(args, thunkApi);
18623
18623
  };
18624
18624
  var runUpdateDialogTitleAction = async (args, thunkApi) => {
18625
- const { updateDialogTitleAction } = await import("./updateDialogTitleAction-RTADGV7A.js");
18625
+ const { updateDialogTitleAction } = await import("./updateDialogTitleAction-XI73NQMU.js");
18626
18626
  return updateDialogTitleAction(args, thunkApi);
18627
18627
  };
18628
18628
  var runAddDialogAgentAction = async (args, thunkApi) => {
@@ -18646,7 +18646,7 @@ var runSetDialogExtraReferencesAction = async (args, thunkApi) => {
18646
18646
  return setDialogExtraReferencesAction(args, thunkApi);
18647
18647
  };
18648
18648
  var runHandleSendMessageAction = async (args, thunkApi) => {
18649
- const { handleSendMessageAction } = await import("./handleSendMessageAction-KJO2QDBM.js");
18649
+ const { handleSendMessageAction } = await import("./handleSendMessageAction-4LGNXH6T.js");
18650
18650
  return handleSendMessageAction(args, thunkApi);
18651
18651
  };
18652
18652
  function clearDialogState() {
@@ -18659,7 +18659,7 @@ var createPageAndAddReference = createAsyncThunk(
18659
18659
  async (payload, { dispatch, getState, rejectWithValue }) => {
18660
18660
  const { slateData, jsonData, title, type, fileId, groupId, dialogKey } = payload;
18661
18661
  try {
18662
- const { createDocState } = await import("./docStore-YSZRNUUD.js");
18662
+ const { createDocState } = await import("./docStore-OBC5QOW7.js");
18663
18663
  const pageKey = await createDocState(
18664
18664
  { slateData, title },
18665
18665
  { dispatch, getState }