Skip to content
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

refactor: move session initialization from WebSocket to REST API #5493

Draft
wants to merge 32 commits into
base: main
Choose a base branch
from

Conversation

rbren
Copy link
Collaborator

@rbren rbren commented Dec 9, 2024

Currently the frontend starts a session by connecting to the websocket and then sending an INIT event with initialization data. This PR changes that to use a REST API endpoint instead.

Changes

  • Add POST /api/conversation endpoint for session initialization
  • Update frontend to use new endpoint instead of WebSocket INIT event
  • Remove WebSocket INIT event handling from backend
  • Move all conversation-related routes (e.g. list-files and submit-feedback) to /api/conversation/{id}/...
  • Main frontend now includes conversation ID in the URL
  • Removed all the JWT token encryption logic
    • SIDs (now conversation IDs) are no longer secret
    • This PR CANNOT BE MERGED until [Refactor]: Changes to Github Authentication #5371 is merged, and a new auth mechanism is put in place here, at least for multi-tenant
    • TBD if we need auth for OSS, since everything is on OSS--would love to hear any opinions here

Resolves #4281


To run this PR locally, use the following command:

docker run -it --rm   -p 3000:3000   -v /var/run/docker.sock:/var/run/docker.sock   --add-host host.docker.internal:host-gateway   -e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:8c36835-nikolaik   --name openhands-app-8c36835   docker.all-hands.dev/all-hands-ai/openhands:8c36835

openhands-agent and others added 30 commits December 9, 2024 21:59
- Add POST /api/conversation endpoint for session initialization
- Update frontend to use new endpoint instead of WebSocket INIT event
- Remove WebSocket INIT event handling from backend
… and rename middleware

- Rename AttachSessionMiddleware to AttachConversationMiddleware
- Move protected endpoints under /api/conversation/{convo_id}/...
- Keep POST /api/conversation endpoint separate (without middleware)
- Add conversation context and update frontend to handle new URL structure
- Add session initialization in ChatInterface when sending first message
- Add loading state while initializing session
- Disable chat input during session initialization
- Move session initialization to TaskForm where users start new conversations
- Add loading state while initializing session
- Revert ChatInterface changes as it shouldn't handle session initialization
- Create new session.py router for POST /api/conversation endpoint
- Move session initialization code to new router
- Fix middleware application to use protected_router instead of main router
- Add comment to clarify middleware application
- Remove session initialization from WsClientProvider
- Add conversation ID to websocket path
- Update backend to validate conversation ID in websocket path
- Store conversation ID in socket session data
- Move ConversationProvider to root component to fix useConversation hook
- Remove ConversationProvider from App component
- Fix TypeScript errors in build
- Update route path to match API structure
- Update TaskForm to navigate to new URL
- Update App component to get conversation ID from URL
- Update all components that referenced /app path
- Generate conversation ID using UUID in backend
- Return conversation_id in session init response
- Update frontend to use conversation_id from response
- Remove JWT token parsing in frontend
- Use existing session ID logic from main branch
- Add auth data to websocket connection
- Add token and GitHub token validation in websocket connect handler
- Verify conversation ID matches token in websocket connection
Comment on lines +76 to +97
try {
setIsInitializing(true);
// Initialize the session before navigating
const { conversation_id: conversationId } = await OpenHands.initSession({
githubToken: gitHubToken || undefined,
selectedRepository: selectedRepository || undefined,
args: settings || undefined,
});

navigate("/app");
posthog.capture("initial_query_submitted", {
entry_point: "task_form",
query_character_length: q.length,
has_repository: !!selectedRepository,
has_files: files.length > 0,
});

navigate(`/conversation/${conversationId}`);
} catch (error) {
// TODO: Show error toast
} finally {
setIsInitializing(false);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -173,7 +150,7 @@ export function WsClientProvider({
sio.off("connect_failed", handleError);
sio.off("disconnect", handleDisconnect);
};
}, [enabled, token, ghToken, selectedRepository]);
}, [enabled, ghToken, selectedRepository]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't we want the effect to trigger when conversationId changes instead of token?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it is misplaced

if (token) navigate("/app");
// If we have a token but no conversation ID, we need to initialize a new session
// This will be handled by the TaskForm
}, [location.pathname]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might as well remove the entire useEffect statement

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Store session ID as a URI param instead of in-memory
3 participants