ibexharness
DocsBlogReleasesRoadmap
GitHub
ibexharness

Documentation

OverviewConfigurationAuthenticationRate limitingRequest routingProvider adapters
Proxy›Provider adapters
Proxy

Provider adapters

Pluggable adapters for OpenAI-compatible and other LLM providers.

Provider adapters translate normalized IBEX chat requests into upstream LLM API calls and stream responses back to clients. Phase 1 ships the adapter interface and registry skeleton only — no adapter is registered at runtime, so every valid chat request stops with 501 PROVIDER_NOT_CONFIGURED.

Phase 2 milestone

The first OpenAI adapter lands in milestone 2.1.1 Provider interface and registry, blocked until Phase 1.5 docs launch completes.

Why adapters exist

IBEX Harness must support multiple LLM vendors without leaking provider specifics into middleware. Adapters isolate:

  • Upstream URL and authentication (API keys, Azure deployment IDs)
  • Request/response dialect differences (tool calls, streaming chunk format)
  • Retry and circuit-breaker policy per provider

The proxy critical path stays provider-agnostic: normalize once, delegate to the registry, stream the response. Target overhead remains under 20ms p99 excluding upstream LLM latency — see Architecture overview.

Mermaid diagram: flowchart LR
+--------------+     +-------------------+     +-------------------+     +-------------------+
|              |     |                   |     |                   |     |                   |
| Chat handler |---->| Provider registry |---->|   OpenAI adapter  |---->|   api.openai.com  |
|              |     |                   |     |                   |     |                   |
+--------------+     +-------------------+     +-------------------+     +-------------------+
                               |                                                              
                               |                                                              
                               |                                                              
                               |                                                              
                               |                                                              
                               |               +-------------------+     +-------------------+
                               |               |                   |     |                   |
                               +-------------->| Anthropic adapter |---->| api.anthropic.com |
                                               |                   |     |                   |
                                               +-------------------+     +-------------------+

Planned adapter contract

1

Register at startup

Each adapter registers a name, supported model prefixes, and a Forward function with the proxy registry.

2

Receive normalized payload

Input is the validated OpenAI chat JSON plus org_id, agent_id, and request_id from middleware context.

3

Call upstream

Adapter applies provider credentials from org-scoped configuration (never from the client request body).

4

Stream response

Return OpenAI-compatible JSON or SSE chunks to the client; accumulate for async trace emission in later phases.

Adapters must not read org_id from the request body. Tenant context comes from verified auth middleware only — Tenant isolation.

Phase 1 behavior

Every authenticated, validated chat request hits the stub handler:

bash
curl -s http://localhost:8080/v1/chat/completions \
  -H "Authorization: Bearer ${IBEX_DEV_TOKEN}" \
  -H "X-IBEX-Agent-ID: ${IBEX_DEV_AGENT_ID}" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o","messages":[{"role":"user","content":"hi"}]}' \
  | jq '.error.code'

Expected output: "PROVIDER_NOT_CONFIGURED".

501 means success in Phase 1

HTTP 501 after validation confirms auth, agent verify, rate limiting, and normalization all passed. Use make dev-smoke to assert this automatically.

Error envelope

JSON
{
  "error": {
    "code": "PROVIDER_NOT_CONFIGURED",
    "message": "No LLM provider adapter is configured for this request",
    "request_id": "0192a3b4-c5d6-7890-abcd-ef1234567890",
    "timestamp": "2026-06-14T12:00:00Z"
  }
}

This is distinct from 503 dependency failures — the proxy itself is healthy; forwarding is simply not implemented yet.

What Phase 2 adds

1

Registry

Model-to-adapter resolution with org-level overrides.

2

OpenAI adapter

First production adapter with streaming SSE support.

3

Circuit breaker

Provider 5xx triggers breaker; clients receive 503 with Retry-After.

4

Context injection

Parallel memory and directive retrieval before upstream call (later milestones).

Provider API keys will be stored per org in Postgres and injected by the adapter — never accepted from client headers. Rotation guidance: Secrets and keys.

Security boundaries

ControlPhase 1Phase 2+
Client supplies provider API keyN/A (no forward)Forbidden
Org from tokenEnforcedEnforced
Audit log per upstream callNoYes (ClickHouse traces)
PII in upstream promptsValidated locallyRedaction pipeline

Verify adapter stub

bash
make compose-dev-up
make db-migrate && make db-seed
make dev-smoke   # asserts 501 on chat without LLM key

Integration tests in services/proxy/ assert PROVIDER_NOT_CONFIGURED for valid authenticated chat bodies.

Related

  • Request routing — normalization before adapter handoff
  • Overview — middleware and failure modes
  • Architecture services — proxy role in the system map
  • Roadmap Phase 2 — adapter delivery timeline

Was this page helpful?

Edit on GitHub

Last updated on

PreviousRequest routingNextOverview

On this page

  • Why adapters exist
  • Planned adapter contract
  • Phase 1 behavior
  • Error envelope
  • What Phase 2 adds
  • Security boundaries
  • Verify adapter stub
  • Related
0%