How Instatic AI Agent Integration Works with External LLM Providers
Instatic's AI agent integrates with external providers through a provider-agnostic runtime that uses plain HTTP calls instead of vendor SDKs, featuring a shared tool loop and adapter pattern that enables lightweight, sandbox-friendly connections to services like OpenAI and OpenRouter.
The CoreBunch/Instatic repository implements a unique approach to LLM integration that prioritizes minimal dependencies and maximum flexibility. By avoiding vendor SDKs entirely, the system reduces bundle size and maintains compatibility with sandboxed environments while supporting multiple providers through a unified interface.
The Three-Layer Architecture
Instatic's AI subsystem organizes provider communication into three distinct layers that separate transport concerns from business logic.
Common HTTP and Tool Loop
The server/ai/drivers/http/toolLoop.ts module contains the provider-agnostic runtime that orchestrates all LLM interactions. This shared loop handles Server-Sent Events (SSE) parsing, multi-turn tool execution, and error classification for every supported provider.
Rather than duplicating streaming logic per vendor, all drivers delegate to runToolLoop(), which manages the HTTP POST request, parses the SSE stream, and yields standardized events.
Responses Adapter
The server/ai/drivers/responses-shared.ts file implements the Responses Adapter pattern that isolates vendor-specific wire protocols. This adapter translates the "Responses" format used by OpenAI and OpenRouter into Instatic's internal AiStreamEvent shape.
It handles endpoint-specific details including URL construction, authentication header formatting, and request payload field mapping. Validation occurs at the boundary using TypeBox schemas (parseValue), ensuring type safety without type assertions.
Provider Drivers
Each external service implements a minimal provider driver that specifies only transport details and model catalogue handling. These drivers implement the AiProvider interface defined in server/ai/runtime/types.ts.
The drivers never import vendor SDKs. Instead, they use native fetch to communicate with HTTP endpoints, making the system bundle-friendly and runtime-agnostic.
Provider Implementation Examples
Instatic currently supports OpenAI and OpenRouter through dedicated driver files that demonstrate the minimal implementation surface required.
OpenAI Driver
The server/ai/drivers/openai.ts file defines the OpenAI integration using direct HTTP calls to https://api.openai.com/v1/responses for chat completions and https://api.openai.com/v1/models for the model catalogue.
The driver builds required headers, defines a stable-hash prompt-cache key, and forwards streaming requests to the shared tool loop:
// server/ai/drivers/openai.ts
export const openaiDriver: AiProvider = {
id: 'openai' as AiProviderId,
label: 'OpenAI',
supportedAuthModes: ['apiKey'],
capabilities(_modelId) {
return {
toolCalling: true,
visionInput: true,
toolResultImages: false,
promptCache: false,
streaming: true,
}
},
async listModels(creds, signal) {
return fetchOpenAiModels(creds, signal) // live catalogue
},
async *stream(req) {
if (req.credentials.authMode !== 'apiKey' || !req.credentials.apiKey) {
yield { type: 'error', message: 'OpenAI requires an API key …' }
return
}
// Delegate to shared tool loop
yield* runToolLoop(openaiAdapter, req)
},
}
OpenRouter Driver
Similarly, server/ai/drivers/openrouter.ts communicates with https://openrouter.ai/api/v1/responses and fetches the model catalogue from https://openrouter.ai/api/v1/models.
The driver adds bearer token authentication to catalogue requests and delegates streaming to runToolLoop():
// server/ai/drivers/openrouter.ts
async function fetchOpenRouterModels(
creds: AiResolvedCredential,
signal?: AbortSignal,
): Promise<AiProviderModel[]> {
const headers: Record<string, string> = {}
if (creds.apiKey) headers.Authorization = `Bearer ${creds.apiKey}`
const res = await fetch(`${OPENROUTER_BASE_URL}/models`, { headers, signal })
const parsed = parseValue(OpenRouterModelsResponseSchema, await res.json())
// Build AiProviderModel objects with capabilities, pricing, etc.
return parsed.data.map(model => ({
id: model.id,
label: model.name ?? model.id,
capabilities: { /* ... */ },
pricing: /* ... */,
contextWindow: /* ... */,
}))
}
The Shared Tool Loop in Action
When a client initiates a request, the flow traverses from the specific driver through the shared infrastructure and back to the client as standardized events.
The runToolLoop function in server/ai/drivers/http/toolLoop.ts handles the actual HTTP communication:
// server/ai/drivers/http/toolLoop.ts (simplified)
export async function* runToolLoop(
adapter: ResponsesAdapter,
req: AiStreamRequest,
): AsyncIterable<AiStreamEvent> {
// 1️⃣ POST request → SSE stream
const response = await fetch(adapter.endpoint, {
method: 'POST',
headers: adapter.buildHeaders(req),
body: JSON.stringify(req),
})
// 2️⃣ Parse SSE, translate with `adapter.translate` into AiStreamEvent
for await (const raw of parseSse(response.body)) {
yield adapter.translate(raw)
}
}
Low-level SSE parsing occurs in server/ai/drivers/http/sse.ts, which the tool loop consumes to handle streaming responses.
Live Model Catalogue Management
Instatic fetches model catalogues dynamically rather than using static definitions. Each driver implements custom logic for processing vendor-specific catalogue formats.
For OpenAI, the driver filters the raw list to include only chat and reasoning models, deriving user-friendly labels and tiers heuristically via deriveLabel and deriveTier functions.
For OpenRouter, fetchOpenRouterModels extracts capabilities, pricing, and context windows directly from the API response, building AiProviderModel objects that include rich metadata about each available model.
Summary
- Instatic AI agent integration avoids vendor SDKs entirely, using plain HTTP fetch requests to communicate with LLM providers.
- The three-layer architecture separates concerns through the shared tool loop (
server/ai/drivers/http/toolLoop.ts), the Responses Adapter (server/ai/drivers/responses-shared.ts), and minimal provider drivers. - Adding new providers requires only implementing the
AiProviderinterface and defining transport details, without pulling in heavy dependencies. - TypeBox schemas validate all data at system boundaries, ensuring runtime type safety without casting.
- The system supports live model catalogue fetching, filtering, and metadata extraction for each provider.
Frequently Asked Questions
Does Instatic use official SDKs for AI providers?
No. According to the CoreBunch/Instatic source code, the system deliberately avoids vendor SDKs to reduce bundle size and maintain sandbox compatibility. All communication occurs through native fetch calls to provider HTTP endpoints, with SSE parsing handled by internal utilities in server/ai/drivers/http/sse.ts.
How does the shared tool loop handle streaming?
The runToolLoop function in server/ai/drivers/http/toolLoop.ts manages the entire streaming lifecycle. It POSTs the request to the provider endpoint, consumes the response body as a stream, parses Server-Sent Events using parseSse(), and translates raw events into AiStreamEvent objects through the adapter's translate method.
What is the AiProvider interface?
The AiProvider interface, defined in server/ai/runtime/types.ts, is the contract that all LLM integrations must implement. It specifies methods for listing models, streaming completions, and reporting capabilities, along with metadata like supported authentication modes and provider labels. Both OpenAI and OpenRouter drivers implement this interface.
How are new providers added to Instatic?
Developers add new providers by creating a driver file that implements the AiProvider interface and plugs into the existing runToolLoop. The driver only needs to specify endpoint URLs, header construction, and model catalogue fetching logic. Because the heavy lifting happens in the shared tool loop and adapter layers, new integrations require minimal code and zero additional dependencies.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →