@earendil-works/pi-coding-agent 0.80.10 → 0.81.0
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 +42 -0
- package/README.md +6 -3
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +13 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +0 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +45 -56
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +2 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -4
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +7 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +47 -14
- 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 +13 -2
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +2 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +31 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +16 -2
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +17 -2
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +2 -0
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +7 -2
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +41 -18
- package/dist/core/model-runtime.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/remote-catalog-provider.d.ts +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +26 -7
- package/dist/core/remote-catalog-provider.js.map +1 -1
- 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/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +9 -4
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +99 -23
- package/dist/core/session-manager.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 +3 -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 +302 -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 +141 -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 +208 -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 +102 -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 +416 -0
- package/dist/extensions/llama/ui.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +9 -4
- package/dist/main.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/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +14 -22
- 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 +4 -0
- 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/docs/compaction.md +8 -3
- package/docs/custom-provider.md +28 -0
- package/docs/extensions.md +51 -9
- package/docs/index.md +1 -0
- package/docs/llama-cpp.md +99 -0
- package/docs/prompt-templates.md +1 -0
- package/docs/providers.md +11 -0
- package/docs/rpc.md +48 -2
- package/docs/session-format.md +17 -3
- package/docs/tui.md +41 -26
- package/docs/usage.md +2 -1
- package/examples/extensions/README.md +1 -1
- package/examples/extensions/custom-compaction.ts +1 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +16 -31
- 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";
|
|
@@ -35,6 +36,7 @@ import { buildSystemPrompt } from "./system-prompt.js";
|
|
|
35
36
|
import { createLocalBashOperations } from "./tools/bash.js";
|
|
36
37
|
import { createAllToolDefinitions } from "./tools/index.js";
|
|
37
38
|
import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
|
|
39
|
+
import { addUsageToTotals, createUsageTotals } from "./usage-totals.js";
|
|
38
40
|
/**
|
|
39
41
|
* Parse a skill block from message text.
|
|
40
42
|
* Returns null if the text doesn't contain a skill block.
|
|
@@ -188,7 +190,7 @@ export class AgentSession {
|
|
|
188
190
|
throw new Error(formatNoApiKeyFoundMessage(model.provider));
|
|
189
191
|
}
|
|
190
192
|
async _getSummarizationRequestAuth(model) {
|
|
191
|
-
if (this.agent.
|
|
193
|
+
if (this.agent.streamFunction === streamSimple) {
|
|
192
194
|
return this._getRequiredRequestAuth(model);
|
|
193
195
|
}
|
|
194
196
|
try {
|
|
@@ -243,6 +245,7 @@ export class AgentSession {
|
|
|
243
245
|
content: result.content,
|
|
244
246
|
details: result.details,
|
|
245
247
|
isError,
|
|
248
|
+
usage: result.usage,
|
|
246
249
|
});
|
|
247
250
|
if (!hookResult) {
|
|
248
251
|
return undefined;
|
|
@@ -251,6 +254,7 @@ export class AgentSession {
|
|
|
251
254
|
content: hookResult.content,
|
|
252
255
|
details: hookResult.details,
|
|
253
256
|
isError: hookResult.isError ?? isError,
|
|
257
|
+
usage: hookResult.usage,
|
|
254
258
|
};
|
|
255
259
|
};
|
|
256
260
|
}
|
|
@@ -325,7 +329,7 @@ export class AgentSession {
|
|
|
325
329
|
// This ensures the UI sees the updated queue state
|
|
326
330
|
if (event.type === "message_start" && event.message.role === "user") {
|
|
327
331
|
this._overflowRecoveryAttempted = false;
|
|
328
|
-
const messageText =
|
|
332
|
+
const messageText = contentText(event.message.content, "");
|
|
329
333
|
if (messageText) {
|
|
330
334
|
// Check steering queue first
|
|
331
335
|
const steeringIndex = this._steeringMessages.indexOf(messageText);
|
|
@@ -394,16 +398,6 @@ export class AgentSession {
|
|
|
394
398
|
}
|
|
395
399
|
return false;
|
|
396
400
|
}
|
|
397
|
-
/** Extract text content from a message */
|
|
398
|
-
_getUserMessageText(message) {
|
|
399
|
-
if (message.role !== "user")
|
|
400
|
-
return "";
|
|
401
|
-
const content = message.content;
|
|
402
|
-
if (typeof content === "string")
|
|
403
|
-
return content;
|
|
404
|
-
const textBlocks = content.filter((c) => c.type === "text");
|
|
405
|
-
return textBlocks.map((c) => c.text).join("");
|
|
406
|
-
}
|
|
407
401
|
/** Find the last assistant message in agent state (including aborted ones) */
|
|
408
402
|
_findLastAssistantMessage() {
|
|
409
403
|
const messages = this.agent.state.messages;
|
|
@@ -1414,26 +1408,29 @@ export class AgentSession {
|
|
|
1414
1408
|
let summary;
|
|
1415
1409
|
let firstKeptEntryId;
|
|
1416
1410
|
let tokensBefore;
|
|
1411
|
+
let usage;
|
|
1417
1412
|
let details;
|
|
1418
1413
|
if (extensionCompaction) {
|
|
1419
1414
|
// Extension provided compaction content
|
|
1420
1415
|
summary = extensionCompaction.summary;
|
|
1421
1416
|
firstKeptEntryId = extensionCompaction.firstKeptEntryId;
|
|
1422
1417
|
tokensBefore = extensionCompaction.tokensBefore;
|
|
1418
|
+
usage = extensionCompaction.usage;
|
|
1423
1419
|
details = extensionCompaction.details;
|
|
1424
1420
|
}
|
|
1425
1421
|
else {
|
|
1426
1422
|
// Generate compaction result
|
|
1427
|
-
const result = await compact(preparation, this.model, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel, this.agent.
|
|
1423
|
+
const result = await compact(preparation, this.model, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel, this.agent.streamFunction, env);
|
|
1428
1424
|
summary = result.summary;
|
|
1429
1425
|
firstKeptEntryId = result.firstKeptEntryId;
|
|
1430
1426
|
tokensBefore = result.tokensBefore;
|
|
1427
|
+
usage = result.usage;
|
|
1431
1428
|
details = result.details;
|
|
1432
1429
|
}
|
|
1433
1430
|
if (this._compactionAbortController.signal.aborted) {
|
|
1434
1431
|
throw new Error("Compaction cancelled");
|
|
1435
1432
|
}
|
|
1436
|
-
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension);
|
|
1433
|
+
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension, usage);
|
|
1437
1434
|
const newEntries = this.sessionManager.getEntries();
|
|
1438
1435
|
const sessionContext = this.sessionManager.buildSessionContext();
|
|
1439
1436
|
this.agent.state.messages = sessionContext.messages;
|
|
@@ -1454,6 +1451,7 @@ export class AgentSession {
|
|
|
1454
1451
|
firstKeptEntryId,
|
|
1455
1452
|
tokensBefore,
|
|
1456
1453
|
estimatedTokensAfter,
|
|
1454
|
+
usage,
|
|
1457
1455
|
details,
|
|
1458
1456
|
};
|
|
1459
1457
|
this._emit({
|
|
@@ -1600,7 +1598,7 @@ export class AgentSession {
|
|
|
1600
1598
|
let apiKey;
|
|
1601
1599
|
let headers;
|
|
1602
1600
|
let env;
|
|
1603
|
-
if (this.agent.
|
|
1601
|
+
if (this.agent.streamFunction === streamSimple) {
|
|
1604
1602
|
const authResult = await this._modelRuntime.getAuth(this.model);
|
|
1605
1603
|
if (!authResult?.auth.apiKey)
|
|
1606
1604
|
return false;
|
|
@@ -1649,20 +1647,23 @@ export class AgentSession {
|
|
|
1649
1647
|
let summary;
|
|
1650
1648
|
let firstKeptEntryId;
|
|
1651
1649
|
let tokensBefore;
|
|
1650
|
+
let usage;
|
|
1652
1651
|
let details;
|
|
1653
1652
|
if (extensionCompaction) {
|
|
1654
1653
|
// Extension provided compaction content
|
|
1655
1654
|
summary = extensionCompaction.summary;
|
|
1656
1655
|
firstKeptEntryId = extensionCompaction.firstKeptEntryId;
|
|
1657
1656
|
tokensBefore = extensionCompaction.tokensBefore;
|
|
1657
|
+
usage = extensionCompaction.usage;
|
|
1658
1658
|
details = extensionCompaction.details;
|
|
1659
1659
|
}
|
|
1660
1660
|
else {
|
|
1661
1661
|
// Generate compaction result
|
|
1662
|
-
const compactResult = await compact(preparation, this.model, apiKey, headers, undefined, this._autoCompactionAbortController.signal, this.thinkingLevel, this.agent.
|
|
1662
|
+
const compactResult = await compact(preparation, this.model, apiKey, headers, undefined, this._autoCompactionAbortController.signal, this.thinkingLevel, this.agent.streamFunction, env);
|
|
1663
1663
|
summary = compactResult.summary;
|
|
1664
1664
|
firstKeptEntryId = compactResult.firstKeptEntryId;
|
|
1665
1665
|
tokensBefore = compactResult.tokensBefore;
|
|
1666
|
+
usage = compactResult.usage;
|
|
1666
1667
|
details = compactResult.details;
|
|
1667
1668
|
}
|
|
1668
1669
|
if (this._autoCompactionAbortController.signal.aborted) {
|
|
@@ -1675,7 +1676,7 @@ export class AgentSession {
|
|
|
1675
1676
|
});
|
|
1676
1677
|
return false;
|
|
1677
1678
|
}
|
|
1678
|
-
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension);
|
|
1679
|
+
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension, usage);
|
|
1679
1680
|
const newEntries = this.sessionManager.getEntries();
|
|
1680
1681
|
const sessionContext = this.sessionManager.buildSessionContext();
|
|
1681
1682
|
this.agent.state.messages = sessionContext.messages;
|
|
@@ -1696,6 +1697,7 @@ export class AgentSession {
|
|
|
1696
1697
|
firstKeptEntryId,
|
|
1697
1698
|
tokensBefore,
|
|
1698
1699
|
estimatedTokensAfter,
|
|
1700
|
+
usage,
|
|
1699
1701
|
details,
|
|
1700
1702
|
};
|
|
1701
1703
|
this._emit({ type: "compaction_end", reason, result, aborted: false, willRetry });
|
|
@@ -1929,6 +1931,10 @@ export class AgentSession {
|
|
|
1929
1931
|
this._modelRuntime.registerProvider(name, config);
|
|
1930
1932
|
this._refreshCurrentModelFromRegistry();
|
|
1931
1933
|
},
|
|
1934
|
+
registerNativeProvider: (provider) => {
|
|
1935
|
+
this._modelRuntime.registerNativeProvider(provider);
|
|
1936
|
+
this._refreshCurrentModelFromRegistry();
|
|
1937
|
+
},
|
|
1932
1938
|
unregisterProvider: (name) => {
|
|
1933
1939
|
this._modelRuntime.unregisterProvider(name);
|
|
1934
1940
|
this._refreshCurrentModelFromRegistry();
|
|
@@ -2327,6 +2333,7 @@ export class AgentSession {
|
|
|
2327
2333
|
// Run default summarizer if needed
|
|
2328
2334
|
let summaryText;
|
|
2329
2335
|
let summaryDetails;
|
|
2336
|
+
let summaryUsage;
|
|
2330
2337
|
if (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {
|
|
2331
2338
|
const model = this.model;
|
|
2332
2339
|
const { apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
|
|
@@ -2340,7 +2347,7 @@ export class AgentSession {
|
|
|
2340
2347
|
customInstructions,
|
|
2341
2348
|
replaceInstructions,
|
|
2342
2349
|
reserveTokens: branchSummarySettings.reserveTokens,
|
|
2343
|
-
streamFn: this.agent.
|
|
2350
|
+
streamFn: this.agent.streamFunction,
|
|
2344
2351
|
});
|
|
2345
2352
|
if (result.aborted) {
|
|
2346
2353
|
return { cancelled: true, aborted: true };
|
|
@@ -2349,6 +2356,7 @@ export class AgentSession {
|
|
|
2349
2356
|
throw new Error(result.error);
|
|
2350
2357
|
}
|
|
2351
2358
|
summaryText = result.summary;
|
|
2359
|
+
summaryUsage = result.usage;
|
|
2352
2360
|
summaryDetails = {
|
|
2353
2361
|
readFiles: result.readFiles || [],
|
|
2354
2362
|
modifiedFiles: result.modifiedFiles || [],
|
|
@@ -2357,6 +2365,7 @@ export class AgentSession {
|
|
|
2357
2365
|
else if (extensionSummary) {
|
|
2358
2366
|
summaryText = extensionSummary.summary;
|
|
2359
2367
|
summaryDetails = extensionSummary.details;
|
|
2368
|
+
summaryUsage = extensionSummary.usage;
|
|
2360
2369
|
}
|
|
2361
2370
|
// Determine the new leaf position based on target type
|
|
2362
2371
|
let newLeafId;
|
|
@@ -2364,18 +2373,12 @@ export class AgentSession {
|
|
|
2364
2373
|
if (targetEntry.type === "message" && targetEntry.message.role === "user") {
|
|
2365
2374
|
// User message: leaf = parent (null if root), text goes to editor
|
|
2366
2375
|
newLeafId = targetEntry.parentId;
|
|
2367
|
-
editorText =
|
|
2376
|
+
editorText = contentText(targetEntry.message.content, "");
|
|
2368
2377
|
}
|
|
2369
2378
|
else if (targetEntry.type === "custom_message") {
|
|
2370
2379
|
// Custom message: leaf = parent (null if root), text goes to editor
|
|
2371
2380
|
newLeafId = targetEntry.parentId;
|
|
2372
|
-
editorText =
|
|
2373
|
-
typeof targetEntry.content === "string"
|
|
2374
|
-
? targetEntry.content
|
|
2375
|
-
: targetEntry.content
|
|
2376
|
-
.filter((c) => c.type === "text")
|
|
2377
|
-
.map((c) => c.text)
|
|
2378
|
-
.join("");
|
|
2381
|
+
editorText = contentText(targetEntry.content, "");
|
|
2379
2382
|
}
|
|
2380
2383
|
else {
|
|
2381
2384
|
// Non-user message: leaf = selected node
|
|
@@ -2386,7 +2389,7 @@ export class AgentSession {
|
|
|
2386
2389
|
let summaryEntry;
|
|
2387
2390
|
if (summaryText) {
|
|
2388
2391
|
// Create summary at target position (can be null for root)
|
|
2389
|
-
const summaryId = this.sessionManager.branchWithSummary(newLeafId, summaryText, summaryDetails, fromExtension);
|
|
2392
|
+
const summaryId = this.sessionManager.branchWithSummary(newLeafId, summaryText, summaryDetails, fromExtension, summaryUsage);
|
|
2390
2393
|
summaryEntry = this.sessionManager.getEntry(summaryId);
|
|
2391
2394
|
// Attach label to the summary entry
|
|
2392
2395
|
if (label) {
|
|
@@ -2434,24 +2437,13 @@ export class AgentSession {
|
|
|
2434
2437
|
continue;
|
|
2435
2438
|
if (entry.message.role !== "user")
|
|
2436
2439
|
continue;
|
|
2437
|
-
const text =
|
|
2440
|
+
const text = contentText(entry.message.content, "");
|
|
2438
2441
|
if (text) {
|
|
2439
2442
|
result.push({ entryId: entry.id, text });
|
|
2440
2443
|
}
|
|
2441
2444
|
}
|
|
2442
2445
|
return result;
|
|
2443
2446
|
}
|
|
2444
|
-
_extractUserMessageText(content) {
|
|
2445
|
-
if (typeof content === "string")
|
|
2446
|
-
return content;
|
|
2447
|
-
if (Array.isArray(content)) {
|
|
2448
|
-
return content
|
|
2449
|
-
.filter((c) => c.type === "text")
|
|
2450
|
-
.map((c) => c.text)
|
|
2451
|
-
.join("");
|
|
2452
|
-
}
|
|
2453
|
-
return "";
|
|
2454
|
-
}
|
|
2455
2447
|
/**
|
|
2456
2448
|
* Get session statistics. Aggregates over ALL session entries (including
|
|
2457
2449
|
* history that was compacted away), so token/cost totals reflect what was
|
|
@@ -2463,12 +2455,11 @@ export class AgentSession {
|
|
|
2463
2455
|
let toolResults = 0;
|
|
2464
2456
|
let totalMessages = 0;
|
|
2465
2457
|
let toolCalls = 0;
|
|
2466
|
-
|
|
2467
|
-
let totalOutput = 0;
|
|
2468
|
-
let totalCacheRead = 0;
|
|
2469
|
-
let totalCacheWrite = 0;
|
|
2470
|
-
let totalCost = 0;
|
|
2458
|
+
const usageTotals = createUsageTotals();
|
|
2471
2459
|
for (const entry of this.sessionManager.getEntries()) {
|
|
2460
|
+
if ((entry.type === "branch_summary" || entry.type === "compaction") && entry.usage) {
|
|
2461
|
+
addUsageToTotals(usageTotals, entry.usage);
|
|
2462
|
+
}
|
|
2472
2463
|
if (entry.type !== "message")
|
|
2473
2464
|
continue;
|
|
2474
2465
|
totalMessages++;
|
|
@@ -2478,6 +2469,9 @@ export class AgentSession {
|
|
|
2478
2469
|
}
|
|
2479
2470
|
else if (message.role === "toolResult") {
|
|
2480
2471
|
toolResults++;
|
|
2472
|
+
if (message.usage) {
|
|
2473
|
+
addUsageToTotals(usageTotals, message.usage);
|
|
2474
|
+
}
|
|
2481
2475
|
}
|
|
2482
2476
|
else if (message.role === "assistant") {
|
|
2483
2477
|
assistantMessages++;
|
|
@@ -2485,12 +2479,7 @@ export class AgentSession {
|
|
|
2485
2479
|
if (Array.isArray(assistantMsg.content)) {
|
|
2486
2480
|
toolCalls += assistantMsg.content.filter((c) => c.type === "toolCall").length;
|
|
2487
2481
|
}
|
|
2488
|
-
|
|
2489
|
-
totalInput += usage.input;
|
|
2490
|
-
totalOutput += usage.output;
|
|
2491
|
-
totalCacheRead += usage.cacheRead;
|
|
2492
|
-
totalCacheWrite += usage.cacheWrite;
|
|
2493
|
-
totalCost += usage.cost.total;
|
|
2482
|
+
addUsageToTotals(usageTotals, assistantMsg.usage);
|
|
2494
2483
|
}
|
|
2495
2484
|
}
|
|
2496
2485
|
return {
|
|
@@ -2502,13 +2491,13 @@ export class AgentSession {
|
|
|
2502
2491
|
toolResults,
|
|
2503
2492
|
totalMessages,
|
|
2504
2493
|
tokens: {
|
|
2505
|
-
input:
|
|
2506
|
-
output:
|
|
2507
|
-
cacheRead:
|
|
2508
|
-
cacheWrite:
|
|
2509
|
-
total:
|
|
2494
|
+
input: usageTotals.input,
|
|
2495
|
+
output: usageTotals.output,
|
|
2496
|
+
cacheRead: usageTotals.cacheRead,
|
|
2497
|
+
cacheWrite: usageTotals.cacheWrite,
|
|
2498
|
+
total: usageTotals.input + usageTotals.output + usageTotals.cacheRead + usageTotals.cacheWrite,
|
|
2510
2499
|
},
|
|
2511
|
-
cost:
|
|
2500
|
+
cost: usageTotals.cost,
|
|
2512
2501
|
contextUsage: this.getContextUsage(),
|
|
2513
2502
|
};
|
|
2514
2503
|
}
|