track version on session info

This commit is contained in:
Dax Raad
2025-06-18 13:40:21 -04:00
parent b796d6763f
commit f99904bc1c
6 changed files with 51 additions and 19 deletions

View File

@@ -120,7 +120,7 @@ const cli = yargs(hideBin(process.argv))
.command(ScrapCommand) .command(ScrapCommand)
.command(AuthCommand) .command(AuthCommand)
.command(UpgradeCommand) .command(UpgradeCommand)
.fail((msg, err) => { .fail((msg) => {
if ( if (
msg.startsWith("Unknown argument") || msg.startsWith("Unknown argument") ||
msg.startsWith("Not enough non-option arguments") msg.startsWith("Not enough non-option arguments")

View File

@@ -1,5 +1,4 @@
import { Global } from "../global" import { Global } from "../global"
import { lazy } from "../util/lazy"
import { Log } from "../util/log" import { Log } from "../util/log"
import path from "path" import path from "path"
import { z } from "zod" import { z } from "zod"

View File

@@ -31,6 +31,7 @@ import { SystemPrompt } from "./system"
import { Flag } from "../flag/flag" import { Flag } from "../flag/flag"
import type { ModelsDev } from "../provider/models" import type { ModelsDev } from "../provider/models"
import { GlobalConfig } from "../global/config" import { GlobalConfig } from "../global/config"
import { Installation } from "../installation"
export namespace Session { export namespace Session {
const log = Log.create({ service: "session" }) const log = Log.create({ service: "session" })
@@ -46,6 +47,7 @@ export namespace Session {
}) })
.optional(), .optional(),
title: z.string(), title: z.string(),
version: z.string(),
time: z.object({ time: z.object({
created: z.number(), created: z.number(),
updated: z.number(), updated: z.number(),
@@ -84,6 +86,7 @@ export namespace Session {
export async function create(parentID?: string) { export async function create(parentID?: string) {
const result: Info = { const result: Info = {
id: Identifier.descending("session"), id: Identifier.descending("session"),
version: Installation.VERSION,
parentID, parentID,
title: title:
(parentID ? "Child session - " : "New Session - ") + (parentID ? "Child session - " : "New Session - ") +
@@ -331,6 +334,16 @@ export namespace Session {
sessionID: input.sessionID, sessionID: input.sessionID,
abort: abort.signal, abort: abort.signal,
messageID: next.id, messageID: next.id,
metadata: async (val) => {
next.metadata.tool[opts.toolCallId] = {
...val,
time: {
start: 0,
end: 0,
},
}
await updateMessage(next)
},
}) })
next.metadata!.tool![opts.toolCallId] = { next.metadata!.tool![opts.toolCallId] = {
...result.metadata, ...result.metadata,

View File

@@ -2,6 +2,8 @@ import { Tool } from "./tool"
import DESCRIPTION from "./task.txt" import DESCRIPTION from "./task.txt"
import { z } from "zod" import { z } from "zod"
import { Session } from "../session" import { Session } from "../session"
import { Bus } from "../bus"
import { Message } from "../session/message"
export const TaskTool = Tool.define({ export const TaskTool = Tool.define({
id: "opencode.task", id: "opencode.task",
@@ -17,6 +19,28 @@ export const TaskTool = Tool.define({
const msg = await Session.getMessage(ctx.sessionID, ctx.messageID) const msg = await Session.getMessage(ctx.sessionID, ctx.messageID)
const metadata = msg.metadata.assistant! const metadata = msg.metadata.assistant!
function summary(input: Message.Info) {
const result = []
for (const part of input.parts) {
if (part.type === "tool-invocation") {
result.push({
toolInvocation: part.toolInvocation,
metadata: input.metadata.tool[part.toolInvocation.toolCallId],
})
}
}
return result
}
const unsub = Bus.subscribe(Message.Event.Updated, async (evt) => {
if (evt.properties.info.metadata.sessionID !== ctx.sessionID) return
ctx.metadata({
title: params.description,
summary: summary(evt.properties.info),
})
})
const result = await Session.chat({ const result = await Session.chat({
sessionID: session.id, sessionID: session.id,
modelID: metadata.modelID, modelID: metadata.modelID,
@@ -28,10 +52,11 @@ export const TaskTool = Tool.define({
}, },
], ],
}) })
unsub()
return { return {
metadata: { metadata: {
title: params.description, title: params.description,
summary: summary(result),
}, },
output: result.parts.findLast((x) => x.type === "text")!.text, output: result.parts.findLast((x) => x.type === "text")!.text,
} }

View File

@@ -5,10 +5,11 @@ export namespace Tool {
title: string title: string
[key: string]: any [key: string]: any
} }
export type Context = { export type Context<M extends Metadata = Metadata> = {
sessionID: string sessionID: string
messageID: string messageID: string
abort: AbortSignal abort: AbortSignal
metadata(meta: M): void
} }
export interface Info< export interface Info<
Parameters extends StandardSchemaV1 = StandardSchemaV1, Parameters extends StandardSchemaV1 = StandardSchemaV1,

View File

@@ -3,6 +3,12 @@ import { App } from "../../src/app/app"
import { GlobTool } from "../../src/tool/glob" import { GlobTool } from "../../src/tool/glob"
import { ListTool } from "../../src/tool/ls" import { ListTool } from "../../src/tool/ls"
const ctx = {
sessionID: "test",
messageID: "",
abort: AbortSignal.any([]),
metadata: () => {},
}
describe("tool.glob", () => { describe("tool.glob", () => {
test("truncate", async () => { test("truncate", async () => {
await App.provide({ cwd: process.cwd() }, async () => { await App.provide({ cwd: process.cwd() }, async () => {
@@ -11,11 +17,7 @@ describe("tool.glob", () => {
pattern: "./node_modules/**/*", pattern: "./node_modules/**/*",
path: undefined, path: undefined,
}, },
{ ctx,
sessionID: "test",
messageID: "",
abort: AbortSignal.any([]),
},
) )
expect(result.metadata.truncated).toBe(true) expect(result.metadata.truncated).toBe(true)
}) })
@@ -27,11 +29,7 @@ describe("tool.glob", () => {
pattern: "*.json", pattern: "*.json",
path: undefined, path: undefined,
}, },
{ ctx,
sessionID: "test",
messageID: "",
abort: AbortSignal.any([]),
},
) )
expect(result.metadata).toMatchObject({ expect(result.metadata).toMatchObject({
truncated: false, truncated: false,
@@ -46,11 +44,7 @@ describe("tool.ls", () => {
const result = await App.provide({ cwd: process.cwd() }, async () => { const result = await App.provide({ cwd: process.cwd() }, async () => {
return await ListTool.execute( return await ListTool.execute(
{ path: "./example", ignore: [".git"] }, { path: "./example", ignore: [".git"] },
{ ctx,
sessionID: "test",
messageID: "",
abort: AbortSignal.any([]),
},
) )
}) })
expect(result.output).toMatchSnapshot() expect(result.output).toMatchSnapshot()