Skip to content

feat: support LiteLLM gateway - #40

Open
prodmanpd wants to merge 1 commit into
e2b-dev:mainfrom
prodmanpd:feat/litellm-provider
Open

feat: support LiteLLM gateway#40
prodmanpd wants to merge 1 commit into
e2b-dev:mainfrom
prodmanpd:feat/litellm-provider

Conversation

@prodmanpd

Copy link
Copy Markdown

Summary

Adds an optional LiteLLM gateway path for Surf's existing computer-use workflow. Deployments can route the OpenAI Responses API requests through a self-hosted or managed LiteLLM proxy while preserving the current OpenAI configuration as the default.

Changes

  • lib/config.ts adds explicit openai and litellm provider selection, dedicated LiteLLM credentials, a configurable proxy URL, and a required gateway model alias.
  • lib/streaming/openai.ts constructs the OpenAI client from the selected provider configuration and uses the configured model for every computer-use turn.
  • Empty completed responses now fail gracefully instead of ending the stream without text or computer actions.
  • README.md documents the LiteLLM setup and the required model capability.
  • Vitest coverage exercises configuration, model forwarding, error behavior, empty responses, and an opt-in live proxy call.

Usage

Configure a LiteLLM alias that supports the OpenAI Responses API computer tool:

E2B_API_KEY=your_e2b_api_key
AI_PROVIDER=litellm
LITELLM_API_KEY=sk-litellm-master-key
LITELLM_BASE_URL=http://localhost:4000/v1
LITELLM_MODEL=your-proxy-model-alias

LITELLM_MODEL accepts any alias exposed by the user's LiteLLM proxy, provided
that its backing model supports the OpenAI Responses API computer tool.
LiteLLM can route that alias across compatible deployments and apply its
configured fallbacks or load balancing.

Start Surf normally:

npm run dev

The application continues to invoke the same streamer:

const streamer = new OpenAIComputerStreamer(desktop, [1024, 720]);

for await (const event of streamer.stream({
  messages,
  signal: abortController.signal,
})) {
  // Existing SSE reasoning, action, error, and done events
}

OpenAIComputerStreamer reads the provider, proxy URL, key, and model alias from the environment. Application callers do not need a separate LiteLLM class or code path.

Tests

Unit and live integration tests

LITELLM_E2E_BASE_URL=http://127.0.0.1:4100/v1 \
LITELLM_E2E_API_KEY=... \
LITELLM_E2E_MODEL=<proxy-model-alias> \
npx vitest run lib/config.test.ts lib/streaming/openai.test.ts

Test Files  2 passed (2)
Tests       12 passed (12)

Coverage includes:

  • proxy URL normalization and exact model-alias forwarding
  • missing LiteLLM credentials and missing model aliases
  • unsupported provider configuration
  • 401 authentication, 404 model, and 400 context-window failures
  • 429 rate-limit guidance
  • timeout and malformed-response failures
  • empty completed responses
  • the final Responses API structure consumed by Surf's SSE workflow

Production build

npm run build
Build completed successfully

The build reported only the repository's existing React hook warnings.

Live provider E2E

The opt-in test exercised the real OpenAIComputerStreamer through a live LiteLLM 1.96 proxy backed by gpt-5.4:

Model alias: LiteLLM test alias backed by gpt-5.4
Provider response items: reasoning, message
Output text: Hello! How can I help?
Final Surf events: REASONING, DONE
Status: PASS

This verifies the complete path from Surf's streamer through the OpenAI SDK, LiteLLM, a real computer-capable model, response parsing, and SSE event generation.

Compatibility boundary

The configured alias must support the OpenAI Responses API computer tool. A generic chat model is not sufficient. LiteLLM 1.96 does not translate OpenAI's computer tool into Anthropic's provider-specific computer-use tool, so an Anthropic alias is intentionally not advertised for this workflow. This limitation is stated in the README rather than failing silently at runtime.

Risk and compatibility

  • Additive and opt-in. Existing deployments continue using OpenAI and gpt-5.4 when AI_PROVIDER is unset.
  • Uses the existing OpenAI client and Responses workflow; no parallel streaming implementation is introduced.
  • LiteLLM credentials are isolated from OPENAI_API_KEY.
  • No database migration or persistent-data change is required.

@cla-bot

cla-bot Bot commented Aug 2, 2026

Copy link
Copy Markdown

We require contributors to sign our Contributor License Agreement, and we don't have @prodmanpd on file. You can sign our CLA at https://e2b.dev/docs/cla . Once you've signed, post a comment here that says '@cla-bot check'

@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown

@prodmanpd is attempting to deploy a commit to the E2B Team on Vercel.

A member of the Team first needs to authorize it.

@cla-bot

cla-bot Bot commented Aug 2, 2026

Copy link
Copy Markdown

We require contributors to sign our Contributor License Agreement, and we don't have @prodmanpd on file. You can sign our CLA at https://e2b.dev/docs/cla . Once you've signed, post a comment here that says '@cla-bot check'

@prodmanpd

Copy link
Copy Markdown
Author

@cla-bot check

@cla-bot cla-bot Bot added the cla-signed label Aug 2, 2026
@cla-bot

cla-bot Bot commented Aug 2, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

@prodmanpd
prodmanpd force-pushed the feat/litellm-provider branch from f4739cb to c36d184 Compare August 2, 2026 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant