@code-yeongyu/senpi 2026.5.14 → 2026.5.15-3
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 +1110 -1175
- package/README.md +1 -2
- package/dist/core/agent-session.d.ts +9 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +109 -7
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/dynamic-prompt/verification.d.ts +31 -0
- package/dist/core/dynamic-prompt/verification.d.ts.map +1 -1
- package/dist/core/dynamic-prompt/verification.js +41 -0
- package/dist/core/dynamic-prompt/verification.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/context-reduction.d.ts +97 -0
- package/dist/core/extensions/builtin/compaction/context-reduction.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/context-reduction.js +420 -0
- package/dist/core/extensions/builtin/compaction/context-reduction.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +168 -31
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +197 -0
- package/dist/core/extensions/builtin/compaction/openai-remote.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/openai-remote.js +690 -0
- package/dist/core/extensions/builtin/compaction/openai-remote.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/prompts.d.ts +3 -3
- package/dist/core/extensions/builtin/compaction/prompts.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/prompts.js +0 -22
- package/dist/core/extensions/builtin/compaction/prompts.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts +4 -0
- package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js +48 -0
- package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative.d.ts +3 -1
- package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +82 -33
- package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts +8 -0
- package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/todo-bridge.js +12 -6
- package/dist/core/extensions/builtin/compaction/todo-bridge.js.map +1 -1
- package/dist/core/extensions/builtin/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/index.js +0 -2
- package/dist/core/extensions/builtin/index.js.map +1 -1
- package/dist/core/extensions/builtin/openai-web-search/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/openai-web-search/index.js +26 -1
- package/dist/core/extensions/builtin/openai-web-search/index.js.map +1 -1
- package/dist/core/extensions/builtin/permission-system/prompt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/prompt.js +0 -5
- package/dist/core/extensions/builtin/permission-system/prompt.js.map +1 -1
- package/dist/core/extensions/builtin/system-messages.d.ts +7 -7
- package/dist/core/extensions/builtin/system-messages.d.ts.map +1 -1
- package/dist/core/extensions/builtin/system-messages.js +10 -10
- package/dist/core/extensions/builtin/system-messages.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts +1 -1
- package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/continuation/prompt.js +1 -1
- package/dist/core/extensions/builtin/todotools/continuation/prompt.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/state.d.ts +1 -1
- package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/state.js +1 -1
- package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/system-messages.d.ts +3 -3
- package/dist/core/extensions/builtin/todotools/system-messages.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/system-messages.js +6 -6
- package/dist/core/extensions/builtin/todotools/system-messages.js.map +1 -1
- package/dist/core/extensions/builtin/tool-pair-guard/index.d.ts +1 -1
- package/dist/core/extensions/builtin/tool-pair-guard/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/tool-pair-guard/index.js +8 -4
- package/dist/core/extensions/builtin/tool-pair-guard/index.js.map +1 -1
- package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.d.ts +3 -0
- package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.js +89 -0
- package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.js.map +1 -0
- package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.d.ts +3 -0
- package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.js +122 -0
- package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.js.map +1 -0
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +2 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +18 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +22 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/messages.d.ts +3 -3
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +5 -10
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +1 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +7 -22
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +1 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +0 -5
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/thinking-levels.d.ts +6 -0
- package/dist/core/thinking-levels.d.ts.map +1 -0
- package/dist/core/thinking-levels.js +36 -0
- package/dist/core/thinking-levels.js.map +1 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +15 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +20 -2
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +3 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +8 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +137 -49
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/working-status.d.ts +15 -0
- package/dist/modes/interactive/working-status.d.ts.map +1 -0
- package/dist/modes/interactive/working-status.js +60 -0
- package/dist/modes/interactive/working-status.js.map +1 -0
- package/docs/extensions.md +0 -1
- package/docs/index.md +0 -1
- package/docs/sdk.md +0 -1
- package/docs/settings.md +1 -29
- package/docs/termux.md +2 -2
- package/docs/usage.md +1 -1
- package/examples/README.md +1 -1
- package/examples/extensions/README.md +0 -1
- package/examples/extensions/overlay-qa-tests.ts +1 -1
- package/package.json +4 -4
- package/dist/core/extensions/builtin/background-task/cancel-tool.d.ts +0 -10
- package/dist/core/extensions/builtin/background-task/cancel-tool.d.ts.map +0 -1
- package/dist/core/extensions/builtin/background-task/cancel-tool.js +0 -109
- package/dist/core/extensions/builtin/background-task/cancel-tool.js.map +0 -1
- package/dist/core/extensions/builtin/background-task/index.d.ts +0 -3
- package/dist/core/extensions/builtin/background-task/index.d.ts.map +0 -1
- package/dist/core/extensions/builtin/background-task/index.js +0 -207
- package/dist/core/extensions/builtin/background-task/index.js.map +0 -1
- package/dist/core/extensions/builtin/background-task/manager.d.ts +0 -17
- package/dist/core/extensions/builtin/background-task/manager.d.ts.map +0 -1
- package/dist/core/extensions/builtin/background-task/manager.js +0 -114
- package/dist/core/extensions/builtin/background-task/manager.js.map +0 -1
- package/dist/core/extensions/builtin/background-task/notification.d.ts +0 -22
- package/dist/core/extensions/builtin/background-task/notification.d.ts.map +0 -1
- package/dist/core/extensions/builtin/background-task/notification.js +0 -105
- package/dist/core/extensions/builtin/background-task/notification.js.map +0 -1
- package/dist/core/extensions/builtin/background-task/output-tool.d.ts +0 -11
- package/dist/core/extensions/builtin/background-task/output-tool.d.ts.map +0 -1
- package/dist/core/extensions/builtin/background-task/output-tool.js +0 -127
- package/dist/core/extensions/builtin/background-task/output-tool.js.map +0 -1
- package/dist/core/extensions/builtin/background-task/spawner.d.ts +0 -8
- package/dist/core/extensions/builtin/background-task/spawner.d.ts.map +0 -1
- package/dist/core/extensions/builtin/background-task/spawner.js +0 -207
- package/dist/core/extensions/builtin/background-task/spawner.js.map +0 -1
- package/dist/core/extensions/builtin/background-task/task-tool.d.ts +0 -20
- package/dist/core/extensions/builtin/background-task/task-tool.d.ts.map +0 -1
- package/dist/core/extensions/builtin/background-task/task-tool.js +0 -302
- package/dist/core/extensions/builtin/background-task/task-tool.js.map +0 -1
- package/dist/core/extensions/builtin/background-task/types.d.ts +0 -72
- package/dist/core/extensions/builtin/background-task/types.d.ts.map +0 -1
- package/dist/core/extensions/builtin/background-task/types.js +0 -32
- package/dist/core/extensions/builtin/background-task/types.js.map +0 -1
- package/docs/agents.md +0 -348
- package/examples/extensions/subagent/README.md +0 -172
- package/examples/extensions/subagent/agents/planner.md +0 -37
- package/examples/extensions/subagent/agents/reviewer.md +0 -35
- package/examples/extensions/subagent/agents/scout.md +0 -50
- package/examples/extensions/subagent/agents/worker.md +0 -24
- package/examples/extensions/subagent/agents.ts +0 -126
- package/examples/extensions/subagent/index.ts +0 -987
- package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
- package/examples/extensions/subagent/prompts/implement.md +0 -10
- package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import { randomUUID } from "node:crypto";
|
|
16
16
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
17
17
|
import { basename, dirname, resolve } from "node:path";
|
|
18
|
-
import { cleanupSessionResources,
|
|
18
|
+
import { cleanupSessionResources, isContextOverflow, modelsAreEqual, resetApiProviders } from "@earendil-works/pi-ai";
|
|
19
19
|
import { expandTildePath } from "../config.js";
|
|
20
20
|
import { theme } from "../modes/interactive/theme/theme.js";
|
|
21
21
|
import { stripFrontmatter } from "../utils/frontmatter.js";
|
|
@@ -34,6 +34,7 @@ import { getModelNarrowingPatterns, resolveModelScope } from "./model-resolver.j
|
|
|
34
34
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
35
35
|
import { buildSessionContext, CURRENT_SESSION_VERSION, getLatestCompactionEntry, } from "./session-manager.js";
|
|
36
36
|
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
37
|
+
import { getSupportedThinkingLevels, supportsMax, supportsXhigh } from "./thinking-levels.js";
|
|
37
38
|
import { createLocalBashOperations } from "./tools/bash.js";
|
|
38
39
|
import { createAllToolDefinitions } from "./tools/index.js";
|
|
39
40
|
import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
|
|
@@ -1377,8 +1378,11 @@ export class AgentSession {
|
|
|
1377
1378
|
if (options.expectedRevision !== undefined && options.expectedRevision !== this._messageRevision) {
|
|
1378
1379
|
return { applied: false, reason: "stale" };
|
|
1379
1380
|
}
|
|
1380
|
-
this._compactionAbortController
|
|
1381
|
-
|
|
1381
|
+
const ownsController = this._compactionAbortController === undefined;
|
|
1382
|
+
if (ownsController) {
|
|
1383
|
+
this._compactionAbortController = new AbortController();
|
|
1384
|
+
this._emit({ type: "compaction_start", reason: options.reason });
|
|
1385
|
+
}
|
|
1382
1386
|
try {
|
|
1383
1387
|
const execution = await this._executeCompaction({
|
|
1384
1388
|
reason: options.reason,
|
|
@@ -1407,6 +1411,38 @@ export class AgentSession {
|
|
|
1407
1411
|
this._compactionAbortController = undefined;
|
|
1408
1412
|
}
|
|
1409
1413
|
}
|
|
1414
|
+
_beginExtensionCompactionFeedback(reason) {
|
|
1415
|
+
if (!this._compactionAbortController) {
|
|
1416
|
+
this._compactionAbortController = new AbortController();
|
|
1417
|
+
this._emit({ type: "compaction_start", reason });
|
|
1418
|
+
}
|
|
1419
|
+
return this._compactionAbortController.signal;
|
|
1420
|
+
}
|
|
1421
|
+
_updateExtensionCompactionFeedback(options) {
|
|
1422
|
+
if (!this._compactionAbortController && !this._autoCompactionAbortController)
|
|
1423
|
+
return;
|
|
1424
|
+
this._emit({
|
|
1425
|
+
type: "compaction_progress",
|
|
1426
|
+
reason: options.reason,
|
|
1427
|
+
...(options.delta !== undefined ? { delta: options.delta } : {}),
|
|
1428
|
+
...(options.text !== undefined ? { text: options.text } : {}),
|
|
1429
|
+
});
|
|
1430
|
+
}
|
|
1431
|
+
_endExtensionCompactionFeedback(options) {
|
|
1432
|
+
const controller = this._compactionAbortController;
|
|
1433
|
+
if (!controller)
|
|
1434
|
+
return;
|
|
1435
|
+
const aborted = options.aborted ?? controller.signal.aborted;
|
|
1436
|
+
this._emit({
|
|
1437
|
+
type: "compaction_end",
|
|
1438
|
+
reason: options.reason,
|
|
1439
|
+
result: undefined,
|
|
1440
|
+
aborted,
|
|
1441
|
+
willRetry: false,
|
|
1442
|
+
errorMessage: aborted ? undefined : options.errorMessage,
|
|
1443
|
+
});
|
|
1444
|
+
this._compactionAbortController = undefined;
|
|
1445
|
+
}
|
|
1410
1446
|
async _executeCompaction(request) {
|
|
1411
1447
|
if (!this.model) {
|
|
1412
1448
|
throw new Error(formatNoModelSelectedMessage());
|
|
@@ -1635,14 +1671,20 @@ export class AgentSession {
|
|
|
1635
1671
|
this._emit({ type: "compaction_start", reason: "pre_prompt" });
|
|
1636
1672
|
this._compactionAbortController = new AbortController();
|
|
1637
1673
|
try {
|
|
1638
|
-
await this._executeCompaction({
|
|
1674
|
+
const execution = await this._executeCompaction({
|
|
1639
1675
|
reason: "pre_prompt",
|
|
1640
1676
|
willRetry: false,
|
|
1641
1677
|
lastAssistantMessage,
|
|
1642
1678
|
skipAbortedCheck,
|
|
1643
1679
|
});
|
|
1680
|
+
if (!execution.accepted && isContextOverflow(lastAssistantMessage, this.model?.contextWindow ?? 0)) {
|
|
1681
|
+
this._overflowRecoveryAttempted = false;
|
|
1682
|
+
}
|
|
1644
1683
|
}
|
|
1645
1684
|
catch (error) {
|
|
1685
|
+
if (isContextOverflow(lastAssistantMessage, this.model?.contextWindow ?? 0)) {
|
|
1686
|
+
this._overflowRecoveryAttempted = false;
|
|
1687
|
+
}
|
|
1646
1688
|
const errorMessage = error instanceof Error ? error.message : "compaction failed";
|
|
1647
1689
|
const aborted = errorMessage === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError");
|
|
1648
1690
|
this._emit({
|
|
@@ -1666,6 +1708,8 @@ export class AgentSession {
|
|
|
1666
1708
|
this._autoCompactionAbortController = new AbortController();
|
|
1667
1709
|
try {
|
|
1668
1710
|
if (!this.model) {
|
|
1711
|
+
if (reason === "overflow")
|
|
1712
|
+
this._overflowRecoveryAttempted = false;
|
|
1669
1713
|
this._emit({
|
|
1670
1714
|
type: "compaction_end",
|
|
1671
1715
|
reason,
|
|
@@ -1677,6 +1721,8 @@ export class AgentSession {
|
|
|
1677
1721
|
}
|
|
1678
1722
|
const authResult = await this._modelRegistry.getApiKeyAndHeaders(this.model);
|
|
1679
1723
|
if (!authResult.ok || !authResult.apiKey) {
|
|
1724
|
+
if (reason === "overflow")
|
|
1725
|
+
this._overflowRecoveryAttempted = false;
|
|
1680
1726
|
this._emit({
|
|
1681
1727
|
type: "compaction_end",
|
|
1682
1728
|
reason,
|
|
@@ -1688,6 +1734,8 @@ export class AgentSession {
|
|
|
1688
1734
|
}
|
|
1689
1735
|
const preparation = prepareCompaction(this.sessionManager.getBranch(), this.settingsManager.getCompactionSettings());
|
|
1690
1736
|
if (!preparation) {
|
|
1737
|
+
if (reason === "overflow")
|
|
1738
|
+
this._overflowRecoveryAttempted = false;
|
|
1691
1739
|
this._emit({
|
|
1692
1740
|
type: "compaction_end",
|
|
1693
1741
|
reason,
|
|
@@ -1699,6 +1747,8 @@ export class AgentSession {
|
|
|
1699
1747
|
}
|
|
1700
1748
|
const execution = await this._executeCompaction({ reason, willRetry });
|
|
1701
1749
|
if (!execution.accepted) {
|
|
1750
|
+
if (reason === "overflow")
|
|
1751
|
+
this._overflowRecoveryAttempted = false;
|
|
1702
1752
|
return;
|
|
1703
1753
|
}
|
|
1704
1754
|
if (willRetry) {
|
|
@@ -1721,6 +1771,8 @@ export class AgentSession {
|
|
|
1721
1771
|
}
|
|
1722
1772
|
}
|
|
1723
1773
|
catch (error) {
|
|
1774
|
+
if (reason === "overflow")
|
|
1775
|
+
this._overflowRecoveryAttempted = false;
|
|
1724
1776
|
const errorMessage = error instanceof Error ? error.message : "compaction failed";
|
|
1725
1777
|
const aborted = errorMessage === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError");
|
|
1726
1778
|
this._emit({
|
|
@@ -1943,6 +1995,9 @@ export class AgentSession {
|
|
|
1943
1995
|
}
|
|
1944
1996
|
})();
|
|
1945
1997
|
},
|
|
1998
|
+
beginCompaction: (options) => this._beginExtensionCompactionFeedback(options.reason),
|
|
1999
|
+
updateCompaction: (options) => this._updateExtensionCompactionFeedback(options),
|
|
2000
|
+
endCompaction: (options) => this._endExtensionCompactionFeedback(options),
|
|
1946
2001
|
getMessageRevision: () => this.getMessageRevision(),
|
|
1947
2002
|
applyCompaction: (precomputed, options) => this.applyCompaction(precomputed, options),
|
|
1948
2003
|
getSystemPrompt: () => this.systemPrompt,
|
|
@@ -2101,16 +2156,49 @@ export class AgentSession {
|
|
|
2101
2156
|
* Context overflow errors are NOT retryable (handled by compaction instead).
|
|
2102
2157
|
*/
|
|
2103
2158
|
_isRetryableError(message) {
|
|
2104
|
-
if (
|
|
2159
|
+
if (!message.errorMessage)
|
|
2105
2160
|
return false;
|
|
2106
2161
|
// Context overflow is handled by compaction, not retry
|
|
2107
2162
|
const contextWindow = this.model?.contextWindow ?? 0;
|
|
2108
2163
|
if (isContextOverflow(message, contextWindow))
|
|
2109
2164
|
return false;
|
|
2110
2165
|
const err = message.errorMessage;
|
|
2166
|
+
if (message.stopReason === "aborted") {
|
|
2167
|
+
return /timed? out|timeout/i.test(err);
|
|
2168
|
+
}
|
|
2169
|
+
if (message.stopReason !== "error")
|
|
2170
|
+
return false;
|
|
2111
2171
|
// 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
|
|
2112
2172
|
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);
|
|
2113
2173
|
}
|
|
2174
|
+
_getProviderRetryDelayMs(errorMessage) {
|
|
2175
|
+
const retryAfterMsMatch = errorMessage.match(/\bretry[-_ ]?after[-_ ]?ms\s*[:=]\s*(\d+(?:\.\d+)?)/i);
|
|
2176
|
+
if (retryAfterMsMatch) {
|
|
2177
|
+
const delayMs = Math.ceil(Number(retryAfterMsMatch[1]));
|
|
2178
|
+
return Number.isFinite(delayMs) && delayMs > 0 ? delayMs : undefined;
|
|
2179
|
+
}
|
|
2180
|
+
const retryAfterSecondsMatch = errorMessage.match(/\bretry[-_ ]?after\s*[:=]\s*(\d+(?:\.\d+)?)/i);
|
|
2181
|
+
if (retryAfterSecondsMatch) {
|
|
2182
|
+
const delayMs = Math.ceil(Number(retryAfterSecondsMatch[1]) * 1000);
|
|
2183
|
+
return Number.isFinite(delayMs) && delayMs > 0 ? delayMs : undefined;
|
|
2184
|
+
}
|
|
2185
|
+
const retryInMatch = errorMessage.match(/\b(?:retry|try again|wait)\s+(?:after|in)\s*(\d+(?:\.\d+)?)\s*(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m)\b/i);
|
|
2186
|
+
if (!retryInMatch) {
|
|
2187
|
+
return undefined;
|
|
2188
|
+
}
|
|
2189
|
+
const value = Number(retryInMatch[1]);
|
|
2190
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
2191
|
+
return undefined;
|
|
2192
|
+
}
|
|
2193
|
+
const unit = retryInMatch[2].toLowerCase();
|
|
2194
|
+
if (unit === "m" || unit.startsWith("min")) {
|
|
2195
|
+
return Math.ceil(value * 60_000);
|
|
2196
|
+
}
|
|
2197
|
+
if (unit.startsWith("s")) {
|
|
2198
|
+
return Math.ceil(value * 1000);
|
|
2199
|
+
}
|
|
2200
|
+
return Math.ceil(value);
|
|
2201
|
+
}
|
|
2114
2202
|
/**
|
|
2115
2203
|
* Handle retryable errors with exponential backoff.
|
|
2116
2204
|
* @returns true if retry was initiated, false if max retries exceeded or disabled
|
|
@@ -2141,13 +2229,27 @@ export class AgentSession {
|
|
|
2141
2229
|
this._resolveRetry(); // Resolve so waitForRetry() completes
|
|
2142
2230
|
return false;
|
|
2143
2231
|
}
|
|
2144
|
-
const
|
|
2232
|
+
const errorMessage = message.errorMessage || "Unknown error";
|
|
2233
|
+
const providerDelayMs = this._getProviderRetryDelayMs(errorMessage);
|
|
2234
|
+
const maxRetryDelayMs = this.settingsManager.getProviderRetrySettings().maxRetryDelayMs;
|
|
2235
|
+
if (providerDelayMs !== undefined && providerDelayMs > maxRetryDelayMs) {
|
|
2236
|
+
this._emit({
|
|
2237
|
+
type: "auto_retry_end",
|
|
2238
|
+
success: false,
|
|
2239
|
+
attempt: this._retryAttempt,
|
|
2240
|
+
finalError: `Provider requested retry delay ${providerDelayMs}ms, exceeding configured maximum ${maxRetryDelayMs}ms`,
|
|
2241
|
+
});
|
|
2242
|
+
this._retryAttempt = 0;
|
|
2243
|
+
this._resolveRetry();
|
|
2244
|
+
return false;
|
|
2245
|
+
}
|
|
2246
|
+
const delayMs = providerDelayMs ?? settings.baseDelayMs * 2 ** (this._retryAttempt - 1);
|
|
2145
2247
|
this._emit({
|
|
2146
2248
|
type: "auto_retry_start",
|
|
2147
2249
|
attempt: this._retryAttempt,
|
|
2148
2250
|
maxAttempts: settings.maxRetries,
|
|
2149
2251
|
delayMs,
|
|
2150
|
-
errorMessage
|
|
2252
|
+
errorMessage,
|
|
2151
2253
|
});
|
|
2152
2254
|
// Remove error message from agent state (keep in session for history)
|
|
2153
2255
|
const messages = this.agent.state.messages;
|