mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-21 09:44:21 +01:00
only display last 100 messages in TUI
This commit is contained in:
@@ -67,7 +67,7 @@ export const ExportCommand = cmd({
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const sessionInfo = await Session.get(sessionID!)
|
const sessionInfo = await Session.get(sessionID!)
|
||||||
const messages = await Session.messages(sessionID!)
|
const messages = await Session.messages({ sessionID: sessionID! })
|
||||||
|
|
||||||
const exportData = {
|
const exportData = {
|
||||||
info: sessionInfo,
|
info: sessionInfo,
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ async function aggregateSessionStats(days?: number, projectFilter?: string): Pro
|
|||||||
const batch = filteredSessions.slice(i, i + BATCH_SIZE)
|
const batch = filteredSessions.slice(i, i + BATCH_SIZE)
|
||||||
|
|
||||||
const batchPromises = batch.map(async (session) => {
|
const batchPromises = batch.map(async (session) => {
|
||||||
const messages = await Session.messages(session.id)
|
const messages = await Session.messages({ sessionID: session.id })
|
||||||
|
|
||||||
let sessionCost = 0
|
let sessionCost = 0
|
||||||
let sessionTokens = { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } }
|
let sessionTokens = { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } }
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|||||||
event.properties.info.sessionID,
|
event.properties.info.sessionID,
|
||||||
produce((draft) => {
|
produce((draft) => {
|
||||||
draft.splice(result.index, 0, event.properties.info)
|
draft.splice(result.index, 0, event.properties.info)
|
||||||
|
if (draft.length > 100) draft.shift()
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
@@ -272,7 +273,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|||||||
console.log("syncing", sessionID)
|
console.log("syncing", sessionID)
|
||||||
const [session, messages, todo, diff] = await Promise.all([
|
const [session, messages, todo, diff] = await Promise.all([
|
||||||
sdk.client.session.get({ path: { id: sessionID }, throwOnError: true }),
|
sdk.client.session.get({ path: { id: sessionID }, throwOnError: true }),
|
||||||
sdk.client.session.messages({ path: { id: sessionID } }),
|
sdk.client.session.messages({ path: { id: sessionID }, query: { limit: 100 } }),
|
||||||
sdk.client.session.todo({ path: { id: sessionID } }),
|
sdk.client.session.todo({ path: { id: sessionID } }),
|
||||||
sdk.client.session.diff({ path: { id: sessionID } }),
|
sdk.client.session.diff({ path: { id: sessionID } }),
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -753,9 +753,19 @@ export namespace Server {
|
|||||||
id: z.string().meta({ description: "Session ID" }),
|
id: z.string().meta({ description: "Session ID" }),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
validator(
|
||||||
|
"query",
|
||||||
|
z.object({
|
||||||
|
limit: z.coerce.number().optional(),
|
||||||
|
}),
|
||||||
|
),
|
||||||
async (c) => {
|
async (c) => {
|
||||||
const messages = await Session.messages(c.req.valid("param").id)
|
const query = c.req.valid("query")
|
||||||
return c.json(messages.slice(-100))
|
const messages = await Session.messages({
|
||||||
|
sessionID: c.req.valid("param").id,
|
||||||
|
limit: query.limit,
|
||||||
|
})
|
||||||
|
return c.json(messages)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.get(
|
.get(
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export namespace SessionCompaction {
|
|||||||
export async function prune(input: { sessionID: string }) {
|
export async function prune(input: { sessionID: string }) {
|
||||||
if (Flag.OPENCODE_DISABLE_PRUNE) return
|
if (Flag.OPENCODE_DISABLE_PRUNE) return
|
||||||
log.info("pruning")
|
log.info("pruning")
|
||||||
const msgs = await Session.messages(input.sessionID)
|
const msgs = await Session.messages({ sessionID: input.sessionID })
|
||||||
let total = 0
|
let total = 0
|
||||||
let pruned = 0
|
let pruned = 0
|
||||||
const toPrune = []
|
const toPrune = []
|
||||||
@@ -111,7 +111,7 @@ export namespace SessionCompaction {
|
|||||||
draft.time.compacting = undefined
|
draft.time.compacting = undefined
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
const toSummarize = await Session.messages(input.sessionID).then(MessageV2.filterCompacted)
|
const toSummarize = await Session.messages({ sessionID: input.sessionID }).then(MessageV2.filterCompacted)
|
||||||
const model = await Provider.getModel(input.providerID, input.modelID)
|
const model = await Provider.getModel(input.providerID, input.modelID)
|
||||||
const system = [
|
const system = [
|
||||||
...SystemPrompt.summarize(model.providerID),
|
...SystemPrompt.summarize(model.providerID),
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ export namespace Session {
|
|||||||
const session = await createNext({
|
const session = await createNext({
|
||||||
directory: Instance.directory,
|
directory: Instance.directory,
|
||||||
})
|
})
|
||||||
const msgs = await messages(input.sessionID)
|
const msgs = await messages({ sessionID: input.sessionID })
|
||||||
for (const msg of msgs) {
|
for (const msg of msgs) {
|
||||||
if (input.messageID && msg.info.id >= input.messageID) break
|
if (input.messageID && msg.info.id >= input.messageID) break
|
||||||
const cloned = await updateMessage({
|
const cloned = await updateMessage({
|
||||||
@@ -237,7 +237,7 @@ export namespace Session {
|
|||||||
})
|
})
|
||||||
await Storage.write(["share", id], share)
|
await Storage.write(["share", id], share)
|
||||||
await Share.sync("session/info/" + id, session)
|
await Share.sync("session/info/" + id, session)
|
||||||
for (const msg of await messages(id)) {
|
for (const msg of await messages({ sessionID: id })) {
|
||||||
await Share.sync("session/message/" + id + "/" + msg.info.id, msg.info)
|
await Share.sync("session/message/" + id + "/" + msg.info.id, msg.info)
|
||||||
for (const part of msg.parts) {
|
for (const part of msg.parts) {
|
||||||
await Share.sync("session/part/" + id + "/" + msg.info.id + "/" + part.id, part)
|
await Share.sync("session/part/" + id + "/" + msg.info.id + "/" + part.id, part)
|
||||||
@@ -273,18 +273,26 @@ export namespace Session {
|
|||||||
return diffs ?? []
|
return diffs ?? []
|
||||||
})
|
})
|
||||||
|
|
||||||
export const messages = fn(Identifier.schema("session"), async (sessionID) => {
|
export const messages = fn(
|
||||||
|
z.object({
|
||||||
|
sessionID: Identifier.schema("session"),
|
||||||
|
limit: z.number().optional(),
|
||||||
|
}),
|
||||||
|
async (input) => {
|
||||||
const result = [] as MessageV2.WithParts[]
|
const result = [] as MessageV2.WithParts[]
|
||||||
for (const p of await Storage.list(["message", sessionID])) {
|
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)
|
const read = await Storage.read<MessageV2.Info>(p)
|
||||||
result.push({
|
result.push({
|
||||||
info: read,
|
info: read,
|
||||||
parts: await getParts(read.id),
|
parts: await getParts(read.id),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
result.sort((a, b) => (a.info.id > b.info.id ? 1 : -1))
|
|
||||||
return result
|
return result
|
||||||
})
|
},
|
||||||
|
)
|
||||||
|
|
||||||
export const getMessage = fn(
|
export const getMessage = fn(
|
||||||
z.object({
|
z.object({
|
||||||
|
|||||||
@@ -434,7 +434,7 @@ export namespace SessionPrompt {
|
|||||||
providerID: string
|
providerID: string
|
||||||
signal: AbortSignal
|
signal: AbortSignal
|
||||||
}) {
|
}) {
|
||||||
let msgs = await Session.messages(input.sessionID).then(MessageV2.filterCompacted)
|
let msgs = await Session.messages({ sessionID: input.sessionID }).then(MessageV2.filterCompacted)
|
||||||
const lastAssistant = msgs.findLast((msg) => msg.info.role === "assistant")
|
const lastAssistant = msgs.findLast((msg) => msg.info.role === "assistant")
|
||||||
if (
|
if (
|
||||||
lastAssistant?.info.role === "assistant" &&
|
lastAssistant?.info.role === "assistant" &&
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export namespace SessionRevert {
|
|||||||
sessionID: input.sessionID,
|
sessionID: input.sessionID,
|
||||||
})
|
})
|
||||||
|
|
||||||
const all = await Session.messages(input.sessionID)
|
const all = await Session.messages({ sessionID: input.sessionID })
|
||||||
let lastUser: MessageV2.User | undefined
|
let lastUser: MessageV2.User | undefined
|
||||||
const session = await Session.get(input.sessionID)
|
const session = await Session.get(input.sessionID)
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ export namespace SessionRevert {
|
|||||||
export async function cleanup(session: Session.Info) {
|
export async function cleanup(session: Session.Info) {
|
||||||
if (!session.revert) return
|
if (!session.revert) return
|
||||||
const sessionID = session.id
|
const sessionID = session.id
|
||||||
let msgs = await Session.messages(sessionID)
|
let msgs = await Session.messages({ sessionID })
|
||||||
const messageID = session.revert.messageID
|
const messageID = session.revert.messageID
|
||||||
const [preserve, remove] = splitWhen(msgs, (x) => x.info.id === messageID)
|
const [preserve, remove] = splitWhen(msgs, (x) => x.info.id === messageID)
|
||||||
msgs = preserve
|
msgs = preserve
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export namespace SessionSummary {
|
|||||||
messageID: z.string(),
|
messageID: z.string(),
|
||||||
}),
|
}),
|
||||||
async (input) => {
|
async (input) => {
|
||||||
const all = await Session.messages(input.sessionID)
|
const all = await Session.messages({ sessionID: input.sessionID })
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
summarizeSession({ sessionID: input.sessionID, messages: all }),
|
summarizeSession({ sessionID: input.sessionID, messages: all }),
|
||||||
summarizeMessage({ messageID: input.messageID, messages: all }),
|
summarizeMessage({ messageID: input.messageID, messages: all }),
|
||||||
@@ -151,7 +151,7 @@ export namespace SessionSummary {
|
|||||||
messageID: Identifier.schema("message").optional(),
|
messageID: Identifier.schema("message").optional(),
|
||||||
}),
|
}),
|
||||||
async (input) => {
|
async (input) => {
|
||||||
let all = await Session.messages(input.sessionID)
|
let all = await Session.messages({ sessionID: input.sessionID })
|
||||||
if (input.messageID)
|
if (input.messageID)
|
||||||
all = all.filter(
|
all = all.filter(
|
||||||
(x) =>
|
(x) =>
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export const TaskTool = Tool.define("task", async () => {
|
|||||||
})
|
})
|
||||||
unsub()
|
unsub()
|
||||||
let all
|
let all
|
||||||
all = await Session.messages(session.id)
|
all = await Session.messages({ sessionID: session.id })
|
||||||
all = all.filter((x) => x.info.role === "assistant")
|
all = all.filter((x) => x.info.role === "assistant")
|
||||||
all = all.flatMap(
|
all = all.flatMap(
|
||||||
(msg) => msg.parts.filter((x: any) => x.type === "tool") as MessageV2.ToolPart[],
|
(msg) => msg.parts.filter((x: any) => x.type === "tool") as MessageV2.ToolPart[],
|
||||||
|
|||||||
@@ -650,7 +650,6 @@ export type AssistantMessage = {
|
|||||||
| MessageOutputLengthError
|
| MessageOutputLengthError
|
||||||
| MessageAbortedError
|
| MessageAbortedError
|
||||||
| ApiError
|
| ApiError
|
||||||
system: Array<string>
|
|
||||||
parentID: string
|
parentID: string
|
||||||
modelID: string
|
modelID: string
|
||||||
providerID: string
|
providerID: string
|
||||||
@@ -1982,6 +1981,7 @@ export type SessionMessagesData = {
|
|||||||
}
|
}
|
||||||
query?: {
|
query?: {
|
||||||
directory?: string
|
directory?: string
|
||||||
|
limit?: number
|
||||||
}
|
}
|
||||||
url: "/session/{id}/message"
|
url: "/session/{id}/message"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user