Download the PHP package tetrixdev/laravel-ai-bridge without Composer

On this page you can find all versions of the php package tetrixdev/laravel-ai-bridge. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-ai-bridge

Laravel AI Bridge

Latest Version on Packagist PHP 8.2+ Laravel 11+

A unified AI streaming interface for Laravel. Connect any Chat Completions-compatible provider (OpenAI, Anthropic, Groq, Ollama, etc.) or local CLI tools (Codex, Claude, Gemini) to your app through a single, normalized streaming pipeline.

What is this?

Laravel AI Bridge provides a unified streaming pipeline: provider -> normalized events -> browser. No matter where the AI response originates, your application receives the same StreamEvent objects through the same callback API. Three modes of operation cover every use case:

Installation

Publish the config file:

Publish the JavaScript client (optional):

Add to your .env:

Quick Start

A minimal BYOK example in three steps.

1. Configure .env

2. Create a Controller

3. Create a Blade View

Modes of Operation

BYOK (Bring Your Own Key)

The user provides an API key and endpoint for any Chat Completions-compatible provider. The server calls the API directly -- no local install required on the user's machine.

Works with any Chat Completions-compatible endpoint: OpenAI, Anthropic (via proxy), Groq, Together, Ollama, LM Studio, vLLM, etc.

Managed

Identical to BYOK but the application provides its own API key. Users pay the app a subscription fee. No separate architecture needed -- same code path, different config source.

CLI Bridge

The user installs the bridge locally via npx @tetrixdev/ai-bridge. It connects to your app's dedicated WebSocket server and proxies AI requests through their local CLI tools (using their existing subscriptions).

Start the bridge server:

Generate a token for the user, then have them connect:

The server-side code is identical:

Configuration

Full reference for config/ai-bridge.php:

Key Env Variable Default Description
mode AI_BRIDGE_MODE byok Active mode: byok, managed, or bridge
token.secret AI_BRIDGE_TOKEN_SECRET null JWT signing secret (required)
token.ttl AI_BRIDGE_TOKEN_TTL 86400 Token TTL in seconds (24h)
websocket.heartbeat_interval -- 30 Seconds between ping/pong
websocket.request_timeout -- 300 Seconds before AI request timeout
chat_completions.endpoint AI_BRIDGE_ENDPOINT null Chat Completions API base URL
chat_completions.api_key AI_BRIDGE_API_KEY null API key for BYOK/managed
chat_completions.model AI_BRIDGE_MODEL null Model name (e.g. gpt-4o)
chat_completions.max_tokens AI_BRIDGE_MAX_TOKENS 4096 Max response tokens
chat_completions.allowed_models -- [] Model allowlist. Empty array allows all models. When non-empty, requests for a model not in the list are rejected with HTTP 422
server.host AI_BRIDGE_SERVER_HOST 127.0.0.1 Bridge WebSocket server bind address (set to 0.0.0.0 in Docker/multi-host setups)
server.port AI_BRIDGE_SERVER_PORT 8085 Bridge WebSocket server port
stream_store.default AI_BRIDGE_STREAM_STORE redis Per-turn event buffer driver. Ships with redis and array (tests); apps register their own via StreamStore::extend().
stream_store.redis.connection AI_BRIDGE_STREAM_REDIS_CONNECTION null Redis connection from config/database.php. null = app default.
stream_store.redis.prefix AI_BRIDGE_STREAM_REDIS_PREFIX ai-bridge:stream Key prefix for buffer entries.
stream_store.redis.ttl_streaming AI_BRIDGE_STREAM_TTL_STREAMING 3600 TTL (s) while a turn is live; refreshed on every event.
stream_store.redis.ttl_completed AI_BRIDGE_STREAM_TTL_COMPLETED 1800 TTL (s) once a turn has terminated; bounds how long a recent page-load can replay.
stream_store.poll_interval_ms AI_BRIDGE_STREAM_POLL_MS 100 SSE long-poll interval while a turn is streaming.
stream_store.keepalive_interval_s AI_BRIDGE_STREAM_KEEPALIVE_S 30 SSE keepalive comment cadence (must beat intermediate proxy idle timeouts).
stream_store.max_connection_s AI_BRIDGE_STREAM_MAX_CONNECTION_S 600 Per-SSE-connection lifetime ceiling; the browser auto-reconnects via Last-Event-ID after.
logging.channel AI_BRIDGE_LOG_CHANNEL null Log channel for the bridge relay path. null uses the app's default channel; point it at a dedicated channel (e.g. a daily channel with its own retention) to keep bridge logs separate. Falls back to the default channel if the named one is undefined.
logging.verbose AI_BRIDGE_LOG_VERBOSE false When true, also log per-event detail (every stream event, relayed payloads) at debug level. Useful in development; noisy in production.
cli.local_path AI_BRIDGE_CLI_LOCAL_PATH null Absolute path to an ai-bridge repo checkout. When set and APP_ENV=local, the "Add a CLI bridge" command runs that checkout's build (node <path>/dist/cli.js) instead of npx @tetrixdev/ai-bridge@latest — for testing CLI changes without an npm publish. Build the checkout first (npm run build).
streaming.suppress_thinking_blocks AI_BRIDGE_SUPPRESS_THINKING true Suppress AI chain-of-thought / thinking blocks from SSE output and the per-turn buffer. Set to false only when intentionally displaying AI reasoning to users.

Relay-path logging

When a bridge-mode chat hangs on "Thinking", the bridge relay log is the first place to look. A healthy turn logs relaying conversation message to bridge, then relayed request to bridge server, then a terminal relayed stream done (or relayed stream error with the cause). With logging.verbose on, every stream event and the relayed payload are logged too.

Point logging.channel at a dedicated channel to keep these out of the main app log and give them their own retention — e.g. in config/logging.php:

then set AI_BRIDGE_LOG_CHANNEL=ai-bridge.

Streaming to Browser

Two methods for delivering AI responses to the browser.

SSE (Server-Sent Events)

Returns an SSE HTTP response. Simplest approach -- no extra infrastructure needed.

Or use the built-in endpoint:

The response is text/event-stream with normalized events. The first event is always conversation_id, carrying the server-generated conversation ID — capture it and send it back with follow-up messages to continue a multi-turn conversation:

Buffered streaming (refresh-safe)

For persisted conversations, use the buffered streaming path. The server writes every event to a short-lived per-turn buffer (Redis by default); the browser tails it over SSE. Native EventSource reconnection via Last-Event-ID makes refresh, tab-switch and network blip recover the in-flight reply for free — without losing tokens or restarting the turn.

Or use the built-in endpoint, which the bundled chat UI uses:

Then tail the per-turn buffer from the browser using native EventSource:

On page load, check whether a turn is in flight and re-attach. The conversation payload (GET /ai-bridge/conversations/{id}) carries streaming_request_id when a turn is live:

Stop an in-flight turn:

JavaScript Client

A lightweight vanilla JS module that wraps the HTTP endpoints with the same refresh-safe semantics the bundled chat UI uses. Publish it first:

This copies ai-bridge.js to resources/js/vendor/ai-bridge.js.

Using with Vite (recommended): Import it in your resources/js/app.js:

Manual approach: Copy the file to public/js/vendor/ai-bridge.js and include with a script tag:

Buffered mode (default — recommended)

For conversation-based streams. POSTs the message, then tails the per-turn buffer over native EventSource. Refresh, tab-switch and network blip recover the in-flight reply automatically via Last-Event-ID.

SSE mode (one-shot, no conversation row)

For non-conversation use — a direct text/event-stream against /ai-bridge/stream/sse. No resumption; a refresh loses the response. Use buffered mode if you need refresh-safety.

With Alpine.js

Conversation Persistence

The package persists multi-turn conversations to the database so they can be listed, resumed, and replayed. Persistence is always on — there is no opt-in flag. Three tables are created by auto-loaded migrations (they are not publishable — do not fork them): ai_bridge_conversations, ai_bridge_messages and ai_bridge_connections, on the application's default database connection.

The tables are deliberately not linked to any of your tables. Your app associates conversations/connections with its own users or sessions via its own pivot tables, and tells the package which rows a request may see by registering two scoping resolvers (e.g. in a service provider's boot()):

Listen for ConversationCreated / ConnectionCreated to link a newly created row to your owner model.

Connection lifecycle events

The package dispatches synchronous events around connection lifecycle so your app can keep its own state in step:

Event When Use it to
ConnectionCreated a connection is registered via the HTTP API link the new row to your owner/session model
ConnectionDeleted a connection is deleted via the HTTP API run non-database cleanup tied to the connection

Each event carries the Connection and the live Request.

Cascading the delete. Give your owner pivot a cascading foreign key so its rows are removed automatically when a connection is deleted — no listener needed for the database side:

With the cascade in place, listen for ConnectionDeleted only when you have other work to do (e.g. notifying a service, clearing a cache). For deletes that should be vetoed or cleaned up transactionally, you can also hook the Eloquent deleting event on Tetrix\AiBridge\Models\Connection.

If your resolver reads the session (e.g. $request->session()), the AI Bridge routes must run with the full cookie + session middleware stack — not StartSession alone. Configure ai-bridge.route_middleware accordingly:

Your web pages set an encrypted session cookie (via the web group). Without EncryptCookies on the AI Bridge routes, StartSession cannot decrypt that cookie and starts a brand-new session on every request — so session-scoped conversations and connections appear to vanish between requests. Apps that scope by an authenticated user instead ($request->user()) can use their normal auth middleware and are unaffected.

HTTP API

Method & path Purpose
GET /ai-bridge/conversations List conversations (scoped + paginated)
POST /ai-bridge/conversations Create a conversation
GET /ai-bridge/conversations/{id} Conversation + messages + tools_stale flag
DELETE /ai-bridge/conversations/{id} Delete a conversation
POST /ai-bridge/conversations/{id}/stream Start a turn — returns {request_id}; the browser tails /streams/{rid}/events
GET /ai-bridge/streams/{rid}/status Status snapshot of an in-flight or recently-completed turn
GET /ai-bridge/streams/{rid}/events SSE tail of the per-turn event buffer; resumes by Last-Event-ID
POST /ai-bridge/streams/{rid}/abort Cancel an in-flight turn (serve process observes the flag, sends cancel to the CLI)
GET /ai-bridge/connections List connections with their advertised providers/models + live connected flag
POST /ai-bridge/connections Register a CLI bridge or BYOK connection
PATCH /ai-bridge/connections/{id} Rename a connection
POST /ai-bridge/connections/{id}/regenerate Rotate a bridge's token (revokes the old one, disconnects any live bridge)
DELETE /ai-bridge/connections/{id} Delete a connection (disconnects any live bridge)

History injection retains prior text and tool calls/results but excludes thinking blocks; switching provider/model/mode mid-conversation is supported.

Reference Chat UI

A drop-in ChatGPT-style chat component ships with the package:

It is a thin wrapper that renders an <ai-bridge-chat> Web Component. The component uses Shadow DOM, so it is fully isolated — it cannot conflict with your app's CSS framework or JavaScript (no global Tailwind, no global Alpine). Its pre-built bundle is served by the package; your app needs no build toolchain. It is entirely optional — the backend is fully usable without it.

Customizing the chat UI

The component is a reference implementation — you are never locked into it.

  1. Build your own UI (recommended for anything beyond light tweaks). Every piece of logic lives server-side, so a custom UI is lightweight: render JSON from the HTTP API above, POST messages to the stream endpoint, tail the returned request_id's buffer over EventSource. Use any stack — Blade, Livewire, Vue, React. The stream emits these events (each as an SSE event: <name> line with a JSON data: payload): block_start, block_delta ({block_type, content}), block_stop, tool_call ({tool_name, parameters}), done ({usage}), error, cancelled.

    The bundled component (resources/dist/ai-bridge-chat.js) is the working reference for everything a client needs to do: API calls, EventSource lifecycle, Last-Event-ID resumption on conversation-open, reassembling block_* events into rendered messages, and watchdog handling for stalled turns. Read it as the example rather than re-deriving the contract.

  2. Fork the component. Copy resources/dist/ai-bridge-chat.js from the package into your app, adjust it, and point your own <script>/element at it. It is a single self-contained file with no build step.

Tool System

Register tools that the AI can call during a conversation. Tools work across all three modes.

Every parameter must be described. A tool registered with a parameter that has no (or an empty) description is rejected with an InvalidArgumentException at registration time. This applies to every registration path below. Tool names must start with a letter and contain only letters, digits, underscores, or hyphens (max 64 characters).

Register with a Closure

The parameters argument is a raw JSON Schema object. Each entry under properties must include a non-empty description.

A tool that takes no parameters passes an empty array (parameters: []).

Register with the Structured AbstractTool API (recommended)

Extending AbstractTool is the recommended way to define a tool. Instead of hand-writing a JSON Schema, you declare each parameter as a ToolParameter. Because ToolParameter requires a non-empty description, it is impossible to define a tool with an undescribed parameter -- the schema is generated for you.

ToolParameter accepts the JSON Schema types string, integer, number, boolean, array, and object. defineParameters() returns a list of them, and AbstractTool turns that list into the JSON Schema the API expects via the final parameters() method.

Register with a ToolHandler Class

You can also implement the ToolHandler interface directly and build the JSON Schema yourself. Every property must still include a non-empty description.

Listening for Tool Calls

Bridge Server

The ai-bridge:serve command starts a dedicated WebSocket server for CLI bridge connections. It runs on its own port and speaks the AI Bridge Protocol — separate from any other realtime infrastructure your app may use.

Options:

The server:

Running bridge mode — one background process is required

Bridge mode needs one long-running process alongside your web server, because the AI response arrives at a different process than the one handling the browser request (see the data-flow diagram in Architecture):

Process Command Why it is needed
AI Bridge server php artisan ai-bridge:serve Accepts the WebSocket connection from the user's local npx @tetrixdev/ai-bridge CLI bridge, and writes stream events from it into the per-turn buffer the browser tails over SSE.

It must run continuously — under a process manager (Supervisor), as a dedicated container, or via Octane in development. A typical Supervisor setup:

A working Redis (used for the per-turn buffer by default) is also required. BYOK / Managed mode needs neither — those stream over SSE directly from the web process, so a plain web server plus Redis is enough.

Artisan Commands

Command Description
ai-bridge:serve Start the dedicated WebSocket server for CLI bridge connections
ai-bridge:token Generate a JWT connection token for testing
ai-bridge:test Send a test request through the configured mode

ai-bridge:serve

Starts the bridge WebSocket server. Bridge clients connect to ws://host:port?token=<JWT>.

ai-bridge:token

Generates a JWT token for testing bridge connections without needing a full auth flow.

ai-bridge:test

Sends a test request and displays streaming events in the console.

Architecture

Data flow (BYOK/Managed):

  1. Browser POSTs the message to /conversations/{id}/stream; Laravel returns {request_id} and runs the upstream AI call in a terminating() callback.
  2. Each streamed event is written to the per-turn buffer keyed by request_id.
  3. Browser opens EventSource('/streams/{rid}/events') and tails the buffer; native Last-Event-ID reconnect makes refresh/blip recover the in-flight reply.

Data flow (CLI Bridge):

  1. Browser POSTs the message; the web worker relays an ai_request to the ai-bridge:serve process over its internal HTTP API.
  2. The serve process sends the request over WebSocket to the user's local bridge; events come back asynchronously into the same serve process.
  3. Each event is written to the per-turn buffer (and the assistant message is persisted at terminal).
  4. Browser tails the buffer over SSE, same as BYOK/Managed — uniform shape across modes.

Protocol

The WebSocket protocol between the server and CLI bridge is documented in PROTOCOL.md.

License

MIT. See LICENSE.


All versions of laravel-ai-bridge with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
illuminate/support Version ^12.0
illuminate/routing Version ^12.0
illuminate/http Version ^12.0
firebase/php-jwt Version ^6.10|^7.0
guzzlehttp/psr7 Version ^2.0
react/socket Version ^1.14
ratchet/rfc6455 Version ^0.4
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package tetrixdev/laravel-ai-bridge contains the following files

Loading the files please wait ...