add usage info to branch summary, compaction and tool result entries (#6671)

* add usage info to branch summary entries

* add usage to compaction entries

* allow custom tools to report llm usage in tool results

* allow observing and patching usage in tool_result hooks

* agent-harness: save usage in entries

for compaction, branch summaries and tool results
This commit is contained in:
David Brailovsky
2026-07-20 16:41:43 +02:00
committed by GitHub
parent c179395218
commit 2fd3868401
29 changed files with 844 additions and 122 deletions
+19 -5
View File
@@ -32,6 +32,7 @@ import type {
AgentHarnessResources,
AgentHarnessStreamOptions,
AgentHarnessStreamOptionsPatch,
CompactResult,
ExecutionEnv,
NavigateTreeResult,
PendingSessionWrite,
@@ -434,9 +435,16 @@ export class AgentHarness<
content: result.content,
details: result.details,
isError,
usage: result.usage,
});
return patch
? { content: patch.content, details: patch.details, isError: patch.isError, terminate: patch.terminate }
? {
content: patch.content,
details: patch.details,
isError: patch.isError,
usage: patch.usage,
terminate: patch.terminate,
}
: undefined;
},
prepareNextTurn: async () => {
@@ -690,9 +698,7 @@ export class AgentHarness<
}
}
async compact(
customInstructions?: string,
): Promise<{ summary: string; firstKeptEntryId: string; tokensBefore: number; details?: unknown }> {
async compact(customInstructions?: string): Promise<CompactResult> {
if (this.phase !== "idle") throw new AgentHarnessError("busy", "compact() requires idle harness");
this.phase = "compaction";
try {
@@ -723,6 +729,7 @@ export class AgentHarness<
result.tokensBefore,
result.details,
provided !== undefined,
result.usage,
);
const entry = await this.session.getEntry(entryId);
if (entry?.type === "compaction") {
@@ -764,6 +771,7 @@ export class AgentHarness<
let summaryEntry: NavigateTreeResult["summaryEntry"];
let summaryText: string | undefined = hookResult?.summary?.summary;
let summaryDetails: unknown = hookResult?.summary?.details;
let summaryUsage = hookResult?.summary?.usage;
if (!summaryText && options?.summarize && entries.length > 0) {
const model = this.model;
if (!model) throw new AgentHarnessError("invalid_state", "No model set for branch summary");
@@ -779,6 +787,7 @@ export class AgentHarness<
throw new AgentHarnessError("branch_summary", branchSummary.error.message, branchSummary.error);
}
summaryText = branchSummary.value.summary;
summaryUsage = branchSummary.value.usage;
summaryDetails = {
readFiles: branchSummary.value.readFiles,
modifiedFiles: branchSummary.value.modifiedFiles,
@@ -798,7 +807,12 @@ export class AgentHarness<
const summaryId = await this.session.moveTo(
newLeafId,
summaryText
? { summary: summaryText, details: summaryDetails, fromHook: hookResult?.summary !== undefined }
? {
summary: summaryText,
details: summaryDetails,
usage: summaryUsage,
fromHook: hookResult?.summary !== undefined,
}
: undefined,
);
if (summaryId) {