mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-21 17:54:23 +01:00
wip: bash commands
This commit is contained in:
@@ -592,6 +592,36 @@ export namespace Server {
|
|||||||
return c.json(msg)
|
return c.json(msg)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
.post(
|
||||||
|
"/session/:id/command",
|
||||||
|
describeRoute({
|
||||||
|
description: "Run a bash command",
|
||||||
|
operationId: "session.chat",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Created message",
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: resolver(MessageV2.Assistant),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
zValidator(
|
||||||
|
"param",
|
||||||
|
z.object({
|
||||||
|
id: z.string().openapi({ description: "Session ID" }),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
zValidator("json", Session.CommandInput.omit({ sessionID: true })),
|
||||||
|
async (c) => {
|
||||||
|
const sessionID = c.req.valid("param").id
|
||||||
|
const body = c.req.valid("json")
|
||||||
|
const msg = await Session.command({ ...body, sessionID })
|
||||||
|
return c.json(msg)
|
||||||
|
},
|
||||||
|
)
|
||||||
.post(
|
.post(
|
||||||
"/session/:id/revert",
|
"/session/:id/revert",
|
||||||
describeRoute({
|
describeRoute({
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ import { Plugin } from "../plugin"
|
|||||||
import { Agent } from "../agent/agent"
|
import { Agent } from "../agent/agent"
|
||||||
import { Permission } from "../permission"
|
import { Permission } from "../permission"
|
||||||
import { Wildcard } from "../util/wildcard"
|
import { Wildcard } from "../util/wildcard"
|
||||||
|
import { BashTool } from "../tool/bash"
|
||||||
|
import { ulid } from "ulid"
|
||||||
|
|
||||||
export namespace Session {
|
export namespace Session {
|
||||||
const log = Log.create({ service: "session" })
|
const log = Log.create({ service: "session" })
|
||||||
@@ -997,6 +999,96 @@ export namespace Session {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const CommandInput = z.object({
|
||||||
|
sessionID: Identifier.schema("session"),
|
||||||
|
agent: z.string(),
|
||||||
|
command: z.string(),
|
||||||
|
})
|
||||||
|
export type CommandInput = z.infer<typeof CommandInput>
|
||||||
|
export async function command(input: CommandInput) {
|
||||||
|
using abort = lock(input.sessionID)
|
||||||
|
const msg: MessageV2.Assistant = {
|
||||||
|
id: Identifier.ascending("message"),
|
||||||
|
sessionID: input.sessionID,
|
||||||
|
system: [],
|
||||||
|
mode: input.agent,
|
||||||
|
cost: 0,
|
||||||
|
path: {
|
||||||
|
cwd: App.info().path.cwd,
|
||||||
|
root: App.info().path.root,
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
created: Date.now(),
|
||||||
|
},
|
||||||
|
role: "assistant",
|
||||||
|
tokens: {
|
||||||
|
input: 0,
|
||||||
|
output: 0,
|
||||||
|
reasoning: 0,
|
||||||
|
cache: { read: 0, write: 0 },
|
||||||
|
},
|
||||||
|
modelID: "",
|
||||||
|
providerID: "",
|
||||||
|
}
|
||||||
|
await updateMessage(msg)
|
||||||
|
const part: MessageV2.Part = {
|
||||||
|
type: "tool",
|
||||||
|
id: Identifier.ascending("part"),
|
||||||
|
messageID: msg.id,
|
||||||
|
sessionID: input.sessionID,
|
||||||
|
tool: "bash",
|
||||||
|
callID: ulid(),
|
||||||
|
state: {
|
||||||
|
status: "running",
|
||||||
|
time: {
|
||||||
|
start: Date.now(),
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
command: input.command,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
await updatePart(part)
|
||||||
|
const tool = await BashTool.init()
|
||||||
|
const result = await tool.execute(
|
||||||
|
{
|
||||||
|
command: input.command,
|
||||||
|
description: "User command",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
messageID: msg.id,
|
||||||
|
sessionID: input.sessionID,
|
||||||
|
abort: abort.signal,
|
||||||
|
callID: part.callID,
|
||||||
|
agent: input.agent,
|
||||||
|
metadata: async (e) => {
|
||||||
|
if (part.state.status === "running") {
|
||||||
|
part.state.title = e.title
|
||||||
|
part.state.metadata = e.metadata
|
||||||
|
await updatePart(part)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
msg.time.completed = Date.now()
|
||||||
|
await updateMessage(msg)
|
||||||
|
if (part.state.status === "running") {
|
||||||
|
part.state = {
|
||||||
|
status: "completed",
|
||||||
|
time: {
|
||||||
|
...part.state.time,
|
||||||
|
end: Date.now(),
|
||||||
|
},
|
||||||
|
input: part.state.input,
|
||||||
|
title: result.title,
|
||||||
|
metadata: result.metadata,
|
||||||
|
output: result.output,
|
||||||
|
}
|
||||||
|
await updatePart(part)
|
||||||
|
}
|
||||||
|
return { info: msg, parts: [part] }
|
||||||
|
}
|
||||||
|
|
||||||
function createProcessor(assistantMsg: MessageV2.Assistant, model: ModelsDev.Model) {
|
function createProcessor(assistantMsg: MessageV2.Assistant, model: ModelsDev.Model) {
|
||||||
const toolcalls: Record<string, MessageV2.ToolPart> = {}
|
const toolcalls: Record<string, MessageV2.ToolPart> = {}
|
||||||
let snapshot: string | undefined
|
let snapshot: string | undefined
|
||||||
|
|||||||
Reference in New Issue
Block a user