This release resolves community issues #9–#13 with a focus on data integrity, ingestion consistency, and streaming extensibility.
IngestionService::ingestFromDisk($disk, $path, $scope) for re-ingesting already-stored files.ChatStreamResponse::withOnComplete(callable) for post-stream persistence/hooks.ProcessTextAssetJob, FetchUrlAssetJob).docs/redundancy-audit-v0.2.4.md with non-blocking follow-up cleanup items.source_meta.chunk_id with ID fallback.AssetIndexed, AssetFailed) now defer at transaction commit boundaries across web/CLI/worker contexts.ingestText() and ingestUrl() now follow async pipeline behavior consistent with ingestFile().0.2.4.ChatCompleted and EmbeddingsCompleted now carry provider-reported token counts
instead of hardcoded zeros, so billing and cost analytics work without a second API call. (#6)LARAI_HEALTH_MIDDLEWARE (pipe-separated) lets monitoring systems hit the
health endpoint without pulling in the full auth guard. (#7)AssetIndexed / AssetFailed fire after the outer DB transaction commits, eliminating the
race that forced callers to match assets by source_name. (#5)ChatCompleted.inputTokens / outputTokens are populated from the SDK's AgentResponse::$usage (non-streaming) and
StreamableAgentResponse::$usage (streaming, read after the stream drains via StreamEnd::combineUsage()). Works for OpenAI,
Anthropic, and Gemini since all three route through the same Usage object.durationMs is now populated on the streaming path too (was hardcoded 0).OpenAiEmbedding::embedManyWithUsage(): EmbeddingResult — new optional method returning vectors + provider-reported token
count. EmbedChunksJob detects it via method_exists() and emits real tokenCount on EmbeddingsCompleted.usage->promptTokens / completionTokens — third-party providers, test doubles, and future
SDK shape changes don't break the pipeline.LARAI_HEALTH_MIDDLEWARE env var accepts a pipe-separated middleware list, e.g. auth|throttle:60,1. Pipe is used
instead of comma because Laravel's rate-limit syntax throttle:60,1 ("60 requests per minute") contains a comma — a
comma-separated parser would silently break it.auth to preserve existing behavior. Set empty for public access behind an ingress allowlist.docs/configuration.md under "Health Endpoint".AssetIndexed and AssetFailed events fired after Ingestion::markState() reaches a terminal state.dispatch()->afterResponse() in web requests, so listeners run after the caller's outer transaction commits
and ai_asset_id is stored on your domain rows.IngestionStateChanged behavior unchanged — prefer the terminal events when you only care about "did it work."phpunit/phpunit ^11.0 and orchestra/testbench ^9.0|^10.0 as dev deps.phpunit.xml.dist, tests/TestCase.php.EmbeddingResult, ChatStreamResponse, and ChatService event dispatch.composer test.OpenAiEmbedding::embedMany() was not actually batching. Despite the name, the implementation looped
$this->embed($text) once per chunk — one HTTP request per input. It now delegates to embedManyWithUsage() which uses
Embeddings::for($texts)->generate() with a batch size of 96. For a 200-chunk document this drops embedding API calls from 200
to 3.Fully backward compatible:
EmbeddingProvider contract unchanged — third-party implementations continue to work (they just report tokenCount: 0 on
EmbeddingsCompleted).ChatCompleted / EmbeddingsCompleted event shape unchanged — only the values inside change from 0 to real numbers.LARAI_HEALTH_MIDDLEWARE unset → defaults to ['auth'] (same as v0.2.2).composer require laraigent/larai-kit:^0.2.3
Critical fix for two regressions introduced in v0.2.1. Upgrade immediately if you're on v0.2.1.
DoctorCommand::warn() was declared private but overrides a public parent method. PHP
refused to load the class, crashing the app on boot. Renamed to printWarn() matching the existing printFail()
pattern.ChatStreamResponse serialized non-text stream events (StreamEnd,
etc.) as JSON and yielded them as text deltas. Now uses duck typing on the delta property; metadata events are
silently skipped.composer update laraigent/larai-kit
Bug fixes for issues reported by the community (#2).
ingestFile(), ingestText(), and ingestUrl() now return the asset
with a fresh ingestion relationship pre-loaded. No more $asset->fresh() needed.scope column — users upgrading from v0.1.x no longer get "table has no column
named scope". Safe for both fresh installs and upgrades.larai:doctor now shows [WARN] Pdf parser and [WARN] Docx parser when
optional packages aren't installed, instead of letting users discover this via runtime crash.composer update laraigent/larai-kit
php artisan migrate
Five new features, all opt-in with zero breaking changes.
Conversation model (UUID primary key, scope-aware) + Message modelConversationManager — create, list, delete conversations, append messagesChatService::sendMessage() accepts optional conversationId — loads history from DB, persists both user +
assistant turnsconversationId is null, behavior is identical to v0.1.x (fully backward compatible)ai_conversations, ai_messagesIngestionService::ingestUrl(string $url, array $scope = []) — fetch, parse, chunk, embedUrlFetcher with SSRF protection — blocks private IPs (10.x, 192.168.x, 127.x), file:// scheme, DNS rebindingHtmlParser — DOMDocument-based content extraction, strips nav/footer/script/style, extracts article/main/bodyLARAI_URL_TIMEOUT, LARAI_URL_MAX_SIZE_MB, LARAI_URL_USER_AGENTChatService::streamMessage() — returns ChatStreamResponseIteratorAggregate (foreach in PHP) + Responsable (return from controller = auto-SSE)sendMessage() is unchangedChatCompleted and EmbeddingsCompleted events dispatched automaticallyUsage model + ai_usage table for opt-in persistenceLARAI_TRACK_USAGE=true — disabled by default, events always fire regardlessRecordUsage listener writes to DB only when enabledHealthCheck service — extracted from DoctorCommand, returns structured JSONHealthController at configurable path (default _larai/health), supports ?deep=trueDoctorCommand refactored to delegate to HealthCheck — same CLI outputLARAI_HEALTH_ENABLED=true — disabled by default3 migrations, 3 models (Conversation, Message, Usage), 2 events, 1 listener, ConversationManager, UrlFetcher, HtmlParser, ChatStreamResponse, HealthCheck, HealthController
composer update laraigent/larai-kit php artisan migrate
Fixes all issues from #1. See CHANGELOG.md for full details.
composer update laraigent/larai-kit php artisan migrate # adds scope column to ai_assets
First public release. See CHANGELOG.md for details.
How can I help you explore Laravel packages today?