fix(core): reject unknown session interrupts
This commit is contained in:
parent
eec6cd5234
commit
fb8d775fec
3 changed files with 35 additions and 13 deletions
|
|
@ -276,7 +276,7 @@ export interface Interface {
|
|||
readonly active: Effect.Effect<ReadonlySet<SessionSchema.ID>>
|
||||
readonly background: (sessionID: SessionSchema.ID) => Effect.Effect<void, NotFoundError>
|
||||
readonly resume: (sessionID: SessionSchema.ID) => Effect.Effect<void, NotFoundError | SessionRunner.RunError>
|
||||
readonly interrupt: (sessionID: SessionSchema.ID) => Effect.Effect<void>
|
||||
readonly interrupt: (sessionID: SessionSchema.ID) => Effect.Effect<void, NotFoundError>
|
||||
readonly synthetic: (input: {
|
||||
id?: SessionMessage.ID
|
||||
sessionID: SessionSchema.ID
|
||||
|
|
@ -804,7 +804,12 @@ const layer = Layer.effect(
|
|||
),
|
||||
),
|
||||
interrupt: Effect.fn("V2Session.interrupt")((sessionID) =>
|
||||
Effect.uninterruptible(execution.interrupt(sessionID)),
|
||||
Effect.uninterruptible(
|
||||
Effect.gen(function* () {
|
||||
yield* result.get(sessionID)
|
||||
yield* execution.interrupt(sessionID)
|
||||
}),
|
||||
),
|
||||
),
|
||||
revert: {
|
||||
stage: Effect.fn("V2Session.revert.stage")(function* (input) {
|
||||
|
|
|
|||
|
|
@ -188,7 +188,13 @@ export const Plugin = {
|
|||
yield* runtime.session.prompt({ sessionID: child.id, text: input.prompt, resume: false })
|
||||
yield* runtime.session.resume(child.id)
|
||||
return yield* latestAssistantText(child.id)
|
||||
}).pipe(Effect.onInterrupt(() => runtime.session.interrupt(child.id)))
|
||||
}).pipe(
|
||||
Effect.onInterrupt(() =>
|
||||
runtime.session
|
||||
.interrupt(child.id)
|
||||
.pipe(Effect.catchTag("Session.NotFoundError", () => Effect.void)),
|
||||
),
|
||||
)
|
||||
|
||||
const info = yield* runtime.job.start({
|
||||
id: child.id,
|
||||
|
|
@ -208,13 +214,21 @@ export const Plugin = {
|
|||
}
|
||||
}
|
||||
|
||||
const result = yield* runtime.job.block({ id: child.id, sessionID: context.sessionID }).pipe(
|
||||
Effect.onInterrupt(() =>
|
||||
Effect.all([runtime.session.interrupt(child.id), runtime.job.cancel(child.id)], {
|
||||
discard: true,
|
||||
}),
|
||||
),
|
||||
)
|
||||
const result = yield* runtime.job
|
||||
.block({ id: child.id, sessionID: context.sessionID })
|
||||
.pipe(
|
||||
Effect.onInterrupt(() =>
|
||||
Effect.all(
|
||||
[
|
||||
runtime.session
|
||||
.interrupt(child.id)
|
||||
.pipe(Effect.catchTag("Session.NotFoundError", () => Effect.void)),
|
||||
runtime.job.cancel(child.id),
|
||||
],
|
||||
{ discard: true },
|
||||
),
|
||||
),
|
||||
)
|
||||
if (result?.type === "backgrounded") {
|
||||
yield* notifyWhenDone(context.sessionID, child.id, agent.name, input.description)
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -156,13 +156,16 @@ describe("SessionV2.prompt", () => {
|
|||
}),
|
||||
)
|
||||
|
||||
it.effect("delegates interruption without requiring a recorded Session", () =>
|
||||
it.effect("rejects interruption for an unknown Session", () =>
|
||||
Effect.gen(function* () {
|
||||
const session = yield* SessionV2.Service
|
||||
interruptCalls.length = 0
|
||||
const missing = SessionV2.ID.make("ses_missing")
|
||||
|
||||
yield* session.interrupt(SessionV2.ID.make("ses_missing"))
|
||||
expect(interruptCalls).toEqual([SessionV2.ID.make("ses_missing")])
|
||||
expect(yield* session.interrupt(missing).pipe(Effect.flip)).toEqual(
|
||||
new SessionV2.NotFoundError({ sessionID: missing }),
|
||||
)
|
||||
expect(interruptCalls).toEqual([])
|
||||
}),
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue