mirror of
https://github.com/anomalyco/opencode.git
synced 2026-09-02 21:14:46 +00:00
fix(core): preserve continuation across chained moves
Carry unfinished model work across consecutive Location handoffs without resetting the logical step allowance. Keep idle moves and queued prompt admission unchanged. Cover steered and queued second moves, preserved tool history, and durable event ordering.
This commit is contained in:
parent
663c2dc1ce
commit
6dd1733bbf
2 changed files with 43 additions and 26 deletions
|
|
@ -96,7 +96,7 @@ const layer = Layer.effect(
|
|||
step = 1
|
||||
}
|
||||
if (pending?.type === "move")
|
||||
return DrainResult.Moved({ continuation: !entering && continuing ? { step } : undefined })
|
||||
return DrainResult.Moved({ continuation: continuing ? { step } : undefined })
|
||||
if (pending?.type === "compaction") {
|
||||
const session = yield* store.get(sessionID)
|
||||
if (!session) return yield* Effect.die(new Error(`Session not found: ${sessionID}`))
|
||||
|
|
|
|||
|
|
@ -1454,32 +1454,49 @@ describe("SessionRunnerLLM", () => {
|
|||
).toEqual([Bus.versionedType(SessionEvent.Moved.type, 1), Bus.versionedType(SessionEvent.InboxDelivered.type, 1)])
|
||||
})
|
||||
|
||||
scenario("preserves a tool continuation across a steered move", function* (s) {
|
||||
yield* s.admit("Echo before moving")
|
||||
yield* s.llm.push(TestLLM.tool("call-move", "echo", { text: "moving" }), TestLLM.text("Done", "text-after-move"))
|
||||
const tools = yield* s.blockTools()
|
||||
const run = yield* s.resume.pipe(Effect.forkChild)
|
||||
yield* tools.started
|
||||
yield* s.sessionInbox.admit({
|
||||
id: SessionMessage.ID.create(),
|
||||
sessionID,
|
||||
item: {
|
||||
type: "move",
|
||||
payload: {
|
||||
location: Location.Ref.make({ directory: AbsolutePath.make("/project") }),
|
||||
projectID: Project.ID.global,
|
||||
},
|
||||
delivery: "steer",
|
||||
},
|
||||
for (const delivery of ["steer", "queue"] as const) {
|
||||
scenario(`preserves a tool continuation and step allowance across chained moves (${delivery})`, function* (s) {
|
||||
const agents = yield* Agent.Service
|
||||
yield* agents.transform((editor) =>
|
||||
editor.update(Agent.ID.make("build"), (agent) => {
|
||||
agent.steps = 2
|
||||
}),
|
||||
)
|
||||
yield* s.admit("Echo before moving")
|
||||
yield* s.llm.push(TestLLM.tool("call-move", "echo", { text: "moving" }), TestLLM.text("Done", "text-after-move"))
|
||||
const tools = yield* s.blockTools()
|
||||
const run = yield* s.resume.pipe(Effect.forkChild)
|
||||
yield* tools.started
|
||||
yield* Effect.forEach(["steer", delivery] as const, (delivery) =>
|
||||
s.sessionInbox.admit({
|
||||
id: SessionMessage.ID.create(),
|
||||
sessionID,
|
||||
item: {
|
||||
type: "move",
|
||||
payload: {
|
||||
location: Location.Ref.make({ directory: AbsolutePath.make("/project") }),
|
||||
projectID: Project.ID.global,
|
||||
},
|
||||
delivery,
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
yield* tools.release
|
||||
yield* Fiber.join(run)
|
||||
|
||||
expect(s.requests).toHaveLength(2)
|
||||
expect(messageRoles(s.requests[1])?.slice(0, 3)).toEqual(["user", "assistant", "tool"])
|
||||
expect(s.requests[0]?.toolChoice).toBeUndefined()
|
||||
expect(s.requests[1]?.toolChoice).toMatchObject({ type: "none" })
|
||||
expect(
|
||||
(yield* recordedEventTypes(sessionID)).filter(
|
||||
(type) => type === "session.step.started.1" || type === "session.moved.1",
|
||||
),
|
||||
).toEqual(["session.step.started.1", "session.moved.1", "session.moved.1", "session.step.started.1"])
|
||||
expect(yield* s.inbox).toEqual([])
|
||||
})
|
||||
|
||||
yield* tools.release
|
||||
yield* Fiber.join(run)
|
||||
|
||||
expect(s.requests).toHaveLength(2)
|
||||
expect(s.requests.map(messageRoles).at(1)?.slice(0, 3)).toEqual(["user", "assistant", "tool"])
|
||||
expect(yield* s.inbox).toEqual([])
|
||||
})
|
||||
}
|
||||
|
||||
scenario("keeps queued input parked across a mid-turn move", function* (s) {
|
||||
yield* s.admit("Echo before moving")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue