mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-17 12:22:34 +03:00
fix(sse): reject unsupported chatgpt-session content parts instead of dropping them
textFromContent threw for image parts but silently skipped everything else, so a `file` or `input_audio` part vanished and the model answered about content it never received. Any part that is neither a text part nor an already-handled image part now throws ChatGptSessionInputError with code "unsupported_content_part" (a terminal 400).
This commit is contained in:
@@ -34,18 +34,27 @@ function textFromContent(content: unknown): string {
|
||||
if (!Array.isArray(content)) return "";
|
||||
const chunks: string[] = [];
|
||||
for (const part of content) {
|
||||
if (!part || typeof part !== "object") continue;
|
||||
const typed = part as Record<string, unknown>;
|
||||
if (typed.type === "text" && typeof typed.text === "string") {
|
||||
const typed =
|
||||
part && typeof part === "object" && !Array.isArray(part)
|
||||
? (part as Record<string, unknown>)
|
||||
: null;
|
||||
if (typed && typed.type === "text" && typeof typed.text === "string") {
|
||||
chunks.push(typed.text);
|
||||
continue;
|
||||
}
|
||||
if (typed.type === "image_url" || typed.type === "image") {
|
||||
if (typed && (typed.type === "image_url" || typed.type === "image")) {
|
||||
throw new ChatGptSessionInputError(
|
||||
"vision_unsupported",
|
||||
"ChatGPT Session does not accept image input yet"
|
||||
);
|
||||
}
|
||||
// Every other part — file, input_audio, a future part type, or anything malformed — would
|
||||
// otherwise be dropped in silence, and the model would answer about content it never
|
||||
// received. Reject loudly instead.
|
||||
throw new ChatGptSessionInputError(
|
||||
"unsupported_content_part",
|
||||
"ChatGPT Session does not accept this message content part type"
|
||||
);
|
||||
}
|
||||
return chunks.join("\n");
|
||||
}
|
||||
|
||||
@@ -116,3 +116,21 @@ test("never carries tools into the parsed context", () => {
|
||||
});
|
||||
assert.equal(parsed.context.tools, undefined);
|
||||
});
|
||||
|
||||
test("rejects any content part that is neither text nor an image", () => {
|
||||
for (const part of [
|
||||
{ type: "file", file: { file_id: "f-1" } },
|
||||
{ type: "input_audio", input_audio: { data: "AA", format: "wav" } },
|
||||
]) {
|
||||
assert.throws(
|
||||
() =>
|
||||
buildParsedRequest({
|
||||
route,
|
||||
messages: [{ role: "user", content: [part] }],
|
||||
stream: false,
|
||||
}),
|
||||
(error: unknown) =>
|
||||
error instanceof ChatGptSessionInputError && error.code === "unsupported_content_part"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user