Prepare shared storage
Follow installation, configure Exa, and choose a durable supported store. Your application owns workers, authorization, retention, and domain records.
| Before dispatch | Requirement |
|---|---|
| Store | Shared durable storage, not memory or ArrayStore |
| Worker | Process the configured queue; default research |
| Other runtimes | MCP or JavaScript can resume stored deep research, not Laravel jobs |
Preview before dispatch
use Jkudish\LaravelAiLibrarium\Facades\Librarium;
$question = 'Compare PostgreSQL pooling for workers';
$plan = Librarium::research($question)
->deep()->only(['exa'])->maxCost('0.50')
->dryRun();
Dry-run is offline and stores nothing; inspect estimates, selected sources, skips, and notices. Keep your cap when reviewing an empty preview (budget rules).
Queue the research
$queued = Librarium::research($question)
->deep()->only(['exa'])->maxCost('0.50')
->queue()->onQueue('research');
$id = $queued->id();
// In a later authorized request:
$run = Librarium::find($id)?->refresh();
$payload = $run?->toArray();
Authorize the Run ID before reading it; refresh() observes existing work, not a new submission. Persist only needed domain facts and keep status, failures, citations, and uncertainty visible; package storage is not your evidence model.
Recover without duplicate spend
The encrypted job has one attempt; worker loss can leave paid upstream work running. Inspect the stored Run and use refresh() before considering another submission (recovery reference).
| Failure | Recovery boundary |
|---|---|
| Calling process stops | Inline work depends on that process staying alive |
| Saved state or signing key lost | Recovery needs valid state and stable private keys |
| Local writer crashes | Remove its marker only after proving it cannot resume; age is not enough |
Test without provider calls
config()->set('librarium.sources.exa.key', 'testing-only');
$fake = Librarium::fake()->preventStrayQueries();
Librarium::research('Produce a report')
->deep()->only(['exa'])->queue();
$fake->assertQueued('Produce a report');
$fake->assertNeverQueried();
Queued fakes record requests without dispatching jobs; assertion closures receive request arrays. Use Laravel’s queue fake and disposable stores for infrastructure tests (testing reference).