fix(good-fences): give the model room to answer
gpt-oss-120b reasons before it answers, and Workers AI's default max_tokens (256) ran out mid-thought: finish_reason "length", content null. Ask for 4096, and when there's no reply text, say which choice and message keys came back instead. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
37faa92649
commit
4a85143a66
1 file changed
+14
-4
@@ -3,14 +3,24 @@
|
|||||||
/** a Workers AI text-generation model with no paid-plan requirement */
|
/** a Workers AI text-generation model with no paid-plan requirement */
|
||||||
export const MODEL = "@cf/openai/gpt-oss-120b";
|
export const MODEL = "@cf/openai/gpt-oss-120b";
|
||||||
|
|
||||||
|
/** room for a reasoning model to think and then answer; the default, 256,
|
||||||
|
* runs out mid-thought (`finish_reason: length`) */
|
||||||
|
const MAX_TOKENS = 4096;
|
||||||
|
|
||||||
export type Message = Readonly<{ role: "system" | "user" | "assistant"; content: string }>;
|
export type Message = Readonly<{ role: "system" | "user" | "assistant"; content: string }>;
|
||||||
|
|
||||||
/** the reply text from an OpenAI-style chat completion */
|
/** the reply text from an OpenAI-style chat completion */
|
||||||
const replyText = (output: unknown): string => {
|
const replyText = (output: unknown): string => {
|
||||||
const { choices } = (output ?? {}) as { choices?: { message?: { content?: unknown } }[] };
|
const { choices } = (output ?? {}) as {
|
||||||
const text = choices?.[0]?.message?.content;
|
choices?: { message?: { content?: unknown }; finish_reason?: unknown }[];
|
||||||
|
};
|
||||||
|
const [choice] = choices ?? [];
|
||||||
|
const text = choice?.message?.content;
|
||||||
if (typeof text !== "string") {
|
if (typeof text !== "string") {
|
||||||
throw Error(`no reply text in model output with keys: ${Object.keys(output ?? {}).join(", ")}`);
|
const where = choice
|
||||||
|
? `choice with finish_reason ${String(choice.finish_reason)} and message keys: ${Object.keys(choice.message ?? {}).join(", ")}`
|
||||||
|
: `model output with keys: ${Object.keys(output ?? {}).join(", ")}`;
|
||||||
|
throw Error(`no reply text in ${where}`);
|
||||||
}
|
}
|
||||||
return text;
|
return text;
|
||||||
};
|
};
|
||||||
@@ -18,7 +28,7 @@ const replyText = (output: unknown): string => {
|
|||||||
/** `complete(messages)` on a Workers AI model; `ai` is the AI binding */
|
/** `complete(messages)` on a Workers AI model; `ai` is the AI binding */
|
||||||
export const makeWorkersAiModel = (ai: Ai, model: string) => ({
|
export const makeWorkersAiModel = (ai: Ai, model: string) => ({
|
||||||
async complete(messages: readonly Message[]): Promise<string> {
|
async complete(messages: readonly Message[]): Promise<string> {
|
||||||
const output = await ai.run(model as Parameters<Ai["run"]>[0], { messages: [...messages] });
|
const output = await ai.run(model as Parameters<Ai["run"]>[0], { messages: [...messages], max_tokens: MAX_TOKENS });
|
||||||
return replyText(output);
|
return replyText(output);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user