diff --git a/packages/opencode/src/index.ts b/packages/opencode/src/index.ts index 9612abad..63f1021d 100644 --- a/packages/opencode/src/index.ts +++ b/packages/opencode/src/index.ts @@ -120,7 +120,7 @@ const cli = yargs(hideBin(process.argv)) .command(ScrapCommand) .command(AuthCommand) .command(UpgradeCommand) - .fail((msg, err) => { + .fail((msg) => { if ( msg.startsWith("Unknown argument") || msg.startsWith("Not enough non-option arguments") diff --git a/packages/opencode/src/provider/models.ts b/packages/opencode/src/provider/models.ts index b53a6983..40d8328d 100644 --- a/packages/opencode/src/provider/models.ts +++ b/packages/opencode/src/provider/models.ts @@ -1,5 +1,4 @@ import { Global } from "../global" -import { lazy } from "../util/lazy" import { Log } from "../util/log" import path from "path" import { z } from "zod" diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts index 7d310b85..61457c9d 100644 --- a/packages/opencode/src/session/index.ts +++ b/packages/opencode/src/session/index.ts @@ -31,6 +31,7 @@ import { SystemPrompt } from "./system" import { Flag } from "../flag/flag" import type { ModelsDev } from "../provider/models" import { GlobalConfig } from "../global/config" +import { Installation } from "../installation" export namespace Session { const log = Log.create({ service: "session" }) @@ -46,6 +47,7 @@ export namespace Session { }) .optional(), title: z.string(), + version: z.string(), time: z.object({ created: z.number(), updated: z.number(), @@ -84,6 +86,7 @@ export namespace Session { export async function create(parentID?: string) { const result: Info = { id: Identifier.descending("session"), + version: Installation.VERSION, parentID, title: (parentID ? "Child session - " : "New Session - ") + @@ -331,6 +334,16 @@ export namespace Session { sessionID: input.sessionID, abort: abort.signal, 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] = { ...result.metadata, diff --git a/packages/opencode/src/tool/task.ts b/packages/opencode/src/tool/task.ts index ce1e1dc0..aace941f 100644 --- a/packages/opencode/src/tool/task.ts +++ b/packages/opencode/src/tool/task.ts @@ -2,6 +2,8 @@ import { Tool } from "./tool" import DESCRIPTION from "./task.txt" import { z } from "zod" import { Session } from "../session" +import { Bus } from "../bus" +import { Message } from "../session/message" export const TaskTool = Tool.define({ id: "opencode.task", @@ -17,6 +19,28 @@ export const TaskTool = Tool.define({ const msg = await Session.getMessage(ctx.sessionID, ctx.messageID) 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({ sessionID: session.id, modelID: metadata.modelID, @@ -28,10 +52,11 @@ export const TaskTool = Tool.define({ }, ], }) - + unsub() return { metadata: { title: params.description, + summary: summary(result), }, output: result.parts.findLast((x) => x.type === "text")!.text, } diff --git a/packages/opencode/src/tool/tool.ts b/packages/opencode/src/tool/tool.ts index ccbcaffe..8c1cbf48 100644 --- a/packages/opencode/src/tool/tool.ts +++ b/packages/opencode/src/tool/tool.ts @@ -5,10 +5,11 @@ export namespace Tool { title: string [key: string]: any } - export type Context = { + export type Context = { sessionID: string messageID: string abort: AbortSignal + metadata(meta: M): void } export interface Info< Parameters extends StandardSchemaV1 = StandardSchemaV1, diff --git a/packages/opencode/test/tool/tool.test.ts b/packages/opencode/test/tool/tool.test.ts index 2d41405d..b0664349 100644 --- a/packages/opencode/test/tool/tool.test.ts +++ b/packages/opencode/test/tool/tool.test.ts @@ -3,6 +3,12 @@ import { App } from "../../src/app/app" import { GlobTool } from "../../src/tool/glob" import { ListTool } from "../../src/tool/ls" +const ctx = { + sessionID: "test", + messageID: "", + abort: AbortSignal.any([]), + metadata: () => {}, +} describe("tool.glob", () => { test("truncate", async () => { await App.provide({ cwd: process.cwd() }, async () => { @@ -11,11 +17,7 @@ describe("tool.glob", () => { pattern: "./node_modules/**/*", path: undefined, }, - { - sessionID: "test", - messageID: "", - abort: AbortSignal.any([]), - }, + ctx, ) expect(result.metadata.truncated).toBe(true) }) @@ -27,11 +29,7 @@ describe("tool.glob", () => { pattern: "*.json", path: undefined, }, - { - sessionID: "test", - messageID: "", - abort: AbortSignal.any([]), - }, + ctx, ) expect(result.metadata).toMatchObject({ truncated: false, @@ -46,11 +44,7 @@ describe("tool.ls", () => { const result = await App.provide({ cwd: process.cwd() }, async () => { return await ListTool.execute( { path: "./example", ignore: [".git"] }, - { - sessionID: "test", - messageID: "", - abort: AbortSignal.any([]), - }, + ctx, ) }) expect(result.output).toMatchSnapshot()