Add support for OpenCode 1.15 DB
This commit is contained in:
@@ -21,6 +21,7 @@ type TestPart = {
|
|||||||
content?: string | Array<{ type: "text"; text: string }>
|
content?: string | Array<{ type: "text"; text: string }>
|
||||||
text?: string
|
text?: string
|
||||||
synthetic?: boolean
|
synthetic?: boolean
|
||||||
|
state?: { status?: string; output?: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestMessage = {
|
type TestMessage = {
|
||||||
@@ -57,6 +58,35 @@ describe("createToolPairValidatorHook", () => {
|
|||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("leaves terminal OpenCode tool parts unchanged", async () => {
|
||||||
|
//#given
|
||||||
|
const messages = [
|
||||||
|
{
|
||||||
|
info: { role: "assistant" },
|
||||||
|
parts: [
|
||||||
|
{ type: "tool", callID: "call_completed", state: { status: "completed", output: "OK" } },
|
||||||
|
{ type: "tool", callID: "call_error", state: { status: "error", output: "File not found" } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ info: { role: "assistant" }, parts: [{ type: "text", text: "final answer" }] },
|
||||||
|
] satisfies TestMessage[]
|
||||||
|
|
||||||
|
//#when
|
||||||
|
await runTransform(messages)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
expect(messages).toEqual([
|
||||||
|
{
|
||||||
|
info: { role: "assistant" },
|
||||||
|
parts: [
|
||||||
|
{ type: "tool", callID: "call_completed", state: { status: "completed", output: "OK" } },
|
||||||
|
{ type: "tool", callID: "call_error", state: { status: "error", output: "File not found" } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ info: { role: "assistant" }, parts: [{ type: "text", text: "final answer" }] },
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
it("injects a missing tool_result into the next user message", async () => {
|
it("injects a missing tool_result into the next user message", async () => {
|
||||||
//#given
|
//#given
|
||||||
const messages = [
|
const messages = [
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { log } from "../../shared/logger"
|
|||||||
|
|
||||||
const TOOL_RESULT_PLACEHOLDER = "Tool output unavailable (context compacted)"
|
const TOOL_RESULT_PLACEHOLDER = "Tool output unavailable (context compacted)"
|
||||||
const TOOL_RESULT_RECOVERY_CONTINUATION = "Recovered missing tool results. Continue from the repaired tool output."
|
const TOOL_RESULT_RECOVERY_CONTINUATION = "Recovered missing tool results. Continue from the repaired tool output."
|
||||||
|
const TERMINAL_OPENCODE_TOOL_STATUSES = new Set(["completed", "error"])
|
||||||
|
|
||||||
type ToolUsePart = {
|
type ToolUsePart = {
|
||||||
type: "tool_use"
|
type: "tool_use"
|
||||||
@@ -46,6 +47,24 @@ type MessagesTransformHook = {
|
|||||||
) => Promise<void>
|
) => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
|
return typeof value === "object" && value !== null
|
||||||
|
}
|
||||||
|
|
||||||
|
function isTerminalOpenCodeToolPart(part: TransformPart): boolean {
|
||||||
|
const candidate = part as { type?: unknown; callID?: unknown; state?: unknown }
|
||||||
|
if (candidate.type !== "tool" || typeof candidate.callID !== "string" || candidate.callID.length === 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isRecord(candidate.state)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const status = candidate.state["status"]
|
||||||
|
return typeof status === "string" && TERMINAL_OPENCODE_TOOL_STATUSES.has(status)
|
||||||
|
}
|
||||||
|
|
||||||
function getToolUseID(part: TransformPart): string | null {
|
function getToolUseID(part: TransformPart): string | null {
|
||||||
const candidate = part as { type?: unknown; id?: unknown; callID?: unknown }
|
const candidate = part as { type?: unknown; id?: unknown; callID?: unknown }
|
||||||
|
|
||||||
@@ -54,7 +73,7 @@ function getToolUseID(part: TransformPart): string | null {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (candidate.type === "tool" && typeof candidate.callID === "string" && candidate.callID.length > 0) {
|
if (candidate.type === "tool" && typeof candidate.callID === "string" && candidate.callID.length > 0) {
|
||||||
return candidate.callID
|
return isTerminalOpenCodeToolPart(part) ? null : candidate.callID
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
|||||||
Reference in New Issue
Block a user