feat(opencode-go): add muse-spark-1.3-contributor and fix parallel tool calls on Responses paths (#3819)

- Add muse-spark-1.3-contributor as responses-only model on OpenCode Go with dedicated executor
- Key Responses→chat streaming tool calls by item_id to prevent parallel tool calls merging into index 0
- Standardize tool coercions and call_id clamping in Responses API translation
This commit is contained in:
Sina Sadeghi
2026-09-05 21:49:00 +07:00
parent 77e6a227fe
commit e74db4d0a6
9 changed files with 541 additions and 24 deletions

View File

@@ -23,6 +23,46 @@ export function normalizeResponsesInput(input) {
return null;
}
// Strict Responses upstreams reject overlong call_ids with InputValidationError (#393).
export const MAX_RESPONSES_CALL_ID_LEN = 64;
export function clampResponsesCallId(id) {
if (typeof id !== "string" || !id) return `call_${Date.now()}`;
return id.length > MAX_RESPONSES_CALL_ID_LEN ? id.substring(0, MAX_RESPONSES_CALL_ID_LEN) : id;
}
// Single-stringify: objects → JSON once; valid JSON strings pass through untouched;
// anything else (partial fragments, empty) falls back to "{}" instead of
// double-encoding and tripping upstream InputValidationError.
export function coerceResponsesArguments(value) {
if (value === undefined || value === null || value === "") return "{}";
if (typeof value !== "string") {
try {
return JSON.stringify(value);
} catch {
return "{}";
}
}
try {
JSON.parse(value);
return value;
} catch {
return "{}";
}
}
// function_call_output.output must be a string — never null/object.
export function coerceResponsesOutput(value) {
if (typeof value === "string") return value;
if (value === undefined || value === null) return "";
if (Array.isArray(value)) return value.map((c) => c?.text ?? JSON.stringify(c)).join("");
try {
return JSON.stringify(value);
} catch {
return String(value);
}
}
/**
* Convert OpenAI Responses API format to standard chat completions format
* Responses API uses: { input: [...], instructions: "..." }