mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-26 08:23:34 +00:00
mini: fix shell tool output display (#37711)
This commit is contained in:
parent
cbcf191fdb
commit
cf6e5b3604
4 changed files with 29 additions and 10 deletions
|
|
@ -2,6 +2,7 @@ import type { EventSubscribeOutput, OpenCodeClient } from "@opencode-ai/client/p
|
|||
import { SessionMessage } from "@opencode-ai/schema/session-message"
|
||||
import { EOL } from "node:os"
|
||||
import { readFile } from "node:fs/promises"
|
||||
import { toolOutputText } from "./tool"
|
||||
import { UI } from "./ui"
|
||||
import type { MiniToolPart } from "./types"
|
||||
|
||||
|
|
@ -274,10 +275,7 @@ export async function runNonInteractivePrompt(input: Input) {
|
|||
state: {
|
||||
status: "completed",
|
||||
input: current.input,
|
||||
output: event.data.content
|
||||
.filter((item) => item.type === "text")
|
||||
.map((item) => item.text)
|
||||
.join("\n"),
|
||||
output: toolOutputText(current.tool, event.data.content),
|
||||
title: current.tool,
|
||||
metadata: {
|
||||
structured: event.data.structured,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import type {
|
|||
} from "@opencode-ai/client/promise"
|
||||
import { Locale } from "@opencode-ai/tui/util/locale"
|
||||
import type { FooterSubagentDetail, FooterSubagentState, FooterSubagentTab, MiniToolPart, StreamCommit } from "./types"
|
||||
import { toolOutputText } from "./tool"
|
||||
|
||||
const CHILD_MESSAGE_LIMIT = 80
|
||||
const CHILD_FRAME_LIMIT = 80
|
||||
|
|
@ -32,10 +33,6 @@ const FALLBACK_LABEL = "Subagent"
|
|||
|
||||
type V2Event = EventSubscribeOutput
|
||||
|
||||
export function outputText(content: ReadonlyArray<{ type: string; text?: string }>) {
|
||||
return content.flatMap((item) => (item.type === "text" && item.text ? [item.text] : [])).join("\n")
|
||||
}
|
||||
|
||||
export function miniTool(input: {
|
||||
sessionID: string
|
||||
messageID: string
|
||||
|
|
@ -82,7 +79,7 @@ export function miniTool(input: {
|
|||
state: {
|
||||
status: "completed",
|
||||
input: tool.state.input,
|
||||
output: outputText(tool.state.content),
|
||||
output: toolOutputText(tool.name, tool.state.content),
|
||||
title: tool.name,
|
||||
metadata: {
|
||||
structured: tool.state.structured,
|
||||
|
|
|
|||
|
|
@ -177,6 +177,12 @@ function text(v: unknown): string {
|
|||
return typeof v === "string" ? v : ""
|
||||
}
|
||||
|
||||
export function toolOutputText(name: string, content: ReadonlyArray<{ type: string; text?: string }>) {
|
||||
// V2 shell content appends model-only status after the user-visible command output.
|
||||
if (name === "shell") return content.find((item) => item.type === "text")?.text ?? ""
|
||||
return content.flatMap((item) => (item.type === "text" && item.text ? [item.text] : [])).join("\n")
|
||||
}
|
||||
|
||||
function num(v: unknown): number | undefined {
|
||||
if (typeof v !== "number" || !Number.isFinite(v)) {
|
||||
return undefined
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { describe, expect, test } from "bun:test"
|
|||
import { InstallationVersion } from "@opencode-ai/core/installation/version"
|
||||
import path from "node:path"
|
||||
import { mergeInteractiveInput, mergeNonInteractiveInput, parseRunModel, pickRunModel } from "../src/mini"
|
||||
import { toolInlineInfo, toolView } from "../src/mini/tool"
|
||||
import { toolInlineInfo, toolOutputText, toolView } from "../src/mini/tool"
|
||||
|
||||
async function cli(args: string[]) {
|
||||
const child = Bun.spawn([process.execPath, "run", "src/index.ts", ...args], {
|
||||
|
|
@ -36,6 +36,24 @@ describe("mini command", () => {
|
|||
expect(toolInlineInfo(part)).toMatchObject({ icon: "$", title: "pwd", mode: "block" })
|
||||
})
|
||||
|
||||
test("uses non-empty V2 shell output without the model-facing status", () => {
|
||||
expect(
|
||||
toolOutputText("shell", [
|
||||
{ type: "text", text: "mini-output\n" },
|
||||
{ type: "text", text: "Command exited with code 0." },
|
||||
]),
|
||||
).toBe("mini-output\n")
|
||||
})
|
||||
|
||||
test("keeps empty V2 shell output empty", () => {
|
||||
expect(
|
||||
toolOutputText("shell", [
|
||||
{ type: "text", text: "" },
|
||||
{ type: "text", text: "Command exited with code 0." },
|
||||
]),
|
||||
).toBe("")
|
||||
})
|
||||
|
||||
test("uses piped stdin as the initial prompt", () => {
|
||||
expect(mergeInteractiveInput("from stdin", undefined)).toBe("from stdin")
|
||||
expect(mergeInteractiveInput("from stdin", "from flag")).toBe("from stdin\nfrom flag")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue