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 Pandora Laravel Package

michal78/laravel-pandora

An agentic framework for Laravel: build agents, tools, approvals, automations and memory under explicit, auditable policy, with a Livewire control center for operating them.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and publish its config and migrations, then run php artisan migrate. The migrations matter more than usual here: runs, run state, run locks, provider health, and sessions all persist state that the security controls depend on.

Look first at:

  1. config/*.php budgets — token, cost, step, and wall-clock limits. All four are enforced by assertWithinBudget() in a fixed order, and the first breach throws. Set every limit deliberately; a generous default on one limit can mask a bug in another.
  2. routes/web.php and src/UI/Livewire/ — authorization is intentionally enforced inside each Livewire component, not only by route middleware. The architectural test asserts every class in src/UI/Livewire/ authorizes somewhere, so any new control-center page must include its own gate.
  3. Agent::deniedTools() and AbilityIntersection — delegation is granted, minus denied. If you use delegated agents, confirm the parent’s deny list is part of the intersection, not just the parent’s missing abilities.

A good first use case is a single agent with one custom tool:

$agent = Agent::make('summarizer')
    ->grant(['docs.read'])
    ->deny(['docs.delete'])
    ->tools([SummarizeTool::class]);

$run = $agent->run('Summarize the attached document.');

Run it through the control center once, then through the programmatic API. The control-center path exercises the Livewire authorization gates, run locking, and budget checks that a unit test may bypass.

Implementation Patterns

Tool execution and wall-clock budgets. A tool’s handle() method is the only place a test or application can act between two iterations of an inline run. If you need to exercise a wall-clock limit, use a SlowTool-style fixture that advances the clock from inside handle(). In production, long-running tools are the realistic way to reach Run::hasExceededDeadline().

Delegation. Resolve child tools through AbilityIntersection::abilitiesOfAgent() rather than constructing the child’s tool list yourself. The parent’s explicit denies must flow into the child’s frozen list. Test the deny path explicitly:

$parent = Agent::make('parent')->grant(['reports.read'])->deny(['reports.export']);
$child  = $parent->delegate('child');
// The child must not receive reports.export, even if it is otherwise granted.

A useful assertion is not only “the child lacks the tool” but “calling the tool returns denied rather than succeeded.” The release notes describe a case where the child executes successfully under ablation because the gatekeeper checks the child’s policy and frozen list, neither of which mentions the parent’s deny list.

Session isolation. Session::isolationKeyFor() folds seven components into one hash. Treat actor_type as load-bearing. ActorContext::system() accepts an arbitrary label as its id, so an automation labelled with a user’s primary key will share that user’s id and differ only in type. If your automation labels can collide with user IDs, ensure the type remains part of the key. When resolving sessions, remember that SessionResolver folds the conversation into the origin so two conversations with the same agent and actor do not share a boundary.

Workspace writes. Prefer WorkspaceFiles::write() over direct filesystem access. It performs quota accounting via storage->size() and containment via LocalStorage::locate(). If you drive LocalStorage directly, call locate(mustExist: false) for write targets that already exist: a contained parent says nothing about whether the leaf is a symlink. The re-check protects against a symlinked leaf; the parent check protects against a symlinked directory. Test both shapes.

Concurrency. Use the database-backed RunLock lease as the authority for run ownership. For tests, use tests/Support/RunsConcurrently.php rather than pest --parallel; the harness starts real OS processes against one database and releases them from a barrier. The barrier is essential because application boot dwarfs the contended section. Without it, processes run serially and a concurrency control can be deleted while the test stays green.

Provider health writes. Record provider outcomes through ProviderHealthMonitor, but keep health writes off the critical path of a provider call where possible. In v0.1.4, rowFor() was changed to avoid a firstOrNew() + save() race on the uniquely indexed provider_key. If you are on an older version, wrap health recording so a duplicate-key exception cannot escape into the run.

Control-center pages. Every Livewire page should authorize explicitly. Index pages and detail pages have different exposure: a detail page can reveal a prompt, a webhook secret, or a full execution trace. Add a denial test for each new page, and rely on the architectural test to catch a page that never authorizes.

Gotchas and Tips

  • RunState::TimedOut does not mean “ran out of time.” It is where every budget breach lands. If you assert only that a BudgetExceeded was thrown, the test passes even when the limit you intended to test has been deleted. Assert the message of the limit under test and set every other limit generously.
  • RunLock serial tests are not enough. The database lease was documented as “the authority” but could be deleted with all 22 serial lock tests green, including one named “grants ownership to one worker and refuses a second.” Only the concurrent harness exposed five processes acquiring the same run.
  • A quota lookup can mask a containment bug. WorkspaceFiles::write() calls storage->size() for quota accounting first, and size() resolves with mustExist: true, so an escaping symlink may be refused by the byte-count lookup before the containment re-check is reached. Test LocalStorage directly to exercise the second layer.
  • The actor-type collision is reachable. An automation labelled with a user’s primary key shares that user’s id and differs only in type. Dropping actor_type from the isolation key merged those sessions while 1,820 tests stayed green.
  • Session resolver composition is easy to miss. The unit test passes origin ready-made and never exercises how SessionResolver folds the conversation into it. Assert the composed origin directly if conversation boundaries matter to you.
  • New Livewire pages can be added ungated. The architectural test only helps if you run it and keep it in the suite. If you add a nineteenth page, implement authorization before the test tells you.
  • Concurrency tests without a barrier are false confidence. Starting N processes is not enough; they must rendezvous after boot. Verify the harness’s own overlap with Queue/ConcurrentHarnessTest before trusting any test built on it.
  • A slow tool is the only hook between inline run iterations. Use a dedicated SlowTool fixture for wall-clock tests rather than sleeping in the test process.
  • Upgrade to v0.1.4 or later for the provider-health race fix. The old firstOrNew() + save() path could fail a run when two workers recorded the first outcome for the same provider at the same instant.
  • Extension points to keep stable: custom tool classes implementing the expected handle() contract, custom actor contexts (especially ActorContext::system() labels), and custom storage implementations that honor LocalStorage::locate(mustExist: false) semantics.
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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator