Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,8 @@ function MainApp() {
activeWorkspace,
models,
selectedModelId,
effort: resolvedEffort,
collaborationMode: collaborationModePayload,
addWorktreeAgent,
connectWorkspace,
startThreadForWorkspace,
Expand Down Expand Up @@ -1962,6 +1964,13 @@ function MainApp() {
modelSelections={workspaceModelSelections}
onToggleModel={toggleWorkspaceModelSelection}
onModelCountChange={setWorkspaceModelCount}
collaborationModes={collaborationModes}
selectedCollaborationModeId={selectedCollaborationModeId}
onSelectCollaborationMode={setSelectedCollaborationModeId}
reasoningOptions={reasoningOptions}
selectedEffort={selectedEffort}
onSelectEffort={setSelectedEffort}
reasoningSupported={reasoningSupported}
error={workspaceRunError}
isSubmitting={workspaceRunSubmitting}
activeWorkspaceId={activeWorkspaceId}
Expand Down
92 changes: 92 additions & 0 deletions src/features/workspaces/components/WorkspaceHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
SkillOption,
WorkspaceInfo,
} from "../../../types";
import { formatCollaborationModeLabel } from "../../../utils/collaborationModes";
import { ComposerInput } from "../../composer/components/ComposerInput";
import { useComposerImages } from "../../composer/hooks/useComposerImages";
import { useComposerAutocompleteState } from "../../composer/hooks/useComposerAutocompleteState";
Expand Down Expand Up @@ -56,6 +57,13 @@ type WorkspaceHomeProps = {
modelSelections: Record<string, number>;
onToggleModel: (modelId: string) => void;
onModelCountChange: (modelId: string, count: number) => void;
collaborationModes: { id: string; label: string }[];
selectedCollaborationModeId: string | null;
onSelectCollaborationMode: (id: string | null) => void;
reasoningOptions: string[];
selectedEffort: string | null;
onSelectEffort: (effort: string) => void;
reasoningSupported: boolean;
error: string | null;
isSubmitting: boolean;
activeWorkspaceId: string | null;
Expand Down Expand Up @@ -124,6 +132,13 @@ export function WorkspaceHome({
modelSelections,
onToggleModel,
onModelCountChange,
collaborationModes,
selectedCollaborationModeId,
onSelectCollaborationMode,
reasoningOptions,
selectedEffort,
onSelectEffort,
reasoningSupported,
error,
isSubmitting,
activeWorkspaceId,
Expand Down Expand Up @@ -671,6 +686,83 @@ export function WorkspaceHome({
</div>
)}
</div>
{collaborationModes.length > 0 && (
<div className="composer-select-wrap workspace-home-control">
<div className="open-app-button">
<span className="composer-icon" aria-hidden>
<svg viewBox="0 0 24 24" fill="none">
<path
d="M7 7h10M7 12h6M7 17h8"
stroke="currentColor"
strokeWidth="1.4"
strokeLinecap="round"
/>
</svg>
</span>
<select
className="composer-select composer-select--model"
aria-label="Collaboration mode"
value={selectedCollaborationModeId ?? ""}
onChange={(event) =>
onSelectCollaborationMode(event.target.value || null)
}
disabled={isSubmitting}
>
{collaborationModes.map((mode) => (
<option key={mode.id} value={mode.id}>
{formatCollaborationModeLabel(mode.label || mode.id)}
</option>
))}
</select>
</div>
</div>
)}
<div className="composer-select-wrap workspace-home-control">
<div className="open-app-button">
<span className="composer-icon" aria-hidden>
<svg viewBox="0 0 24 24" fill="none">
<path
d="M8.5 4.5a3.5 3.5 0 0 0-3.46 4.03A4 4 0 0 0 6 16.5h2"
stroke="currentColor"
strokeWidth="1.4"
strokeLinecap="round"
/>
<path
d="M15.5 4.5a3.5 3.5 0 0 1 3.46 4.03A4 4 0 0 1 18 16.5h-2"
stroke="currentColor"
strokeWidth="1.4"
strokeLinecap="round"
/>
<path
d="M9 12h6"
stroke="currentColor"
strokeWidth="1.4"
strokeLinecap="round"
/>
<path
d="M12 12v6"
stroke="currentColor"
strokeWidth="1.4"
strokeLinecap="round"
/>
</svg>
</span>
<select
className="composer-select composer-select--effort"
aria-label="Thinking mode"
value={selectedEffort ?? ""}
onChange={(event) => onSelectEffort(event.target.value)}
disabled={isSubmitting || !reasoningSupported}
>
{reasoningOptions.length === 0 && <option value="">Default</option>}
{reasoningOptions.map((effortOption) => (
<option key={effortOption} value={effortOption}>
{effortOption}
</option>
))}
</select>
</div>
</div>
</div>

<div className="workspace-home-agent">
Expand Down
17 changes: 15 additions & 2 deletions src/features/workspaces/hooks/useWorkspaceHome.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ type UseWorkspaceHomeOptions = {
activeWorkspace: WorkspaceInfo | null;
models: ModelOption[];
selectedModelId: string | null;
effort?: string | null;
collaborationMode?: Record<string, unknown> | null;
addWorktreeAgent: (
workspace: WorkspaceInfo,
branch: string,
Expand All @@ -45,7 +47,11 @@ type UseWorkspaceHomeOptions = {
threadId: string,
text: string,
images?: string[],
options?: { model?: string | null; effort?: string | null },
options?: {
model?: string | null;
effort?: string | null;
collaborationMode?: Record<string, unknown> | null;
},
) => Promise<void>;
onWorktreeCreated?: (worktree: WorkspaceInfo, parent: WorkspaceInfo) => Promise<void> | void;
};
Expand Down Expand Up @@ -166,6 +172,8 @@ export function useWorkspaceHome({
activeWorkspace,
models,
selectedModelId,
effort = null,
collaborationMode = null,
addWorktreeAgent,
connectWorkspace,
startThreadForWorkspace,
Expand Down Expand Up @@ -469,6 +477,8 @@ export function useWorkspaceHome({
: null;
await sendUserMessageToThread(activeWorkspace, threadId, prompt, images, {
model: localModel,
effort,
collaborationMode,
});
const model =
selectedModelId ? modelLookup.get(selectedModelId) ?? null : null;
Expand Down Expand Up @@ -530,7 +540,8 @@ export function useWorkspaceHome({
images,
{
model: selection.model?.model ?? selection.modelId,
effort: null,
effort,
collaborationMode,
},
);
instances.push({
Expand Down Expand Up @@ -580,9 +591,11 @@ export function useWorkspaceHome({
activeWorkspace,
activeWorkspaceId,
addWorktreeAgent,
collaborationMode,
connectWorkspace,
onWorktreeCreated,
draft,
effort,
isSubmitting,
modelLookup,
modelSelections,
Expand Down
8 changes: 4 additions & 4 deletions src/styles/composer.css
Original file line number Diff line number Diff line change
Expand Up @@ -661,13 +661,13 @@
}

.composer-select--collab {
width: 88px;
max-width: 88px;
width: 110px;
max-width: 110px;
}

.composer-select--effort {
width: 60px;
max-width: 60px;
width: 80px;
max-width: 80px;
}

.composer-select--approval {
Expand Down
23 changes: 23 additions & 0 deletions src/styles/workspace-home.css
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,29 @@
background: var(--surface-card);
}

.workspace-home-control.composer-select-wrap {
padding: 0;
background: transparent;
border: none;
border-radius: 0;
min-height: 0;
}

.workspace-home-control.composer-select-wrap .open-app-button {
border-color: var(--border-muted);
background: var(--surface-card);
border-radius: 10px;
padding: 6px 10px;
align-items: center;
gap: 6px;
}

.workspace-home-control.composer-select-wrap .composer-select {
font-size: 12px;
color: var(--text-stronger);
padding: 0 16px 0 0;
}

.workspace-home-dropdown {
left: 0;
}
Expand Down