fix(session): type message list not found errors (#27275)

This commit is contained in:
Shoubhit Dash
2026-05-13 13:22:12 +05:30
committed by GitHub
parent fed043a1ad
commit f01c6b3e37
9 changed files with 95 additions and 23 deletions

View File

@@ -565,7 +565,9 @@ export const layer: Layer.Layer<
if (processor.message.error) return "stop"
if (result === "continue") {
const summary = summaryText(
(yield* session.messages({ sessionID: input.sessionID })).find((item) => item.info.id === msg.id) ?? {
(yield* session.messages({ sessionID: input.sessionID }).pipe(Effect.orDie)).find(
(item) => item.info.id === msg.id,
) ?? {
info: msg,
parts: [],
},

View File

@@ -1077,7 +1077,9 @@ NOTE: At any point in time through this workflow you should feel free to ask the
...(current.model.variant && current.model.variant !== "default" ? { variant: current.model.variant } : {}),
}
}
const match = yield* sessions.findMessage(sessionID, (m) => m.info.role === "user" && !!m.info.model)
const match = yield* sessions
.findMessage(sessionID, (m) => m.info.role === "user" && !!m.info.model)
.pipe(Effect.orDie)
if (Option.isSome(match) && match.value.info.role === "user") return match.value.info.model
return yield* provider.defaultModel()
})
@@ -1615,9 +1617,9 @@ NOTE: At any point in time through this workflow you should feel free to ask the
)
const lastAssistant = Effect.fnUntraced(function* (sessionID: SessionID) {
const match = yield* sessions.findMessage(sessionID, (m) => m.info.role !== "user")
const match = yield* sessions.findMessage(sessionID, (m) => m.info.role !== "user").pipe(Effect.orDie)
if (Option.isSome(match)) return match.value
const msgs = yield* sessions.messages({ sessionID, limit: 1 })
const msgs = yield* sessions.messages({ sessionID, limit: 1 }).pipe(Effect.orDie)
if (msgs.length > 0) return msgs[0]
throw new Error("Impossible")
})

View File

@@ -40,7 +40,7 @@ export const layer = Layer.effect(
const revert = Effect.fn("SessionRevert.revert")(function* (input: RevertInput) {
yield* state.assertNotBusy(input.sessionID)
const all = yield* sessions.messages({ sessionID: input.sessionID })
const all = yield* sessions.messages({ sessionID: input.sessionID }).pipe(Effect.orDie)
let lastUser: MessageV2.User | undefined
const session = yield* sessions.get(input.sessionID).pipe(Effect.orDie)
@@ -103,7 +103,7 @@ export const layer = Layer.effect(
const cleanup = Effect.fn("SessionRevert.cleanup")(function* (session: Session.Info) {
if (!session.revert) return
const sessionID = session.id
const msgs = yield* sessions.messages({ sessionID })
const msgs = yield* sessions.messages({ sessionID }).pipe(Effect.orDie)
const messageID = session.revert.messageID
const remove = [] as MessageV2.WithParts[]
let target: MessageV2.WithParts | undefined

View File

@@ -474,7 +474,7 @@ export interface Interface {
readonly clearRevert: (sessionID: SessionID) => Effect.Effect<void>
readonly setSummary: (input: { sessionID: SessionID; summary: Info["summary"] }) => Effect.Effect<void>
readonly diff: (sessionID: SessionID) => Effect.Effect<Snapshot.FileDiff[]>
readonly messages: (input: { sessionID: SessionID; limit?: number }) => Effect.Effect<MessageV2.WithParts[]>
readonly messages: (input: { sessionID: SessionID; limit?: number }) => Effect.Effect<MessageV2.WithParts[], NotFound>
readonly children: (parentID: SessionID) => Effect.Effect<Info[]>
readonly remove: (sessionID: SessionID) => Effect.Effect<void, NotFound>
readonly updateMessage: <T extends MessageV2.Info>(msg: T) => Effect.Effect<T>
@@ -497,7 +497,7 @@ export interface Interface {
readonly findMessage: (
sessionID: SessionID,
predicate: (msg: MessageV2.WithParts) => boolean,
) => Effect.Effect<Option.Option<MessageV2.WithParts>>
) => Effect.Effect<Option.Option<MessageV2.WithParts>, NotFound>
}
export class Service extends Context.Service<Service, Interface>()("@opencode/Session") {}
@@ -757,11 +757,25 @@ export const layer: Layer.Layer<Service, never, Bus.Service | Storage.Service |
.pipe(Effect.orElseSucceed((): Snapshot.FileDiff[] => []))
})
const messages = Effect.fn("Session.messages")(function* (input: { sessionID: SessionID; limit?: number }) {
const messages: Interface["messages"] = Effect.fn("Session.messages")(function* (input) {
if (input.limit) {
return MessageV2.page({ sessionID: input.sessionID, limit: input.limit }).items
return (yield* MessageV2.pageEffect({ sessionID: input.sessionID, limit: input.limit })).items
}
return Array.from(MessageV2.stream(input.sessionID)).reverse()
const size = 50
const result = [] as MessageV2.WithParts[]
let before: string | undefined
while (true) {
const page = yield* MessageV2.pageEffect({ sessionID: input.sessionID, limit: size, before })
if (page.items.length === 0) break
for (let i = page.items.length - 1; i >= 0; i--) {
const item = page.items[i]
if (item) result.push(item)
}
if (!page.more || !page.cursor) break
before = page.cursor
}
return result.reverse()
})
const removeMessage = Effect.fn("Session.removeMessage")(function* (input: {
@@ -799,12 +813,18 @@ export const layer: Layer.Layer<Service, never, Bus.Service | Storage.Service |
})
/** Finds the first message matching the predicate, searching newest-first. */
const findMessage = Effect.fn("Session.findMessage")(function* (
sessionID: SessionID,
predicate: (msg: MessageV2.WithParts) => boolean,
) {
for (const item of MessageV2.stream(sessionID)) {
if (predicate(item)) return Option.some(item)
const findMessage: Interface["findMessage"] = Effect.fn("Session.findMessage")(function* (sessionID, predicate) {
const size = 50
let before: string | undefined
while (true) {
const page = yield* MessageV2.pageEffect({ sessionID, limit: size, before })
if (page.items.length === 0) break
for (let i = page.items.length - 1; i >= 0; i--) {
const item = page.items[i]
if (item && predicate(item)) return Option.some(item)
}
if (!page.more || !page.cursor) break
before = page.cursor
}
return Option.none<MessageV2.WithParts>()
})

View File

@@ -102,7 +102,7 @@ export const layer = Layer.effect(
sessionID: SessionID
messageID: MessageID
}) {
const all = yield* sessions.messages({ sessionID: input.sessionID })
const all = yield* sessions.messages({ sessionID: input.sessionID }).pipe(Effect.orDie)
if (!all.length) return
const diffs = yield* computeDiff({ messages: all })