-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add direct sessions API for browser/CLI clients #92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add HTTP+SSE endpoints for direct API access without platform adapters: - POST /api/sessions - Create session with working directory and provider - GET /api/sessions/:id/events - SSE stream for agent output - POST /api/sessions/:id/messages - Send messages to agent - POST /api/sessions/:id/approve - Respond to tool approvals - GET /api/sessions/:id - Get session status - DELETE /api/sessions/:id - End session Key changes: - New API platform adapter with response renderer for SSE broadcasting - Session token authentication (reuses existing worker token infrastructure) - API key support for cloud deployments (PEERBOT_API_KEY env var) - Local mode allows sessions without API key - Add platformMetadata to ThreadResponsePayload for routing - Add touchSession to ISessionManager interface - Add status field to ThreadSession This enables browser extensions and CLI tools to interact with peerbot directly without going through Slack/WhatsApp/Discord.
|
Claude finished @buremba's task —— View job Pull Request Review: Direct Sessions API
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8f78d87b39
ℹ️ 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".
| const token = authHeader.substring(7); | ||
| const tokenData = verifyWorkerToken(token); | ||
|
|
||
| if (!tokenData) { | ||
| res.status(401).json({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enforce session token expiry instead of trusting token age
The API advertises a 24‑hour session token TTL, but authenticateSession only calls verifyWorkerToken and never checks tokenData.timestamp against TOKEN_EXPIRATION_MS. That means any token remains valid as long as the session still exists (and touchSession can keep that alive), so a leaked token can be reused well past the advertised expiry. Consider rejecting tokens whose timestamp is older than the intended TTL, or aligning the response with actual enforcement.
Useful? React with 👍 / 👎.
| const body = req.body as CreateSessionRequest; | ||
| const { | ||
| workingDirectory = process.cwd(), | ||
| provider = "claude", | ||
| userId = `api-${randomUUID().slice(0, 8)}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Persist workingDirectory/provider for API sessions
The create‑session API accepts workingDirectory and provider but these values are never stored on the session or forwarded to the worker. As a result, clients cannot actually influence the agent working directory or provider despite the documented request body, and the worker will continue to use defaults. If these inputs are intended to work, they need to be persisted (e.g., on the session or in agentOptions) and consumed when building worker context.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Performed full review of abc195f...8f78d87
Analysis
-
Scaling Issue: The in-memory Map for SSE connections won't work in multi-instance deployments, as messages routed to one instance won't reach clients connected to different instances. A distributed solution like Redis pub/sub is needed.
-
Security Vulnerabilities: Multiple security concerns exist - timing-attack vulnerable API key validation, no rate limiting, lack of session hijacking protection, and missing CORS headers for browser extensions.
-
Token Management Weaknesses: Session tokens have 24-hour expiration but lack revocation mechanisms, leaving compromised tokens valid until they expire naturally.
-
Race Conditions: Several potential race conditions exist in SSE cleanup, session deletion with in-flight messages, and concurrent session creation requests.
-
Resource Management: No session limits per user could lead to resource exhaustion, and the implementation may be missing proper session activity tracking.
Tip
Help
Slash Commands:
/review- Request a full code review/review latest- Review only changes since the last review/describe- Generate PR description. This will update the PR body or issue comment depending on your configuration/help- Get help with Mesa commands and configuration options
0 files reviewed | 1 comments | Edit Agent Settings • Read Docs
| } | ||
|
|
||
| // Active SSE connections by session ID | ||
| const sseConnections = new Map<string, Set<Response>>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The in-memory Map for SSE connections will not work correctly in multi-instance deployments. If the gateway is horizontally scaled, worker responses may be routed to a different gateway instance than the one holding the client's SSE connection, causing messages to be lost. Consider using Redis pub/sub or a similar distributed mechanism to broadcast messages across all gateway instances.
Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: buremba/peerbot#92
File: packages/gateway/src/routes/public/sessions.ts#L62
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.
Feedback:
The in-memory Map for SSE connections will not work correctly in multi-instance deployments. If the gateway is horizontally scaled, worker responses may be routed to a different gateway instance than the one holding the client's SSE connection, causing messages to be lost. Consider using Redis pub/sub or a similar distributed mechanism to broadcast messages across all gateway instances.
Mesa DescriptionTL;DRAdds HTTP+SSE API endpoints for direct client access (browser extensions, CLI tools) without platform adapters, enabling real-time agent interaction via standard HTTP requests and server-sent events. What changed?
Description generated by Mesa. Update settings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cursor Bugbot has reviewed your changes and found 2 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
You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
| provider = "claude", | ||
| userId = `api-${randomUUID().slice(0, 8)}`, | ||
| spaceId, | ||
| } = body; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Session parameters workingDirectory and provider are ignored
High Severity
The workingDirectory and provider parameters are extracted from the session creation request but never stored in the session, encoded in the token, or passed to the worker when messages are enqueued. The agentOptions object passed to queueProducer.enqueueMessage() is empty {}, unlike other platforms (e.g., Slack) that pass model, timeoutMinutes, and other agent configuration. This breaks the documented API contract where clients expect to configure agent behavior via these parameters.
Additional Locations (1)
| */ | ||
| async renderInteraction(): Promise<void> { | ||
| // Interactions are handled via SSE in the response renderer | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tool approval requests never reach SSE clients
High Severity
The ApiPlatform never subscribes to interaction:created events from InteractionService, unlike Slack and WhatsApp platforms which both listen for this event to render tool approvals. The renderInteraction() method is a no-op with a comment claiming "Interactions are handled via SSE in the response renderer," but ApiResponseRenderer has no method to handle interactions. This means when a worker requests tool approval, the SSE client never receives the tool_approval event documented in the PR, breaking the entire approval flow.
Additional Locations (1)
|
@claude read alll reviews and fix all consolidate and simplify without breaking, delete dead code. push code |
|
Claude finished @buremba's task —— View job Claude finished @buremba's task —— View job Direct Sessions API - Critical Issues Fixed ✅I've successfully addressed all the critical security and functionality issues identified in the reviews. 🔧 Fixed IssuesCritical Security Fixes:
Functional Bugs Resolved:
Scalability & Reliability Improvements:
📁 Files Modified
🚀 Ready for UseThe API is now secure and functional with proper:
All changes have been committed and pushed to the |
…sions API - Fix API key validation (prevent bypass with any key) - Enforce session token expiration (24h TTL) - Store and use session parameters (workingDirectory, provider) - Fix tool approval flow by subscribing to interaction:created events - Add connection limits and better cleanup for SSE connections - Improve error handling and input validation - Document scaling limitations for multi-instance deployments Co-authored-by: Burak Emre Kabakcı <buremba@users.noreply.github.com>

Summary
Add HTTP+SSE endpoints for direct API access without platform adapters (Slack, WhatsApp, etc.):
POST /api/sessions- Create session with working directory and providerGET /api/sessions/:id/events- SSE stream for agent outputPOST /api/sessions/:id/messages- Send messages to agentPOST /api/sessions/:id/approve- Respond to tool approvalsGET /api/sessions/:id- Get session statusDELETE /api/sessions/:id- End sessionKey Changes
PEERBOT_API_KEYenv var)platformMetadatatoThreadResponsePayloadfor routingtouchSessiontoISessionManagerinterfacestatusfield toThreadSessionUse Case
This enables browser extensions and CLI tools to interact with peerbot directly:
Test Plan
connectedeventoutput,completeevents from worker/approveendpointNote
Enables direct API access (no Slack/WhatsApp) via HTTP + SSE for browser/CLI clients.
ApiPlatformandApiResponseRendererbroadcast worker output over SSE (packages/gateway/src/api/*)sessionsroutes:POST /api/sessions,GET /api/sessions/:id/events,POST /api/sessions/:id/messages,POST /api/sessions/:id/approve,GET/DELETE /api/sessions/:id(routes/public/sessions.ts)ApiPlatformin gateway (cli/gateway.ts)ThreadResponsePayloadwithplatformMetadataand updatesplatformcomment (infrastructure/queue/types.ts)statusandtouchSession(session.ts); sessions authenticated via worker tokens, optionalX-API-Keyfor cloud modeWritten by Cursor Bugbot for commit 8f78d87. This will update automatically on new commits. Configure here.