session summaries in data

This commit is contained in:
Dax Raad
2025-10-23 16:28:20 -04:00
parent f4dfae0bb0
commit cee7106054
4 changed files with 60 additions and 39 deletions

View File

@@ -36,7 +36,7 @@ import { MCP } from "../mcp"
import { Storage } from "../storage/storage"
import type { ContentfulStatusCode } from "hono/utils/http-status"
import { Snapshot } from "@/snapshot"
import { MessageSummary } from "@/session/summary"
import { SessionSummary } from "@/session/summary"
const ERRORS = {
400: {
@@ -629,19 +629,19 @@ export namespace Server {
validator(
"param",
z.object({
id: MessageSummary.diff.schema.shape.sessionID,
id: SessionSummary.diff.schema.shape.sessionID,
}),
),
validator(
"query",
z.object({
messageID: MessageSummary.diff.schema.shape.messageID,
messageID: SessionSummary.diff.schema.shape.messageID,
}),
),
async (c) => {
const query = c.req.valid("query")
const params = c.req.valid("param")
const result = await MessageSummary.diff({
const result = await SessionSummary.diff({
sessionID: params.id,
messageID: query.messageID,
})

View File

@@ -36,6 +36,11 @@ export namespace Session {
projectID: z.string(),
directory: z.string(),
parentID: Identifier.schema("session").optional(),
summary: z
.object({
diffs: Snapshot.FileDiff.array(),
})
.optional(),
share: z
.object({
url: z.string(),

View File

@@ -49,7 +49,7 @@ import { spawn } from "child_process"
import { Command } from "../command"
import { $, fileURLToPath } from "bun"
import { ConfigMarkdown } from "../config/markdown"
import { MessageSummary } from "./summary"
import { SessionSummary } from "./summary"
export namespace SessionPrompt {
const log = Log.create({ service: "session.prompt" })
@@ -1292,7 +1292,7 @@ export namespace SessionPrompt {
}
snapshot = undefined
}
MessageSummary.summarize({
SessionSummary.summarize({
sessionID: input.sessionID,
messageID: assistantMsg.parentID,
providerID: assistantMsg.modelID,

View File

@@ -8,7 +8,7 @@ import { Flag } from "@/flag/flag"
import { Identifier } from "@/id/id"
import { Snapshot } from "@/snapshot"
export namespace MessageSummary {
export namespace SessionSummary {
export const summarize = fn(
z.object({
sessionID: z.string(),
@@ -16,10 +16,26 @@ export namespace MessageSummary {
providerID: z.string(),
}),
async (input) => {
const messages = await Session.messages(input.sessionID).then((msgs) =>
msgs.filter(
const all = await Session.messages(input.sessionID)
await Promise.all([
summarizeSession({ sessionID: input.sessionID, messages: all }),
summarizeMessage({ messageID: input.messageID, messages: all }),
])
},
)
async function summarizeSession(input: { sessionID: string; messages: MessageV2.WithParts[] }) {
const diffs = await computeDiff({ messages: input.messages })
await Session.update(input.sessionID, (draft) => {
draft.summary = {
diffs,
}
})
}
async function summarizeMessage(input: { messageID: string; messages: MessageV2.WithParts[] }) {
const messages = input.messages.filter(
(m) => m.info.id === input.messageID || (m.info.role === "assistant" && m.info.parentID === input.messageID),
),
)
const userMsg = messages.find((m) => m.info.id === input.messageID)!
const diffs = await computeDiff({ messages })
@@ -31,7 +47,8 @@ export namespace MessageSummary {
Flag.OPENCODE_EXPERIMENTAL_TURN_SUMMARY &&
messages.every((m) => m.info.role !== "assistant" || m.info.time.completed)
) {
const small = await Provider.getSmallModel(input.providerID)
const assistantMsg = messages.find((m) => m.info.role === "assistant")!.info as MessageV2.Assistant
const small = await Provider.getSmallModel(assistantMsg.providerID)
if (!small) return
const result = await generateText({
model: small.language,
@@ -54,8 +71,7 @@ export namespace MessageSummary {
}
}
await Session.updateMessage(userMsg.info)
},
)
}
export const diff = fn(
z.object({