mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-27 22:10:11 -04:00
feat(core): adjust bg shell completion msg (include output file) (#45461)
This commit is contained in:
@@ -19,9 +19,8 @@ import { ToolOutput } from "../../tool-output.js"
|
||||
export const name = "shell"
|
||||
export const DEFAULT_TIMEOUT_MS = 2 * 60 * 1_000
|
||||
|
||||
const BACKGROUND_STARTED = "The command was moved to the background."
|
||||
const BACKGROUND_INSTRUCTION =
|
||||
"You will be notified automatically when the command finishes. DO NOT sleep, poll, or proactively check on its progress."
|
||||
"You will be notified automatically when the command finishes. Avoid sleep commands or polling for completion; if you need the output before then, read the file directly."
|
||||
const OS =
|
||||
process.platform === "darwin"
|
||||
? "macOS"
|
||||
@@ -95,8 +94,8 @@ const toolResult = (output: Output) => {
|
||||
}
|
||||
}
|
||||
|
||||
const backgroundResult = (shellID: string) => ({
|
||||
output: BACKGROUND_STARTED,
|
||||
const backgroundResult = (shellID: string, file: string) => ({
|
||||
output: `Command moved to the background (shell ID: ${shellID}).\nOutput is streaming to: ${file}`,
|
||||
shellID,
|
||||
truncated: false,
|
||||
status: "running" as const,
|
||||
@@ -295,7 +294,7 @@ export const Plugin = {
|
||||
if (input.background === true) {
|
||||
yield* runtime.job.background(job.id)
|
||||
yield* notifyWhenDone(context.sessionID, context.id, info.id, info.command, settled)
|
||||
return backgroundResult(info.id)
|
||||
return backgroundResult(info.id, info.file)
|
||||
}
|
||||
|
||||
const result = yield* runtime.job
|
||||
@@ -304,7 +303,7 @@ export const Plugin = {
|
||||
if (result?.type === "backgrounded") {
|
||||
yield* shell.timeout(info.id, 0)
|
||||
yield* notifyWhenDone(context.sessionID, context.id, info.id, info.command, settled)
|
||||
return backgroundResult(info.id)
|
||||
return backgroundResult(info.id, info.file)
|
||||
}
|
||||
if (result?.info.status === "error")
|
||||
return yield* Effect.fail(new Error(result.info.error ?? "Command failed"))
|
||||
|
||||
@@ -1298,6 +1298,17 @@ describe("ShellTool", () => {
|
||||
const shell = yield* Shell.Service
|
||||
if (!shellID) return
|
||||
const id = ShellSchema.ID.make(shellID)
|
||||
const info = yield* shell.get(id)
|
||||
expect(settled.content).toEqual([
|
||||
{
|
||||
type: "text",
|
||||
text: `Command moved to the background (shell ID: ${shellID}).\nOutput is streaming to: ${info.file}`,
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
text: "You will be notified automatically when the command finishes. Avoid sleep commands or polling for completion; if you need the output before then, read the file directly.",
|
||||
},
|
||||
])
|
||||
expect((yield* shell.list()).map((info) => info.id)).toContain(id)
|
||||
expect((yield* shell.wait(id)).status).toBe("timeout")
|
||||
expect((yield* Fiber.join(admitted)).valueOrUndefined?.data.item.payload).toMatchObject({
|
||||
@@ -1523,19 +1534,20 @@ describe("ShellTool", () => {
|
||||
const settled = yield* Fiber.join(waiting)
|
||||
const shellID = typeof settled.metadata?.shellID === "string" ? settled.metadata.shellID : undefined
|
||||
expect(settled.metadata).toMatchObject({ truncated: false })
|
||||
expect(settled.content?.[0]).toEqual({
|
||||
type: "text",
|
||||
text: "The command was moved to the background.",
|
||||
})
|
||||
expect(settled.content?.[1]).toMatchObject({
|
||||
type: "text",
|
||||
text: expect.stringContaining("DO NOT sleep, poll"),
|
||||
})
|
||||
expect(shellID).toStartWith("sh_")
|
||||
|
||||
const shell = yield* Shell.Service
|
||||
if (!shellID) return
|
||||
const id = ShellSchema.ID.make(shellID)
|
||||
const info = yield* shell.get(id)
|
||||
expect(settled.content?.[0]).toEqual({
|
||||
type: "text",
|
||||
text: `Command moved to the background (shell ID: ${shellID}).\nOutput is streaming to: ${info.file}`,
|
||||
})
|
||||
expect(settled.content?.[1]).toEqual({
|
||||
type: "text",
|
||||
text: "You will be notified automatically when the command finishes. Avoid sleep commands or polling for completion; if you need the output before then, read the file directly.",
|
||||
})
|
||||
yield* Effect.sleep(Duration.millis(100))
|
||||
expect((yield* shell.get(id)).status).toBe("running")
|
||||
expect((yield* shell.list()).map((info) => info.id)).toContain(id)
|
||||
|
||||
Reference in New Issue
Block a user