Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Ollama Laravel Package

halilcosdu/laravel-ollama

A Laravel package for Ollama that provides a fluent, expressive API to interact with local LLMs. Run chat and completion requests, generate embeddings, stream responses, manage models, and keep AI workloads private in your Laravel app with simple configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

This package wraps a local or remote Ollama instance in Laravel's HTTP client and config, and v1.2.0 is the first release that makes streaming a first-class citizen. It is not a breaking release — if you were using the non-streaming ask()/chat() methods, nothing changes.

Minimum path to first token:

  1. composer require the package, then php artisan vendor:publish to get the config file.
  2. Set OLLAMA_BASE_URL (default http://localhost:11434) and OLLAMA_MODEL in .env. Make sure the daemon is running (ollama serve) and the model is actually pulled (ollama pull llama3.2) — a missing model is the most common "connection works but requests fail" cause.
  3. Read the rewritten README first: it now has a working end-to-end example, which is more useful than the config file for orientation. Then skim CHANGELOG.md for the streaming and format() signatures.

First use case I'd give a new developer:

// app/Console/Commands/AskOllama.php
foreach (Ollama::streamAsk('Summarise the Laravel release notes in one sentence.') as $chunk) {
    $this->output->write($chunk);   // or ->write($chunk->content) depending on chunk shape
}

Run it from the CLI before touching HTTP. Streaming through a browser involves response buffering (see Gotchas), and debugging buffering and Ollama connectivity at the same time is miserable.

Platform note: v1.2.0 explicitly supports Laravel 11, 12 and 13, with CI on PHP 8.5. That means the upgrade is safe across a wide matrix, but it also means the maintainer is tracking unreleased Laravel versions — pin your laravel/framework constraint normally and don't infer from this that you need PHP 8.5.

Implementation Patterns

Wrap the client, don't scatter calls. Put Ollama calls behind a small service or action class and inject it. Config-driven model names (config('ollama.model')) let you swap models per environment without touching call sites, and make tests trivial.

Non-streaming for anything that feeds a template. If you render the result into a Blade view or persist it, use ask()/chat(). Streaming buys you perceived latency in a UI and nothing else; it complicates error handling, retries and testing.

Streaming to the browser. The reliable shape is a StreamedResponse that loops over the lazy iterable and flushes:

return response()->stream(function () use ($prompt) {
    foreach (Ollama::streamAsk($prompt) as $chunk) {
        echo $chunk;           // NDJSON/plain delta depending on chunk type
        ob_flush();
        flush();
    }
}, 200, [
    'Content-Type'      => 'text/plain; charset=utf-8',
    'X-Accel-Buffering' => 'no',
    'Cache-Control'     => 'no-cache',
]);

For a chat UI, an SSE endpoint or a Livewire component that appends deltas both work; SSE is closer to the wire format and avoids Livewire's round-trip per token.

Multi-turn chat. Keep the messages array yourself and pass it to streamChat() on each turn. The package does not manage conversation state — this is deliberate and it means you own persistence (session, cache, or a conversations table with a JSON column).

Structured output — the highest-leverage new feature. format() accepts a JSON Schema array, which pairs naturally with DTOs and validation:

$schema = [
    'type' => 'object',
    'properties' => [
        'title'    => ['type' => 'string'],
        'priority' => ['type' => 'string', 'enum' => ['low', 'medium', 'high']],
    ],
    'required' => ['title', 'priority'],
];

$raw = Ollama::format($schema)->ask($ticketBody);
$data = json_decode($raw, true);   // validate before trusting

Use this for extraction, classification and routing tasks where you'd otherwise be writing regex over prose. Still validate — schema adherence is much better than free-form prompting but is not a guarantee.

Queue anything slow. Generations routinely exceed a web request budget. Dispatch a job, stream into a cache/DB column or broadcast deltas over a private channel, and keep the HTTP layer responsive.

Testing. Http::fake() with a fixture body of NDJSON lines covers stream parsing without a running Ollama. The release notes confirm a Pest 3/4-compatible matrix, so whatever Pest version you're on, the docs' test examples apply. Treat the two live integration tests as skipped-by-default smoke tests and run them manually against a real daemon before upgrading.

Gotchas and Tips

NDJSON chunking. Each line is an independent JSON object and can arrive split across reads. The package handles reassembly, but if you write your own consumer over the raw response you will eventually get a half-object. Use the provided iterables rather than iterating the HTTP body.

Stream exceptions arrive late. v1.2.0 adds explicit exceptions for server errors and malformed chunks — good, but if the failure happens after the first byte, your HTTP status is already 200 and headers are sent. Design the UI to detect an error sentinel or a truncated final chunk, and log server-side with the prompt and model attached. Don't assume try/catch around the controller action will produce a clean error page.

Buffering will make streaming look broken. Nginx proxy buffering, PHP output buffering, gzip compression and some reverse proxies all coalesce the stream into one blob at the end. If tokens "arrive all at once", it's almost never the package. Check php.ini output_buffering, add X-Accel-Buffering: no, and disable gzip on that route.

format() wants a schema array, not a class or a string. Other SDKs take a PHP class or a 'json' flag. Passing the wrong shape tends to produce a schema the model politely ignores rather than a hard error — you get prose back and your json_decode returns null silently.

Timeouts and long generations. The default HTTP timeout will cut off long streams. Set a per-request or per-config timeout generously, and remember the queue worker's --timeout is a separate limit that will kill the job mid-stream.

Chunk shape varies. streamAsk() and streamChat() deltas are not necessarily plain strings — check whether you need $chunk directly or $chunk->content. Read the return type rather than assuming; it's the most likely source of "blank output" bug reports after upgrading.

Config quirks worth knowing. Model, temperature and other options are usually passed through a options array; unknown keys are forwarded to Ollama rather than rejected, so typos fail quietly. Test one parameter change end-to-end when you first configure it.

Extension points. If the config doesn't expose what you need, bind your own instance of the underlying client in a service provider rather than forking — the facade resolves from the container. Custom HTTP client options (retries, proxy, middleware for logging token counts) go in the same place.

Version pinning. Laravel 13 support means the package may resolve against a framework version you aren't running locally. Lock your composer.json, and run the full suite plus one live smoke test after any minor bump — the release notes are honest about the two skipped integration tests, which is exactly the coverage you don't get in CI.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle