fix(core): simplify compaction semantics (#36267)
This commit is contained in:
parent
41d0a9f010
commit
cf5e0adf02
4 changed files with 192 additions and 196 deletions
|
|
@ -147,10 +147,11 @@ it.effect("manual compaction summarizes short context instead of no-op", () =>
|
|||
messages: [userMessage],
|
||||
inputID: SessionMessage.ID.make("msg_manual_compaction"),
|
||||
}),
|
||||
).toBe(true)
|
||||
).toEqual({ status: "completed" })
|
||||
expect(Array.from(yield* Fiber.join(delta)).map((event) => event.data.text)).toEqual(["manual summary"])
|
||||
|
||||
expect(requests).toHaveLength(1)
|
||||
expect(requests[0]?.generation).toBeUndefined()
|
||||
expect(JSON.stringify(requests[0]?.messages)).toContain("Manual compaction should include this short conversation.")
|
||||
expect(yield* store.context(sessionID)).toMatchObject([
|
||||
{ type: "compaction", reason: "manual", summary: "manual summary", recent: "" },
|
||||
|
|
|
|||
|
|
@ -113,6 +113,16 @@ const reply = {
|
|||
LLMEvent.finish({ reason: "stop" }),
|
||||
],
|
||||
text: (text: string, id: string) => fragmentFixture("text", id, [text]).completeEvents,
|
||||
textWithUsage: (text: string, id: string, inputTokens: number) =>
|
||||
fragmentFixture("text", id, [text]).completeEvents.map((event) =>
|
||||
LLMEvent.is.stepFinish(event)
|
||||
? LLMEvent.stepFinish({
|
||||
index: event.index,
|
||||
reason: event.reason,
|
||||
usage: { inputTokens, nonCachedInputTokens: inputTokens },
|
||||
})
|
||||
: event,
|
||||
),
|
||||
tool: (id: string, name: string, input: unknown) => [
|
||||
LLMEvent.stepStart({ index: 0 }),
|
||||
LLMEvent.toolCall({ id, name, input }),
|
||||
|
|
@ -1696,7 +1706,7 @@ describe("SessionRunnerLLM", () => {
|
|||
it.effect("automatically compacts into a completed summary and retained recent turn", () =>
|
||||
Effect.gen(function* () {
|
||||
const session = yield* setup
|
||||
response = reply.text("Earlier answer", "text-first")
|
||||
response = reply.textWithUsage("Earlier answer", "text-first", 3_950)
|
||||
yield* admit(session, "Earlier question ".repeat(180))
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
|
|
@ -1704,7 +1714,7 @@ describe("SessionRunnerLLM", () => {
|
|||
requests.length = 0
|
||||
responses = [
|
||||
reply.text("## Objective\n- Preserve the task", "text-summary"),
|
||||
reply.text("Continued", "text-final"),
|
||||
reply.textWithUsage("Continued", "text-final", 3_950),
|
||||
]
|
||||
yield* admit(session, "Recent exact request ".repeat(180))
|
||||
yield* session.resume(sessionID)
|
||||
|
|
@ -1743,6 +1753,35 @@ describe("SessionRunnerLLM", () => {
|
|||
}),
|
||||
)
|
||||
|
||||
it.effect("stops after required automatic compaction fails", () =>
|
||||
Effect.gen(function* () {
|
||||
const session = yield* setup
|
||||
response = reply.textWithUsage("Earlier answer", "text-before-failed-compaction", 3_950)
|
||||
yield* admit(session, "Earlier question ".repeat(180))
|
||||
yield* session.resume(sessionID)
|
||||
|
||||
currentModel = compactModel
|
||||
requests.length = 0
|
||||
responses = [
|
||||
[LLMEvent.providerError({ message: "Unsupported parameter: max_output_tokens" })],
|
||||
reply.text("Must not run", "text-after-failed-compaction"),
|
||||
]
|
||||
yield* admit(session, "Recent exact request ".repeat(180))
|
||||
expect(yield* Effect.exit(session.resume(sessionID))).toMatchObject({ _tag: "Failure" })
|
||||
|
||||
expect(requests).toHaveLength(1)
|
||||
expect(requests[0]?.generation).toBeUndefined()
|
||||
expect(yield* session.context(sessionID)).toContainEqual(
|
||||
expect.objectContaining({
|
||||
type: "compaction",
|
||||
status: "failed",
|
||||
reason: "auto",
|
||||
error: expect.objectContaining({ message: "Unsupported parameter: max_output_tokens" }),
|
||||
}),
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("forces one compaction and retries after provider context overflow", () =>
|
||||
Effect.gen(function* () {
|
||||
const session = yield* setupOverflowRecovery
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue