فهرست منبع

message storage performance improvements

Dax Raad 3 ماه پیش
والد
کامیت
9554abb56e

+ 0 - 1
packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx

@@ -3,7 +3,6 @@ import {
   BoxRenderable,
   TextareaRenderable,
   MouseEvent,
-  KeyEvent,
   PasteEvent,
   t,
   dim,

+ 1 - 0
packages/opencode/src/cli/cmd/tui/context/sync.tsx

@@ -270,6 +270,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
         },
         async sync(sessionID: string) {
           const now = Date.now()
+          if (store.message[sessionID]) return
           console.log("syncing", sessionID)
           const [session, messages, todo, diff] = await Promise.all([
             sdk.client.session.get({ path: { id: sessionID }, throwOnError: true }),

+ 1 - 1
packages/opencode/src/server/server.ts

@@ -756,7 +756,7 @@ export namespace Server {
         validator(
           "query",
           z.object({
-            limit: z.coerce.number().optional(),
+            limit: z.coerce.number(),
           }),
         ),
         async (c) => {

+ 1 - 3
packages/opencode/src/session/compaction.ts

@@ -111,9 +111,7 @@ export namespace SessionCompaction {
         draft.time.compacting = undefined
       })
     })
-    const toSummarize = await Session.messages({ sessionID: input.sessionID }).then(
-      MessageV2.filterCompacted,
-    )
+    const toSummarize = await MessageV2.filterCompacted(Session.messageStream(input.sessionID))
     const model = await Provider.getModel(input.providerID, input.modelID)
     const system = [
       ...SystemPrompt.summarize(model.providerID),

+ 15 - 9
packages/opencode/src/session/index.ts

@@ -273,6 +273,17 @@ export namespace Session {
     return diffs ?? []
   })
 
+  export const messageStream = fn(Identifier.schema("session"), async function* (sessionID) {
+    const list = await Array.fromAsync(await Storage.list(["message", sessionID]))
+    for (let i = list.length - 1; i >= 0; i--) {
+      const read = await Storage.read<MessageV2.Info>(list[i])
+      yield {
+        info: read,
+        parts: await getParts(read.id),
+      }
+    }
+  })
+
   export const messages = fn(
     z.object({
       sessionID: Identifier.schema("session"),
@@ -280,16 +291,11 @@ export namespace Session {
     }),
     async (input) => {
       const result = [] as MessageV2.WithParts[]
-      const list = (await Array.fromAsync(await Storage.list(["message", input.sessionID])))
-        .toSorted((a, b) => a.at(-1)!.localeCompare(b.at(-1)!))
-        .slice(-1 * (input.limit ?? 1_000_000))
-      for (const p of list) {
-        const read = await Storage.read<MessageV2.Info>(p)
-        result.push({
-          info: read,
-          parts: await getParts(read.id),
-        })
+      for await (const msg of messageStream(input.sessionID)) {
+        if (input.limit && result.length >= input.limit) break
+        result.push(msg)
       }
+      result.reverse()
       return result
     },
   )

+ 8 - 4
packages/opencode/src/session/message-v2.ts

@@ -655,10 +655,14 @@ export namespace MessageV2 {
     return convertToModelMessages(result)
   }
 
-  export function filterCompacted(msgs: { info: MessageV2.Info; parts: MessageV2.Part[] }[]) {
-    const i = msgs.findLastIndex((m) => m.info.role === "assistant" && !!m.info.summary)
-    if (i === -1) return msgs.slice()
-    return msgs.slice(i)
+  export async function filterCompacted(stream: AsyncIterable<MessageV2.WithParts>) {
+    const result = [] as MessageV2.WithParts[]
+    for await (const msg of stream) {
+      result.push(msg)
+      if (msg.info.role === "assistant" && msg.info.summary === true) break
+    }
+    result.reverse()
+    return result
   }
 
   export function fromError(e: unknown, ctx: { providerID: string }) {

+ 1 - 3
packages/opencode/src/session/prompt.ts

@@ -434,9 +434,7 @@ export namespace SessionPrompt {
     providerID: string
     signal: AbortSignal
   }) {
-    let msgs = await Session.messages({ sessionID: input.sessionID }).then(
-      MessageV2.filterCompacted,
-    )
+    let msgs = await MessageV2.filterCompacted(Session.messageStream(input.sessionID))
     const lastAssistant = msgs.findLast((msg) => msg.info.role === "assistant")
     if (
       lastAssistant?.info.role === "assistant" &&

+ 1 - 11
packages/opencode/src/session/summary.ts

@@ -151,17 +151,7 @@ export namespace SessionSummary {
       messageID: Identifier.schema("message").optional(),
     }),
     async (input) => {
-      let all = await Session.messages({ sessionID: input.sessionID })
-      if (input.messageID)
-        all = all.filter(
-          (x) =>
-            x.info.id === input.messageID ||
-            (x.info.role === "assistant" && x.info.parentID === input.messageID),
-        )
-
-      return computeDiff({
-        messages: all,
-      })
+      return Storage.read<Snapshot.FileDiff[]>(["session_diff", input.sessionID]) ?? []
     },
   )