@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.
| Field | Type | Description |
|---|---|---|
client | OpenAI | The OpenAI client instance |
Returns:
| Method | Description |
|---|---|
.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)
| Field | Type | Description |
|---|---|---|
prompt | Prompt | The prompt to execute |
options.model | string | Model name |
options.input | object | Input values |
options.tools | Record<string, unknown>? | Additional Crux tools to merge at call time |
options.toolMiddleware | ToolMiddleware | readonly ToolMiddleware[]? | Tool execution hooks, including Crux resumable approvals through result.messages. |
options.toolApproval | ToolApprovalMap? | Call-site approval policy; exact tool names beat '*'. |
options.toolsContext | Record<string, unknown>? | Required for composed tools that declare contextSchema; values are Zod-validated before the tool loop starts. |
options.runtimeContext | unknown? | 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.tools | ChatCompletionTool[]? | OpenAI-native tools that bypass Crux tool conversion |
options.extra.tool_choice | string? | OpenAI-native tool selection |
options.extra.parallel_tool_calls | boolean? | Allow parallel tool calls |
Returns: normalized Crux generate result with:
result.text: extracted assistant textresult.usage: accumulated usage when every provider-call step reported usageresult.cost: provider-reported cost when availableresult.finalStep: final provider-call text, usage, finish reason, response id, and actual model idresult.raw: raw OpenAI SDK responseresult._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.
| Field | Type | Description |
|---|---|---|
prompt | Prompt | The prompt to execute |
options.model | string | Model name |
options.input | object | Input values |
options.tools | Record<string, unknown>? | Additional Crux tools to merge at call time |
options.toolMiddleware | ToolMiddleware | readonly ToolMiddleware[]? | Tool execution hooks, including Crux resumable approvals through result.messages. |
options.toolApproval | ToolApprovalMap? | Call-site approval policy; exact tool names beat '*'. |
options.toolsContext | Record<string, unknown>? | Required for composed tools that declare contextSchema; values are Zod-validated before the tool loop starts. |
options.runtimeContext | unknown? | Shared per-run context visible to tool execute, middleware, and function-form toolApproval policies. |
options.extra.tools | ChatCompletionTool[]? | OpenAI-native tools that bypass Crux tool conversion |
options.extra.tool_choice | string? | OpenAI-native tool selection |
options.extra.parallel_tool_calls | boolean? | Allow parallel tool calls |
Returns: StreamResult<TRawStream>:
result.textStream: provider-neutral text deltasresult.raw: raw OpenAI SDK streamresult.completion: promise resolving to the canonical completion envelope (text, optionalusage, optionalcost,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[].
| Field | Type | Description |
|---|---|---|
sdkMessages | ChatCompletionMessageParam[] | OpenAI SDK messages |
Returns: Message[]
fromMessages(messages)
Convert canonical Message[] to OpenAI ChatCompletionMessageParam[].
| Field | Type | Description |
|---|---|---|
messages | Message[] | 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.
| Field | Type | Description |
|---|---|---|
client | OpenAI | OpenAI client instance |
model | string | Model 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.
| Field | Type | Description |
|---|---|---|
client | OpenAI | OpenAI client instance |
model | string | Model 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.
| Field | Type | Description |
|---|---|---|
client | OpenAI | OpenAI client instance |
config.name | string | Stable embedding identifier |
config.model | string | OpenAI embedding model |
config.dimensions | number? | Explicit vector dimensionality. Required for unknown/custom model IDs. |
config.maxInputTokens | number? | Per-input token ceiling. Defaults to 8192. |
config.batch.maxSize | number? | Top-level Crux batch size. Defaults to 100. |
config.batch.concurrency | number? | Top-level Crux batch concurrency. Defaults to 1. |
config.user | string? | Optional OpenAI end-user identifier |
Types
import type {
OpenAIChatRequest,
OpenAIEmbeddingConfig,
OpenAIExtra,
} from "@use-crux/openai";Related
- Guide: Execution
- Guide: Embeddings
- Reference: Prompts
- Reference: @use-crux/ai (Vercel AI SDK)