Skip to main content
ElevenLabs Documentation Docs
current

Search documentation

Type to search this documentation.

Integrate your own model

Connect an agent to your own LLM or host your own server.

  1. Define the Extra Parameters

    Create an object containing your custom parameters:

    Python
    from elevenlabs.conversational_ai.conversation import Conversation, ConversationInitiationData
    
    extra_body_for_convai = {
        "UUID": "123e4567-e89b-12d3-a456-426614174000",
        "parameter-1": "value-1",
        "parameter-2": "value-2",
    }
    
    config = ConversationInitiationData(
        extra_body=extra_body_for_convai,
    )
  2. Update the LLM Implementation

    Modify your custom LLM code to handle the additional parameters:

    Python
    import json
    import os
    import fastapi
    from fastapi.responses import StreamingResponse
    from fastapi import Request
    from openai import AsyncOpenAI
    import uvicorn
    import logging
    from dotenv import load_dotenv
    from pydantic import BaseModel
    from typing import List, Optional
    
    # Load environment variables from .env file
    load_dotenv()
    
    # Retrieve API key from environment
    OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
    if not OPENAI_API_KEY:
        raise ValueError("OPENAI_API_KEY not found in environment variables")
    
    app = fastapi.FastAPI()
    oai_client = AsyncOpenAI(api_key=OPENAI_API_KEY)
    
    class Message(BaseModel):
        role: str
        content: str
    
    class ChatCompletionRequest(BaseModel):
        messages: List[Message]
        model: str
        temperature: Optional[float] = 0.7
        max_tokens: Optional[int] = None
        stream: Optional[bool] = False
        user_id: Optional[str] = None
        elevenlabs_extra_body: Optional[dict] = None
    
    @app.post("/v1/chat/completions")
    async def create_chat_completion(request: ChatCompletionRequest) -> StreamingResponse:
        oai_request = request.dict(exclude_none=True)
        print(oai_request)
        if "user_id" in oai_request:
            oai_request["user"] = oai_request.pop("user_id")
    
        if "elevenlabs_extra_body" in oai_request:
            oai_request.pop("elevenlabs_extra_body")
    
        chat_completion_coroutine = await oai_client.chat.completions.create(**oai_request)
    
        async def event_stream():
            try:
                async for chunk in chat_completion_coroutine:
                    chunk_dict = chunk.model_dump()
                    yield f"data: {json.dumps(chunk_dict)}\n\n"
                yield "data: [DONE]\n\n"
            except Exception as e:
                logging.error("An error occurred: %s", str(e))
                yield f"data: {json.dumps({'error': 'Internal error occurred!'})}\n\n"
    
        return StreamingResponse(event_stream(), media_type="text/event-stream")
    
    if __name__ == "__main__":
        uvicorn.run(app, host="0.0.0.0", port=8013)

Example Request

With this custom message setup, your LLM will receive requests in this format:

JSON
{
  "messages": [
    {
      "role": "system",
      "content": "\n  <Redacted>"
    },
    {
      "role": "assistant",
      "content": "Hey I'm currently unavailable."
    },
    {
      "role": "user",
      "content": "Hey, who are you?"
    }
  ],
  "model": "gpt-4o",
  "temperature": 0.5,
  "max_tokens": 5000,
  "stream": true,
  "elevenlabs_extra_body": {
    "UUID": "123e4567-e89b-12d3-a456-426614174000",
    "parameter-1": "value-1",
    "parameter-2": "value-2"
  }
}
server.ts
import express, { Request, Response } from "express";
import OpenAI from "openai";

const app = express();
app.use(express.json());

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

interface InputMessage {
  role: string;
  content: string;
}

interface ResponseCreateRequest {
  model: string;
  input: InputMessage[];
  instructions?: string;
  temperature?: number;
  max_output_tokens?: number;
  stream?: boolean;
}

app.post("/v1/responses", async (req: Request, res: Response) => {
  const request = req.body as ResponseCreateRequest;

  res.setHeader("Content-Type", "text/event-stream");
  res.setHeader("Cache-Control", "no-cache");
  res.setHeader("Connection", "keep-alive");

  try {
    const stream = await openai.responses.create({
      model: request.model,
      input: request.input,
      instructions: request.instructions,
      temperature: request.temperature ?? 0.7,
      max_output_tokens: request.max_output_tokens,
      stream: true,
    });

    for await (const event of stream) {
      if (event.type === "response.output_text.delta") {
        res.write(
          `event: response.output_text.delta\ndata: ${JSON.stringify({ type: "response.output_text.delta", delta: event.delta })}\n\n`
        );
      } else if (event.type === "response.completed") {
        res.write(
          `event: response.completed\ndata: ${JSON.stringify({ type: "response.completed", response: { id: event.response.id, status: "completed" } })}\n\n`
        );
      }
    }

    res.write("data: [DONE]\n\n");
    res.end();
  } catch (error) {
    console.error("An error occurred:", error);
    res.write(
      `event: error\ndata: ${JSON.stringify({ type: "error", error: { message: String(error) } })}\n\n`
    );
    res.end();
  }
});

app.listen(8013, () => console.log("Server running on port 8013"));

Run this code or your own server code.

Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu