@selesai/code 0.5.14 → 0.5.15
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/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js +2 -0
- package/dist/bun/cli.js.map +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +3 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/list-models.d.ts +2 -2
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +3 -3
- package/dist/cli/list-models.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-auto-handoff.test.d.ts.map +1 -1
- package/dist/core/agent-session-auto-handoff.test.js +2 -2
- package/dist/core/agent-session-auto-handoff.test.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +3 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +3 -6
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +23 -9
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +28 -10
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +136 -90
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +20 -98
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +59 -251
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/built-in-extensions.d.ts +3 -0
- package/dist/core/built-in-extensions.d.ts.map +1 -0
- package/dist/core/built-in-extensions.js +3 -0
- package/dist/core/built-in-extensions.js.map +1 -0
- package/dist/core/cache-stats.d.ts +2 -2
- package/dist/core/cache-stats.d.ts.map +1 -1
- package/dist/core/cache-stats.js +1 -1
- package/dist/core/cache-stats.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +8 -2
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +8 -11
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +19 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +63 -26
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/utils.d.ts +1 -1
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js +6 -17
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +21 -4
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +4 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +39 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +24 -3
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +22 -3
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/keybindings.d.ts +8 -3
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +7 -3
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/llama/client.d.ts +61 -0
- package/dist/core/llama/client.d.ts.map +1 -0
- package/dist/core/llama/client.js +302 -0
- package/dist/core/llama/client.js.map +1 -0
- package/dist/core/llama/huggingface.d.ts +23 -0
- package/dist/core/llama/huggingface.d.ts.map +1 -0
- package/dist/core/llama/huggingface.js +141 -0
- package/dist/core/llama/huggingface.js.map +1 -0
- package/dist/core/llama/index.d.ts +3 -0
- package/dist/core/llama/index.d.ts.map +1 -0
- package/dist/core/llama/index.js +208 -0
- package/dist/core/llama/index.js.map +1 -0
- package/dist/core/llama/provider.d.ts +10 -0
- package/dist/core/llama/provider.d.ts.map +1 -0
- package/dist/core/llama/provider.js +102 -0
- package/dist/core/llama/provider.js.map +1 -0
- package/dist/core/llama/ui.d.ts +42 -0
- package/dist/core/llama/ui.d.ts.map +1 -0
- package/dist/core/llama/ui.js +416 -0
- package/dist/core/llama/ui.js.map +1 -0
- package/dist/core/model-config.d.ts +513 -0
- package/dist/core/model-config.d.ts.map +1 -0
- package/dist/core/model-config.js +272 -0
- package/dist/core/model-config.js.map +1 -0
- package/dist/core/model-registry.d.ts +20 -126
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +62 -780
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +6 -6
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +21 -18
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +83 -0
- package/dist/core/model-runtime.d.ts.map +1 -0
- package/dist/core/model-runtime.js +451 -0
- package/dist/core/model-runtime.js.map +1 -0
- package/dist/core/models-store.d.ts +17 -0
- package/dist/core/models-store.d.ts.map +1 -0
- package/dist/core/models-store.js +45 -0
- package/dist/core/models-store.js.map +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +7 -2
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +1 -0
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +4 -4
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-composer.d.ts +55 -0
- package/dist/core/provider-composer.d.ts.map +1 -0
- package/dist/core/provider-composer.js +375 -0
- package/dist/core/provider-composer.js.map +1 -0
- package/dist/core/radius.d.ts +2 -0
- package/dist/core/radius.d.ts.map +1 -0
- package/dist/core/radius.js +2 -0
- package/dist/core/radius.js.map +1 -0
- package/dist/core/remote-catalog-provider.d.ts +5 -0
- package/dist/core/remote-catalog-provider.d.ts.map +1 -0
- package/dist/core/remote-catalog-provider.js +102 -0
- package/dist/core/remote-catalog-provider.js.map +1 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +1 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts +17 -0
- package/dist/core/runtime-credentials.d.ts.map +1 -0
- package/dist/core/runtime-credentials.js +42 -0
- package/dist/core/runtime-credentials.js.map +1 -0
- package/dist/core/sdk.d.ts +4 -7
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +18 -25
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +12 -7
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +103 -27
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +1 -11
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/usage-totals.d.ts +19 -0
- package/dist/core/usage-totals.d.ts.map +1 -0
- package/dist/core/usage-totals.js +52 -0
- package/dist/core/usage-totals.js.map +1 -0
- package/dist/extensions/index.d.ts +3 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +9 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/llama/client.d.ts +61 -0
- package/dist/extensions/llama/client.d.ts.map +1 -0
- package/dist/extensions/llama/client.js +309 -0
- package/dist/extensions/llama/client.js.map +1 -0
- package/dist/extensions/llama/huggingface.d.ts +23 -0
- package/dist/extensions/llama/huggingface.d.ts.map +1 -0
- package/dist/extensions/llama/huggingface.js +146 -0
- package/dist/extensions/llama/huggingface.js.map +1 -0
- package/dist/extensions/llama/index.d.ts +3 -0
- package/dist/extensions/llama/index.d.ts.map +1 -0
- package/dist/extensions/llama/index.js +211 -0
- package/dist/extensions/llama/index.js.map +1 -0
- package/dist/extensions/llama/provider.d.ts +10 -0
- package/dist/extensions/llama/provider.d.ts.map +1 -0
- package/dist/extensions/llama/provider.js +106 -0
- package/dist/extensions/llama/provider.js.map +1 -0
- package/dist/extensions/llama/ui.d.ts +42 -0
- package/dist/extensions/llama/ui.d.ts.map +1 -0
- package/dist/extensions/llama/ui.js +420 -0
- package/dist/extensions/llama/ui.js.map +1 -0
- package/dist/extensions/tokenin-onboarding.ts +3 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +21 -19
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +22 -10
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +1 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +24 -23
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +5 -5
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +17 -8
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +11 -4
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +72 -41
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +4 -4
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +14 -27
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +5 -0
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +49 -12
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +8 -5
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +253 -225
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +4 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +7 -0
- 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 +6 -2
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +11 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +67 -5
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts +1 -0
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +13 -0
- package/dist/utils/clipboard.js.map +1 -1
- package/package.json +4 -4
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
16
16
|
import { basename, dirname } from "node:path";
|
|
17
|
+
import { contentText } from "@earendil-works/pi-ai";
|
|
17
18
|
import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isRetryableAssistantError, modelsAreEqual, resetApiProviders, streamSimple, } from "@earendil-works/pi-ai/compat";
|
|
18
19
|
import { getThemeByName, theme } from "../modes/interactive/theme/theme.js";
|
|
19
20
|
import { stripFrontmatter } from "../utils/frontmatter.js";
|
|
@@ -28,6 +29,7 @@ import { exportSessionToHtml } from "./export-html/index.js";
|
|
|
28
29
|
import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
|
|
29
30
|
import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
|
|
30
31
|
import { emitSessionShutdownEvent } from "./extensions/runner.js";
|
|
32
|
+
import { ModelRegistry } from "./model-registry.js";
|
|
31
33
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
32
34
|
import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-manager.js";
|
|
33
35
|
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
@@ -35,6 +37,7 @@ import { buildSystemPrompt } from "./system-prompt.js";
|
|
|
35
37
|
import { createLocalBashOperations } from "./tools/bash.js";
|
|
36
38
|
import { createAllToolDefinitions } from "./tools/index.js";
|
|
37
39
|
import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
|
|
40
|
+
import { addUsageToTotals, createUsageTotals } from "./usage-totals.js";
|
|
38
41
|
/**
|
|
39
42
|
* Parse a skill block from message text.
|
|
40
43
|
* Returns null if the text doesn't contain a skill block.
|
|
@@ -50,6 +53,14 @@ export function parseSkillBlock(text) {
|
|
|
50
53
|
userMessage: match[4]?.trim() || undefined,
|
|
51
54
|
};
|
|
52
55
|
}
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// Types
|
|
58
|
+
// ============================================================================
|
|
59
|
+
function withoutDeletedHeaders(headers) {
|
|
60
|
+
return headers
|
|
61
|
+
? Object.fromEntries(Object.entries(headers).filter((entry) => entry[1] !== null))
|
|
62
|
+
: undefined;
|
|
63
|
+
}
|
|
53
64
|
function estimateMessagesTokens(messages) {
|
|
54
65
|
let tokens = 0;
|
|
55
66
|
for (const message of messages) {
|
|
@@ -114,8 +125,7 @@ export class AgentSession {
|
|
|
114
125
|
_extensionShutdownHandler;
|
|
115
126
|
_extensionErrorListener;
|
|
116
127
|
_extensionErrorUnsubscriber;
|
|
117
|
-
|
|
118
|
-
_modelRegistry;
|
|
128
|
+
_modelRuntime;
|
|
119
129
|
// Tool registry for extension getTools/setTools
|
|
120
130
|
_toolRegistry = new Map();
|
|
121
131
|
_toolDefinitions = new Map();
|
|
@@ -133,7 +143,7 @@ export class AgentSession {
|
|
|
133
143
|
this._resourceLoader = config.resourceLoader;
|
|
134
144
|
this._customTools = config.customTools ?? [];
|
|
135
145
|
this._cwd = config.cwd;
|
|
136
|
-
this.
|
|
146
|
+
this._modelRuntime = config.modelRuntime;
|
|
137
147
|
this._extensionRunnerRef = config.extensionRunnerRef;
|
|
138
148
|
this._initialActiveToolNames = config.initialActiveToolNames;
|
|
139
149
|
this._allowedToolNames = config.allowedToolNames ? new Set(config.allowedToolNames) : undefined;
|
|
@@ -150,22 +160,29 @@ export class AgentSession {
|
|
|
150
160
|
includeAllExtensionTools: true,
|
|
151
161
|
});
|
|
152
162
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
return this._modelRegistry;
|
|
163
|
+
get modelRuntime() {
|
|
164
|
+
return this._modelRuntime;
|
|
156
165
|
}
|
|
157
166
|
async _getRequiredRequestAuth(model) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
167
|
+
let result;
|
|
168
|
+
try {
|
|
169
|
+
result = await this._modelRuntime.getAuth(model);
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
const cause = error instanceof Error ? error.cause : undefined;
|
|
173
|
+
if (cause instanceof Error && cause.message === "authHeader requires a resolved API key") {
|
|
161
174
|
throw new Error(formatNoApiKeyFoundMessage(model.provider));
|
|
162
175
|
}
|
|
163
|
-
throw
|
|
176
|
+
throw error;
|
|
164
177
|
}
|
|
165
|
-
if (result.apiKey) {
|
|
166
|
-
return {
|
|
178
|
+
if (result?.auth.apiKey) {
|
|
179
|
+
return {
|
|
180
|
+
apiKey: result.auth.apiKey,
|
|
181
|
+
headers: withoutDeletedHeaders(result.auth.headers),
|
|
182
|
+
env: result.env,
|
|
183
|
+
};
|
|
167
184
|
}
|
|
168
|
-
const isOAuth = this.
|
|
185
|
+
const isOAuth = this._modelRuntime.isUsingOAuth(model.provider);
|
|
169
186
|
if (isOAuth) {
|
|
170
187
|
throw new Error(`Authentication failed for "${model.provider}". ` +
|
|
171
188
|
`Credentials may have expired or network is unavailable. ` +
|
|
@@ -173,12 +190,19 @@ export class AgentSession {
|
|
|
173
190
|
}
|
|
174
191
|
throw new Error(formatNoApiKeyFoundMessage(model.provider));
|
|
175
192
|
}
|
|
176
|
-
async
|
|
177
|
-
if (this.agent.
|
|
193
|
+
async _getSummarizationRequestAuth(model) {
|
|
194
|
+
if (this.agent.streamFunction === streamSimple) {
|
|
178
195
|
return this._getRequiredRequestAuth(model);
|
|
179
196
|
}
|
|
180
|
-
|
|
181
|
-
|
|
197
|
+
try {
|
|
198
|
+
const result = await this._modelRuntime.getAuth(model);
|
|
199
|
+
return result
|
|
200
|
+
? { apiKey: result.auth.apiKey, headers: withoutDeletedHeaders(result.auth.headers), env: result.env }
|
|
201
|
+
: {};
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return {};
|
|
205
|
+
}
|
|
182
206
|
}
|
|
183
207
|
/**
|
|
184
208
|
* Install tool hooks once on the Agent instance.
|
|
@@ -222,6 +246,7 @@ export class AgentSession {
|
|
|
222
246
|
content: result.content,
|
|
223
247
|
details: result.details,
|
|
224
248
|
isError,
|
|
249
|
+
usage: result.usage,
|
|
225
250
|
});
|
|
226
251
|
if (!hookResult) {
|
|
227
252
|
return undefined;
|
|
@@ -230,6 +255,7 @@ export class AgentSession {
|
|
|
230
255
|
content: hookResult.content,
|
|
231
256
|
details: hookResult.details,
|
|
232
257
|
isError: hookResult.isError ?? isError,
|
|
258
|
+
usage: hookResult.usage,
|
|
233
259
|
};
|
|
234
260
|
};
|
|
235
261
|
}
|
|
@@ -341,7 +367,7 @@ export class AgentSession {
|
|
|
341
367
|
// This ensures the UI sees the updated queue state
|
|
342
368
|
if (event.type === "message_start" && event.message.role === "user") {
|
|
343
369
|
this._overflowRecoveryAttempted = false;
|
|
344
|
-
const messageText =
|
|
370
|
+
const messageText = contentText(event.message.content, "");
|
|
345
371
|
if (messageText) {
|
|
346
372
|
// Check steering queue first
|
|
347
373
|
const steeringIndex = this._steeringMessages.indexOf(messageText);
|
|
@@ -410,16 +436,6 @@ export class AgentSession {
|
|
|
410
436
|
}
|
|
411
437
|
return false;
|
|
412
438
|
}
|
|
413
|
-
/** Extract text content from a message */
|
|
414
|
-
_getUserMessageText(message) {
|
|
415
|
-
if (message.role !== "user")
|
|
416
|
-
return "";
|
|
417
|
-
const content = message.content;
|
|
418
|
-
if (typeof content === "string")
|
|
419
|
-
return content;
|
|
420
|
-
const textBlocks = content.filter((c) => c.type === "text");
|
|
421
|
-
return textBlocks.map((c) => c.text).join("");
|
|
422
|
-
}
|
|
423
439
|
/** Find the last assistant message in agent state (including aborted ones) */
|
|
424
440
|
_findLastAssistantMessage() {
|
|
425
441
|
const messages = this.agent.state.messages;
|
|
@@ -875,8 +891,10 @@ export class AgentSession {
|
|
|
875
891
|
if (!this.model) {
|
|
876
892
|
throw new Error(formatNoModelSelectedMessage());
|
|
877
893
|
}
|
|
878
|
-
|
|
879
|
-
|
|
894
|
+
const hasConfiguredAuth = this._modelRuntime.hasConfiguredAuth(this.model.provider) ||
|
|
895
|
+
(await this._modelRuntime.checkAuth(this.model.provider)) !== undefined;
|
|
896
|
+
if (!hasConfiguredAuth) {
|
|
897
|
+
const isOAuth = this._modelRuntime.isUsingOAuth(this.model.provider);
|
|
880
898
|
if (isOAuth) {
|
|
881
899
|
throw new Error(`Authentication failed for "${this.model.provider}". ` +
|
|
882
900
|
`Credentials may have expired or network is unavailable. ` +
|
|
@@ -1221,7 +1239,7 @@ export class AgentSession {
|
|
|
1221
1239
|
* @throws Error if no auth is configured for the model
|
|
1222
1240
|
*/
|
|
1223
1241
|
async setModel(model) {
|
|
1224
|
-
if (!this.
|
|
1242
|
+
if (!(await this._modelRuntime.checkAuth(model.provider))) {
|
|
1225
1243
|
throw new Error(`No API key for ${model.provider}/${model.id}`);
|
|
1226
1244
|
}
|
|
1227
1245
|
const previousModel = this.model;
|
|
@@ -1246,7 +1264,11 @@ export class AgentSession {
|
|
|
1246
1264
|
return this._cycleAvailableModel(direction);
|
|
1247
1265
|
}
|
|
1248
1266
|
async _cycleScopedModel(direction) {
|
|
1249
|
-
const
|
|
1267
|
+
const checks = await Promise.all(this._scopedModels.map(async (scoped) => ({
|
|
1268
|
+
scoped,
|
|
1269
|
+
auth: await this._modelRuntime.checkAuth(scoped.model.provider),
|
|
1270
|
+
})));
|
|
1271
|
+
const scopedModels = checks.filter(({ auth }) => auth !== undefined).map(({ scoped }) => scoped);
|
|
1250
1272
|
if (scopedModels.length <= 1)
|
|
1251
1273
|
return undefined;
|
|
1252
1274
|
const currentModel = this.model;
|
|
@@ -1270,7 +1292,7 @@ export class AgentSession {
|
|
|
1270
1292
|
return { model: next.model, thinkingLevel: this.thinkingLevel, isScoped: true };
|
|
1271
1293
|
}
|
|
1272
1294
|
async _cycleAvailableModel(direction) {
|
|
1273
|
-
const availableModels = await this.
|
|
1295
|
+
const availableModels = await this._modelRuntime.getAvailable();
|
|
1274
1296
|
if (availableModels.length <= 1)
|
|
1275
1297
|
return undefined;
|
|
1276
1298
|
const currentModel = this.model;
|
|
@@ -1398,7 +1420,7 @@ export class AgentSession {
|
|
|
1398
1420
|
if (!this.model) {
|
|
1399
1421
|
throw new Error(formatNoModelSelectedMessage());
|
|
1400
1422
|
}
|
|
1401
|
-
const { apiKey, headers, env } = await this.
|
|
1423
|
+
const { apiKey, headers, env } = await this._getSummarizationRequestAuth(this.model);
|
|
1402
1424
|
const pathEntries = this.sessionManager.getBranch();
|
|
1403
1425
|
const settings = this.settingsManager.getCompactionSettings();
|
|
1404
1426
|
const preparation = prepareCompaction(pathEntries, settings);
|
|
@@ -1433,26 +1455,29 @@ export class AgentSession {
|
|
|
1433
1455
|
let summary;
|
|
1434
1456
|
let firstKeptEntryId;
|
|
1435
1457
|
let tokensBefore;
|
|
1458
|
+
let usage;
|
|
1436
1459
|
let details;
|
|
1437
1460
|
if (extensionCompaction) {
|
|
1438
1461
|
// Extension provided compaction content
|
|
1439
1462
|
summary = extensionCompaction.summary;
|
|
1440
1463
|
firstKeptEntryId = extensionCompaction.firstKeptEntryId;
|
|
1441
1464
|
tokensBefore = extensionCompaction.tokensBefore;
|
|
1465
|
+
usage = extensionCompaction.usage;
|
|
1442
1466
|
details = extensionCompaction.details;
|
|
1443
1467
|
}
|
|
1444
1468
|
else {
|
|
1445
1469
|
// Generate compaction result
|
|
1446
|
-
const result = await compact(preparation, this.model, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel, this.agent.
|
|
1470
|
+
const result = await compact(preparation, this.model, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason: "manual" }));
|
|
1447
1471
|
summary = result.summary;
|
|
1448
1472
|
firstKeptEntryId = result.firstKeptEntryId;
|
|
1449
1473
|
tokensBefore = result.tokensBefore;
|
|
1474
|
+
usage = result.usage;
|
|
1450
1475
|
details = result.details;
|
|
1451
1476
|
}
|
|
1452
1477
|
if (this._compactionAbortController.signal.aborted) {
|
|
1453
1478
|
throw new Error("Compaction cancelled");
|
|
1454
1479
|
}
|
|
1455
|
-
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension);
|
|
1480
|
+
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension, usage);
|
|
1456
1481
|
const newEntries = this.sessionManager.getEntries();
|
|
1457
1482
|
const sessionContext = this.sessionManager.buildSessionContext();
|
|
1458
1483
|
this.agent.state.messages = sessionContext.messages;
|
|
@@ -1473,6 +1498,7 @@ export class AgentSession {
|
|
|
1473
1498
|
firstKeptEntryId,
|
|
1474
1499
|
tokensBefore,
|
|
1475
1500
|
estimatedTokensAfter,
|
|
1501
|
+
usage,
|
|
1476
1502
|
details,
|
|
1477
1503
|
};
|
|
1478
1504
|
this._emit({
|
|
@@ -1619,17 +1645,16 @@ export class AgentSession {
|
|
|
1619
1645
|
let apiKey;
|
|
1620
1646
|
let headers;
|
|
1621
1647
|
let env;
|
|
1622
|
-
if (this.agent.
|
|
1623
|
-
const authResult = await this.
|
|
1624
|
-
if (!authResult.
|
|
1648
|
+
if (this.agent.streamFunction === streamSimple) {
|
|
1649
|
+
const authResult = await this._modelRuntime.getAuth(this.model);
|
|
1650
|
+
if (!authResult?.auth.apiKey)
|
|
1625
1651
|
return false;
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
headers = authResult.headers;
|
|
1652
|
+
apiKey = authResult.auth.apiKey;
|
|
1653
|
+
headers = withoutDeletedHeaders(authResult.auth.headers);
|
|
1629
1654
|
env = authResult.env;
|
|
1630
1655
|
}
|
|
1631
1656
|
else {
|
|
1632
|
-
({ apiKey, headers, env } = await this.
|
|
1657
|
+
({ apiKey, headers, env } = await this._getSummarizationRequestAuth(this.model));
|
|
1633
1658
|
}
|
|
1634
1659
|
const pathEntries = this.sessionManager.getBranch();
|
|
1635
1660
|
const preparation = prepareCompaction(pathEntries, settings);
|
|
@@ -1669,20 +1694,23 @@ export class AgentSession {
|
|
|
1669
1694
|
let summary;
|
|
1670
1695
|
let firstKeptEntryId;
|
|
1671
1696
|
let tokensBefore;
|
|
1697
|
+
let usage;
|
|
1672
1698
|
let details;
|
|
1673
1699
|
if (extensionCompaction) {
|
|
1674
1700
|
// Extension provided compaction content
|
|
1675
1701
|
summary = extensionCompaction.summary;
|
|
1676
1702
|
firstKeptEntryId = extensionCompaction.firstKeptEntryId;
|
|
1677
1703
|
tokensBefore = extensionCompaction.tokensBefore;
|
|
1704
|
+
usage = extensionCompaction.usage;
|
|
1678
1705
|
details = extensionCompaction.details;
|
|
1679
1706
|
}
|
|
1680
1707
|
else {
|
|
1681
1708
|
// Generate compaction result
|
|
1682
|
-
const compactResult = await compact(preparation, this.model, apiKey, headers, undefined, this._autoCompactionAbortController.signal, this.thinkingLevel, this.agent.
|
|
1709
|
+
const compactResult = await compact(preparation, this.model, apiKey, headers, undefined, this._autoCompactionAbortController.signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }));
|
|
1683
1710
|
summary = compactResult.summary;
|
|
1684
1711
|
firstKeptEntryId = compactResult.firstKeptEntryId;
|
|
1685
1712
|
tokensBefore = compactResult.tokensBefore;
|
|
1713
|
+
usage = compactResult.usage;
|
|
1686
1714
|
details = compactResult.details;
|
|
1687
1715
|
}
|
|
1688
1716
|
if (this._autoCompactionAbortController.signal.aborted) {
|
|
@@ -1695,7 +1723,7 @@ export class AgentSession {
|
|
|
1695
1723
|
});
|
|
1696
1724
|
return false;
|
|
1697
1725
|
}
|
|
1698
|
-
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension);
|
|
1726
|
+
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension, usage);
|
|
1699
1727
|
const newEntries = this.sessionManager.getEntries();
|
|
1700
1728
|
const sessionContext = this.sessionManager.buildSessionContext();
|
|
1701
1729
|
this.agent.state.messages = sessionContext.messages;
|
|
@@ -1716,6 +1744,7 @@ export class AgentSession {
|
|
|
1716
1744
|
firstKeptEntryId,
|
|
1717
1745
|
tokensBefore,
|
|
1718
1746
|
estimatedTokensAfter,
|
|
1747
|
+
usage,
|
|
1719
1748
|
details,
|
|
1720
1749
|
};
|
|
1721
1750
|
this._emit({ type: "compaction_end", reason, result, aborted: false, willRetry });
|
|
@@ -1843,7 +1872,7 @@ export class AgentSession {
|
|
|
1843
1872
|
if (!currentModel) {
|
|
1844
1873
|
return;
|
|
1845
1874
|
}
|
|
1846
|
-
const refreshedModel = this.
|
|
1875
|
+
const refreshedModel = this._modelRuntime.getModel(currentModel.provider, currentModel.id);
|
|
1847
1876
|
if (!refreshedModel || refreshedModel === currentModel) {
|
|
1848
1877
|
return;
|
|
1849
1878
|
}
|
|
@@ -1912,7 +1941,7 @@ export class AgentSession {
|
|
|
1912
1941
|
refreshTools: () => this._refreshToolRegistry(),
|
|
1913
1942
|
getCommands,
|
|
1914
1943
|
setModel: async (model) => {
|
|
1915
|
-
if (!this.
|
|
1944
|
+
if (!this._modelRuntime.hasConfiguredAuth(model.provider))
|
|
1916
1945
|
return false;
|
|
1917
1946
|
await this.setModel(model);
|
|
1918
1947
|
return true;
|
|
@@ -1952,11 +1981,15 @@ export class AgentSession {
|
|
|
1952
1981
|
getSystemPromptOptions: () => this._baseSystemPromptOptions,
|
|
1953
1982
|
}, {
|
|
1954
1983
|
registerProvider: (name, config) => {
|
|
1955
|
-
this.
|
|
1984
|
+
this._modelRuntime.registerProvider(name, config);
|
|
1985
|
+
this._refreshCurrentModelFromRegistry();
|
|
1986
|
+
},
|
|
1987
|
+
registerNativeProvider: (provider) => {
|
|
1988
|
+
this._modelRuntime.registerNativeProvider(provider);
|
|
1956
1989
|
this._refreshCurrentModelFromRegistry();
|
|
1957
1990
|
},
|
|
1958
1991
|
unregisterProvider: (name) => {
|
|
1959
|
-
this.
|
|
1992
|
+
this._modelRuntime.unregisterProvider(name);
|
|
1960
1993
|
this._refreshCurrentModelFromRegistry();
|
|
1961
1994
|
},
|
|
1962
1995
|
});
|
|
@@ -2058,7 +2091,7 @@ export class AgentSession {
|
|
|
2058
2091
|
extensionsResult.runtime.flagValues.set(name, value);
|
|
2059
2092
|
}
|
|
2060
2093
|
}
|
|
2061
|
-
this._extensionRunner = new ExtensionRunner(extensionsResult.extensions, extensionsResult.runtime, this._cwd, this.sessionManager, this.
|
|
2094
|
+
this._extensionRunner = new ExtensionRunner(extensionsResult.extensions, extensionsResult.runtime, this._cwd, this.sessionManager, new ModelRegistry(this._modelRuntime));
|
|
2062
2095
|
if (this._extensionRunnerRef) {
|
|
2063
2096
|
this._extensionRunnerRef.current = this._extensionRunner;
|
|
2064
2097
|
}
|
|
@@ -2108,6 +2141,34 @@ export class AgentSession {
|
|
|
2108
2141
|
return false;
|
|
2109
2142
|
return isRetryableAssistantError(message);
|
|
2110
2143
|
}
|
|
2144
|
+
/**
|
|
2145
|
+
* Retry policy + callbacks shared by compaction and branch-summary summarization calls.
|
|
2146
|
+
* Uses the same `settings.retry` budget/backoff as agent-turn retries so a single transient
|
|
2147
|
+
* stream drop no longer fails the whole operation. `source` carries the context
|
|
2148
|
+
* the TUI needs to render the retry and recreate the underlying indicator.
|
|
2149
|
+
*/
|
|
2150
|
+
_summarizationRetryCallbacks(source) {
|
|
2151
|
+
return {
|
|
2152
|
+
onRetryScheduled: (attempt, maxAttempts, delayMs, errorMessage) => {
|
|
2153
|
+
this._emit({
|
|
2154
|
+
type: "summarization_retry_scheduled",
|
|
2155
|
+
attempt,
|
|
2156
|
+
maxAttempts,
|
|
2157
|
+
delayMs,
|
|
2158
|
+
errorMessage,
|
|
2159
|
+
});
|
|
2160
|
+
},
|
|
2161
|
+
onRetryAttemptStart: () => {
|
|
2162
|
+
this._emit({
|
|
2163
|
+
type: "summarization_retry_attempt_start",
|
|
2164
|
+
...source,
|
|
2165
|
+
});
|
|
2166
|
+
},
|
|
2167
|
+
onRetryFinished: () => {
|
|
2168
|
+
this._emit({ type: "summarization_retry_finished" });
|
|
2169
|
+
},
|
|
2170
|
+
};
|
|
2171
|
+
}
|
|
2111
2172
|
/**
|
|
2112
2173
|
* Prepare a retryable error for continuation with exponential backoff.
|
|
2113
2174
|
* @returns true if the caller should continue the agent, false otherwise
|
|
@@ -2353,9 +2414,10 @@ export class AgentSession {
|
|
|
2353
2414
|
// Run default summarizer if needed
|
|
2354
2415
|
let summaryText;
|
|
2355
2416
|
let summaryDetails;
|
|
2417
|
+
let summaryUsage;
|
|
2356
2418
|
if (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {
|
|
2357
2419
|
const model = this.model;
|
|
2358
|
-
const { apiKey, headers, env } = await this.
|
|
2420
|
+
const { apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
|
|
2359
2421
|
const branchSummarySettings = this.settingsManager.getBranchSummarySettings();
|
|
2360
2422
|
const result = await generateBranchSummary(entriesToSummarize, {
|
|
2361
2423
|
model,
|
|
@@ -2366,7 +2428,9 @@ export class AgentSession {
|
|
|
2366
2428
|
customInstructions,
|
|
2367
2429
|
replaceInstructions,
|
|
2368
2430
|
reserveTokens: branchSummarySettings.reserveTokens,
|
|
2369
|
-
streamFn: this.agent.
|
|
2431
|
+
streamFn: this.agent.streamFunction,
|
|
2432
|
+
retry: this.settingsManager.getRetrySettings(),
|
|
2433
|
+
callbacks: this._summarizationRetryCallbacks({ source: "branchSummary" }),
|
|
2370
2434
|
});
|
|
2371
2435
|
if (result.aborted) {
|
|
2372
2436
|
return { cancelled: true, aborted: true };
|
|
@@ -2375,6 +2439,7 @@ export class AgentSession {
|
|
|
2375
2439
|
throw new Error(result.error);
|
|
2376
2440
|
}
|
|
2377
2441
|
summaryText = result.summary;
|
|
2442
|
+
summaryUsage = result.usage;
|
|
2378
2443
|
summaryDetails = {
|
|
2379
2444
|
readFiles: result.readFiles || [],
|
|
2380
2445
|
modifiedFiles: result.modifiedFiles || [],
|
|
@@ -2383,6 +2448,7 @@ export class AgentSession {
|
|
|
2383
2448
|
else if (extensionSummary) {
|
|
2384
2449
|
summaryText = extensionSummary.summary;
|
|
2385
2450
|
summaryDetails = extensionSummary.details;
|
|
2451
|
+
summaryUsage = extensionSummary.usage;
|
|
2386
2452
|
}
|
|
2387
2453
|
// Determine the new leaf position based on target type
|
|
2388
2454
|
let newLeafId;
|
|
@@ -2390,18 +2456,12 @@ export class AgentSession {
|
|
|
2390
2456
|
if (targetEntry.type === "message" && targetEntry.message.role === "user") {
|
|
2391
2457
|
// User message: leaf = parent (null if root), text goes to editor
|
|
2392
2458
|
newLeafId = targetEntry.parentId;
|
|
2393
|
-
editorText =
|
|
2459
|
+
editorText = contentText(targetEntry.message.content, "");
|
|
2394
2460
|
}
|
|
2395
2461
|
else if (targetEntry.type === "custom_message") {
|
|
2396
2462
|
// Custom message: leaf = parent (null if root), text goes to editor
|
|
2397
2463
|
newLeafId = targetEntry.parentId;
|
|
2398
|
-
editorText =
|
|
2399
|
-
typeof targetEntry.content === "string"
|
|
2400
|
-
? targetEntry.content
|
|
2401
|
-
: targetEntry.content
|
|
2402
|
-
.filter((c) => c.type === "text")
|
|
2403
|
-
.map((c) => c.text)
|
|
2404
|
-
.join("");
|
|
2464
|
+
editorText = contentText(targetEntry.content, "");
|
|
2405
2465
|
}
|
|
2406
2466
|
else {
|
|
2407
2467
|
// Non-user message: leaf = selected node
|
|
@@ -2412,7 +2472,7 @@ export class AgentSession {
|
|
|
2412
2472
|
let summaryEntry;
|
|
2413
2473
|
if (summaryText) {
|
|
2414
2474
|
// Create summary at target position (can be null for root)
|
|
2415
|
-
const summaryId = this.sessionManager.branchWithSummary(newLeafId, summaryText, summaryDetails, fromExtension);
|
|
2475
|
+
const summaryId = this.sessionManager.branchWithSummary(newLeafId, summaryText, summaryDetails, fromExtension, summaryUsage);
|
|
2416
2476
|
summaryEntry = this.sessionManager.getEntry(summaryId);
|
|
2417
2477
|
// Attach label to the summary entry
|
|
2418
2478
|
if (label) {
|
|
@@ -2460,24 +2520,13 @@ export class AgentSession {
|
|
|
2460
2520
|
continue;
|
|
2461
2521
|
if (entry.message.role !== "user")
|
|
2462
2522
|
continue;
|
|
2463
|
-
const text =
|
|
2523
|
+
const text = contentText(entry.message.content, "");
|
|
2464
2524
|
if (text) {
|
|
2465
2525
|
result.push({ entryId: entry.id, text });
|
|
2466
2526
|
}
|
|
2467
2527
|
}
|
|
2468
2528
|
return result;
|
|
2469
2529
|
}
|
|
2470
|
-
_extractUserMessageText(content) {
|
|
2471
|
-
if (typeof content === "string")
|
|
2472
|
-
return content;
|
|
2473
|
-
if (Array.isArray(content)) {
|
|
2474
|
-
return content
|
|
2475
|
-
.filter((c) => c.type === "text")
|
|
2476
|
-
.map((c) => c.text)
|
|
2477
|
-
.join("");
|
|
2478
|
-
}
|
|
2479
|
-
return "";
|
|
2480
|
-
}
|
|
2481
2530
|
/**
|
|
2482
2531
|
* Get session statistics. Aggregates over ALL session entries (including
|
|
2483
2532
|
* history that was compacted away), so token/cost totals reflect what was
|
|
@@ -2489,12 +2538,11 @@ export class AgentSession {
|
|
|
2489
2538
|
let toolResults = 0;
|
|
2490
2539
|
let totalMessages = 0;
|
|
2491
2540
|
let toolCalls = 0;
|
|
2492
|
-
|
|
2493
|
-
let totalOutput = 0;
|
|
2494
|
-
let totalCacheRead = 0;
|
|
2495
|
-
let totalCacheWrite = 0;
|
|
2496
|
-
let totalCost = 0;
|
|
2541
|
+
const usageTotals = createUsageTotals();
|
|
2497
2542
|
for (const entry of this.sessionManager.getEntries()) {
|
|
2543
|
+
if ((entry.type === "branch_summary" || entry.type === "compaction") && entry.usage) {
|
|
2544
|
+
addUsageToTotals(usageTotals, entry.usage);
|
|
2545
|
+
}
|
|
2498
2546
|
if (entry.type !== "message")
|
|
2499
2547
|
continue;
|
|
2500
2548
|
totalMessages++;
|
|
@@ -2504,6 +2552,9 @@ export class AgentSession {
|
|
|
2504
2552
|
}
|
|
2505
2553
|
else if (message.role === "toolResult") {
|
|
2506
2554
|
toolResults++;
|
|
2555
|
+
if (message.usage) {
|
|
2556
|
+
addUsageToTotals(usageTotals, message.usage);
|
|
2557
|
+
}
|
|
2507
2558
|
}
|
|
2508
2559
|
else if (message.role === "assistant") {
|
|
2509
2560
|
assistantMessages++;
|
|
@@ -2511,12 +2562,7 @@ export class AgentSession {
|
|
|
2511
2562
|
if (Array.isArray(assistantMsg.content)) {
|
|
2512
2563
|
toolCalls += assistantMsg.content.filter((c) => c.type === "toolCall").length;
|
|
2513
2564
|
}
|
|
2514
|
-
|
|
2515
|
-
totalInput += usage.input;
|
|
2516
|
-
totalOutput += usage.output;
|
|
2517
|
-
totalCacheRead += usage.cacheRead;
|
|
2518
|
-
totalCacheWrite += usage.cacheWrite;
|
|
2519
|
-
totalCost += usage.cost.total;
|
|
2565
|
+
addUsageToTotals(usageTotals, assistantMsg.usage);
|
|
2520
2566
|
}
|
|
2521
2567
|
}
|
|
2522
2568
|
return {
|
|
@@ -2528,13 +2574,13 @@ export class AgentSession {
|
|
|
2528
2574
|
toolResults,
|
|
2529
2575
|
totalMessages,
|
|
2530
2576
|
tokens: {
|
|
2531
|
-
input:
|
|
2532
|
-
output:
|
|
2533
|
-
cacheRead:
|
|
2534
|
-
cacheWrite:
|
|
2535
|
-
total:
|
|
2577
|
+
input: usageTotals.input,
|
|
2578
|
+
output: usageTotals.output,
|
|
2579
|
+
cacheRead: usageTotals.cacheRead,
|
|
2580
|
+
cacheWrite: usageTotals.cacheWrite,
|
|
2581
|
+
total: usageTotals.input + usageTotals.output + usageTotals.cacheRead + usageTotals.cacheWrite,
|
|
2536
2582
|
},
|
|
2537
|
-
cost:
|
|
2583
|
+
cost: usageTotals.cost,
|
|
2538
2584
|
contextUsage: this.getContextUsage(),
|
|
2539
2585
|
};
|
|
2540
2586
|
}
|