Looking to hire Laravel developers? Try LaraJobs

laravel-pandora maintained by michal78

Description
Pandora — a Laravel-native agentic framework: agents, tools, approvals, automations, memory and a Livewire control center.
Last update
2026/08/12 16:45 (dev-master)
License
Links
Downloads
0

Comments
comments powered by Disqus

⚠ v0.1.0 — first published release, and deliberately 0.x

What works today: define an agent, start a conversation, dispatch a queued run, stream it over Reverb, persist an immutable trace, reload without losing anything, cancel it, and inspect it in the control center — with tools under five layers of authorization and human approval gates on the risky ones, multi-provider routing with failover and budgets, automations on four engines, scoped memory and context that works with no vector database installed, delegation and MCP where nothing remote is approved by discovering it, workspaces on local or S3-compatible storage, and messaging channels where an unlinked identity gets no run, no session and no seat.

What does not exist yet: release hardening — the full threat-model sweep, performance tests and the example application (Phase 9, at 3 of 34 criteria). See docs/roadmap.md.

Verified by 1,756 tests across SQLite, MySQL 8.4, MariaDB 11, PostgreSQL 17, pgvector and MinIO · PHPStan level 8, no baseline · Pint.

Before depending on this, read docs/product/support-statement.md — it names what is supported, what is excluded by design, and what ships known untested. The API is usable and in use; it is not yet promised. 1.0.0 is defined as the day Phase 9's criteria are met, not a date.


Why

Two kinds of thing exist today, and neither fits a Laravel application.

Personal agent daemons (OpenClaw, Hermes Agent) are excellent — for one operator, on one machine. OpenClaw's own security documentation is explicit that it "is not a hostile multi-tenant security boundary." You cannot put one in front of your customers.

LLM SDKs give you ->chat() and leave durability, approvals, tenancy, auditing, cost control and resumability as an exercise for the reader.

Pandora takes the capabilities of the first and gives them the trust, tenancy and authorization model of the framework you already run on. An agent run is a durable, queued, resumable, authorized, audited unit of work — closer to a job with a state machine than to a chat request.

The idea in one screen

Expose an application action. It is an ordinary PHP class, with ordinary Laravel authorization:

final class IssueRefund extends Tool
{
    public function name(): string
    {
        return 'issue_refund';
    }

    public function description(): string
    {
        return 'Issue a refund for an existing order.';
    }

    public function rules(): array
    {
        // The JSON schema shown to the model is generated from these, so the
        // interface it is told about and the one enforced cannot drift.
        return [
            'order_id' => 'required|string|exists:orders,id',
            'amount_minor' => 'required|integer|min:1|max:100000',
        ];
    }

    public function risk(): RiskLevel
    {
        return RiskLevel::High;     // → requires human approval by default
    }

    public function authorize(ToolInput $input, ToolContext $context): bool
    {
        // The *acting user's* policy. An agent can never exceed the person it acts for.
        return Gate::forUser($context->user())
            ->allows('refund', Order::find($input->string('order_id')));
    }

    public function handle(ToolInput $input, ToolContext $context): ToolResult
    {
        $this->refunds->issue($input->string('order_id'), $input->integer('amount_minor'));

        return ToolResult::success('Refund issued.');
    }
}

Register it, then grant it — registering installs a tool; each agent must still be given it:

// config/pandora.php
'tools' => ['registered' => [App\Tools\IssueRefund::class]],

Give it to an agent, and run it:

$run = Pandora::agent('support')
    ->forUser($user)
    ->withContext(['order_id' => $order->getKey()])
    ->stream()
    ->dispatch('Help this customer resolve their order problem.');

The request returns immediately. A queue worker performs the run. The browser streams it over Reverb. The refund pauses for a human approval — costing nothing while it waits, surviving a deploy — then resumes. Every step is in the trace. Every decision is in the audit log.

What makes it different

Multi-tenant and multi-user from the first migration Not a single-operator daemon. Tenant and session isolation are tested, not assumed.
Authorized against the actor, not the agent A tool call is checked against the acting user's Laravel gates and policies. An agent cannot do what the user could not.
Runs pause for free An approval pause holds no worker and no memory. It can wait three days across two deploys.
Resumable by construction All continuation state is in the database. A worker crash loses at most one iteration.
Memory needs no vector database Lexical retrieval is the shipped path across all four databases. A vector store is an accelerator, never an authority.
Reverb is optional The database is authoritative; broadcasts are notifications. Turn realtime off and polling is still correct.
Redis and Horizon are optional The core runtime needs a plain Laravel queue and nothing else.
Nothing is forced Headless mode installs no routes, no views, no Livewire.

Requirements

PHP 8.3 · 8.4
Laravel 13.x
Database SQLite · MySQL 8.4 · MariaDB 11 · PostgreSQL 17 — all in CI
Queue any Laravel queue backend
Optional Livewire 4 (control center) · Reverb (streaming) · Redis/Horizon · pgvector

Installation

composer require michal78/laravel-pandora
php artisan pandora:install
php artisan queue:work

That is the headless install — agents, tools and runs from your own code, with no routes and no frontend. The control center at /pandora is Livewire, which Pandora suggests rather than requires, so add it if you want the UI:

composer require livewire/livewire

Without it, no /pandora route is registered at all — the page 404s rather than erroring, and php artisan pandora:status tells you which of the two you have.

Want the unstable branch instead? development is where everything lands before it is released, and Composer will take it without changing your minimum-stability — requiring a dev- version sets the stability flag for that package on its own:

composer require michal78/laravel-pandora:dev-development

The installer is idempotent, publishes config and migrations, explains Reverb / queue / scheduler setup, and deliberately creates no default agent.

Then define an agent and run it:

final class SupportAgent implements AgentDefinition
{
    public function define(AgentBlueprint $agent): AgentBlueprint
    {
        return $agent
            ->name('Support')
            ->instructions('Help customers resolve support issues.')
            ->model('openai', 'gpt-4o-mini');
    }
}
php artisan pandora:agent:run support "Where is order 1234?" --trace

Control center

A Livewire control center ships with the package and looks finished the moment it is installed — its own logo, palette and design tokens, light and dark themes resolved before the first paint, and every colour meeting WCAG AA on the surface it sits on. Retheme it by overriding one layer of custom properties; replace the mark by editing one Blade component.

See docs/visual-identity.md and docs/brand-guide.md.

// config/pandora.php
'ui' => ['brand' => 'Acme Agents', 'theme' => 'dark'],

Documentation

Guidesinstallation · quick start · agents · tools · providers · automations · memory · workspaces · MCP · channels · writing extensions

Architectureoverview · security model · execution model · provider model · database model · realtime model

Productvision · feature parity · terminology

DecisionsADRs — each with the alternatives and why they lost

Deliveryroadmap · changelog · acceptance plans · progress log · open questions

Security

Pandora executes model-directed actions inside your application. Read docs/architecture/security-model.md before deploying it.

We do not claim to solve prompt injection. We build layered controls that bound what an injected instruction can reach: least authority, approval gates, tool allowlists, argument validation, egress control, budgets and audit. See SECURITY.md for the full statement of limitations — including where policy restriction is not sandboxing.

Contributing

See CONTRIBUTING.md. Read the ADRs first — most design questions are already answered there, including the ones where we chose the harder option on purpose.

Acknowledgements

OpenClaw and Hermes Agent shaped what users now expect from a self-hosted agent platform, and studying them publicly informed our parity matrix. Pandora shares no code, assets, wording or implementation details with either project — every capability here is an independent Laravel-native reimplementation.

License

MIT. See LICENSE.md.