fix: preserve context window data when turn_completed lacks usage (#2494)
* fix: preserve context window data when turn_completed lacks usage Merge incoming usage into agent.lastUsage instead of replacing it wholesale. Some providers (Claude autonomous turns, OpenCode) emit turn_completed without a usage payload, which previously wiped the contextWindowMaxTokens/contextWindowUsedTokens accumulated during streaming usage_updated events. The result was the context window meter disappearing from the composer once the agent finished work. * test(server): preserve usage after autonomous completion --------- Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
parent
acb8506d1f
commit
b897c59e9c
@@ -4757,7 +4757,7 @@ test("replaceAgentRun stays running when a stale old terminal arrives before the
|
||||
unsubscribe();
|
||||
});
|
||||
|
||||
test("applies live autonomous events while no foreground run is active", async () => {
|
||||
test("applies live autonomous events and preserves usage omitted from completion", async () => {
|
||||
const workdir = mkdtempSync(join(tmpdir(), "agent-manager-live-events-"));
|
||||
const storagePath = join(workdir, "agents");
|
||||
const storage = new AgentStorage(storagePath, logger);
|
||||
@@ -4816,6 +4816,16 @@ test("applies live autonomous events while no foreground run is active", async (
|
||||
provider: "codex",
|
||||
turnId: autonomousTurnId,
|
||||
});
|
||||
capturedSession!.pushEvent({
|
||||
type: "usage_updated",
|
||||
provider: "codex",
|
||||
usage: {
|
||||
inputTokens: 10,
|
||||
contextWindowMaxTokens: 200_000,
|
||||
contextWindowUsedTokens: 175,
|
||||
},
|
||||
turnId: autonomousTurnId,
|
||||
});
|
||||
capturedSession!.pushEvent({
|
||||
type: "timeline",
|
||||
provider: "codex",
|
||||
@@ -4831,6 +4841,11 @@ test("applies live autonomous events while no foreground run is active", async (
|
||||
|
||||
const updated = manager.getAgent(snapshot.id);
|
||||
expect(updated?.lifecycle).toBe("idle");
|
||||
expect(updated?.lastUsage).toEqual({
|
||||
inputTokens: 10,
|
||||
contextWindowMaxTokens: 200_000,
|
||||
contextWindowUsedTokens: 175,
|
||||
});
|
||||
expect(manager.getTimeline(snapshot.id)).toContainEqual({
|
||||
type: "assistant_message",
|
||||
text: "AUTONOMOUS_PUMP_MESSAGE",
|
||||
|
||||
@@ -3552,7 +3552,12 @@ export class AgentManager {
|
||||
},
|
||||
"agent.manager.turn.completed",
|
||||
);
|
||||
agent.lastUsage = event.usage;
|
||||
if (event.usage) {
|
||||
agent.lastUsage = { ...agent.lastUsage, ...event.usage };
|
||||
}
|
||||
// If no usage on turn_completed, keep lastUsage as-is so context window
|
||||
// data accumulated during streaming isn't lost when the provider omits
|
||||
// it from the completion event.
|
||||
agent.lastError = undefined;
|
||||
if (!isForegroundEvent && agent.lifecycle !== "idle" && !agent.pendingReplacement) {
|
||||
(agent as ActiveManagedAgent).lifecycle = "idle";
|
||||
|
||||
Reference in New Issue
Block a user