mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-10 04:10:26 +00:00
refactor(session): eliminate Effect.promise roundtrips for sync MessageV2.stream (#21973)
This commit is contained in:
parent
19ae8c88b0
commit
cd004cf0b2
2 changed files with 27 additions and 17 deletions
|
|
@ -29,7 +29,7 @@ import type { Provider } from "@/provider/provider"
|
|||
import { Permission } from "@/permission"
|
||||
import { Global } from "@/global"
|
||||
import type { LanguageModelV2Usage } from "@ai-sdk/provider"
|
||||
import { Effect, Layer, Context } from "effect"
|
||||
import { Effect, Layer, Option, Context } from "effect"
|
||||
import { makeRuntime } from "@/effect/run-service"
|
||||
|
||||
export namespace Session {
|
||||
|
|
@ -352,6 +352,11 @@ export namespace Session {
|
|||
field: string
|
||||
delta: string
|
||||
}) => Effect.Effect<void>
|
||||
/** Finds the first message matching the predicate, searching newest-first. */
|
||||
readonly findMessage: (
|
||||
sessionID: SessionID,
|
||||
predicate: (msg: MessageV2.WithParts) => boolean,
|
||||
) => Effect.Effect<Option.Option<MessageV2.WithParts>>
|
||||
}
|
||||
|
||||
export class Service extends Context.Service<Service, Interface>()("@opencode/Session") {}
|
||||
|
|
@ -636,6 +641,17 @@ export namespace Session {
|
|||
yield* bus.publish(MessageV2.Event.PartDelta, input)
|
||||
})
|
||||
|
||||
/** 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)
|
||||
}
|
||||
return Option.none<MessageV2.WithParts>()
|
||||
})
|
||||
|
||||
return Service.of({
|
||||
create,
|
||||
fork,
|
||||
|
|
@ -657,6 +673,7 @@ export namespace Session {
|
|||
updatePart,
|
||||
getPart,
|
||||
updatePartDelta,
|
||||
findMessage,
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -902,12 +902,8 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
|||
})
|
||||
|
||||
const lastModel = Effect.fnUntraced(function* (sessionID: SessionID) {
|
||||
const model = yield* Effect.promise(async () => {
|
||||
for await (const item of MessageV2.stream(sessionID)) {
|
||||
if (item.info.role === "user" && item.info.model) return item.info.model
|
||||
}
|
||||
})
|
||||
if (model) return model
|
||||
const match = yield* sessions.findMessage(sessionID, (m) => m.info.role === "user" && !!m.info.model)
|
||||
if (Option.isSome(match) && match.value.info.role === "user") return match.value.info.model
|
||||
return yield* provider.defaultModel()
|
||||
})
|
||||
|
||||
|
|
@ -1290,16 +1286,13 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
|||
},
|
||||
)
|
||||
|
||||
const lastAssistant = (sessionID: SessionID) =>
|
||||
Effect.promise(async () => {
|
||||
let latest: MessageV2.WithParts | undefined
|
||||
for await (const item of MessageV2.stream(sessionID)) {
|
||||
latest ??= item
|
||||
if (item.info.role !== "user") return item
|
||||
}
|
||||
if (latest) return latest
|
||||
throw new Error("Impossible")
|
||||
})
|
||||
const lastAssistant = Effect.fnUntraced(function* (sessionID: SessionID) {
|
||||
const match = yield* sessions.findMessage(sessionID, (m) => m.info.role !== "user")
|
||||
if (Option.isSome(match)) return match.value
|
||||
const msgs = yield* sessions.messages({ sessionID, limit: 1 })
|
||||
if (msgs.length > 0) return msgs[0]
|
||||
throw new Error("Impossible")
|
||||
})
|
||||
|
||||
const runLoop: (sessionID: SessionID) => Effect.Effect<MessageV2.WithParts> = Effect.fn("SessionPrompt.run")(
|
||||
function* (sessionID: SessionID) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue