fix(ai): require OpenAI Responses terminal events
This commit is contained in:
@@ -8,6 +8,10 @@
|
||||
- `compact()`, `generateSummary()`, and `generateBranchSummary()` take a `Models` parameter and no longer accept explicit `apiKey`/`headers`.
|
||||
- `StreamFn` is defined structurally (`(model, context, options?) => AssistantMessageEventStream | Promise<...>`); `Models.streamSimple` satisfies it.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed harness compaction estimates to ignore malformed all-zero assistant usage after truncated responses ([#5526](https://github.com/earendil-works/pi/pull/5526) by [@dmmulroy](https://github.com/dmmulroy)).
|
||||
|
||||
## [0.79.10] - 2026-06-22
|
||||
|
||||
## [0.79.9] - 2026-06-20
|
||||
|
||||
@@ -121,14 +121,19 @@ export function calculateContextTokens(usage: Usage): number {
|
||||
function getAssistantUsage(msg: AgentMessage): Usage | undefined {
|
||||
if (msg.role === "assistant" && "usage" in msg) {
|
||||
const assistantMsg = msg as AssistantMessage;
|
||||
if (assistantMsg.stopReason !== "aborted" && assistantMsg.stopReason !== "error" && assistantMsg.usage) {
|
||||
if (
|
||||
assistantMsg.stopReason !== "aborted" &&
|
||||
assistantMsg.stopReason !== "error" &&
|
||||
assistantMsg.usage &&
|
||||
calculateContextTokens(assistantMsg.usage) > 0
|
||||
) {
|
||||
return assistantMsg.usage;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Return usage from the last successful assistant message in session entries. */
|
||||
/** Return usage from the last valid assistant message in session entries. */
|
||||
export function getLastAssistantUsage(entries: SessionTreeEntry[]): Usage | undefined {
|
||||
for (let i = entries.length - 1; i >= 0; i--) {
|
||||
const entry = entries[i];
|
||||
|
||||
@@ -301,11 +301,28 @@ describe("harness compaction", () => {
|
||||
createMessageEntry({ ...assistant, stopReason: "error" }),
|
||||
]),
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
getLastAssistantUsage([
|
||||
createMessageEntry(createUserMessage("user")),
|
||||
createMessageEntry(assistant),
|
||||
createMessageEntry(createAssistantMessage("partial", createMockUsage(0, 0))),
|
||||
]),
|
||||
).toBe(usage);
|
||||
expect(estimateContextTokens([createUserMessage("no usage")]).lastUsageIndex).toBeNull();
|
||||
expect(estimateContextTokens([assistant, createUserMessage("tail")])).toMatchObject({
|
||||
usageTokens: 20,
|
||||
lastUsageIndex: 0,
|
||||
});
|
||||
const estimate = estimateContextTokens([
|
||||
createUserMessage("Hello"),
|
||||
assistant,
|
||||
createUserMessage("continue"),
|
||||
createAssistantMessage("Partial thinking", createMockUsage(0, 0)),
|
||||
]);
|
||||
expect(estimate.usageTokens).toBe(20);
|
||||
expect(estimate.lastUsageIndex).toBe(1);
|
||||
expect(estimate.trailingTokens).toBeGreaterThan(0);
|
||||
expect(estimate.tokens).toBe(20 + estimate.trailingTokens);
|
||||
});
|
||||
|
||||
it("builds session context with a compaction entry", () => {
|
||||
|
||||
Reference in New Issue
Block a user