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 Ai Chatbox Laravel Package

developer-unijaya/laravel-ai-chatbox

View on GitHub
Deep Wiki
Context7
0.4.0

Added

  • Chunks viewer page (GET /ai-chatbox/rag/{id}/chunks) — new admin page showing every chunk stored for a document: chunk index, character count, content in a scrollable monospace box, and a Vector (green) or Keyword (gray) badge indicating whether the chunk has a stored embedding vector
  • Per-document test chat (POST /ai-chatbox/rag/{id}/chat) — chat panel on the chunks viewer page for testing AI responses against a single document's chunks; uses vector retrieval (cosine similarity) when embeddings exist, falls back to keyword search otherwise; AI replies are rendered as Markdown via marked.js; the chat panel and input are automatically disabled with a warning when the active provider's api_url or api_token is not configured
  • Separated Chunking / Embedding status columns in the Knowledge Base table — the single "Status" + "Chunks" columns are replaced by two dedicated columns:
    • Chunking — spinner while processing; green "N chunks" when text is stored; red "Failed" when chunking itself errored
    • Embedding — green "N vectors" (all chunks embedded); amber "N / M" (partial); gray "Keyword-only" (no embedding URL configured); red "0 / N" (embedding URL set but all calls failed); spinner while processing; populated from a live vector_count subquery — no migration required
  • DocumentChunkerTest — 16 new unit tests covering all DocumentChunker::chunk() paths: empty/whitespace input, UTF-8 BOM stripping, CRLF normalisation, single-chunk output, paragraph-boundary splitting, multi-blank-line boundaries, overlap carry-over, zero-overlap isolation, long-paragraph sentence splitting, sentence-terminal punctuation (. / ! / ?), output trimming, no-empty-chunks guarantee, sequential zero-based indices, and default-parameter smoke test
  • RagChunksPageTest — 21 new feature tests covering GET /ai-chatbox/rag/{id}/chunks (200, title display, chunk content, Vector/Keyword badges, 404, chat-panel disabled when provider not configured) and POST /ai-chatbox/rag/{id}/chat (missing/oversized message, no-chunks 422, keyword retrieval, vector retrieval, below-threshold vector fallback to keyword, no-match reply, 502 on network failure and HTTP 500, chunks_used count)
  • Anthropic (Claude) engine — native support for the Anthropic Messages API alongside the OpenAI-compatible providers:
    • New AnthropicEngine (extends OpenAiCompatibleEngine) that targets the native Messages API (/v1/messages) with x-api-key and anthropic-version: 2023-06-01 headers — Anthropic is not OpenAI-compatible, so it needs a dedicated engine
    • System messages are hoisted into Anthropic's top-level system field; the remaining turns are sent as messages. complete() reads content[0].text; beginStream() parses SSE content_block_delta events and stops on message_stop
    • max_tokens defaults to 300 when unset (Anthropic requires the field and rejects null; the value matches the global max_tokens config default)
    • Automatic engine selection — AiManager::resolveEngine() returns AnthropicEngine when the resolved provider's api_url contains anthropic.com or the engine key is set to 'anthropic'; otherwise the bound AiEngineInterface (OpenAI-compatible) is used; no manual binding required
    • New default anthropic provider block in config/ai-chatbox.php — ANTH_URL (default https://api.anthropic.com/v1/messages), ANTH_API_KEY, ANTH_MODEL (default claude-sonnet-4-6), ANTH_VERSION (default 2023-06-01), ANTH_EMBEDDING_URL, ANTH_EMBEDDING_MODEL, ANTH_EMBEDDING_TOKEN
    • Explicit engine: 'anthropic' key in the anthropic provider block — both the engine key and the api_url containing anthropic.com trigger engine selection; either alone is sufficient
    • Configurable anthropic_version per-provider key (ANTH_VERSION, default 2023-06-01) — pin the anthropic-version request header without modifying source code; useful when Anthropic releases a new API version
  • rag_no_context_prompt config key — RAG grounding guard — a new system instruction injected when RAG is enabled but no chunk matches the user's query (nothing cleared rag_similarity_threshold, no indexed documents, or retrieval failed). The default refuses factual answers from general knowledge while still allowing greetings and small talk; set it to an empty string to restore the previous unconstrained behaviour
  • rag_keyword_fallback config key (AI_CHATBOX_RAG_KEYWORD_FALLBACK, default true) — when rag_embedding_url is absent or the embedding call returns null, RagRetriever falls back to a SQL LIKE keyword search across chunk content instead of returning an empty result set. Words shorter than 3 characters are ignored. Set to false to disable the fallback and inject rag_no_context_prompt when no embedding is available
  • RAG upload without an embedding URL — RagController::processDocument() now detects when no embedding URL is configured and stores text chunks with a null embedding vector, marking the document ready immediately; chunks are available for keyword retrieval straight away without any embedding service. The Knowledge Base UI shows an amber warning explaining keyword-only mode; the upload form, file input, title input, and reprocess button remain enabled
  • rag_embedding_token per-provider config key (ANTH_EMBEDDING_TOKEN for the anthropic provider) — allows specifying a separate API token for the embedding service when it is provided by a different vendor than the chat API. PromptBuilder and RagController both prefer rag_embedding_token over api_token when building the EmbeddingService; falls back to api_token when not set

Changed

  • "Chunks" button visible for any document with existing chunks — the view-chunks action in the Knowledge Base table now appears whenever chunk_count > 0 rather than only when status = 'ready'; documents whose embedding entirely failed but whose text is chunked can still be browsed and tested
  • Per-document test chat accepts documents with chunks regardless of status — RagController::chat() guard changed from status !== 'ready' to chunk_count === 0; a document with status = 'failed' but non-zero chunks (e.g. all embeddings failed) can still be queried via keyword retrieval
  • Consolidated message-table index migration — the standalone add_index_to_ai_chatbox_messages_table migration has been merged directly into create_ai_chatbox_messages_table; the composite (conversation_id, id) index is now defined at table creation time; migrate:fresh and new installs are unaffected; existing installations with both migrations already applied are also unaffected
  • Stricter default rag_context_prompt — reworded from "use this as your PRIMARY source / prioritize this context" to "answer using ONLY these excerpts; do not use general knowledge; reply 'I don't have that information in my knowledge base.' if the answer isn't present" (greetings/small talk still allowed). The old wording explicitly permitted the model to fall back on training data
  • ChatboxController resolves the engine per request via AiManager — the controller now injects AiManager instead of AiEngineInterface directly and calls $aiManager->resolveEngine($cfg) in sendMessage() and streamMessage(), so the correct engine (OpenAI-compatible or Anthropic) is chosen from the active provider's config on every request
  • OpenAiCompatibleEngine::assertConfig() changed from private to protected — so AnthropicEngine can reuse the same E01–E04 config validation
  • Admin conversations modal — animated open/close — the message-preview modal now fades and scales in/out via CSS transitions and an .is-open class instead of toggling display, replacing the previous instant show/hide
  • AiManager::resolveEngine() URL match broadened — now matches any URL containing anthropic.com (not just api.anthropic.com); custom Anthropic-compatible reverse proxies on any *.anthropic.com subdomain are automatically routed to AnthropicEngine; the explicit engine: 'anthropic' key is also checked first, so the URL is not even required
  • RAG Knowledge Base UI (/ai-chatbox/rag) — keyword-only mode — when rag_embedding_url is not set the page previously showed a red blocking error and disabled all uploads; it now shows an amber warning explaining that uploads still work and chunks will be retrieved by keyword matching; a red error is shown only when the URL is configured but the model name is missing (genuinely broken config)
  • Admin diagnostics (/ai-chatbox/admin) — checkRag() rewritten: an absent rag_embedding_url is now reported as an info notice ("keyword-only mode") instead of an error; rag_embedding_model missing is only flagged as an error when the URL is also present; the null_chunks warning downgrades to info when rag_keyword_fallback is enabled; rag_keyword_fallback added to the RAG config group display; engine, anthropic_version, and rag_embedding_token added to the AI API config group display

Fixed

  • Knowledge Base nav link stays highlighted on the chunks page — the admin nav active-state check changed from routeIs('ai-chatbox.rag.index') to routeIs('ai-chatbox.rag.*')
  • Bot answering outside the knowledge base when no chunk matched — when RAG retrieval returned no results, PromptBuilder previously injected nothing, leaving the model with only the generic "helpful assistant" system prompt and free to answer from its training data. It now injects rag_no_context_prompt in that case (and when retrieval throws), so the model stays grounded instead of going off-context. Covered by the new RagContextInjectionTest
  • Document upload with no embedding URL was marking documents as failed — RagController::processDocument() detected no embedding URL but still attempted to run the embedding pipeline, resulting in a failed status for every document; documents without an embedding URL are now marked ready immediately after chunking

Performance

  • Two-phase RAG retrieval in RagRetriever — the corpus scoring pass now loads only id + embedding columns (no chunk text); a second targeted whereIn query fetches content for the top-K IDs only, eliminating ~500 chars × chunk-count of data transfer on every chat request
  • trimToLimit guard in ChatboxController — both sendMessage() and streamMessage() check the in-memory history count before calling the DB trim method, eliminating two redundant DB queries (SELECT conversation + COUNT messages) on every message when history is within the configured limit
  • Pre-computed fixed token cost in ContextManager::trim() — system messages + current user message token count is calculated once before the trim loop instead of being re-computed on every iteration

0.3.0

Added

  • Admin conversations keyword search — the /ai-chatbox/admin/conversations/data endpoint now accepts a search query parameter; conversations are filtered server-side to those containing at least one message matching the term (SQL LIKE) so large conversation lists can be narrowed down without a page reload
  • Keyword highlighting in conversation search results — matching search terms are highlighted in the admin conversations list view
  • saveMessage() on ConversationRepositoryInterface — new interface method that persists a single message immediately (before the AI call starts); DatabaseConversationRepository creates the conversation record if it doesn't exist and appends the message directly; SessionConversationRepository is a no-op (session history is saved atomically by saveHistory())
  • Streaming configuration diagnostics — the admin diagnostic panel now checks several real-world streaming issues:
    • PHP output_buffering ini setting — warns when enabled, as it can silently buffer SSE tokens before they reach the browser
    • NginX server software — info notice to confirm proxy_buffering off / X-Accel-Buffering: no is set (the package sets the header automatically, but NginX config may override it)
    • Apache server software — warning about mod_deflate gzip compression buffering SSE streams
    • Reverse proxy headers (X-Forwarded-For, X-Forwarded-Host, X-Forwarded-Proto) — info notice to verify that the CDN or proxy forwards SSE without buffering
  • Extended admin diagnostic checks — additional config validations across multiple categories: temperature range, max_tokens floor, timeout, history/context-token-limit mismatch estimate, frontend driver validity, widget appearance settings (color_scheme, position, sound_volume, toggle_icon), admin middleware security posture, and RAG pipeline configuration completeness

Changed

  • Default max_tokens changed from null to 300 — gives small local models a sensible upper bound out of the box; set to null to restore the model's own default
  • Default temperature changed from 0.7 to 0.5 — more consistent and factual responses by default; increase for creative use cases
  • AdminController::index() refactored to modular style — the monolithic index() method has been split into 11 focused private check methods (checkPhpExtensions, checkActiveProvider, checkNamedProviders, checkSecurity, checkResponse, checkHistory, checkFrontendAndWidget, checkRag, checkMemoryDriver, checkAdminProtection, checkStreaming) plus dedicated data-builder helpers; index() is now ~30 lines; class constants hold shared placeholder arrays
  • Admin diagnostics UI changed to a 3-column grid — errors, warnings, and notices are now displayed side by side in a responsive grid-cols-1 md:grid-cols-3 layout; each column always renders and shows "No errors / No warnings / No notices" with a checkmark when empty, replacing the previous stacked conditional panels and separate all-clear banner
  • CORS wildcard * handling corrected — CorsMiddleware now sets Access-Control-Allow-Origin: * on both preflight and regular responses when allowed_origins contains '*'; previously it echoed the request Origin header instead, which is technically incorrect and may be rejected by strict CORS implementations

Fixed

  • max_tokens not forwarded to AI API during streaming — OpenAiCompatibleEngine::beginStream() was missing max_tokens from the JSON payload; the value is now read from the resolved config and included in the stream request (excluded when null via array_filter)
  • rag_chunk_size and rag_chunk_overlap ignored in per-provider config — RagController was reading these values directly from the global config() helper instead of from the resolved provider config array; switching providers or overriding chunk settings per-provider now takes effect correctly
  • User messages lost when AI call fails — in both sendMessage() and streamMessage(), the user's turn is now persisted to the repository immediately before the AI call begins; if the AI call fails the user message is already stored rather than being discarded
  • Streaming history not saved after stream errors — in streamMessage() the history persistence block was nested inside the stream-reading try/catch, causing it to be skipped when any stream error occurred; restructured so history is saved after the stream finishes (successfully or not) as long as $fullReply is non-empty
  • History persistence exceptions crashing responses — sendMessage() and streamMessage() now wrap all repository save calls in try/catch blocks; a persistence failure is logged but does not abort the HTTP response

0.2.9

Added

  • admin_middleware config key — new admin_middleware key (null by default) lets you set separate middleware for the admin dashboard (diagnostics, config viewer, conversations) independently of rag_admin_middleware which guards the Knowledge Base; when null, the dashboard inherits rag_admin_middleware so existing deployments are unaffected
  • Admin security diagnostics split — the diagnostics panel now emits separate warnings for the admin dashboard and the Knowledge Base (RAG) pages instead of a single combined warning, giving clearer guidance on which middleware to configure
  • Conversation::latestMessage() relation — new HasOne relation on the Conversation model using latestOfMany('id'); used in the admin conversations list to eager-load the last message and avoid N+1 queries
  • Paginated conversation messages — AdminController::conversationMessages() now returns messages in pages of 50 (with current_page, last_page, total, per_page metadata) instead of fetching all messages in one query
  • RAG token budget reservation in ContextManager — ContextManager::trim() accepts a new $ragBudget parameter; when RAG is enabled the controller estimates the token cost of the top-K chunks (rag_top_k × rag_chunk_size) and passes it as headroom so history is trimmed to leave room for injected RAG context
  • CORS preflight (OPTIONS) support — CorsMiddleware now short-circuits OPTIONS requests with a 204 response including Access-Control-Max-Age: 86400 before the request reaches any controller, fixing browsers that require a successful preflight before sending the actual request
  • thread_id validation on clear-history — ChatboxController::clearHistory() now validates that thread_id is a nullable string with a maximum length of 36 characters

Changed

  • DatabaseConversationRepository scopes reads and writes to the authenticated user — getHistory(), saveHistory(), trimToLimit(), and clear() all use a new private findConversation() helper that adds a user_id constraint when a user is authenticated; this prevents one authenticated user from reading or writing into another user's thread while preserving guest (unauthenticated) behaviour unchanged
  • SessionConversationRepository::key() hashes non-UUID thread IDs — previously any non-UUID thread_id fell back to the shared base session key; now every distinct non-empty thread_id gets its own slot via md5 truncated to 16 hex chars, preventing thread collisions for custom thread identifiers
  • ContextManager::estimateTokens() uses mb_strlen — token estimation now uses mb_strlen(..., 'UTF-8') instead of strlen so multi-byte characters (CJK, Arabic, emoji) are counted by character rather than by byte, producing more accurate token estimates
  • PruneConversations empty-conversation query scoped correctly — the fresh-empty query (doesntHave('messages')->where('updated_at', '>=', $cutoff)) now excludes conversations already covered by the stale pass, preventing double-counting and reporting the real deleted count from the Eloquent return value
  • AiChatboxServiceProvider::boot() uses AiManager::resolveConfig() — the debug-mode API token check now resolves via AiManager (matching all other provider resolution paths) and catches InvalidArgumentException when no providers are configured, instead of reading raw config keys directly
  • adminRouteConfiguration() reads admin_middleware first — the admin route group now uses admin_middleware ?? rag_admin_middleware so the new key takes effect without requiring changes to existing configs
  • AdminController conversations list eager-loads latestMessage — replaced the per-row messages()->orderByDesc('id')->first() sub-query with a with('latestMessage') eager load, eliminating N+1 queries on the conversations list endpoint
  • classifyConnectException() and classifyHttpStatus() changed to protected — these methods in OpenAiCompatibleEngine were public but are internal helpers; visibility narrowed to protected to clarify the intended API surface
  • Default theme_color updated — config default changed from #4f46e5 (indigo) to #0dad35 (green)
  • groq provider removed from default config — the sample groq provider block has been removed from src/Config/ai-chatbox.php; Groq can still be configured as a custom OpenAI-compatible provider using any provider name

Fixed

  • healthCheck returns 400 for unknown provider names — previously an InvalidArgumentException from AiManager::resolveConfig() would bubble up as a 500; the controller now catches it and returns a JSON 400 with a clear error message
  • Admin diagnostics no longer expose raw token values — the placeholder-token diagnostic message now redacts the actual token string from the error message

0.2.7

Added

  • Admin conversations modal — Markdown rendering — AI messages in the admin conversation preview modal now render as formatted Markdown (headings, bold, lists, code blocks, tables, blockquotes) using marked.js + DOMPurify loaded from CDN; user messages continue to display as plain escaped text
  • Admin conversations modal — copy conversation button — clipboard icon added to the modal header; clicking it copies the full conversation (user and AI turns) to the clipboard; falls back to document.execCommand('copy') on HTTP (non-secure) contexts where navigator.clipboard is unavailable; icon switches to a checkmark for 2 seconds to confirm success
  • Textarea auto-grow input — the message input field across all three frontend drivers (Vue, Blade, Livewire) is now a <textarea> that auto-expands up to 3 visible rows as the user types; text wraps naturally with no horizontal overflow; the field shrinks back to one row after the message is sent

Changed

  • Soft-clear — messages preserved on "Clear conversation" — clearing a conversation no longer deletes messages from the database; instead, a cleared_after_id cursor is recorded on the conversation row; messages before the cursor remain stored and visible to admins in the conversations modal, while the AI context starts fresh from the next message
  • ai-chatbox:prune-conversations now deletes empty conversations — the prune command runs a second pass using doesntHave('messages') to remove conversations that were created but never received any messages; both stale and empty counts are reported separately in --dry-run output
  • Textarea scrollbar styling — the textarea scrollbar is now 3 px wide on WebKit browsers and scrollbar-width: thin on Firefox, using the --chatbox-scrollbar CSS variable to match the messages-area scrollbar; pre-built chatbox.css updated accordingly

Fixed

  • Missing messages from database — ChatboxController::sendMessage() and streamMessage() were saving the context-trimmed history subset back to the database instead of the full history, causing older messages to be permanently lost on each turn; the controller now keeps $fullHistory (for persistence) separate from $contextHistory (passed to the AI prompt only)
  • ai-chatbox:prune-conversations compatibility — replaced self::SUCCESS / self::FAILURE class constants (introduced in Laravel 9 / Symfony Console 5.1) with integer literals 0 and 1 so the command works on Laravel 8 and earlier

Database

  • New migration 2024_01_01_000005_add_cleared_after_id_to_ai_chatbox_conversations_table — adds a nullable cleared_after_id (unsigned big integer) column to ai_chatbox_conversations; run php artisan migrate after updating

0.2.6

Added

  • color_scheme now applies to the chat widget — the color_scheme config key (AI_CHATBOX_COLOR_SCHEME) previously only controlled admin pages; it now also forces the chat widget into light or dark mode across all three frontend drivers (vue, blade, livewire); auto (default) continues to follow the OS/browser prefers-color-scheme preference with no change required

Changed

  • rag_embedding_timeout promoted to universal global config — previously a per-provider key that had to be duplicated across every named provider entry; it is now a single top-level rag_embedding_timeout key (AI_CHATBOX_EMBEDDING_TIMEOUT, default 10 seconds) shared by all providers; if you published the config and have rag_embedding_timeout inside a provider block, remove it — the top-level value takes effect automatically
  • EmbeddingService no longer reads config values directly — all parameters (URL, model, token, timeout) must be injected via the constructor; the service now correctly sources all embedding settings from AiManager::resolveConfig() rather than ever falling back to global config() calls; two new getters (resolvedUrl(), resolvedModel()) expose the active values for accurate log output
  • RagRetriever log messages now report the actual resolved embedding URL and model (via the new EmbeddingService getters) rather than the potentially-wrong global config values
  • color_scheme config comment updated — header changed from Color Scheme (Admin RAG UI) to Color Scheme; description clarifies it applies to both the widget and all admin pages

0.2.5

Added

  • ai-chatbox:prune-conversations Artisan command — bulk-delete conversations that have been inactive beyond a configurable retention period:
    • --days=N — override the retention threshold for this run
    • --dry-run — preview how many conversations would be removed without deleting anything
    • --force — proceed even when memory_driver is not database
    • Pre-flight checks: validates that memory_driver is database, that both ai_chatbox_conversations and ai_chatbox_messages tables exist, and that --days is ≥ 1
    • Messages are removed automatically via the existing foreign key cascade — no manual joins required
    • Suitable for scheduling via Laravel's task scheduler (see README for Laravel 10 / 11+ examples)
  • conversation_prune_days config key (AI_CHATBOX_PRUNE_DAYS, default 30) — sets the default retention period used by ai-chatbox:prune-conversations when --days is not passed
  • PruneConversationsTest — 19 feature tests covering pre-flight validation, happy-path deletion, boundary conditions, cascade behaviour, --dry-run, --force, config key precedence, and the saveHistory updated_at touch behaviour
  • Flow.md — architecture flow documentation describing the request lifecycle across the three-layer architecture

Changed

  • DatabaseConversationRepository::saveHistory() now calls $conversation->touch() after persisting messages so that updated_at always reflects the time of the last message, not just the conversation creation time; this makes the prune command's inactivity window accurate

0.2.4

Changed

  • Named-provider config is now the only source of API credentials — the legacy top-level api_url, api_token, and api_model config keys (and their AI_CHATBOX_API_* env vars) have been removed; all provider settings must now be defined under providers.{name} in the config file. This change had been the documented practice since 0.2.1; this release enforces it.
  • AiManager::resolveConfig('default') now routes through active_provider — previously it returned the (now-removed) top-level keys; it now resolves the active named provider by reading active_provider config, falling back to the first defined provider if active_provider is 'default' or empty
  • AdminController uses resolved provider config for diagnostics — the admin dashboard now calls AiManager::resolveConfig() to obtain the effective api_url, api_token, and api_model values; diagnostic messages now reference provider-specific env var names (e.g. OLLAMA_URL, OPENAI_URL) rather than the removed AI_CHATBOX_API_* names; a try/catch ensures the page still renders when the active provider is misconfigured
  • Config/ai-chatbox.php documentation reorganised — inline comments rewritten to reflect the named-provider model; the top-level API credential block is removed
  • CSS polish — chatbox widget visual refinements (spacing, focus states, scrollbar styling)
  • composer.json keywords expanded — added Packagist keywords for improved discoverability (llm, gpt, local-llm, multi-provider, admin-dashboard, knowledge-base, token-streaming, and others)
  • README and TROUBLESHOOTING.md updated — all references to AI_CHATBOX_API_URL, AI_CHATBOX_API_TOKEN, and AI_CHATBOX_API_MODEL replaced with named-provider equivalents

Fixed

  • Admin diagnostics no longer warn about missing api_url/api_token/api_model "inheriting from top-level defaults" — those defaults no longer exist; the error messages now correctly point to provider-specific env vars

0.2.3

Added

  • rag_embedding_timeout config key (AI_CHATBOX_EMBEDDING_TIMEOUT, default 10) — dedicated timeout in seconds for embedding API calls; previously the embedding HTTP client was hardcoded to 60 s regardless of model speed
  • EmbeddingService now accepts an optional $timeout constructor parameter; RagController passes the active provider's resolved timeout when instantiating the service

Fixed

  • LM Studio default provider config — default api_url and rag_embedding_url changed from localhost to 127.0.0.1 to avoid DNS resolution issues on some Windows setups; default api_model updated to phi-3.5-mini-instruct; default rag_embedding_model updated to text-embedding-nomic-embed-text-v1.5

0.2.2

Added

  • EmbeddingService constructor injection — EmbeddingService now accepts optional $url, $model, $token constructor parameters so it can be instantiated with per-provider settings; falls back to config values when parameters are null
  • RagController active-provider awareness — embedding config (URL, model, token) is now resolved through the active provider (active_provider config key) rather than always reading the top-level config; switching providers via .env now also updates which embedding endpoint is used
  • Expanded test suite — added AdminDiagnosticsTest, EmbeddingServiceTest, expanded AiManagerTest, RagDocumentTest, HealthCheckTest, SendMessageTest, StreamMessageTest; TestCase base class updated to expose mockGuzzle() helper for HTTP mocking
  • Admin dashboard and RAG Knowledge Base UI polish

0.2.1

Added

  • 3-layer architecture — the package is now organised into three explicit layers:
    • Layer 1 — AI Engine (src/Engine/): AiEngineInterface, OpenAiCompatibleEngine, PromptBuilder, HealthChecker, AiEngineException. All HTTP calls, prompt assembly, error classification, and health checks live here.
    • Layer 2 — Memory (src/Memory/): ConversationRepositoryInterface, SessionConversationRepository, DatabaseConversationRepository, ContextManager, Conversation model, Message model. All history persistence and context trimming live here.
    • Layer 3 — UI (src/Http/Controllers/, src/resources/): ChatboxController handles HTTP request/response only and delegates entirely to Layers 1 and 2.
  • AI facade (DeveloperUnijaya\AiChatbox\AI) — call AI::chat($prompt) or AI::provider('openai')->chat($prompt) from any controller, job, or service
  • AiManager — resolves named providers from the providers config group, merging each entry with the global defaults
  • AiProvider — fluent immutable wrapper; each modifier (withModel, withTemperature, withSystemPrompt, withLanguage, withMaxTokens, withTimeout, withConfig) returns a new cloned instance so the original is never mutated
  • AiEngineInterface — public contract for the AI engine; implement it to add a custom provider (e.g. Anthropic, Gemini, Cohere) and bind it in the service provider
  • ConversationRepositoryInterface — public contract for the memory layer; implement it to add a custom storage backend (e.g. Redis, MongoDB)
  • beginStream() on the engine — establishes the AI HTTP connection before response()->stream() starts, so network errors can still return a proper JSON error response (non-200) rather than a corrupted SSE stream
  • Database memory driver — new memory_driver config key (AI_CHATBOX_MEMORY_DRIVER, default session). Set to database to persist conversation history in the ai_chatbox_conversations / ai_chatbox_messages tables; history survives PHP session expiry and is queryable via Eloquent
  • New migrations: ai_chatbox_conversations (thread_id, user_id) and ai_chatbox_messages (conversation_id, role, content) — auto-loaded; no manual registration required
  • active_provider config key (AI_CHATBOX_ACTIVE_PROVIDER, default ollama) — point the chatbox widget at a named provider without duplicating credentials
  • providers config group — define named providers (ollama, openai, groq, lmstudio); each entry only needs the keys that differ from the global defaults; all other settings are inherited automatically
  • AdminController and admin views (admin.blade.php, admin-conversations.blade.php) — admin dashboard with configuration diagnostics, stat cards, named provider overview, and async-paginated conversations viewer with message modal
  • New admin routes: GET /ai-chatbox/admin, GET /ai-chatbox/admin/conversations, GET /ai-chatbox/admin/conversations/data, GET /ai-chatbox/admin/conversations/{id}/messages
  • Expanded test suite: AiFacadeTest, AiManagerTest, AiProviderTest (unit), ContextManagerTest (unit), PromptBuilderTest (unit), DatabaseMemoryTest

Changed

  • ChatboxController reduced from ~600 lines to ~120 lines — pure HTTP I/O, no business logic
  • Error classification (E01–E19) moved from ChatboxController to OpenAiCompatibleEngine (now public methods, directly testable)
  • ErrorClassificationTest updated to target OpenAiCompatibleEngine directly (no more reflection into the controller)
  • Expanded composer.json keywords for better Packagist discoverability
  • Updated package description in composer.json to reflect RAG and streaming capabilities

0.2.0

Added

  • Four frontend drivers — the frontend config key (AI_CHATBOX_FRONTEND) controls which UI [@aichatbox](https://github.com/aichatbox) renders:
    • vue (default) — pre-compiled Vue 3 SFC bundle; zero config, no CDN calls
    • blade — self-contained vanilla JS widget; no framework dependency; marked.js + DOMPurify loaded from CDN only when markdown=true
    • livewire — Alpine.js widget mounted via Livewire 3; Alpine.js is bundled automatically by Livewire
    • none — outputs only window.AiChatboxConfig; use this when bringing your own React/Svelte/Vue component
  • [@aichatboxConfig](https://github.com/aichatboxConfig) Blade directive — outputs only window.AiChatboxConfig regardless of the frontend setting; useful when mounting <livewire:ai-chatbox /> independently or building a custom frontend
  • Livewire component (ai-chatbox) — auto-registered when livewire/livewire is installed; mount anywhere with <livewire:ai-chatbox />
  • chatbox-config.blade.php — shared config injector view extracted from the main chatbox view; all drivers read window.AiChatboxConfig
  • chatbox-blade.blade.php — new vanilla JS driver; identical HTML structure and CSS class names as the Vue driver; no compilation required

Changed

  • chatbox.blade.php refactored into a dispatcher — reads frontend config and includes the appropriate driver partial

0.1.9

Added

  • RAG admin dark mode — the /ai-chatbox/rag admin UI now fully supports light and dark themes with a new color_scheme config key (auto / light / dark)
    • auto (default) follows the user's OS/browser preference via prefers-color-scheme and updates live without a page reload
    • light / dark forces a fixed mode server-side with no flash-of-wrong-theme
    • All elements themed: cards, table, inputs, file picker, status badges, buttons, flash messages
  • Configurable RAG context prompt — new rag_context_prompt config key (AI_CHATBOX_RAG_CONTEXT_PROMPT) lets you customise the instruction prepended to retrieved chunks; use {chunks} as a placeholder for where the retrieved text is inserted
  • Configurable RAG processing timeout — new rag_processing_timeout config key (AI_CHATBOX_RAG_PROCESSING_TIMEOUT, default 0 = no limit) controls how long PHP is allowed to run during document upload/reprocess, preventing Maximum execution time exceeded errors on slow local embedding models

Fixed

  • RAG message ordering — RAG context is now injected immediately before the user's turn ([system → history → RAG context → user]) rather than at the front of the message list; models pay most attention to content nearest the end of the context window, so this significantly improves answer accuracy
  • RAG similarity threshold — lowered default from 0.3 to 0.2 to improve recall for local embedding models (e.g. nomic-embed-text) which typically produce lower cosine similarity scores than OpenAI models

0.1.8

Added

  • RAG — Retrieval-Augmented Generation — full implementation allowing the chatbox to answer questions about your own documents:
    • Upload .md and .txt files (up to 10 MB) via the admin UI at /ai-chatbox/rag
    • Documents are chunked (paragraph-aware with configurable size and overlap) and embedded via any OpenAI-compatible embeddings API
    • On every chat message, the user's query is embedded and cosine similarity is computed in PHP against all stored chunks — the top-K most relevant chunks are injected as context into the AI request
    • Admin UI shows indexing status (Pending → Processing → Ready / Failed), chunk count, and error details
    • Supports Reprocess (re-chunk and re-embed with new settings) and Delete actions
    • Admin routes protected by ['web', 'auth'] middleware by default (configurable)
  • New config keys: rag_enabled, rag_embedding_url, rag_embedding_model, rag_top_k, rag_chunk_size, rag_chunk_overlap, rag_similarity_threshold, rag_admin_middleware
  • New database tables: ai_chatbox_rag_documents, ai_chatbox_rag_chunks (auto-loaded migrations, no manual registration required)
  • New service classes: DocumentChunker, EmbeddingService, RagRetriever
  • New Eloquent models: RagDocument, RagChunk
  • New controller: RagController with index, store, destroy, reprocess actions
  • New publishable tag: ai-chatbox-migrations — publish migrations before running if you want to review or customise them
  • Embedding response format auto-detection — works with Ollama /v1/embeddings, Ollama /api/embed, and OpenAI /v1/embeddings without any extra configuration
  • RAG admin UI uses Tailwind CDN with a CSS custom property (--theme) so it inherits the configured theme_color without a build step

Changed

  • ChatboxController now injects RAG context into every chat and stream request when rag_enabled is true

0.1.7

Added

  • Conversation threads — each browser session gets a UUID v4 thread ID stored in localStorage/sessionStorage, scoped to both the app URL and the authenticated user; multiple independent conversations never share context
  • New thread button (pencil icon) in the chat header — generates a new UUID and resets the client display while leaving old server-side history to expire naturally
  • Real-time token streaming via Server-Sent Events (SSE) — AI replies stream token-by-token with a blinking ▋ cursor; uses POST /ai-chatbox/stream (Fetch API + ReadableStream on the client, Guzzle stream: true on the server)
  • Context token limit — new context_token_limit config key (AI_CHATBOX_CONTEXT_TOKENS, default 4000) trims conversation history oldest-pair-first by estimated token count (~4 chars/token) to stay within the model's context window
  • Stream config key — stream / AI_CHATBOX_STREAM (default true) to toggle between SSE streaming and full-response mode
  • POST /ai-chatbox/clear route to clear the server-side session history for a specific thread
  • New feature tests: StreamMessageTest, expanded SendMessageTest, ClearHistoryTest
  • X-Accel-Buffering: no response header set automatically on SSE responses to disable Nginx proxy buffering

Changed

  • History is now stored and retrieved per thread ID rather than in a single global session key

0.1.6

Fixed

  • Resolved Vue.js template string escaping issues that caused JavaScript errors in certain Blade rendering contexts
  • Improved TROUBLESHOOTING.md with additional error scenarios

0.1.5

Changed

  • Frontend rewritten in Vue 3 — replaced the vanilla JavaScript + jQuery implementation with a Vue 3 single-file component (AiChatbox.vue) using the Composition API, compiled to a self-contained IIFE bundle via Vite
  • Bundle now includes Vue 3, axios, marked, and DOMPurify — no external CDN calls required at runtime
  • Blade view significantly simplified; all reactive UI logic moved into the Vue component
  • Added package.json and vite.config.js for contributors to rebuild the frontend assets (npm run build)

0.1.4

Changed

  • Improved asset loading — assets are served more reliably across different server configurations
  • Config values are now cached-compatible (safe to use with php artisan config:cache)
  • Removed redundant route registrations

0.1.3

Changed

  • Expanded README with configuration reference, provider examples, and usage notes

0.1.2

Added

  • Full test suite with PHPUnit 11 and Orchestra Testbench:
    • SendMessageTest — message proxying, error handling, history, language enforcement
    • ClearHistoryTest — session history clearing per thread
    • CorsMiddlewareTest — origin validation, preflight requests
    • HealthCheckTest — AI service ping, SSRF blocking
    • ErrorClassificationTest — all E01–E19 error codes
  • GitHub Actions CI workflow (.github/workflows/tests.yml) running tests on PHP 8.2/8.3 × Laravel 10/11/12
  • phpunit.xml configuration with SQLite in-memory database for fast test runs

0.1.1

Added

  • Structured error codes (E01–E19) — every failure path in the controller now returns a machine-readable error code alongside the human-readable message, making it easy to diagnose issues from storage/logs/laravel.log
  • TROUBLESHOOTING.md — full reference guide mapping each error code to its cause and resolution steps
  • Error codes cover: authentication failures, connection errors, timeouts, model not found, context length exceeded, content policy violations, rate limiting, invalid responses, and more

0.1.0

Added

  • CORS middleware (ai-chatbox.cors) — restricts chatbox endpoints to requests originating from your app's own URL (APP_URL); additional origins can be added via allowed_origins config
  • SSRF protection — the health check endpoint now blocks requests to private and reserved IP ranges (localhost, 10.x, 172.16.x, 192.168.x, 169.254.x) to prevent Server-Side Request Forgery attacks; disable with AI_CHATBOX_SSRF_PROTECTION=false for local development
  • New config keys: ssrf_protection, allowed_origins

0.0.9

Fixed

  • localStorage key is now scoped to both the application URL and the authenticated user — previously all users on the same browser shared the same chat history key, causing messages from one user to appear for another

0.0.8

Fixed

  • Resolved session persistence bugs — chat history now reliably survives page refresh
  • localStorage is written and read correctly; state is no longer lost on navigation

0.0.7

Added

  • Chat history persistence — conversation messages are saved to localStorage and restored when the user returns to the page; chat no longer resets on every page load

0.0.6

Added

  • Ollama cloud (ollama.com) compatibility — auto-detects the Ollama native chat response format (different from the OpenAI-compatible format) and parses it correctly; both Ollama local (OpenAI-compatible) and Ollama cloud (native) APIs now work without any extra configuration
  • Updated config comments to document Ollama cloud .env example

0.0.5

Changed

  • README cleanup and corrections

0.0.4

Added

  • Language preference — new language / AI_CHATBOX_LANGUAGE config forces the AI to always reply in a specified language regardless of the language the user writes in; uses both a system prompt instruction and a per-message reminder for better compliance on small models
  • system_prompt config key for a fully customisable system message with a {language} placeholder

Fixed

  • Fixed a broken icon rendering bug in the chat button

Changed

  • Removed unused CSS and simplified the stylesheet significantly

0.0.3

Added

  • Health check — clicking the chat button now pings the AI service first; if unreachable, a toast is shown near the button for 4 seconds (health_check, offline_message config keys)
  • Widget position — configurable corner placement: bottom-right, bottom-left, top-right, top-left (position / AI_CHATBOX_POSITION)
  • Sound notification — soft Web Audio API ping when the AI replies (sound, sound_volume config keys)
  • Markdown rendering — AI replies rendered as formatted Markdown (bold, lists, code blocks, tables) using marked.js + DOMPurify, both bundled (markdown / AI_CHATBOX_MARKDOWN)
  • Conversation history — previous messages sent back to the AI on every request for context (history_enabled, history_limit config keys)
  • Response tuning — temperature and max_tokens config keys
  • Client-side storage driver — switch between localStorage and sessionStorage (storage / AI_CHATBOX_STORAGE)
  • Dark mode — chat widget automatically adapts to prefers-color-scheme: dark
  • Rate limiting — throttle:20,1 middleware applied to all chatbox routes (rate_limit, rate_window config keys)
  • Route prefix — configurable URL prefix (route_prefix config key, default ai-chatbox)

0.0.2

Added

  • Chatbox title now configurable via AI_CHATBOX_TITLE

0.0.1

Added

  • Initial release
  • Floating chat widget injected via [@aichatbox](https://github.com/aichatbox) Blade directive — no build tools required in the host application
  • Messages proxied through Laravel to any OpenAI-compatible API
  • Default configuration targets Ollama running locally on localhost:11434 with phi3:mini
  • Supports Ollama (local), OpenAI, Groq, OpenRouter, and LM Studio out of the box
  • Configurable API URL, token, and model via .env
  • Service provider with auto-discovery, asset publishing, and view publishing
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.
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc