@code-yeongyu/senpi 2026.5.24 → 2026.5.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/dist/cli/args.d.ts +0 -6
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +15 -2
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +4 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +116 -80
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +18 -24
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/streaming-render.d.ts.map +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/streaming-render.js +4 -2
- package/dist/core/extensions/builtin/gpt-apply-patch/streaming-render.js.map +1 -1
- package/dist/core/extensions/builtin/session-observer/overlay.d.ts.map +1 -1
- package/dist/core/extensions/builtin/session-observer/overlay.js +0 -5
- package/dist/core/extensions/builtin/session-observer/overlay.js.map +1 -1
- package/dist/core/extensions/builtin/session-observer/scanner.d.ts.map +1 -1
- package/dist/core/extensions/builtin/session-observer/scanner.js +2 -0
- package/dist/core/extensions/builtin/session-observer/scanner.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +21 -9
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/output-guard.d.ts +1 -0
- package/dist/core/output-guard.d.ts.map +1 -1
- package/dist/core/output-guard.js +52 -22
- package/dist/core/output-guard.js.map +1 -1
- package/dist/core/session-work-barrier.d.ts +9 -0
- package/dist/core/session-work-barrier.d.ts.map +1 -0
- package/dist/core/session-work-barrier.js +50 -0
- package/dist/core/session-work-barrier.js.map +1 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +0 -15
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +1 -1
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +6 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +3 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +64 -7
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +15 -3
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/docs/settings.md +3 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js +18 -24
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +46 -29
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +5 -2
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js +2 -17
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +40 -55
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/input.js +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/components/input.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +7 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +12 -2
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/slash-command-autocomplete.d.ts +3 -0
- package/node_modules/@earendil-works/pi-tui/dist/slash-command-autocomplete.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/slash-command-autocomplete.js +38 -0
- package/node_modules/@earendil-works/pi-tui/dist/slash-command-autocomplete.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +4 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +5 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.js +66 -14
- package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/npm-shrinkwrap.json +13 -13
- package/package.json +6 -7
- package/dist/modes/neo-mode.d.ts +0 -43
- package/dist/modes/neo-mode.d.ts.map +0 -1
- package/dist/modes/neo-mode.js +0 -142
- package/dist/modes/neo-mode.js.map +0 -1
- package/dist/neo-tui-bin/senpi-neo-tui-linux-x64 +0 -0
|
@@ -33,6 +33,7 @@ import { filterContextExcludedMessages } from "./messages.js";
|
|
|
33
33
|
import { getModelNarrowingPatterns, resolveModelScope } from "./model-resolver.js";
|
|
34
34
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
35
35
|
import { buildSessionContext, CURRENT_SESSION_VERSION, getLatestCompactionEntry, } from "./session-manager.js";
|
|
36
|
+
import { SessionWorkBarrier } from "./session-work-barrier.js";
|
|
36
37
|
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
37
38
|
import { getSupportedThinkingLevels, supportsMax, supportsXhigh } from "./thinking-levels.js";
|
|
38
39
|
import { createLocalBashOperations } from "./tools/bash.js";
|
|
@@ -88,6 +89,7 @@ export class AgentSession {
|
|
|
88
89
|
// Compaction state
|
|
89
90
|
_compactionAbortController = undefined;
|
|
90
91
|
_autoCompactionAbortController = undefined;
|
|
92
|
+
_sessionWorkBarrier = new SessionWorkBarrier();
|
|
91
93
|
_overflowRecoveryAttempted = false;
|
|
92
94
|
_messageRevision = 0;
|
|
93
95
|
// Branch summarization state
|
|
@@ -275,6 +277,9 @@ export class AgentSession {
|
|
|
275
277
|
getMessageRevision() {
|
|
276
278
|
return this._messageRevision;
|
|
277
279
|
}
|
|
280
|
+
async _waitForSettledSessionWork() {
|
|
281
|
+
await this._sessionWorkBarrier.waitForSettled(() => this._agentEventQueue);
|
|
282
|
+
}
|
|
278
283
|
_modelSelectionChangesContext(previousModel, nextModel) {
|
|
279
284
|
if (!modelsAreEqual(previousModel, nextModel))
|
|
280
285
|
return true;
|
|
@@ -807,6 +812,11 @@ export class AgentSession {
|
|
|
807
812
|
if (userAbortPromise) {
|
|
808
813
|
await userAbortPromise;
|
|
809
814
|
}
|
|
815
|
+
const shouldWaitForSessionWork = options?.source !== "extension";
|
|
816
|
+
if (shouldWaitForSessionWork &&
|
|
817
|
+
(!this.isStreaming || this.isCompacting || this._sessionWorkBarrier.hasActiveWork)) {
|
|
818
|
+
await this._waitForSettledSessionWork();
|
|
819
|
+
}
|
|
810
820
|
const expandPromptTemplates = options?.expandPromptTemplates ?? true;
|
|
811
821
|
const preflightResult = options?.preflightResult;
|
|
812
822
|
let messages;
|
|
@@ -926,7 +936,12 @@ export class AgentSession {
|
|
|
926
936
|
preflightResult?.(true);
|
|
927
937
|
await this.agent.prompt(messages);
|
|
928
938
|
await this.waitForRetry();
|
|
929
|
-
|
|
939
|
+
if (shouldWaitForSessionWork) {
|
|
940
|
+
await this._waitForSettledSessionWork();
|
|
941
|
+
}
|
|
942
|
+
else {
|
|
943
|
+
await this.agent.waitForIdle();
|
|
944
|
+
}
|
|
930
945
|
}
|
|
931
946
|
/**
|
|
932
947
|
* Try to execute an extension command. Returns true if command was found and executed.
|
|
@@ -1532,83 +1547,89 @@ export class AgentSession {
|
|
|
1532
1547
|
this._compactionAbortController = undefined;
|
|
1533
1548
|
}
|
|
1534
1549
|
async _executeCompaction(request) {
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
if (!
|
|
1550
|
-
const
|
|
1551
|
-
if (
|
|
1552
|
-
|
|
1550
|
+
const finishCompactionWork = this._sessionWorkBarrier.begin();
|
|
1551
|
+
try {
|
|
1552
|
+
if (!this.model) {
|
|
1553
|
+
throw new Error(formatNoModelSelectedMessage());
|
|
1554
|
+
}
|
|
1555
|
+
const requestId = randomUUID();
|
|
1556
|
+
const pathEntries = this.sessionManager.getBranch();
|
|
1557
|
+
const settings = this.settingsManager.getCompactionSettings();
|
|
1558
|
+
const signal = this._compactionAbortController?.signal ?? this._autoCompactionAbortController?.signal;
|
|
1559
|
+
if (!signal) {
|
|
1560
|
+
throw new Error("Compaction abort controller unavailable");
|
|
1561
|
+
}
|
|
1562
|
+
let compactionResult = request.precomputed;
|
|
1563
|
+
let fromExtension = request.precomputed !== undefined;
|
|
1564
|
+
if (!compactionResult) {
|
|
1565
|
+
const preparation = prepareCompaction(pathEntries, settings);
|
|
1566
|
+
if (!preparation) {
|
|
1567
|
+
const lastEntry = pathEntries[pathEntries.length - 1];
|
|
1568
|
+
if (lastEntry?.type === "compaction") {
|
|
1569
|
+
throw new Error("Already compacted");
|
|
1570
|
+
}
|
|
1571
|
+
throw new Error("Nothing to compact (session too small)");
|
|
1553
1572
|
}
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1573
|
+
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
1574
|
+
const extensionResult = (await this._extensionRunner.emit({
|
|
1575
|
+
type: "session_before_compact",
|
|
1576
|
+
reason: request.reason,
|
|
1577
|
+
willRetry: request.willRetry,
|
|
1578
|
+
requestId,
|
|
1579
|
+
preparation,
|
|
1580
|
+
branchEntries: pathEntries,
|
|
1581
|
+
customInstructions: request.customInstructions,
|
|
1582
|
+
signal,
|
|
1583
|
+
}));
|
|
1584
|
+
if (extensionResult?.cancel) {
|
|
1585
|
+
return await this._rejectCompaction(request, requestId, "cancelled-by-extension", true);
|
|
1586
|
+
}
|
|
1587
|
+
if (extensionResult?.compaction) {
|
|
1588
|
+
compactionResult = extensionResult.compaction;
|
|
1589
|
+
fromExtension = true;
|
|
1590
|
+
}
|
|
1569
1591
|
}
|
|
1570
|
-
if (
|
|
1571
|
-
|
|
1572
|
-
|
|
1592
|
+
if (!compactionResult) {
|
|
1593
|
+
const { apiKey, headers, extraBody } = await this._getCompactionRequestAuth(this.model);
|
|
1594
|
+
compactionResult = await compact(preparation, this.model, apiKey, headers, request.customInstructions, signal, extraBody, this.thinkingLevel, this.agent.streamFn);
|
|
1573
1595
|
}
|
|
1574
1596
|
}
|
|
1575
|
-
if (
|
|
1576
|
-
|
|
1577
|
-
compactionResult = await compact(preparation, this.model, apiKey, headers, request.customInstructions, signal, extraBody, this.thinkingLevel, this.agent.streamFn);
|
|
1597
|
+
if (signal.aborted) {
|
|
1598
|
+
throw new Error("Compaction cancelled");
|
|
1578
1599
|
}
|
|
1600
|
+
if (this._wouldCompactionOverflow(pathEntries, compactionResult, fromExtension)) {
|
|
1601
|
+
return await this._rejectCompaction(request, requestId, "would-overflow", false);
|
|
1602
|
+
}
|
|
1603
|
+
const compactionEntryId = this.sessionManager.appendCompaction(compactionResult.summary, compactionResult.firstKeptEntryId, compactionResult.tokensBefore, compactionResult.details, fromExtension);
|
|
1604
|
+
const savedEntry = this.sessionManager.getEntry(compactionEntryId);
|
|
1605
|
+
if (!savedEntry || savedEntry.type !== "compaction") {
|
|
1606
|
+
throw new Error("Compaction entry was not saved");
|
|
1607
|
+
}
|
|
1608
|
+
const sessionContext = this.sessionManager.buildSessionContext();
|
|
1609
|
+
this.agent.state.messages = sessionContext.messages;
|
|
1610
|
+
this._incrementMessageRevision();
|
|
1611
|
+
await this._extensionRunner.emit({
|
|
1612
|
+
type: "session_compact",
|
|
1613
|
+
reason: request.reason,
|
|
1614
|
+
requestId,
|
|
1615
|
+
accepted: true,
|
|
1616
|
+
compactionEntry: savedEntry,
|
|
1617
|
+
fromExtension,
|
|
1618
|
+
});
|
|
1619
|
+
this._emit({
|
|
1620
|
+
type: "compaction_end",
|
|
1621
|
+
reason: request.reason,
|
|
1622
|
+
result: compactionResult,
|
|
1623
|
+
aborted: false,
|
|
1624
|
+
willRetry: request.willRetry,
|
|
1625
|
+
requestId,
|
|
1626
|
+
accepted: true,
|
|
1627
|
+
});
|
|
1628
|
+
return { accepted: true, requestId, result: compactionResult, compactionEntry: savedEntry, fromExtension };
|
|
1579
1629
|
}
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
}
|
|
1583
|
-
if (this._wouldCompactionOverflow(pathEntries, compactionResult, fromExtension)) {
|
|
1584
|
-
return await this._rejectCompaction(request, requestId, "would-overflow", false);
|
|
1585
|
-
}
|
|
1586
|
-
const compactionEntryId = this.sessionManager.appendCompaction(compactionResult.summary, compactionResult.firstKeptEntryId, compactionResult.tokensBefore, compactionResult.details, fromExtension);
|
|
1587
|
-
const savedEntry = this.sessionManager.getEntry(compactionEntryId);
|
|
1588
|
-
if (!savedEntry || savedEntry.type !== "compaction") {
|
|
1589
|
-
throw new Error("Compaction entry was not saved");
|
|
1630
|
+
finally {
|
|
1631
|
+
finishCompactionWork();
|
|
1590
1632
|
}
|
|
1591
|
-
const sessionContext = this.sessionManager.buildSessionContext();
|
|
1592
|
-
this.agent.state.messages = sessionContext.messages;
|
|
1593
|
-
this._incrementMessageRevision();
|
|
1594
|
-
await this._extensionRunner.emit({
|
|
1595
|
-
type: "session_compact",
|
|
1596
|
-
reason: request.reason,
|
|
1597
|
-
requestId,
|
|
1598
|
-
accepted: true,
|
|
1599
|
-
compactionEntry: savedEntry,
|
|
1600
|
-
fromExtension,
|
|
1601
|
-
});
|
|
1602
|
-
this._emit({
|
|
1603
|
-
type: "compaction_end",
|
|
1604
|
-
reason: request.reason,
|
|
1605
|
-
result: compactionResult,
|
|
1606
|
-
aborted: false,
|
|
1607
|
-
willRetry: request.willRetry,
|
|
1608
|
-
requestId,
|
|
1609
|
-
accepted: true,
|
|
1610
|
-
});
|
|
1611
|
-
return { accepted: true, requestId, result: compactionResult, compactionEntry: savedEntry, fromExtension };
|
|
1612
1633
|
}
|
|
1613
1634
|
_wouldCompactionOverflow(pathEntries, compactionResult, fromExtension) {
|
|
1614
1635
|
const currentLeaf = pathEntries[pathEntries.length - 1];
|
|
@@ -1792,10 +1813,24 @@ export class AgentSession {
|
|
|
1792
1813
|
this._compactionAbortController = undefined;
|
|
1793
1814
|
}
|
|
1794
1815
|
}
|
|
1816
|
+
async _continueAgentAfterCurrentRun() {
|
|
1817
|
+
await this.agent.waitForIdle();
|
|
1818
|
+
try {
|
|
1819
|
+
await this.agent.continue();
|
|
1820
|
+
return true;
|
|
1821
|
+
}
|
|
1822
|
+
catch (error) {
|
|
1823
|
+
if (error instanceof Error) {
|
|
1824
|
+
return false;
|
|
1825
|
+
}
|
|
1826
|
+
throw error;
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1795
1829
|
/**
|
|
1796
1830
|
* Internal: Run auto-compaction with events.
|
|
1797
1831
|
*/
|
|
1798
1832
|
async _runAutoCompaction(reason, willRetry) {
|
|
1833
|
+
const finishCompactionWork = this._sessionWorkBarrier.begin();
|
|
1799
1834
|
this._emit({ type: "compaction_start", reason });
|
|
1800
1835
|
this._autoCompactionAbortController = new AbortController();
|
|
1801
1836
|
try {
|
|
@@ -1850,17 +1885,12 @@ export class AgentSession {
|
|
|
1850
1885
|
this.agent.state.messages = messages.slice(0, -1);
|
|
1851
1886
|
this._incrementMessageRevision();
|
|
1852
1887
|
}
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
return
|
|
1888
|
+
return await this._continueAgentAfterCurrentRun();
|
|
1889
|
+
}
|
|
1890
|
+
else if (this.pendingMessageCount > 0) {
|
|
1891
|
+
return await this._continueAgentAfterCurrentRun();
|
|
1857
1892
|
}
|
|
1858
1893
|
else if (this.agent.hasQueuedMessages()) {
|
|
1859
|
-
// Auto-compaction can complete while follow-up/steering/custom messages are waiting.
|
|
1860
|
-
// Kick the loop so queued messages are actually delivered.
|
|
1861
|
-
setTimeout(() => {
|
|
1862
|
-
this.agent.continue().catch(() => { });
|
|
1863
|
-
}, 100);
|
|
1864
1894
|
return true;
|
|
1865
1895
|
}
|
|
1866
1896
|
return false;
|
|
@@ -1886,6 +1916,7 @@ export class AgentSession {
|
|
|
1886
1916
|
}
|
|
1887
1917
|
finally {
|
|
1888
1918
|
this._autoCompactionAbortController = undefined;
|
|
1919
|
+
finishCompactionWork();
|
|
1889
1920
|
}
|
|
1890
1921
|
}
|
|
1891
1922
|
/**
|
|
@@ -2250,6 +2281,9 @@ export class AgentSession {
|
|
|
2250
2281
|
// =========================================================================
|
|
2251
2282
|
// Auto-Retry
|
|
2252
2283
|
// =========================================================================
|
|
2284
|
+
_isNonRetryableProviderLimitError(errorMessage) {
|
|
2285
|
+
return /GoUsageLimitError|FreeUsageLimitError|Monthly usage limit reached|available balance|insufficient_quota|out of budget|quota exceeded|billing/i.test(errorMessage);
|
|
2286
|
+
}
|
|
2253
2287
|
/**
|
|
2254
2288
|
* Check if an error is retryable (overloaded, rate limit, server errors).
|
|
2255
2289
|
* Context overflow errors are NOT retryable (handled by compaction instead).
|
|
@@ -2267,6 +2301,8 @@ export class AgentSession {
|
|
|
2267
2301
|
}
|
|
2268
2302
|
if (message.stopReason !== "error")
|
|
2269
2303
|
return false;
|
|
2304
|
+
if (this._isNonRetryableProviderLimitError(err))
|
|
2305
|
+
return false;
|
|
2270
2306
|
// Match: overloaded_error, provider returned error, rate limit, 429, 500, 502, 503, 504, service unavailable, network/connection errors (including connection lost), WebSocket transport closes/errors, fetch failed, premature stream endings, HTTP/2 closed before response, terminated, retry delay exceeded
|
|
2271
2307
|
return /overloaded|provider.?returned.?error|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|network.?error|connection.?error|connection.?refused|connection.?lost|websocket.?closed|websocket.?error|other side closed|fetch failed|upstream.?connect|reset before headers|socket hang up|ended without|stream ended before message_stop|http2 request did not get a response|timed? out|timeout|terminated|retry delay/i.test(err);
|
|
2272
2308
|
}
|