Conversation
- Add ChatkitAdapter for converting OpenAI Agents SDK events to ChatKit ThreadStreamEvent format - Add /chatkit FastAPI endpoint via enable_chatkit=True in run_fastapi() - Add agency.chatkit_demo() method mirroring copilot_demo() pattern - Ship bundled React frontend (Vite + @openai/chatkit-react) for demo - Implement in-memory thread storage for multi-turn conversation persistence - Add 36 unit tests for ChatkitAdapter, 5 integration tests for endpoint - Update FastAPI integration docs with ChatKit section and architecture diagram
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
- Add ChatKit web component CDN script to index.html (required for web component to initialize) - Simplify chatkit_handlers.py to stateless design (users handle persistence via hooks_override) - Create dedicated chatkit-integration.mdx docs page - Move ChatKit content from fastapi-integration.mdx to new page
24f3f55 to
255e09a
Compare
ArtemShatokhin
left a comment
There was a problem hiding this comment.
Along with the bug below, here's a list of bugs found during QA:
- Selecting chat from history leads this error:
Failed to load conversation.
We encountered an error. Reload to try again.
-
Chats are not isolated. In new chats agents still retain memory from previous ones.
-
Chat hangs after agent uses send_message or handoff tool.
-
Tool calls are not shown
| """Create a thread.item.done event to finalize an item.""" | ||
| return { | ||
| "type": "thread.item.done", | ||
| "item_id": item_id, |
There was a problem hiding this comment.
done event expects "item" field and not "item_id":
https://openai.github.io/chatkit-python/api/chatkit/types/#chatkit.types.ThreadItemDoneEvent
| item: dict[str, Any] = { | ||
| "id": item_id, | ||
| "type": item_type, | ||
| "created_at": int(time.time()), |
There was a problem hiding this comment.
Some messages can include other fields, like thread_id:
https://openai.github.io/chatkit-python/api/chatkit/types/#chatkit.types.AssistantMessageItem
https://openai.github.io/chatkit-python/api/chatkit/types/#chatkit.types.ThreadItemBase
|
This PR is stale because it has been open for 10 days with no activity. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ) | ||
|
|
||
| agency = agency_factory() | ||
| await attach_persistent_mcp_servers(agency) | ||
|
|
There was a problem hiding this comment.
ChatKit endpoint drops thread history
The new ChatKit FastAPI handler builds a thread_id for each request but then creates the agency via agency_factory() without supplying the usual load_threads_callback/save_threads_callback, so the thread state is never loaded or persisted. Follow‑up ChatKit calls such as threads.add_user_message therefore start with an empty conversation regardless of the thread_id, breaking multi‑turn continuity and persistence compared to the existing AG‑UI endpoints that pass the callbacks. This affects any ChatKit client sending multiple messages in the same thread.
Useful? React with 👍 / 👎.
| Agency Swarm ChatKit Demo | ||
|
|
||
| This example demonstrates the ChatKit UI capabilities of Agency Swarm v1.x. | ||
| Sets up a frontend and backend server for the OpenAI ChatKit UI chat demo. | ||
| """ |
There was a problem hiding this comment.
ChatKit demo script is syntactically invalid
The new examples/interactive/chatkit_demo.py lacks an opening triple‑quote before the intended module docstring, leaving bare words (Agency Swarm ChatKit Demo) at the top level. Importing or running the demo raises a SyntaxError before any code executes, so the documented ChatKit demo cannot be launched.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| thread_id = params.get("thread_id") or str(uuid.uuid4()) | ||
| run_id = str(uuid.uuid4()) | ||
| is_new_thread = req_type == "threads.create" | ||
|
|
||
| # Extract user message | ||
| user_message = "" | ||
| user_input = params.get("input", {}) | ||
| if user_input: | ||
| content_list = user_input.get("content", []) | ||
| for part in content_list: | ||
| if isinstance(part, dict): | ||
| if part.get("type") == "input_text": | ||
| user_message += part.get("text", "") | ||
| elif "text" in part: | ||
| user_message += part.get("text", "") | ||
|
|
||
| if not user_message: | ||
| return Response( | ||
| content=json.dumps({"thread_id": thread_id, "status": "no_input"}), | ||
| media_type="application/json", | ||
| ) | ||
|
|
||
| agency = agency_factory() | ||
| await attach_persistent_mcp_servers(agency) |
There was a problem hiding this comment.
Load prior messages for ChatKit thread requests
ChatKit requests send a thread_id, but the handler always builds a fresh agency without passing any load_threads_callback or previously saved messages, so the thread manager starts empty on every call. This makes multi-turn ChatKit sessions stateless: sending threads.add_user_message or reloading a thread will ignore earlier conversation state even if persistence callbacks are configured. Consider loading history (e.g., via ChatkitAdapter.chatkit_messages_to_chat_history or the agency’s persistence hooks) before streaming the response.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 4 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
This PR is being reviewed by Cursor Bugbot
Details
Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
| return { | ||
| "type": "thread.item.done", | ||
| "item_id": item_id, | ||
| } |
There was a problem hiding this comment.
Done event uses wrong field name item_id
High Severity
The _create_item_done_event method returns {"type": "thread.item.done", "item_id": item_id} but the ChatKit API expects {"type": "thread.item.done", "item": {...}} with the full item object. The handler in chatkit_handlers.py line 144 correctly uses "item": user_item, but this adapter method uses the wrong field name. This was also flagged in the PR discussion by @ArtemShatokhin.
| return { | ||
| "type": "thread.item.added", | ||
| "item": item, | ||
| } |
There was a problem hiding this comment.
Items missing required thread_id field
Medium Severity
The _create_item_added_event method creates items without including thread_id, though the ChatKit API types (ThreadItemBase, AssistantMessageItem) expect items to include this field. The thread_id parameter is available in openai_to_chatkit_events but isn't passed down to item creation methods. The handler correctly includes thread_id in user items (line 139), but assistant message and tool call items created by the adapter lack it.
| from pathlib import Path | ||
|
|
||
| # Add the src directory to the path so we can import agency_swarm | ||
| sys.path.insert(0, str(Path(__file__).parent.parent / "src")) |
There was a problem hiding this comment.
Example file has incorrect module path calculation
Medium Severity
The path Path(__file__).parent.parent / "src" resolves to examples/src instead of the root src/ directory. Since this file is in examples/interactive/, it needs .parent.parent.parent / "src" (three levels up) to reach the repository root where src/ is located.
| agency_name = agency_name.replace(" ", "_") | ||
|
|
||
| # Set environment variables for the Vite frontend | ||
| os.environ["CHATKIT_BACKEND_URL"] = f"http://{host}:{port}" |
There was a problem hiding this comment.
Backend URL uses bind address instead of routable address
High Severity
The CHATKIT_BACKEND_URL environment variable is set to f"http://{host}:{port}", which becomes http://0.0.0.0:8000 when using the default host. The Vite proxy uses this URL as its target, but 0.0.0.0 is a bind address (meaning "all interfaces"), not a routable destination address. The proxy target needs to be 127.0.0.1 or localhost to successfully connect to the backend, regardless of what address the backend binds to.
|
This PR is stale because it has been open for 10 days with no activity. |


Note
Medium Risk
Adds a new public FastAPI endpoint and SSE streaming translation layer, which could impact API surface and streaming correctness, but is gated behind
enable_chatkitand covered by new tests.Overview
Adds first-class OpenAI ChatKit support:
run_fastapi(..., enable_chatkit=True)now exposes aPOST /{agency_name}/chatkitendpoint that streams ChatKit-compatible SSE events.Introduces a
ChatkitAdapterto translate Agents SDK streaming events (assistant text deltas and tool calls/outputs) into ChatKitThreadStreamEventobjects, plus achatkit_demo()launcher onAgencythat starts FastAPI + a bundled Vite/React ChatKit frontend.Updates docs/navigation to document the new integration and demo, expands packaging config to ship the new frontend assets, and adds unit + integration tests covering adapter conversions and endpoint behavior.
Written by Cursor Bugbot for commit 255e09a. This will update automatically on new commits. Configure here.