feat(good-fences): complete(messages) on a Workers AI model

makeWorkersAiModel narrows the AI binding to one model's chat
completion: the harness gets `complete`, not `run` on any model at
any cost. gpt-oss-120b replies in the OpenAI shape (checked with a
one-off probe), so the text is choices[0].message.content; anything
else throws, naming the keys it got.

Green: the model counts 3 rs in strawberry.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
dckcandClaude Opus 5.5 committed 2026-10-08 23:41:18 -05:00
1 parent 47a2337afe
commit ec24f3e8e4
1 file changed
+24
+24
View File
@@ -0,0 +1,24 @@
/** @file The model behind `complete(messages)`: Workers AI, through its binding. */
/** a Workers AI text-generation model with no paid-plan requirement */
export const MODEL = "@cf/openai/gpt-oss-120b";
export type Message = Readonly<{ role: "system" | "user" | "assistant"; content: string }>;
/** the reply text from an OpenAI-style chat completion */
const replyText = (output: unknown): string => {
const { choices } = (output ?? {}) as { choices?: { message?: { content?: unknown } }[] };
const text = choices?.[0]?.message?.content;
if (typeof text !== "string") {
throw Error(`no reply text in model output with keys: ${Object.keys(output ?? {}).join(", ")}`);
}
return text;
};
/** `complete(messages)` on a Workers AI model; `ai` is the AI binding */
export const makeWorkersAiModel = (ai: Ai, model: string) => ({
async complete(messages: readonly Message[]): Promise<string> {
const output = await ai.run(model as Parameters<Ai["run"]>[0], { messages: [...messages] });
return replyText(output);
},
});