outl1ne/nova-openai
OpenAI integration for Laravel Nova. This package adds AI-powered text generation to your Nova admin panel, letting you configure prompts and models and generate or rewrite content directly from resources. Useful for drafting copy, summarizing text, and streamlining content workflows.
outl1ne/nova-openai is a Laravel Nova integration for OpenAI: it exposes AI text generation inside Nova (as a field/tool) so editors and admins can draft or rewrite content without leaving the admin panel. As of 0.17.7 the package targets Nova 4.x and now includes Responses API endpoints, i.e. it can talk to OpenAI's newer /v1/responses surface rather than only chat completions.
Minimal setup:
composer require outl1ne/nova-openai in a Laravel app that already has Nova 4 installed.php artisan vendor:publish and pick the nova-openai provider/tag listed in the README) so you get an editable config file for API key, default model, and endpoint settings.OPENAI_API_KEY (and organization/project ID if your account requires it) to .env, then php artisan config:clear.app/Nova/NovaServiceProvider.php (tools([...])) if you want the standalone Nova tool, or skip straight to the field if you only need per-field generation.Text/Textarea column on a Page or Post resource, and open that resource's create form in Nova.Where to look first:
src/Fields and src/Http/Controllers (or equivalent) in the package — the field is the primary integration point; the Response API support shows up here as the request/response shaping layer.First real use case: give content editors a "Generate draft" button on a resource's body field so they can seed copy from a short prompt, then edit it in place before saving. That single flow exercises the API key, model config, and the field wiring end to end — if it works, everything else is tuning.
Field-driven generation (the common case). Declare the OpenAI field on a resource form next to the attribute it fills. Keep the prompt input small (a topic/instruction field) and let the package write into the target attribute. Treat the generated text as draft input: the human still hits Save. This keeps you out of the business of validating model output as truth.
Tool-driven console. If you register the Nova tool, use it as an internal scratchpad for ops/support staff — summarizing a record, rewriting a bio, drafting an email. Tools are good for one-off, non-persisted work; fields are good for work that lands in the database.
Responses API vs. chat completions. The 0.17.7 addition matters if you need multi-turn context, built-in tool use, or the newer model families that expect /v1/responses. Pattern: keep chat completions as the default in config for existing fields (cheap, stable, well-understood message arrays), and opt into the responses endpoint per field/tool where you specifically want conversation state or structured output. Don't flip the global default without re-testing every field — response shapes differ.
Prompt context from the record. Pass the current model's existing attributes into the prompt (title, category, tone) so generated copy is grounded. This is where the package earns its keep over a raw HTTP call: the field sits inside Nova's form lifecycle, so it already has the record in scope.
Long-running generations. For anything beyond short drafts, prefer a pattern where the field triggers generation, the result is stored, and the user is not blocked on a 30-second HTTP round trip. In Nova that usually means lowering expectations on the field (short outputs) or moving bulk generation into a queued job that writes to the attribute and notifies on completion.
Cost and abuse control. Wrap fields behind Nova policies/permissions so only trusted roles can trigger generation, and set per-model config so production uses a cheap model by default. Log token usage from the package's response object if it exposes it; otherwise log at the HTTP client layer.
Local/testing. Never let feature tests hit OpenAI. Bind a fake HTTP client (Http::fake()) or stub the package's service in the container, and assert on the request payload (model, endpoint, prompt) rather than on generated prose.
composer.json if you are mid-migration..env, run php artisan config:clear (and optimize:clear in deployed environments). A stale cached key produces confusing 401s that look like code bugs.null in a field is the usual symptom.How can I help you explore Laravel packages today?