Crux
API ReferenceAdapters

@use-crux/openai

OpenAI SDK adapter, factory pattern with native generation options plus dense embedding helpers.

Peer dependency: openai

import {
  createOpenAI,
  embedding,
  openaiProviderRuntime,
  openAITranscript,
  toMessages,
  fromMessages,
} from "@use-crux/openai";
import { createGenerateObjectFn, createGenerateTextFn } from "@use-crux/openai";

For usage examples and provider comparison, see the Execution guide.

createOpenAI(client)

Create an adapter bound to an OpenAI client.

createOpenAI() is openaiProviderRuntime.create. The package-owned openAITranscript owns message conversion plus assistant text/tool-call extraction; response metadata normalization, stream deltas, and settings/schema mapping stay in this package too. Crux still owns prompt resolution, tool loops, safety, validation retry, memory capture, and observability.

OpenAI Chat content support maps image parts to image_url, wav/mp3 file parts with data sources to input_audio, and supported file data/provider-file sources to OpenAI file parts. Unsupported model/content combinations throw after prompt resolution and before the client or custom transport runs. Assistant/user media returned in provider content arrays decodes back into canonical ContentPart[]. Chat Completions tool messages remain text-only; when a tool returns media, Crux sends the correlated text tool result followed by native media in a user content part on the same next turn.

The package also exports native generateImage(), transcribe(), and generateSpeech() operations. Translation is selected through the transcription task union; requested timing/detail must match the selected endpoint. Returned image/audio assets are usable immediately and are never persisted implicitly. Typed extra records expose endpoint-specific controls.

FieldTypeDescription
clientOpenAIThe OpenAI client instance

Returns:

MethodDescription
.generate(prompt, options)Execute a prompt via chat.completions.parse (structured) or .create (text)
.stream(prompt, options)Stream a prompt execution
.prepare(prompt, options)Prepare a sans-I/O call handle with OpenAI params
.retrievalModel(config)Bind OpenAI generation to core retrieval recipe steps
.reranker(config)Create a judge-backed core Reranker
import { createOpenAI } from "@use-crux/openai";
import OpenAI from "openai";

const adapter = createOpenAI(
  new OpenAI({ apiKey: process.env.OPENAI_API_KEY }),
);

const result = await adapter.generate(editDraft, {
  model: "gpt-4o",
  input: { instruction: "Fix the intro" },
});
result.text;
result.usage;
result.finalStep;

Media uses the same call and message list:

import { prompt } from "@use-crux/core";

const describeChart = prompt({ id: "describe-chart" });

await adapter.generate(describeChart, {
  model: "gpt-4o",
  messages: [
    {
      role: "user",
      content: [
        { type: "text", text: "Describe this chart." },
        {
          type: "image",
          source: new URL("https://example.com/chart.png"),
          providerOptions: { openai: { detail: "high" } },
        },
      ],
    },
  ],
});

adapter.generate(prompt, options)

FieldTypeDescription
promptPromptThe prompt to execute
options.modelstringModel name
options.inputobjectInput values
options.toolsRecord<string, unknown>?Additional Crux tools to merge at call time
options.toolMiddlewareToolMiddleware | readonly ToolMiddleware[]?Tool execution hooks, including Crux resumable approvals through result.messages.
options.toolApprovalToolApprovalMap?Call-site approval policy; exact tool names beat '*'.
options.toolsContextRecord<string, unknown>?Required for composed tools that declare contextSchema; values are Zod-validated before the tool loop starts.
options.runtimeContextunknown?Shared per-run context visible to tool execute, middleware, and function-form toolApproval policies.
options.transport(params, info) => Promise<ChatCompletion>BYO wire call. Crux still owns tools, approvals, validation retry, routing, and timeouts.
options.extra.toolsChatCompletionTool[]?OpenAI-native tools that bypass Crux tool conversion
options.extra.tool_choicestring?OpenAI-native tool selection
options.extra.parallel_tool_callsboolean?Allow parallel tool calls

Returns: normalized Crux generate result with:

  • result.text: extracted assistant text
  • result.usage: accumulated usage when every provider-call step reported usage
  • result.cost: provider-reported cost when available
  • result.finalStep: final provider-call text, usage, finish reason, response id, and actual model id
  • result.raw: raw OpenAI SDK response
  • result._meta: retained trace metadata for observability plumbing

When the prompt has an output schema, the provider-parsed value remains available on result.raw.choices[0].message.parsed.

adapter.stream(prompt, options)

Stream a prompt execution.

FieldTypeDescription
promptPromptThe prompt to execute
options.modelstringModel name
options.inputobjectInput values
options.toolsRecord<string, unknown>?Additional Crux tools to merge at call time
options.toolMiddlewareToolMiddleware | readonly ToolMiddleware[]?Tool execution hooks, including Crux resumable approvals through result.messages.
options.toolApprovalToolApprovalMap?Call-site approval policy; exact tool names beat '*'.
options.toolsContextRecord<string, unknown>?Required for composed tools that declare contextSchema; values are Zod-validated before the tool loop starts.
options.runtimeContextunknown?Shared per-run context visible to tool execute, middleware, and function-form toolApproval policies.
options.extra.toolsChatCompletionTool[]?OpenAI-native tools that bypass Crux tool conversion
options.extra.tool_choicestring?OpenAI-native tool selection
options.extra.parallel_tool_callsboolean?Allow parallel tool calls

Returns: StreamResult<TRawStream>:

  • result.textStream: provider-neutral text deltas
  • result.raw: raw OpenAI SDK stream
  • result.completion: promise resolving to the canonical completion envelope (text, optional usage, optional cost, steps, finalStep, messages, and pending approvals)

toParams(resolved, options) / fromResponse(response)

toParams() converts a ResolvedPrompt plus { model, settings?, extra? } into OpenAI chat-completion params. ResolvedPrompt does not include a model, so options.model is required. fromResponse() normalizes an OpenAI response into Crux AdapterResponse facts.

These codecs are translation-only. Use managed generate()/stream() when Crux should run tools, approvals, validation retry, memory capture, safety, and observability.

adapter.prepare(prompt, options)

Prepare a headless OpenAI call. Crux resolves the prompt and returns public OpenAI params without making the SDK call. Feed a raw OpenAI response back with finish(response), or use step(response) when tools, validation retry, or approval suspension may need another provider turn.

generate(prompt, { ...options, transport }) is the BYO-wire mode where Crux keeps owning the loop and invokes your callback for each OpenAI request. stream() with transport is intentionally unsupported and rejects with CruxTransportStreamUnsupportedError.

adapter.retrievalModel(config)

Create a core RetrievalModel from the adapter instance.

const retrievalModel = adapter.retrievalModel({ model: "gpt-4o-mini" });

Use it as a recipe-level model or step-level model.

adapter.reranker(config)

Create a core Reranker for rerank({ engine }).

const engine = adapter.reranker({
  model: "gpt-4o-mini",
  topN: 12,
});

OpenAI's direct SDK adapter does not expose a native rerank endpoint. adapter.reranker() uses Crux's judgeReranker() over the configured OpenAI model, so each rerank call spends generation tokens.

toMessages(sdkMessages)

Convert OpenAI ChatCompletionMessageParam[] to canonical Message[].

FieldTypeDescription
sdkMessagesChatCompletionMessageParam[]OpenAI SDK messages

Returns: Message[]

fromMessages(messages)

Convert canonical Message[] to OpenAI ChatCompletionMessageParam[].

FieldTypeDescription
messagesMessage[]Canonical messages

Returns: ChatCompletionMessageParam[]

Assistant tool calls become OpenAI tool_calls; tool results become tool role messages with tool_call_id. For rich tool output, that correlated tool message keeps the safe text projection and a following user message carries the native media parts.

openAITranscript is the lower-level NativeTranscriptCodec used by createOpenAI(). The public toMessages() and fromMessages() wrappers delegate to it.

createGenerateObjectFn(client, model)

Create a GenerateObjectFn bound to a client and model.

FieldTypeDescription
clientOpenAIOpenAI client instance
modelstringModel name

Returns: GenerateObjectFn

This is a provider-native helper generated from the same native chat profile as createOpenAI(). It uses OpenAI's structured parse surface and returns the parsed { object }, preserving provider errors. It does not run Crux prompt resolution, validation retry, safety, cassettes, tools, memory capture, or instrumentation. Use createGenerateObjectFnFromGenerate(generate) from @use-crux/core/compaction when a GenerateObjectFn needs full adapter runtime behavior.

createGenerateTextFn(client, model)

Create a GenerateTextFn bound to a client and model.

FieldTypeDescription
clientOpenAIOpenAI client instance
modelstringModel name

Returns: GenerateTextFn

This helper is also generated from the native chat profile, so text helper calls and adapter calls share request construction and response extraction.

embedding(client, config)

Create a dense Crux embedding backed by client.embeddings.create().

import OpenAI from "openai";
import { embedding } from "@use-crux/openai";

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const docsEmbedding = embedding(client, {
  name: "docs-embedding",
  model: "text-embedding-3-small",
});

Known OpenAI embedding models infer their default dimensions automatically. For custom model IDs, pass dimensions explicitly.

FieldTypeDescription
clientOpenAIOpenAI client instance
config.namestringStable embedding identifier
config.modelstringOpenAI embedding model
config.dimensionsnumber?Explicit vector dimensionality. Required for unknown/custom model IDs.
config.maxInputTokensnumber?Per-input token ceiling. Defaults to 8192.
config.batch.maxSizenumber?Top-level Crux batch size. Defaults to 100.
config.batch.concurrencynumber?Top-level Crux batch concurrency. Defaults to 1.
config.userstring?Optional OpenAI end-user identifier

Types

import type {
  OpenAIChatRequest,
  OpenAIEmbeddingConfig,
  OpenAIExtra,
} from "@use-crux/openai";

On this page