diff --git a/canvas/src/components/CreateWorkspaceDialog.tsx b/canvas/src/components/CreateWorkspaceDialog.tsx index 265c48824..c5849a534 100644 --- a/canvas/src/components/CreateWorkspaceDialog.tsx +++ b/canvas/src/components/CreateWorkspaceDialog.tsx @@ -33,6 +33,8 @@ interface HermesProvider { models: string[]; } +const DEFAULT_CREATE_MODEL = "anthropic:claude-opus-4-7"; + // All providers supported by Hermes runtime via providers.resolve_provider(). // `defaultModel` is the slug injected into the workspace provision request // when the user picks this provider โ€” template-hermes's derive-provider.sh @@ -68,6 +70,10 @@ export function CreateWorkspaceButton() { const [creating, setCreating] = useState(false); const [error, setError] = useState(null); const [workspaces, setWorkspaces] = useState([]); + const [displayEnabled, setDisplayEnabled] = useState(false); + const [displayInstanceType, setDisplayInstanceType] = useState("t3.xlarge"); + const [displayRootGB, setDisplayRootGB] = useState("80"); + const [displayResolution, setDisplayResolution] = useState("1920x1080"); // Templates fetched from /api/templates โ€” drives the dynamic provider // filter below. Same data source ConfigTab uses (PR #2454). When the // selected template declares `runtime_config.providers` in its @@ -223,6 +229,10 @@ export function CreateWorkspaceButton() { setParentId(""); setBudgetLimit(""); setError(null); + setDisplayEnabled(false); + setDisplayInstanceType("t3.xlarge"); + setDisplayRootGB("80"); + setDisplayResolution("1920x1080"); setHermesProvider("anthropic"); setExternalRuntime("external"); setHermesApiKey(""); @@ -264,6 +274,8 @@ export function CreateWorkspaceButton() { const parsedBudget = budgetLimit.trim() ? parseFloat(budgetLimit) : null; + const [displayWidth, displayHeight] = displayResolution.split("x").map((v) => parseInt(v, 10)); + const parsedRootGB = parseInt(displayRootGB, 10); const createResp = await api.post<{ id: string; @@ -280,6 +292,21 @@ export function CreateWorkspaceButton() { tier, parent_id: parentId || undefined, budget_limit: parsedBudget, + ...(!isExternal && !isHermes ? { model: DEFAULT_CREATE_MODEL } : {}), + ...(displayEnabled + ? { + compute: { + instance_type: displayInstanceType, + volume: { root_gb: Number.isFinite(parsedRootGB) ? parsedRootGB : 80 }, + display: { + mode: "desktop-control", + protocol: "novnc", + width: Number.isFinite(displayWidth) ? displayWidth : 1920, + height: Number.isFinite(displayHeight) ? displayHeight : 1080, + }, + }, + } + : {}), canvas: { x: Math.random() * 400 + 100, y: Math.random() * 300 + 100 }, // Runtime=external flips the backend into awaiting-agent mode: // no container provisioning, token minted, connection payload @@ -447,6 +474,73 @@ export function CreateWorkspaceButton() { + {!isExternal && ( +
+
+ Container Config +
+ + {displayEnabled && ( +
+
+ + +
+
+ + setDisplayRootGB(e.target.value)} + className="w-full bg-surface-card/60 border border-line/50 rounded-lg px-2 py-2 text-xs text-ink focus:outline-none focus:border-accent/60 focus:ring-1 focus:ring-accent/20 transition-colors" + /> +
+
+ + +
+
+ )} +
+ )} +