Documentation

OpenAI Chat

Use Milkey inline or hosted tools with Chat Completions while keeping full transcript control.

Overview

OpenAI Chat is the right path when your app already lives on Chat Completions or when you intentionally want fine-grained control over the entire transcript loop.

The SDK supports both inline and hosted modes here, but `mode: "auto"` resolves to `inline` because that is the most portable shape across OpenAI-compatible chat providers.

Recommended

Recommended default: inline

Supported modes

inline, hosted, auto

Helpers

  • milkey.openai.chat.tools(...)
  • milkey.openai.chat.messages(...)
  • milkey.openai.chat.resolveMode(...)

Examples

Full GitHub example
Use the complete provider example in the SDK repo when you want the full runnable file with imports, env handling, and a realistic integration shape. Open the GitHub example.
import OpenAI from "openai"import { milkey } from "@milkeyskills/sdk" const openai = new OpenAI({  apiKey: process.env.OPENAI_API_KEY!,}) const milkeyClient = milkey.createClient({  baseUrl: process.env.MILKEY_BASE_URL!,  apiKey: process.env.MILKEY_API_KEY!,}) const tools = milkey.openai.chat.tools({  client: milkeyClient,  mode: "inline",}) const messages = [  {    role: "user",    content: "Find the best Milkey skill for PostgreSQL query optimization.",  },] for (let turn = 1; turn <= 4; turn += 1) {  const completion = await openai.chat.completions.create({    model: process.env.OPENAI_MODEL ?? "gpt-5",    messages,    tools,    tool_choice: "auto",  })   const assistant = completion.choices[0]?.message  if (!assistant) throw new Error("No assistant message returned.")   messages.push({    role: "assistant",    content: assistant.content ?? "",    tool_calls: assistant.tool_calls?.map((toolCall) => ({      id: toolCall.id,      type: "function",      function: {        name: toolCall.function.name,        arguments: toolCall.function.arguments,      },    })),  })   if (!assistant.tool_calls?.length) break   const toolMessages = await milkey.openai.chat.messages(assistant, milkeyClient)  messages.push(...toolMessages)}

Inline bounded loop

examples/openai-chat-completions.ts

Hosted tools

Edge cases and production notes

  • Keep a bounded max-turn loop. The SDK helps with tool formatting, but your app still owns convergence and stop conditions.
  • Assistant messages that contain tool calls and no natural-language text are normal in inline mode.
  • Hosted mode is supported, but Responses is still the cleaner OpenAI-native hosted path when you have that option.
Watch for these edges
  • Malformed function arguments will surface as `MilkeyToolCallError` before execution reaches Milkey.
  • Optional tool parameters are normalized for OpenAI strict mode compatibility.

© 2026 Milkey MCP