@code-yeongyu/senpi 2026.7.20-2 → 2026.7.20
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 +0 -18
- package/dist/core/agent-session.d.ts +0 -32
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +68 -368
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +2 -2
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +11 -39
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +8 -24
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/goal/command-registration.d.ts +2 -2
- package/dist/core/extensions/builtin/goal/command-registration.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/command-registration.js +4 -3
- package/dist/core/extensions/builtin/goal/command-registration.js.map +1 -1
- package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/index.js +27 -11
- package/dist/core/extensions/builtin/goal/index.js.map +1 -1
- package/dist/core/extensions/builtin/goal/tool-registration.d.ts +2 -2
- package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/tool-registration.js +3 -2
- package/dist/core/extensions/builtin/goal/tool-registration.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/nested-agents-md/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/nested-agents-md/index.js +1 -4
- package/dist/core/extensions/builtin/nested-agents-md/index.js.map +1 -1
- package/dist/core/extensions/builtin/rules/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/rules/index.js +1 -4
- package/dist/core/extensions/builtin/rules/index.js.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/renderers.d.ts.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/renderers.js +4 -13
- package/dist/core/extensions/builtin/websearch/websearch/renderers.js.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/search.d.ts +2 -3
- package/dist/core/extensions/builtin/websearch/websearch/search.d.ts.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/search.js +1 -2
- package/dist/core/extensions/builtin/websearch/websearch/search.js.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/tool.d.ts.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/tool.js +1 -17
- package/dist/core/extensions/builtin/websearch/websearch/tool.js.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/types.d.ts +0 -2
- package/dist/core/extensions/builtin/websearch/websearch/types.d.ts.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/types.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +0 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +0 -31
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +10 -67
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +0 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +1 -6
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +3 -19
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +0 -15
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +1 -80
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +1 -2
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +2 -21
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +0 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +3 -78
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/extensions.md +0 -28
- package/docs/settings.md +0 -35
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +0 -12
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +8 -76
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +1 -26
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.js +2 -24
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +0 -5
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +25 -68
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js +52 -62
- package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.js +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/kimi-coding.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/faux.d.ts +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/faux.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/faux.js +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/faux.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +0 -15
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +1 -5
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +6 -6
- package/dist/core/extensions/builtin/goal/turn-usage.d.ts +0 -20
- package/dist/core/extensions/builtin/goal/turn-usage.d.ts.map +0 -1
- package/dist/core/extensions/builtin/goal/turn-usage.js +0 -61
- package/dist/core/extensions/builtin/goal/turn-usage.js.map +0 -1
- package/dist/core/extensions/builtin/model-fallback/index.d.ts +0 -4
- package/dist/core/extensions/builtin/model-fallback/index.d.ts.map +0 -1
- package/dist/core/extensions/builtin/model-fallback/index.js +0 -55
- package/dist/core/extensions/builtin/model-fallback/index.js.map +0 -1
- package/dist/core/extensions/builtin/model-fallback/settings.d.ts +0 -6
- package/dist/core/extensions/builtin/model-fallback/settings.d.ts.map +0 -1
- package/dist/core/extensions/builtin/model-fallback/settings.js +0 -11
- package/dist/core/extensions/builtin/model-fallback/settings.js.map +0 -1
- package/dist/core/extensions/builtin/model-fallback/ui.d.ts +0 -12
- package/dist/core/extensions/builtin/model-fallback/ui.d.ts.map +0 -1
- package/dist/core/extensions/builtin/model-fallback/ui.js +0 -72
- package/dist/core/extensions/builtin/model-fallback/ui.js.map +0 -1
- package/dist/core/retry-fallback/chains.d.ts +0 -29
- package/dist/core/retry-fallback/chains.d.ts.map +0 -1
- package/dist/core/retry-fallback/chains.js +0 -109
- package/dist/core/retry-fallback/chains.js.map +0 -1
- package/dist/core/retry-fallback/controller.d.ts +0 -77
- package/dist/core/retry-fallback/controller.d.ts.map +0 -1
- package/dist/core/retry-fallback/controller.js +0 -157
- package/dist/core/retry-fallback/controller.js.map +0 -1
- package/dist/core/retry-fallback/cooldown.d.ts +0 -21
- package/dist/core/retry-fallback/cooldown.d.ts.map +0 -1
- package/dist/core/retry-fallback/cooldown.js +0 -49
- package/dist/core/retry-fallback/cooldown.js.map +0 -1
- package/dist/core/retry-fallback/log.d.ts +0 -10
- package/dist/core/retry-fallback/log.d.ts.map +0 -1
- package/dist/core/retry-fallback/log.js +0 -128
- package/dist/core/retry-fallback/log.js.map +0 -1
- package/dist/core/retry-fallback/validate.d.ts +0 -8
- package/dist/core/retry-fallback/validate.d.ts.map +0 -1
- package/dist/core/retry-fallback/validate.js +0 -63
- package/dist/core/retry-fallback/validate.js.map +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts +0 -4
- package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js +0 -6
- package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@earendil-works/pi-tui",
|
|
3
3
|
"private": true,
|
|
4
|
-
"version": "2026.7.20
|
|
4
|
+
"version": "2026.7.20",
|
|
5
5
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/senpi",
|
|
3
|
-
"version": "2026.7.20
|
|
3
|
+
"version": "2026.7.20",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piConfig": {
|
|
@@ -43,11 +43,11 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@anthropic-ai/sdk": "0.91.1",
|
|
45
45
|
"@aws-sdk/client-bedrock-runtime": "3.1048.0",
|
|
46
|
-
"@code-yeongyu/senpi-codemode": "^2026.7.20
|
|
47
|
-
"@earendil-works/pi-agent-core": "^2026.7.20
|
|
48
|
-
"@earendil-works/pi-ai": "^2026.7.20
|
|
49
|
-
"@earendil-works/pi-pty": "^2026.7.20
|
|
50
|
-
"@earendil-works/pi-tui": "^2026.7.20
|
|
46
|
+
"@code-yeongyu/senpi-codemode": "^2026.7.20",
|
|
47
|
+
"@earendil-works/pi-agent-core": "^2026.7.20",
|
|
48
|
+
"@earendil-works/pi-ai": "^2026.7.20",
|
|
49
|
+
"@earendil-works/pi-pty": "^2026.7.20",
|
|
50
|
+
"@earendil-works/pi-tui": "^2026.7.20",
|
|
51
51
|
"@mistralai/mistralai": "2.2.6",
|
|
52
52
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
53
53
|
"@mozilla/readability": "0.6.0",
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { TokenUsageSnapshot } from "./types.ts";
|
|
2
|
-
export declare function emptyUsage(): TokenUsageSnapshot;
|
|
3
|
-
export declare function collectAssistantUsage(messages: unknown[]): TokenUsageSnapshot;
|
|
4
|
-
/**
|
|
5
|
-
* Accumulates assistant token usage streamed during the current agent run so
|
|
6
|
-
* goal accounting can checkpoint mid-turn (tool calls, commands, shutdown)
|
|
7
|
-
* without waiting for `agent_end` and without double counting when it fires.
|
|
8
|
-
*/
|
|
9
|
-
export declare class TurnUsageTracker {
|
|
10
|
-
private pending;
|
|
11
|
-
private flushed;
|
|
12
|
-
reset(): void;
|
|
13
|
-
noteMessageEnd(message: unknown): void;
|
|
14
|
-
takePending(): TokenUsageSnapshot;
|
|
15
|
-
/** Drop usage streamed before a new accounting window opened mid-turn. */
|
|
16
|
-
discardPending(): void;
|
|
17
|
-
/** Return the run's total usage minus what checkpoints already accounted. */
|
|
18
|
-
takeRemaining(agentRunMessages: unknown[]): TokenUsageSnapshot;
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=turn-usage.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"turn-usage.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/turn-usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAKrD,wBAAgB,UAAU,IAAI,kBAAkB,CAE/C;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,kBAAkB,CAI7E;AAED;;;;GAIG;AACH,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,OAAO,CAAgB;IAE/B,KAAK,IAAI,IAAI,CAGZ;IAED,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAErC;IAED,WAAW,IAAI,kBAAkB,CAKhC;IAED,0EAA0E;IAC1E,cAAc,IAAI,IAAI,CAErB;IAED,6EAA6E;IAC7E,aAAa,CAAC,gBAAgB,EAAE,OAAO,EAAE,GAAG,kBAAkB,CAS7D;CACD"}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { isRecord } from "./types.js";
|
|
2
|
-
const USAGE_FIELDS = ["input", "output", "cacheRead", "cacheWrite", "totalTokens"];
|
|
3
|
-
export function emptyUsage() {
|
|
4
|
-
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0 };
|
|
5
|
-
}
|
|
6
|
-
export function collectAssistantUsage(messages) {
|
|
7
|
-
const usage = emptyUsage();
|
|
8
|
-
for (const message of messages)
|
|
9
|
-
addAssistantMessageUsage(usage, message);
|
|
10
|
-
return usage;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Accumulates assistant token usage streamed during the current agent run so
|
|
14
|
-
* goal accounting can checkpoint mid-turn (tool calls, commands, shutdown)
|
|
15
|
-
* without waiting for `agent_end` and without double counting when it fires.
|
|
16
|
-
*/
|
|
17
|
-
export class TurnUsageTracker {
|
|
18
|
-
constructor() {
|
|
19
|
-
this.pending = emptyUsage();
|
|
20
|
-
this.flushed = emptyUsage();
|
|
21
|
-
}
|
|
22
|
-
reset() {
|
|
23
|
-
this.pending = emptyUsage();
|
|
24
|
-
this.flushed = emptyUsage();
|
|
25
|
-
}
|
|
26
|
-
noteMessageEnd(message) {
|
|
27
|
-
addAssistantMessageUsage(this.pending, message);
|
|
28
|
-
}
|
|
29
|
-
takePending() {
|
|
30
|
-
const taken = this.pending;
|
|
31
|
-
this.pending = emptyUsage();
|
|
32
|
-
for (const field of USAGE_FIELDS)
|
|
33
|
-
this.flushed[field] += taken[field];
|
|
34
|
-
return taken;
|
|
35
|
-
}
|
|
36
|
-
/** Drop usage streamed before a new accounting window opened mid-turn. */
|
|
37
|
-
discardPending() {
|
|
38
|
-
this.takePending();
|
|
39
|
-
}
|
|
40
|
-
/** Return the run's total usage minus what checkpoints already accounted. */
|
|
41
|
-
takeRemaining(agentRunMessages) {
|
|
42
|
-
const collected = collectAssistantUsage(agentRunMessages);
|
|
43
|
-
const remaining = emptyUsage();
|
|
44
|
-
for (const field of USAGE_FIELDS) {
|
|
45
|
-
remaining[field] = Math.max(0, collected[field] - this.flushed[field]);
|
|
46
|
-
this.flushed[field] = Math.max(this.flushed[field], collected[field]);
|
|
47
|
-
}
|
|
48
|
-
this.pending = emptyUsage();
|
|
49
|
-
return remaining;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
function addAssistantMessageUsage(target, message) {
|
|
53
|
-
if (!isRecord(message) || message.role !== "assistant" || !isRecord(message.usage))
|
|
54
|
-
return;
|
|
55
|
-
for (const field of USAGE_FIELDS) {
|
|
56
|
-
const value = message.usage[field];
|
|
57
|
-
if (typeof value === "number" && Number.isFinite(value))
|
|
58
|
-
target[field] += value;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
//# sourceMappingURL=turn-usage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"turn-usage.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/turn-usage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,CAAU,CAAC;AAE5F,MAAM,UAAU,UAAU;IACzB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAmB;IACxD,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAC3B,KAAK,MAAM,OAAO,IAAI,QAAQ;QAAE,wBAAwB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzE,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAA7B;QACS,YAAO,GAAG,UAAU,EAAE,CAAC;QACvB,YAAO,GAAG,UAAU,EAAE,CAAC;IAkChC,CAAC;IAhCA,KAAK;QACJ,IAAI,CAAC,OAAO,GAAG,UAAU,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,CAAC;IAED,cAAc,CAAC,OAAgB;QAC9B,wBAAwB,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,WAAW;QACV,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,UAAU,EAAE,CAAC;QAC5B,KAAK,MAAM,KAAK,IAAI,YAAY;YAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;QACtE,OAAO,KAAK,CAAC;IACd,CAAC;IAED,0EAA0E;IAC1E,cAAc;QACb,IAAI,CAAC,WAAW,EAAE,CAAC;IACpB,CAAC;IAED,6EAA6E;IAC7E,aAAa,CAAC,gBAA2B;QACxC,MAAM,SAAS,GAAG,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;YAClC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YACvE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,UAAU,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAC;IAClB,CAAC;CACD;AAED,SAAS,wBAAwB,CAAC,MAA0B,EAAE,OAAgB;IAC7E,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO;IAC3F,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;IACjF,CAAC;AACF,CAAC","sourcesContent":["import type { TokenUsageSnapshot } from \"./types.ts\";\nimport { isRecord } from \"./types.ts\";\n\nconst USAGE_FIELDS = [\"input\", \"output\", \"cacheRead\", \"cacheWrite\", \"totalTokens\"] as const;\n\nexport function emptyUsage(): TokenUsageSnapshot {\n\treturn { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0 };\n}\n\nexport function collectAssistantUsage(messages: unknown[]): TokenUsageSnapshot {\n\tconst usage = emptyUsage();\n\tfor (const message of messages) addAssistantMessageUsage(usage, message);\n\treturn usage;\n}\n\n/**\n * Accumulates assistant token usage streamed during the current agent run so\n * goal accounting can checkpoint mid-turn (tool calls, commands, shutdown)\n * without waiting for `agent_end` and without double counting when it fires.\n */\nexport class TurnUsageTracker {\n\tprivate pending = emptyUsage();\n\tprivate flushed = emptyUsage();\n\n\treset(): void {\n\t\tthis.pending = emptyUsage();\n\t\tthis.flushed = emptyUsage();\n\t}\n\n\tnoteMessageEnd(message: unknown): void {\n\t\taddAssistantMessageUsage(this.pending, message);\n\t}\n\n\ttakePending(): TokenUsageSnapshot {\n\t\tconst taken = this.pending;\n\t\tthis.pending = emptyUsage();\n\t\tfor (const field of USAGE_FIELDS) this.flushed[field] += taken[field];\n\t\treturn taken;\n\t}\n\n\t/** Drop usage streamed before a new accounting window opened mid-turn. */\n\tdiscardPending(): void {\n\t\tthis.takePending();\n\t}\n\n\t/** Return the run's total usage minus what checkpoints already accounted. */\n\ttakeRemaining(agentRunMessages: unknown[]): TokenUsageSnapshot {\n\t\tconst collected = collectAssistantUsage(agentRunMessages);\n\t\tconst remaining = emptyUsage();\n\t\tfor (const field of USAGE_FIELDS) {\n\t\t\tremaining[field] = Math.max(0, collected[field] - this.flushed[field]);\n\t\t\tthis.flushed[field] = Math.max(this.flushed[field], collected[field]);\n\t\t}\n\t\tthis.pending = emptyUsage();\n\t\treturn remaining;\n\t}\n}\n\nfunction addAssistantMessageUsage(target: TokenUsageSnapshot, message: unknown): void {\n\tif (!isRecord(message) || message.role !== \"assistant\" || !isRecord(message.usage)) return;\n\tfor (const field of USAGE_FIELDS) {\n\t\tconst value = message.usage[field];\n\t\tif (typeof value === \"number\" && Number.isFinite(value)) target[field] += value;\n\t}\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/model-fallback/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,gBAAgB,CAAC;AAM5E,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAWrE;AAiDD,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { validateFallbackChains } from "../../../retry-fallback/validate.js";
|
|
2
|
-
import { loadFallbackSettings, updateFallbackSettings } from "./settings.js";
|
|
3
|
-
import { runFallbackMenu } from "./ui.js";
|
|
4
|
-
const FLAG_NAME = "no-model-fallback";
|
|
5
|
-
export default function modelFallbackExtension(pi) {
|
|
6
|
-
pi.registerFlag(FLAG_NAME, {
|
|
7
|
-
type: "boolean",
|
|
8
|
-
default: false,
|
|
9
|
-
description: "Disable retry model fallback for this run.",
|
|
10
|
-
});
|
|
11
|
-
pi.registerCommand("fallback", {
|
|
12
|
-
description: "View and manage retry model fallback chains.",
|
|
13
|
-
argumentHint: "[target [fallback1 fallback2 ...]]",
|
|
14
|
-
handler: async (rawArgs, ctx) => handleFallbackCommand(rawArgs, ctx),
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
async function handleFallbackCommand(rawArgs, ctx) {
|
|
18
|
-
const args = rawArgs.trim().split(/\s+/).filter(Boolean);
|
|
19
|
-
if (args.length === 0) {
|
|
20
|
-
const settings = loadFallbackSettings(ctx.sessionSettings);
|
|
21
|
-
await runFallbackMenu(ctx, settings, {
|
|
22
|
-
setChain: (target, entries) => saveChain(ctx, target, entries),
|
|
23
|
-
removeChain: async (target) => {
|
|
24
|
-
await updateFallbackSettings(ctx.sessionSettings, (sessionSettings) => sessionSettings.removeFallbackChain(target));
|
|
25
|
-
ctx.ui.notify(`Removed fallback chain for ${target}.`);
|
|
26
|
-
},
|
|
27
|
-
toggle: async () => {
|
|
28
|
-
await updateFallbackSettings(ctx.sessionSettings, (sessionSettings) => sessionSettings.setModelFallbackEnabled(!settings.modelFallback));
|
|
29
|
-
ctx.ui.notify(`Model fallback ${settings.modelFallback ? "disabled" : "enabled"}.`);
|
|
30
|
-
},
|
|
31
|
-
setRevertPolicy: async (policy) => {
|
|
32
|
-
await updateFallbackSettings(ctx.sessionSettings, (sessionSettings) => sessionSettings.setFallbackRevertPolicy(policy));
|
|
33
|
-
ctx.ui.notify(`Fallback revert policy set to ${policy}.`);
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
if (args.length < 2) {
|
|
39
|
-
ctx.ui.notify("Usage: /fallback <target> <fallback1> [fallback2 ...]", "error");
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
await saveChain(ctx, args[0], args.slice(1));
|
|
43
|
-
}
|
|
44
|
-
async function saveChain(ctx, target, entries) {
|
|
45
|
-
const warnings = validateFallbackChains({ [target]: entries }, ctx.modelRegistry);
|
|
46
|
-
if (warnings.length > 0) {
|
|
47
|
-
ctx.ui.notify(warnings.join("\n"), "warning");
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
await updateFallbackSettings(ctx.sessionSettings, (sessionSettings) => sessionSettings.setFallbackChain(target, entries));
|
|
51
|
-
ctx.ui.notify(`Fallback chain saved for ${target}.`);
|
|
52
|
-
return true;
|
|
53
|
-
}
|
|
54
|
-
export { isModelFallbackDisabled } from "./settings.js";
|
|
55
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/model-fallback/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { validateFallbackChains } from \"../../../retry-fallback/validate.ts\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../types.ts\";\nimport { loadFallbackSettings, updateFallbackSettings } from \"./settings.ts\";\nimport { runFallbackMenu } from \"./ui.ts\";\n\nconst FLAG_NAME = \"no-model-fallback\";\n\nexport default function modelFallbackExtension(pi: ExtensionAPI): void {\n\tpi.registerFlag(FLAG_NAME, {\n\t\ttype: \"boolean\",\n\t\tdefault: false,\n\t\tdescription: \"Disable retry model fallback for this run.\",\n\t});\n\tpi.registerCommand(\"fallback\", {\n\t\tdescription: \"View and manage retry model fallback chains.\",\n\t\targumentHint: \"[target [fallback1 fallback2 ...]]\",\n\t\thandler: async (rawArgs, ctx) => handleFallbackCommand(rawArgs, ctx),\n\t});\n}\n\nasync function handleFallbackCommand(rawArgs: string, ctx: ExtensionCommandContext): Promise<void> {\n\tconst args = rawArgs.trim().split(/\\s+/).filter(Boolean);\n\tif (args.length === 0) {\n\t\tconst settings = loadFallbackSettings(ctx.sessionSettings);\n\t\tawait runFallbackMenu(ctx, settings, {\n\t\t\tsetChain: (target, entries) => saveChain(ctx, target, entries),\n\t\t\tremoveChain: async (target) => {\n\t\t\t\tawait updateFallbackSettings(ctx.sessionSettings, (sessionSettings) =>\n\t\t\t\t\tsessionSettings.removeFallbackChain(target),\n\t\t\t\t);\n\t\t\t\tctx.ui.notify(`Removed fallback chain for ${target}.`);\n\t\t\t},\n\t\t\ttoggle: async () => {\n\t\t\t\tawait updateFallbackSettings(ctx.sessionSettings, (sessionSettings) =>\n\t\t\t\t\tsessionSettings.setModelFallbackEnabled(!settings.modelFallback),\n\t\t\t\t);\n\t\t\t\tctx.ui.notify(`Model fallback ${settings.modelFallback ? \"disabled\" : \"enabled\"}.`);\n\t\t\t},\n\t\t\tsetRevertPolicy: async (policy) => {\n\t\t\t\tawait updateFallbackSettings(ctx.sessionSettings, (sessionSettings) =>\n\t\t\t\t\tsessionSettings.setFallbackRevertPolicy(policy),\n\t\t\t\t);\n\t\t\t\tctx.ui.notify(`Fallback revert policy set to ${policy}.`);\n\t\t\t},\n\t\t});\n\t\treturn;\n\t}\n\tif (args.length < 2) {\n\t\tctx.ui.notify(\"Usage: /fallback <target> <fallback1> [fallback2 ...]\", \"error\");\n\t\treturn;\n\t}\n\tawait saveChain(ctx, args[0], args.slice(1));\n}\n\nasync function saveChain(ctx: ExtensionCommandContext, target: string, entries: string[]): Promise<boolean> {\n\tconst warnings = validateFallbackChains({ [target]: entries }, ctx.modelRegistry);\n\tif (warnings.length > 0) {\n\t\tctx.ui.notify(warnings.join(\"\\n\"), \"warning\");\n\t\treturn false;\n\t}\n\tawait updateFallbackSettings(ctx.sessionSettings, (sessionSettings) =>\n\t\tsessionSettings.setFallbackChain(target, entries),\n\t);\n\tctx.ui.notify(`Fallback chain saved for ${target}.`);\n\treturn true;\n}\n\nexport { isModelFallbackDisabled } from \"./settings.ts\";\n"]}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { ExtensionSessionSettings, RetryFallbackSettings } from "../../types.ts";
|
|
2
|
-
export type FallbackSettings = RetryFallbackSettings;
|
|
3
|
-
export declare function loadFallbackSettings(settings: ExtensionSessionSettings): FallbackSettings;
|
|
4
|
-
export declare function updateFallbackSettings(settings: ExtensionSessionSettings, update: (settings: ExtensionSessionSettings) => Promise<void>): Promise<FallbackSettings>;
|
|
5
|
-
export declare function isModelFallbackDisabled(flag: boolean | string | undefined, environment?: NodeJS.ProcessEnv): boolean;
|
|
6
|
-
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/model-fallback/settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAEtF,MAAM,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAErD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,gBAAgB,CAEzF;AAED,wBAAsB,sBAAsB,CAC3C,QAAQ,EAAE,wBAAwB,EAClC,MAAM,EAAE,CAAC,QAAQ,EAAE,wBAAwB,KAAK,OAAO,CAAC,IAAI,CAAC,GAC3D,OAAO,CAAC,gBAAgB,CAAC,CAG3B;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,EAAE,WAAW,oBAAc,GAAG,OAAO,CAE9G"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export function loadFallbackSettings(settings) {
|
|
2
|
-
return settings.getRetryFallbackSettings();
|
|
3
|
-
}
|
|
4
|
-
export async function updateFallbackSettings(settings, update) {
|
|
5
|
-
await update(settings);
|
|
6
|
-
return settings.getRetryFallbackSettings();
|
|
7
|
-
}
|
|
8
|
-
export function isModelFallbackDisabled(flag, environment = process.env) {
|
|
9
|
-
return flag === true || environment.SENPI_NO_FALLBACK === "1";
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=settings.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/model-fallback/settings.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,oBAAoB,CAAC,QAAkC;IACtE,OAAO,QAAQ,CAAC,wBAAwB,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC3C,QAAkC,EAClC,MAA6D;IAE7D,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvB,OAAO,QAAQ,CAAC,wBAAwB,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAkC,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG;IACpG,OAAO,IAAI,KAAK,IAAI,IAAI,WAAW,CAAC,iBAAiB,KAAK,GAAG,CAAC;AAC/D,CAAC","sourcesContent":["import type { ExtensionSessionSettings, RetryFallbackSettings } from \"../../types.ts\";\n\nexport type FallbackSettings = RetryFallbackSettings;\n\nexport function loadFallbackSettings(settings: ExtensionSessionSettings): FallbackSettings {\n\treturn settings.getRetryFallbackSettings();\n}\n\nexport async function updateFallbackSettings(\n\tsettings: ExtensionSessionSettings,\n\tupdate: (settings: ExtensionSessionSettings) => Promise<void>,\n): Promise<FallbackSettings> {\n\tawait update(settings);\n\treturn settings.getRetryFallbackSettings();\n}\n\nexport function isModelFallbackDisabled(flag: boolean | string | undefined, environment = process.env): boolean {\n\treturn flag === true || environment.SENPI_NO_FALLBACK === \"1\";\n}\n"]}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
2
|
-
import type { ExtensionCommandContext } from "../../types.ts";
|
|
3
|
-
import type { FallbackSettings } from "./settings.ts";
|
|
4
|
-
export declare function formatModel(model: Model<Api>): string;
|
|
5
|
-
export declare function renderFallbackState(ctx: ExtensionCommandContext, settings: FallbackSettings): string;
|
|
6
|
-
export declare function runFallbackMenu(ctx: ExtensionCommandContext, settings: FallbackSettings, actions: {
|
|
7
|
-
setChain(target: string, entries: string[]): Promise<boolean>;
|
|
8
|
-
removeChain(target: string): Promise<void>;
|
|
9
|
-
toggle(): Promise<void>;
|
|
10
|
-
setRevertPolicy(policy: "cooldown-expiry" | "never"): Promise<void>;
|
|
11
|
-
}): Promise<void>;
|
|
12
|
-
//# sourceMappingURL=ui.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/model-fallback/ui.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAUtD,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAErD;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,uBAAuB,EAAE,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAQpG;AAED,wBAAsB,eAAe,CACpC,GAAG,EAAE,uBAAuB,EAC5B,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE;IACR,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,eAAe,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpE,GACC,OAAO,CAAC,IAAI,CAAC,CA0Bf"}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { getSupportedThinkingLevels } from "../../../thinking-levels.js";
|
|
2
|
-
const MENU = [
|
|
3
|
-
"Show chains & live state",
|
|
4
|
-
"Add/edit chain",
|
|
5
|
-
"Remove chain",
|
|
6
|
-
"Toggle model fallback",
|
|
7
|
-
"Revert policy",
|
|
8
|
-
];
|
|
9
|
-
export function formatModel(model) {
|
|
10
|
-
return `${model.provider}/${model.id}`;
|
|
11
|
-
}
|
|
12
|
-
export function renderFallbackState(ctx, settings) {
|
|
13
|
-
const rows = Object.entries(settings.chains).map(([target, entries]) => `${target} -> ${entries.join(", ")}`);
|
|
14
|
-
const chains = rows.length > 0 ? rows.join("\n") : "No fallback chains configured.";
|
|
15
|
-
const status = ctx.sessionSettings.getFallbackStatus();
|
|
16
|
-
const live = status?.active
|
|
17
|
-
? `active on ${status.currentModel ?? "unknown"} from ${status.originalSelector ?? "unknown"}${status.pinned ? " (pinned)" : ""}`
|
|
18
|
-
: "inactive";
|
|
19
|
-
return `${chains}\nModel fallback: ${settings.modelFallback ? "enabled" : "disabled"}\nRevert policy: ${settings.revertPolicy}\nLive retry state: ${live}`;
|
|
20
|
-
}
|
|
21
|
-
export async function runFallbackMenu(ctx, settings, actions) {
|
|
22
|
-
if (!ctx.hasUI) {
|
|
23
|
-
ctx.ui.notify("Fallback menu requires interactive UI. Use /fallback <target> <fallback...>.", "error");
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
const choice = await ctx.ui.select("Model fallback", [...MENU]);
|
|
27
|
-
if (!choice)
|
|
28
|
-
return;
|
|
29
|
-
if (choice === MENU[0]) {
|
|
30
|
-
ctx.ui.notify(renderFallbackState(ctx, settings));
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
if (choice === MENU[1]) {
|
|
34
|
-
await editChain(ctx, actions);
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
if (choice === MENU[2]) {
|
|
38
|
-
const target = await ctx.ui.select("Remove fallback chain", Object.keys(settings.chains));
|
|
39
|
-
if (target)
|
|
40
|
-
await actions.removeChain(target);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
if (choice === MENU[3]) {
|
|
44
|
-
await actions.toggle();
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
const policy = await ctx.ui.select("Fallback revert policy", ["cooldown-expiry", "never"]);
|
|
48
|
-
if (policy === "cooldown-expiry" || policy === "never")
|
|
49
|
-
await actions.setRevertPolicy(policy);
|
|
50
|
-
}
|
|
51
|
-
async function editChain(ctx, actions) {
|
|
52
|
-
const available = ctx.modelRegistry.getAvailable();
|
|
53
|
-
const target = await ctx.ui.select("Fallback target model", available.map(formatModel));
|
|
54
|
-
if (!target)
|
|
55
|
-
return;
|
|
56
|
-
const entries = [];
|
|
57
|
-
while (true) {
|
|
58
|
-
const fallback = await ctx.ui.select("Fallback model (Done to save)", ["Done", ...available.map(formatModel)]);
|
|
59
|
-
if (!fallback || fallback === "Done")
|
|
60
|
-
break;
|
|
61
|
-
const model = available.find((item) => formatModel(item) === fallback);
|
|
62
|
-
if (!model)
|
|
63
|
-
return;
|
|
64
|
-
const thinking = await ctx.ui.select("Thinking level", ["inherit", ...getSupportedThinkingLevels(model)]);
|
|
65
|
-
if (!thinking)
|
|
66
|
-
return;
|
|
67
|
-
entries.push(thinking === "inherit" ? fallback : `${fallback}:${thinking}`);
|
|
68
|
-
}
|
|
69
|
-
if (entries.length > 0)
|
|
70
|
-
await actions.setChain(target, entries);
|
|
71
|
-
}
|
|
72
|
-
//# sourceMappingURL=ui.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/model-fallback/ui.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { getSupportedThinkingLevels } from \"../../../thinking-levels.ts\";\nimport type { ExtensionCommandContext } from \"../../types.ts\";\nimport type { FallbackSettings } from \"./settings.ts\";\n\nconst MENU = [\n\t\"Show chains & live state\",\n\t\"Add/edit chain\",\n\t\"Remove chain\",\n\t\"Toggle model fallback\",\n\t\"Revert policy\",\n] as const;\n\nexport function formatModel(model: Model<Api>): string {\n\treturn `${model.provider}/${model.id}`;\n}\n\nexport function renderFallbackState(ctx: ExtensionCommandContext, settings: FallbackSettings): string {\n\tconst rows = Object.entries(settings.chains).map(([target, entries]) => `${target} -> ${entries.join(\", \")}`);\n\tconst chains = rows.length > 0 ? rows.join(\"\\n\") : \"No fallback chains configured.\";\n\tconst status = ctx.sessionSettings.getFallbackStatus();\n\tconst live = status?.active\n\t\t? `active on ${status.currentModel ?? \"unknown\"} from ${status.originalSelector ?? \"unknown\"}${status.pinned ? \" (pinned)\" : \"\"}`\n\t\t: \"inactive\";\n\treturn `${chains}\\nModel fallback: ${settings.modelFallback ? \"enabled\" : \"disabled\"}\\nRevert policy: ${settings.revertPolicy}\\nLive retry state: ${live}`;\n}\n\nexport async function runFallbackMenu(\n\tctx: ExtensionCommandContext,\n\tsettings: FallbackSettings,\n\tactions: {\n\t\tsetChain(target: string, entries: string[]): Promise<boolean>;\n\t\tremoveChain(target: string): Promise<void>;\n\t\ttoggle(): Promise<void>;\n\t\tsetRevertPolicy(policy: \"cooldown-expiry\" | \"never\"): Promise<void>;\n\t},\n): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(\"Fallback menu requires interactive UI. Use /fallback <target> <fallback...>.\", \"error\");\n\t\treturn;\n\t}\n\tconst choice = await ctx.ui.select(\"Model fallback\", [...MENU]);\n\tif (!choice) return;\n\tif (choice === MENU[0]) {\n\t\tctx.ui.notify(renderFallbackState(ctx, settings));\n\t\treturn;\n\t}\n\tif (choice === MENU[1]) {\n\t\tawait editChain(ctx, actions);\n\t\treturn;\n\t}\n\tif (choice === MENU[2]) {\n\t\tconst target = await ctx.ui.select(\"Remove fallback chain\", Object.keys(settings.chains));\n\t\tif (target) await actions.removeChain(target);\n\t\treturn;\n\t}\n\tif (choice === MENU[3]) {\n\t\tawait actions.toggle();\n\t\treturn;\n\t}\n\tconst policy = await ctx.ui.select(\"Fallback revert policy\", [\"cooldown-expiry\", \"never\"]);\n\tif (policy === \"cooldown-expiry\" || policy === \"never\") await actions.setRevertPolicy(policy);\n}\n\nasync function editChain(\n\tctx: ExtensionCommandContext,\n\tactions: { setChain(target: string, entries: string[]): Promise<boolean> },\n): Promise<void> {\n\tconst available = ctx.modelRegistry.getAvailable();\n\tconst target = await ctx.ui.select(\"Fallback target model\", available.map(formatModel));\n\tif (!target) return;\n\tconst entries: string[] = [];\n\twhile (true) {\n\t\tconst fallback = await ctx.ui.select(\"Fallback model (Done to save)\", [\"Done\", ...available.map(formatModel)]);\n\t\tif (!fallback || fallback === \"Done\") break;\n\t\tconst model = available.find((item) => formatModel(item) === fallback);\n\t\tif (!model) return;\n\t\tconst thinking = await ctx.ui.select(\"Thinking level\", [\"inherit\", ...getSupportedThinkingLevels(model)]);\n\t\tif (!thinking) return;\n\t\tentries.push(thinking === \"inherit\" ? fallback : `${fallback}:${thinking}`);\n\t}\n\tif (entries.length > 0) await actions.setChain(target, entries);\n}\n"]}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
|
2
|
-
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
3
|
-
export interface FallbackSelector {
|
|
4
|
-
raw: string;
|
|
5
|
-
provider: string;
|
|
6
|
-
id: string;
|
|
7
|
-
thinkingLevel?: ThinkingLevel;
|
|
8
|
-
}
|
|
9
|
-
export type FallbackChains = Readonly<Record<string, readonly string[]>>;
|
|
10
|
-
export type FallbackModelLookup = readonly Model<Api>[] | {
|
|
11
|
-
getAll(): Model<Api>[];
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Resolves only complete provider/model selectors. The full input is resolved first
|
|
15
|
-
* so colons belonging to a model id remain part of that id; aliases then resolve
|
|
16
|
-
* against the model-id portion while retaining the explicitly selected provider.
|
|
17
|
-
*/
|
|
18
|
-
export declare function parseFallbackSelector(raw: string, lookup: FallbackModelLookup): FallbackSelector | undefined;
|
|
19
|
-
export declare function formatSelector(model: Model<Api>, thinkingLevel?: ThinkingLevel): string;
|
|
20
|
-
export declare function baseSelector(selector: Pick<FallbackSelector, "provider" | "id">): string;
|
|
21
|
-
/** Converts validated configuration to canonical selector strings for runtime lookup. */
|
|
22
|
-
export declare function canonicalizeFallbackChains(chains: FallbackChains, lookup: FallbackModelLookup): FallbackChains;
|
|
23
|
-
export declare function resolveChainKey(currentModel: Model<Api>, currentThinking: ThinkingLevel | undefined, chains: FallbackChains): string | undefined;
|
|
24
|
-
/**
|
|
25
|
-
* Returns entries after the current fallback. A primary or unknown selector starts
|
|
26
|
-
* from the beginning, which also makes re-entry after stale runtime state safe.
|
|
27
|
-
*/
|
|
28
|
-
export declare function candidatesAfter(chainEntries: readonly string[], currentSelector: FallbackSelector | string): readonly string[];
|
|
29
|
-
//# sourceMappingURL=chains.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../../../src/core/retry-fallback/chains.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAIxD,MAAM,WAAW,gBAAgB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;AAEzE,MAAM,MAAM,mBAAmB,GAAG,SAAS,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG;IAAE,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAA;CAAE,CAAC;AAmBrF;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,gBAAgB,GAAG,SAAS,CA+B5G;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,EAAE,aAAa,GAAG,MAAM,CAGvF;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,GAAG,IAAI,CAAC,GAAG,MAAM,CAExF;AAED,yFAAyF;AACzF,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,mBAAmB,GAAG,cAAc,CAe9G;AAED,wBAAgB,eAAe,CAC9B,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,EACxB,eAAe,EAAE,aAAa,GAAG,SAAS,EAC1C,MAAM,EAAE,cAAc,GACpB,MAAM,GAAG,SAAS,CAKpB;AAoBD;;;GAGG;AACH,wBAAgB,eAAe,CAC9B,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,eAAe,EAAE,gBAAgB,GAAG,MAAM,GACxC,SAAS,MAAM,EAAE,CAQnB"}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { isValidThinkingLevel } from "../../cli/args.js";
|
|
2
|
-
import { findExactModelReferenceMatch, parseModelPattern } from "../model-resolver.js";
|
|
3
|
-
function availableModels(lookup) {
|
|
4
|
-
return "getAll" in lookup ? lookup.getAll() : [...lookup];
|
|
5
|
-
}
|
|
6
|
-
function selectorReference(raw) {
|
|
7
|
-
const trimmed = raw.trim();
|
|
8
|
-
if (!trimmed.includes("/") || trimmed.includes("*"))
|
|
9
|
-
return undefined;
|
|
10
|
-
const lastColon = trimmed.lastIndexOf(":");
|
|
11
|
-
if (lastColon === -1)
|
|
12
|
-
return { reference: trimmed };
|
|
13
|
-
const prefix = trimmed.slice(0, lastColon);
|
|
14
|
-
const suffix = trimmed.slice(lastColon + 1).toLowerCase();
|
|
15
|
-
if (!isValidThinkingLevel(suffix))
|
|
16
|
-
return { reference: trimmed };
|
|
17
|
-
return { reference: prefix, thinkingLevel: suffix };
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Resolves only complete provider/model selectors. The full input is resolved first
|
|
21
|
-
* so colons belonging to a model id remain part of that id; aliases then resolve
|
|
22
|
-
* against the model-id portion while retaining the explicitly selected provider.
|
|
23
|
-
*/
|
|
24
|
-
export function parseFallbackSelector(raw, lookup) {
|
|
25
|
-
const models = availableModels(lookup);
|
|
26
|
-
const trimmed = raw.trim();
|
|
27
|
-
const parsedReference = selectorReference(trimmed);
|
|
28
|
-
if (!parsedReference)
|
|
29
|
-
return undefined;
|
|
30
|
-
const fullMatch = findExactModelReferenceMatch(trimmed, models);
|
|
31
|
-
if (fullMatch) {
|
|
32
|
-
return { raw: trimmed, provider: fullMatch.provider, id: fullMatch.id };
|
|
33
|
-
}
|
|
34
|
-
const slashIndex = parsedReference.reference.indexOf("/");
|
|
35
|
-
const provider = parsedReference.reference.slice(0, slashIndex).trim();
|
|
36
|
-
const modelPattern = parsedReference.reference.slice(slashIndex + 1).trim();
|
|
37
|
-
if (!provider || !modelPattern)
|
|
38
|
-
return undefined;
|
|
39
|
-
const parsed = parseModelPattern(parsedReference.thinkingLevel ? `${modelPattern}:${parsedReference.thinkingLevel}` : modelPattern, models, { allowInvalidThinkingLevelFallback: false });
|
|
40
|
-
if (!parsed.model || parsed.warning || parsed.model.provider.toLowerCase() !== provider.toLowerCase())
|
|
41
|
-
return undefined;
|
|
42
|
-
if (parsedReference.thinkingLevel && !parsed.thinkingLevel)
|
|
43
|
-
return undefined;
|
|
44
|
-
return {
|
|
45
|
-
raw: trimmed,
|
|
46
|
-
provider: parsed.model.provider,
|
|
47
|
-
id: parsed.model.id,
|
|
48
|
-
thinkingLevel: parsed.thinkingLevel,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
export function formatSelector(model, thinkingLevel) {
|
|
52
|
-
const base = `${model.provider}/${model.id}`;
|
|
53
|
-
return thinkingLevel ? `${base}:${thinkingLevel}` : base;
|
|
54
|
-
}
|
|
55
|
-
export function baseSelector(selector) {
|
|
56
|
-
return `${selector.provider}/${selector.id}`;
|
|
57
|
-
}
|
|
58
|
-
/** Converts validated configuration to canonical selector strings for runtime lookup. */
|
|
59
|
-
export function canonicalizeFallbackChains(chains, lookup) {
|
|
60
|
-
const canonical = {};
|
|
61
|
-
for (const [key, entries] of Object.entries(chains)) {
|
|
62
|
-
const parsedKey = parseFallbackSelector(key, lookup);
|
|
63
|
-
if (!parsedKey || !Array.isArray(entries))
|
|
64
|
-
continue;
|
|
65
|
-
const canonicalEntries = entries.flatMap((entry) => {
|
|
66
|
-
const parsedEntry = parseFallbackSelector(entry, lookup);
|
|
67
|
-
return parsedEntry ? [formatParsedSelector(parsedEntry)] : [];
|
|
68
|
-
});
|
|
69
|
-
canonical[formatParsedSelector(parsedKey)] = canonicalEntries;
|
|
70
|
-
}
|
|
71
|
-
return canonical;
|
|
72
|
-
}
|
|
73
|
-
export function resolveChainKey(currentModel, currentThinking, chains) {
|
|
74
|
-
const base = formatSelector(currentModel);
|
|
75
|
-
const exact = currentThinking ? `${base}:${currentThinking}` : base;
|
|
76
|
-
if (Object.hasOwn(chains, exact))
|
|
77
|
-
return exact;
|
|
78
|
-
return Object.hasOwn(chains, base) ? base : undefined;
|
|
79
|
-
}
|
|
80
|
-
function formatParsedSelector(selector) {
|
|
81
|
-
const base = baseSelector(selector);
|
|
82
|
-
return selector.thinkingLevel ? `${base}:${selector.thinkingLevel}` : base;
|
|
83
|
-
}
|
|
84
|
-
function normalizedBase(selector) {
|
|
85
|
-
if (typeof selector !== "string")
|
|
86
|
-
return baseSelector(selector).toLowerCase();
|
|
87
|
-
const normalized = selector.trim().toLowerCase();
|
|
88
|
-
const lastColon = normalized.lastIndexOf(":");
|
|
89
|
-
if (lastColon === -1 || !isValidThinkingLevel(normalized.slice(lastColon + 1)))
|
|
90
|
-
return normalized;
|
|
91
|
-
return normalized.slice(0, lastColon);
|
|
92
|
-
}
|
|
93
|
-
function normalizedExact(selector) {
|
|
94
|
-
return typeof selector === "string" ? selector.trim().toLowerCase() : formatParsedSelector(selector).toLowerCase();
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Returns entries after the current fallback. A primary or unknown selector starts
|
|
98
|
-
* from the beginning, which also makes re-entry after stale runtime state safe.
|
|
99
|
-
*/
|
|
100
|
-
export function candidatesAfter(chainEntries, currentSelector) {
|
|
101
|
-
const exact = normalizedExact(currentSelector);
|
|
102
|
-
const exactIndex = chainEntries.findIndex((entry) => entry.toLowerCase() === exact);
|
|
103
|
-
if (exactIndex !== -1)
|
|
104
|
-
return chainEntries.slice(exactIndex + 1);
|
|
105
|
-
const base = normalizedBase(currentSelector);
|
|
106
|
-
const baseIndex = chainEntries.findIndex((entry) => normalizedBase(entry) === base);
|
|
107
|
-
return baseIndex === -1 ? chainEntries : chainEntries.slice(baseIndex + 1);
|
|
108
|
-
}
|
|
109
|
-
//# sourceMappingURL=chains.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chains.js","sourceRoot":"","sources":["../../../src/core/retry-fallback/chains.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { isValidThinkingLevel } from \"../../cli/args.ts\";\nimport { findExactModelReferenceMatch, parseModelPattern } from \"../model-resolver.ts\";\n\nexport interface FallbackSelector {\n\traw: string;\n\tprovider: string;\n\tid: string;\n\tthinkingLevel?: ThinkingLevel;\n}\n\nexport type FallbackChains = Readonly<Record<string, readonly string[]>>;\n\nexport type FallbackModelLookup = readonly Model<Api>[] | { getAll(): Model<Api>[] };\n\nfunction availableModels(lookup: FallbackModelLookup): Model<Api>[] {\n\treturn \"getAll\" in lookup ? lookup.getAll() : [...lookup];\n}\n\nfunction selectorReference(raw: string): { reference: string; thinkingLevel?: ThinkingLevel } | undefined {\n\tconst trimmed = raw.trim();\n\tif (!trimmed.includes(\"/\") || trimmed.includes(\"*\")) return undefined;\n\n\tconst lastColon = trimmed.lastIndexOf(\":\");\n\tif (lastColon === -1) return { reference: trimmed };\n\n\tconst prefix = trimmed.slice(0, lastColon);\n\tconst suffix = trimmed.slice(lastColon + 1).toLowerCase();\n\tif (!isValidThinkingLevel(suffix)) return { reference: trimmed };\n\treturn { reference: prefix, thinkingLevel: suffix };\n}\n\n/**\n * Resolves only complete provider/model selectors. The full input is resolved first\n * so colons belonging to a model id remain part of that id; aliases then resolve\n * against the model-id portion while retaining the explicitly selected provider.\n */\nexport function parseFallbackSelector(raw: string, lookup: FallbackModelLookup): FallbackSelector | undefined {\n\tconst models = availableModels(lookup);\n\tconst trimmed = raw.trim();\n\tconst parsedReference = selectorReference(trimmed);\n\tif (!parsedReference) return undefined;\n\n\tconst fullMatch = findExactModelReferenceMatch(trimmed, models);\n\tif (fullMatch) {\n\t\treturn { raw: trimmed, provider: fullMatch.provider, id: fullMatch.id };\n\t}\n\n\tconst slashIndex = parsedReference.reference.indexOf(\"/\");\n\tconst provider = parsedReference.reference.slice(0, slashIndex).trim();\n\tconst modelPattern = parsedReference.reference.slice(slashIndex + 1).trim();\n\tif (!provider || !modelPattern) return undefined;\n\n\tconst parsed = parseModelPattern(\n\t\tparsedReference.thinkingLevel ? `${modelPattern}:${parsedReference.thinkingLevel}` : modelPattern,\n\t\tmodels,\n\t\t{ allowInvalidThinkingLevelFallback: false },\n\t);\n\tif (!parsed.model || parsed.warning || parsed.model.provider.toLowerCase() !== provider.toLowerCase())\n\t\treturn undefined;\n\tif (parsedReference.thinkingLevel && !parsed.thinkingLevel) return undefined;\n\n\treturn {\n\t\traw: trimmed,\n\t\tprovider: parsed.model.provider,\n\t\tid: parsed.model.id,\n\t\tthinkingLevel: parsed.thinkingLevel,\n\t};\n}\n\nexport function formatSelector(model: Model<Api>, thinkingLevel?: ThinkingLevel): string {\n\tconst base = `${model.provider}/${model.id}`;\n\treturn thinkingLevel ? `${base}:${thinkingLevel}` : base;\n}\n\nexport function baseSelector(selector: Pick<FallbackSelector, \"provider\" | \"id\">): string {\n\treturn `${selector.provider}/${selector.id}`;\n}\n\n/** Converts validated configuration to canonical selector strings for runtime lookup. */\nexport function canonicalizeFallbackChains(chains: FallbackChains, lookup: FallbackModelLookup): FallbackChains {\n\tconst canonical: Record<string, readonly string[]> = {};\n\n\tfor (const [key, entries] of Object.entries(chains)) {\n\t\tconst parsedKey = parseFallbackSelector(key, lookup);\n\t\tif (!parsedKey || !Array.isArray(entries)) continue;\n\n\t\tconst canonicalEntries = entries.flatMap((entry) => {\n\t\t\tconst parsedEntry = parseFallbackSelector(entry, lookup);\n\t\t\treturn parsedEntry ? [formatParsedSelector(parsedEntry)] : [];\n\t\t});\n\t\tcanonical[formatParsedSelector(parsedKey)] = canonicalEntries;\n\t}\n\n\treturn canonical;\n}\n\nexport function resolveChainKey(\n\tcurrentModel: Model<Api>,\n\tcurrentThinking: ThinkingLevel | undefined,\n\tchains: FallbackChains,\n): string | undefined {\n\tconst base = formatSelector(currentModel);\n\tconst exact = currentThinking ? `${base}:${currentThinking}` : base;\n\tif (Object.hasOwn(chains, exact)) return exact;\n\treturn Object.hasOwn(chains, base) ? base : undefined;\n}\n\nfunction formatParsedSelector(selector: FallbackSelector): string {\n\tconst base = baseSelector(selector);\n\treturn selector.thinkingLevel ? `${base}:${selector.thinkingLevel}` : base;\n}\n\nfunction normalizedBase(selector: FallbackSelector | string): string {\n\tif (typeof selector !== \"string\") return baseSelector(selector).toLowerCase();\n\n\tconst normalized = selector.trim().toLowerCase();\n\tconst lastColon = normalized.lastIndexOf(\":\");\n\tif (lastColon === -1 || !isValidThinkingLevel(normalized.slice(lastColon + 1))) return normalized;\n\treturn normalized.slice(0, lastColon);\n}\n\nfunction normalizedExact(selector: FallbackSelector | string): string {\n\treturn typeof selector === \"string\" ? selector.trim().toLowerCase() : formatParsedSelector(selector).toLowerCase();\n}\n\n/**\n * Returns entries after the current fallback. A primary or unknown selector starts\n * from the beginning, which also makes re-entry after stale runtime state safe.\n */\nexport function candidatesAfter(\n\tchainEntries: readonly string[],\n\tcurrentSelector: FallbackSelector | string,\n): readonly string[] {\n\tconst exact = normalizedExact(currentSelector);\n\tconst exactIndex = chainEntries.findIndex((entry) => entry.toLowerCase() === exact);\n\tif (exactIndex !== -1) return chainEntries.slice(exactIndex + 1);\n\n\tconst base = normalizedBase(currentSelector);\n\tconst baseIndex = chainEntries.findIndex((entry) => normalizedBase(entry) === base);\n\treturn baseIndex === -1 ? chainEntries : chainEntries.slice(baseIndex + 1);\n}\n"]}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
|
2
|
-
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
3
|
-
import type { SelectorCooldowns } from "./cooldown.ts";
|
|
4
|
-
import type { FallbackLogger } from "./log.ts";
|
|
5
|
-
export interface ActiveFallbackState {
|
|
6
|
-
chainKey: string;
|
|
7
|
-
originalSelector: string;
|
|
8
|
-
originalThinkingLevel?: ThinkingLevel;
|
|
9
|
-
lastAppliedThinkingLevel?: ThinkingLevel;
|
|
10
|
-
pinned: boolean;
|
|
11
|
-
}
|
|
12
|
-
type FallbackReason = "transient" | "refusal" | "hard-error";
|
|
13
|
-
interface FallbackSettings {
|
|
14
|
-
modelFallback: boolean;
|
|
15
|
-
chains: Readonly<Record<string, readonly string[]>>;
|
|
16
|
-
}
|
|
17
|
-
export interface RetryFallbackControllerDeps {
|
|
18
|
-
getSettings(): FallbackSettings;
|
|
19
|
-
registry: {
|
|
20
|
-
find(provider: string, id: string): Model<Api> | undefined;
|
|
21
|
-
getAll(): Model<Api>[];
|
|
22
|
-
};
|
|
23
|
-
cooldowns: SelectorCooldowns;
|
|
24
|
-
logger: FallbackLogger;
|
|
25
|
-
switchModel(model: Model<Api>, thinking: ThinkingLevel, reason: "fallback" | "fallback-revert"): Promise<void>;
|
|
26
|
-
emit(event: {
|
|
27
|
-
type: "retry_fallback_applied";
|
|
28
|
-
from: string;
|
|
29
|
-
to: string;
|
|
30
|
-
chainKey: string;
|
|
31
|
-
reason: FallbackReason;
|
|
32
|
-
} | {
|
|
33
|
-
type: "retry_fallback_reverted";
|
|
34
|
-
from: string;
|
|
35
|
-
to: string;
|
|
36
|
-
}): void;
|
|
37
|
-
getCurrentSelector(): {
|
|
38
|
-
model: Model<Api>;
|
|
39
|
-
thinkingLevel?: ThinkingLevel;
|
|
40
|
-
} | undefined;
|
|
41
|
-
isAuthAvailable(provider: string): boolean;
|
|
42
|
-
}
|
|
43
|
-
export declare class RetryFallbackController {
|
|
44
|
-
private readonly deps;
|
|
45
|
-
private readonly triedSelectors;
|
|
46
|
-
private state;
|
|
47
|
-
private lastExhaustedChainKey;
|
|
48
|
-
constructor(deps: RetryFallbackControllerDeps);
|
|
49
|
-
get activeState(): Readonly<ActiveFallbackState> | undefined;
|
|
50
|
-
get exhaustedChainKey(): string | undefined;
|
|
51
|
-
resetTurn(): void;
|
|
52
|
-
clear(): void;
|
|
53
|
-
canTryFallback(): boolean;
|
|
54
|
-
/**
|
|
55
|
-
* Revert to the chain's original model at a turn boundary. Only fires for
|
|
56
|
-
* unpinned state under the cooldown-expiry policy once the original selector
|
|
57
|
-
* is no longer suppressed and is still usable; pinned (refusal) state and the
|
|
58
|
-
* "never" policy always hold the fallback model.
|
|
59
|
-
*/
|
|
60
|
-
maybeRestorePrimary(revertPolicy: "cooldown-expiry" | "never"): Promise<boolean>;
|
|
61
|
-
/**
|
|
62
|
-
* A user-driven setThinkingLevel makes the current level a deliberate choice,
|
|
63
|
-
* so the revert restore-rule must no longer treat it as fallback-applied.
|
|
64
|
-
*/
|
|
65
|
-
noteManualThinkingLevel(): void;
|
|
66
|
-
/** A user-driven model change abandons the fallback window entirely. */
|
|
67
|
-
clearForManualModelChange(model: Model<Api>): void;
|
|
68
|
-
tryFallback(reason: FallbackReason, failure: {
|
|
69
|
-
errorMessage?: string;
|
|
70
|
-
retryAfterMs?: number;
|
|
71
|
-
}): Promise<boolean>;
|
|
72
|
-
private nextCandidate;
|
|
73
|
-
private selectThinking;
|
|
74
|
-
private skip;
|
|
75
|
-
}
|
|
76
|
-
export {};
|
|
77
|
-
//# sourceMappingURL=controller.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../src/core/retry-fallback/controller.ts"],"names":[],"mappings":"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"}
|