SPB Git

Repository Public

custom-chatkit.md 9.8 KB 251 lines markdown

1# Advanced integrations with ChatKit23> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.45When you need full control—custom authentication, data residency, on‑prem deployment, or bespoke agent orchestration—you can run ChatKit on your own infrastructure. Use OpenAI's advanced self‑hosted option to use your own server and customized ChatKit.67Agent Builder-hosted ChatKit workflows are in a transition window. For new8  ChatKit apps, build on your own server-side agent implementation with the9  ChatKit SDKs and the Agents SDK. See [ChatKit transition guidance10  →](https://developers.openai.com/api/docs/guides/chatkit)1112## Run ChatKit on your own infrastructure1314At a high level, an advanced ChatKit integration is a process of building your own ChatKit server and adding widgets to build out your chat surface. You'll use OpenAI APIs and your ChatKit server to build a custom chat powered by OpenAI models.1516![OpenAI-hosted ChatKit](https://cdn.openai.com/API/docs/images/self-hosted.png)1718## Set up your ChatKit server1920Follow the [server guide on GitHub](https://github.com/openai/chatkit-python/blob/main/docs/server.md) to learn how to handle incoming requests, run tools, and21stream results back to the client. The snippets below highlight the main components.2223### 1. Install the server package2425```bash26pip install openai-chatkit27```2829### 2. Implement a server class3031`ChatKitServer` drives the conversation. Override `respond` to stream events whenever a32user message or client tool output arrives. Helpers like `stream_agent_response` connect33the server to the Agents SDK.3435```python36class MyChatKitServer(ChatKitServer[RequestContext]):37    async def respond(38        self,39        thread: ThreadMetadata,40        input: UserMessageItem | ClientToolCallOutputItem | None,41        context: RequestContext,42    ) -> AsyncIterator[Event]:43        items_page = await self.store.load_thread_items(44            thread.id,45            after=None,46            limit=20,47            order="desc",48            context=context,49        )50        input_items = await simple_to_agent_input(list(reversed(items_page.data)))51        agent_context = AgentContext(52            thread=thread,53            store=self.store,54            request_context=context,55        )56        result = Runner.run_streamed(57            assistant_agent,58            input_items,59            context=agent_context,60        )61        async for event in stream_agent_response(agent_context, result):62            yield event63```646566### 3. Expose the endpoint6768Use your framework of choice to forward HTTP requests to the server instance. For69example, with FastAPI:7071```python72from fastapi import FastAPI, Request, Response73from fastapi.responses import StreamingResponse7475app = FastAPI()76data_store = MemoryStore()77server = MyChatKitServer(data_store)787980@app.post("/chatkit")81async def chatkit_endpoint(request: Request):82    result = await server.process(await request.body(), {})83    if isinstance(result, StreamingResult):84        return StreamingResponse(result, media_type="text/event-stream")85    return Response(content=result.json, media_type="application/json")86```878889### 4. Establish data store contract9091Implement `chatkit.store.Store` to persist threads, messages, and files using your92preferred database. For local development, you can use an in-memory `Store`93implementation. For production, use durable storage and consider storing the models as94JSON blobs so library updates can evolve the schema without migrations.9596### 5. Provide file store contract9798Provide a `FileStore` implementation if you support uploads. ChatKit works with direct99uploads (the client POSTs the file to your endpoint) or two-phase uploads (the client100requests a signed URL, then uploads to cloud storage). Expose previews to support inline101thumbnails and handle deletions when threads are removed.102103### 6. Trigger client tools from the server104105Client tools must be registered both in the client options and on your agent. Use106`ctx.context.client_tool_call` to enqueue a call from an Agents SDK tool.107108```python109@function_tool(description_override="Add an item to the user's todo list.")110async def add_to_todo_list(ctx: RunContextWrapper[AgentContext], item: str) -> None:111    ctx.context.client_tool_call = ClientToolCall(112        name="add_to_todo_list",113        arguments={"item": item},114    )115116117assistant_agent = Agent[AgentContext](118    model="gpt-6-astra",119    name="Assistant",120    instructions="You are a helpful assistant",121    tools=[add_to_todo_list],122    tool_use_behavior=StopAtTools(stop_at_tool_names=[add_to_todo_list.name]),123)124```125126127### 7. Use thread metadata and state128129Use `thread.metadata` to store server-side state such as the previous Responses API run130ID or custom labels. Metadata is not exposed to the client but is available in every131`respond` call.132133### 8. Get tool status updates134135Long-running tools can stream progress to the UI with `ProgressUpdateEvent`. ChatKit136replaces the progress event with the next assistant message or widget output.137138### 9. Using server context139140Pass a custom context object to `server.process(body, context)` to enforce permissions or141propagate user identity through your store and file store implementations.142143## Add inline interactive widgets144145Widgets let agents surface rich UI inside the chat surface. Use them for cards, forms,146text blocks, lists, and other layouts. The helper `stream_widget` can render a widget147immediately or stream updates as they arrive.148149```python150async def respond(151    self,152    thread: ThreadMetadata,153    input: UserMessageItem | ClientToolCallOutputItem | None,154    context: RequestContext,155) -> AsyncIterator[Event]:156    widget = Card(157        children=[158            Text(159                id="description",160                value="Generated summary",161            )162        ]163    )164    async for event in stream_widget(165        thread,166        widget,167        generate_id=lambda item_type: self.store.generate_item_id(168            item_type, thread, context169        ),170    ):171        yield event172```173174175ChatKit ships with a wide set of widget nodes (cards, lists, forms, text, buttons, and176more). See [widgets guide on GitHub](https://github.com/openai/chatkit-python/blob/main/docs/widgets.md) for all components, props, and177streaming guidance.178179See the [Widget Builder](https://widgets.chatkit.studio/) to explore and create widgets in an interactive UI.180181## Use actions182183Actions let the ChatKit UI trigger work without sending a user message. Attach an184`ActionConfig` to any widget node that supports it—buttons, selects, and other controls185can stream new thread items or update widgets in place. When a widget lives inside a186`Form`, ChatKit includes the collected form values in the action payload.187188On the server, implement the `action` method on `ChatKitServer` to process the payload189and optionally stream additional events. You can also handle actions on the client by190setting `handler="client"` and responding in JavaScript before forwarding follow-up191work to the server.192193See the [actions guide on GitHub](https://github.com/openai/chatkit-python/blob/main/docs/actions.md) for patterns like chaining actions, creating194strongly typed payloads, and coordinating client/server handlers.195196## Resources197198Use the following resources and reference to complete your integration.199200### Design resources201202- Download [OpenAI Sans Variable](https://drive.google.com/file/d/10-dMu1Oknxg3cNPHZOda9a1nEkSwSXE1/view?usp=sharing).203- Duplicate the file and customize components for your product.204205### Events reference206207ChatKit emits `CustomEvent` instances from the Web Component. Listen for lifecycle events and read payload data from `event.detail`:208209```javascript210chatkit.addEventListener("chatkit.error", (event) => {211  console.error(event.detail.error);212});213214chatkit.addEventListener("chatkit.response.start", () => {215  console.log("Response started");216});217218chatkit.addEventListener("chatkit.response.end", () => {219  console.log("Response ended");220});221222chatkit.addEventListener("chatkit.thread.change", (event) => {223  console.log("Active thread:", event.detail.threadId);224});225226chatkit.addEventListener("chatkit.log", (event) => {227  console.log(event.detail.name, event.detail.data);228});229```230231232### Options reference233234| Option          | Type                       | Description                                                | Default        |235| --------------- | -------------------------- | ---------------------------------------------------------- | -------------- |236| `apiURL`        | `string`                   | Endpoint that implements the ChatKit server protocol.      | _required_     |237| `fetch`         | `typeof fetch`             | Override fetch calls (for custom headers or auth).         | `window.fetch` |238| `theme`         | `"light" \| "dark"`        | UI theme.                                                  | `"light"`      |239| `initialThread` | `string \| null`           | Thread to open on mount; `null` shows the new thread view. | `null`         |240| `clientTools`   | `Record<string, Function>` | Client-executed tools exposed to the model.                |                |241| `header`        | `object \| boolean`        | Header configuration or `false` to hide the header.        | `true`         |242| `newThreadView` | `object`                   | Customize greeting text and starter prompts.               |                |243| `messages`      | `object`                   | Configure message features (feedback, annotations, etc.).  |                |244| `composer`      | `object`                   | Control attachments, entity tags, and placeholder text.    |                |245| `entities`      | `object`                   | Callbacks for entity lookup, click handling, and previews. |                |246247### Plain-text aliases248249- "light" | "dark"250- string | null251- object | boolean
Files main
Menu

Theme