-
Notifications
You must be signed in to change notification settings - Fork 11
🤖 feat: AI-generated workspace creation on first message #500
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
base: main
Are you sure you want to change the base?
Conversation
- Add workspaceTitleGenerator service using Vercel AI SDK - Generate human-readable titles and git-safe branch names - Add sendFirstMessage IPC handler that creates workspace automatically - Add ProjectSelector and FirstMessageInput components for empty state - Update App.tsx to show project selector when no workspace exists - Gracefully fall back to timestamp names if AI generation fails Users can now type a message and hit send to create a workspace with an AI-generated title and branch name based on their message. Generated with `cmux`
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.
ℹ️ 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".
The 'name' field is used throughout the backend to compute filesystem paths (e.g., runtime.getWorkspacePath uses metadata.name as the directory). Storing the AI-generated title there would break path resolution. Solution: - Add optional 'displayName' field to WorkspaceMetadata - Store git-safe branch name in 'name' (used for paths) - Store human-readable title in 'displayName' (used for display) - UI prefers displayName over name when rendering This maintains backward compatibility - existing workspaces without displayName continue to work, showing the branch name as before. Generated with `cmux`
FirstMessageInput was using useSendMessageOptions which internally uses useThinking hook, causing 'useThinking must be used within a ThinkingProvider' error in E2E tests when empty state was rendered. Instead, directly use useModelLRU to get the most recent model without requiring context providers. Generated with `cmux`
Instead of showing a project selector dropdown when no workspace is selected, we now: - If only one project exists: Show FirstMessageInput immediately - If multiple projects exist: Show welcome message asking user to select/create workspace via sidebar This is cleaner UX - users already interact with projects via the left sidebar, no need for duplicate selection UI. Generated with `cmux`
| invokeIPC(IPC_CHANNELS.WORKSPACE_RENAME, workspaceId, newName), | ||
| fork: (sourceWorkspaceId, newName) => | ||
| invokeIPC(IPC_CHANNELS.WORKSPACE_FORK, sourceWorkspaceId, newName), | ||
| sendMessage: (workspaceId, message, options) => |
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.
can we make workspaceId optional here? Then we reduce duplication in the IPC.
| const inputRef = useRef<HTMLTextAreaElement>(null); | ||
|
|
||
| // Get most recent model from LRU (no workspace-specific model yet) | ||
| const { recentModels } = useModelLRU(); |
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.
we should probably use the standard useSendMessage options
| * Select a cheap model for title generation | ||
| * Prefers Haiku > GPT-4o-mini > Gemini Flash > null | ||
| */ | ||
| function selectCheapModel(config: Config): LanguageModel | null { |
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.
I think we should use the model as provided to send message, bc, for example, this might break those that using a custom BaseURL with unexpected model names available. Also, we want to minimize the number of places we need to manually update when a new model comes out.
| } | ||
| /> | ||
| </ErrorBoundary> | ||
| ) : projects.size === 1 ? ( |
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.
Don't we wanna show this as the default path when creating a new workspace in a project? Like, even when you have existing workspaces / projects?
Overview
Make workspace creation automatic and invisible. When no workspace exists, typing and sending a message creates one with an AI-generated title and branch name based on the message content.
Changes
Backend
workspaceTitleGenerator.ts- Generates workspace titles and branch names using AIsendFirstMessage- Creates workspace and sends message in one operationFrontend
ProjectSelector- Dropdown for selecting project (auto-hides if single project)FirstMessageInput- Simplified input for first messageApp.tsxto render empty state with project selector + chat inputUser Flow
Before:
After:
Key Design Decisions
Title vs Branch Name:
user-auth-rest-api)Graceful Degradation:
Chat ${timestamp}Backwards Compatibility:
nameequals branch name (unchanged)Testing
Generated with
cmux