astrophp/trail
Trail is a Laravel package that adds a simple audit trail to your Eloquent models. It automatically logs create, update, and delete events, capturing who made each change and when. Use it to improve debugging, accountability, and compliance with minimal setup.
Architecture fit. This remains a Laravel-native observability layer for AI SDK activity: it consumes the SDK's events and writes spans, runs, token totals and prices into Trail's own tables, with the runs list, CSV export and Boost trace listing as the read surfaces. v0.4.0 broadens coverage from chat/embedding-style calls to the multimodal set (image generation, text-to-speech, transcription) using three new span types — image, audio, transcription. The modelling is consistent with what already exists: a standalone call becomes its own root trace, a call made inside a tool becomes a child span, which means existing trace-tree rendering and run-detail views should work unchanged in shape.
Integration feasibility. No migrations and no new configuration, so adoption cost is close to zero from an infrastructure standpoint. The two real prerequisites are (a) SDK 1.2.2 or later, which supplies the ImageFailed / AudioFailed / TranscriptionFailed events, and (b) a deliberate deploy ordering — every process that reads Trail's tables must be on v0.4.0 before anything records the new span types, because an earlier version cannot read them. That is a compatibility constraint on the read path, not the write path, and it is the single highest-risk item in this release.
Technical risk.
Key questions. Which image/audio/transcription models and providers are in scope, and do any of them report zero tokens (i.e. will they be permanently Not captured)? Who owns the price table, and what is the SLA for making a new model priced rather than Unpriced? Are there any readers of Trail's tables outside the Laravel app — BI extracts, notebooks, saved CSV pipelines — and are they enumerated? Does our retention/PII policy cover captured transcription text? Do downstream consumers of the CSV export or Boost listing hard-code the previous set of root operations?
Stack fit. Assumes a Laravel application already using the AI SDK and Trail, with Trail's tables in the app's database and the runs UI / CSV export / Boost listing as the consumption surfaces. The package continues to need nothing beyond the app's DB connection and queue/event plumbing; there is no new external dependency, broker or storage bucket introduced by multimodal spans.
Migration path. Effectively a composer bump plus an SDK floor: require the AI SDK at ^1.2.2 (or higher) and Trail at v0.4.0, then add price rows for the image/audio/transcription models you actually use. Nothing to migrate — but "no migrations" does not mean "no coordination," because the read-path version floor is a hard gate.
Compatibility. Two axes. Forward: v0.4.0 writes span types that pre-0.4.0 readers cannot interpret — this is a one-way data change and cannot be undone by rolling back the writer, since rows already written remain unreadable to the old code. Backward: on SDK < 1.2.2 everything still runs; you simply lose Failed classification for the three new modalities. Pin the SDK floor explicitly rather than relying on transitive resolution.
Sequencing.
Maintenance. Low and steady-state: no schema or config surface to own. The recurring work is a price-table chore — every new multimodal model is Unpriced until someone adds rates, which converts a code release into an ongoing finance/observability data-maintenance task. Assign that owner now rather than discovering it when a cost report is questioned.
Support. Expect two classes of ticket. First, "why is this run's cost zero / missing" — answers are Unpriced (no price row) or Not captured (provider reported no tokens), both of which are configuration facts, not bugs, and both worth a short runbook entry. Second, "the runs page broke after deploy" — almost always a lagging reader mid-rollout; the fix is the deploy order, not the package.
Scaling. Span volume grows with multimodal usage: image and TTS calls are frequently higher-frequency and shorter than chat calls, and each produces its own trace or span. Storage growth stays bounded because bytes are never persisted — that is the important design property here. The variable is captured text: with payload capture enabled, transcription text can be large and sensitive, so retention windows and capture scope should be decided before, not after, enabling the modality.
Failure modes.
Ramp-up. Small for engineers (a version bump and an event already emitted by the SDK). Material for the TPM: the pre-work is inventory and coordination, not coding. Budget roughly a sprint of cross-team sequencing — enumerate readers, align the deploy order, agree the price-table owner and the text-retention policy — and treat the actual upgrade as a same-day change once those are settled.
How can I help you explore Laravel packages today?