From 17320bf7cd6b5a61cddf73577a7fbe3fdb4482c7 Mon Sep 17 00:00:00 2001 From: Roland Tannous Date: Fri, 15 May 2026 22:11:07 +0400 Subject: [PATCH] studio/chat: always pre-create OpenAI containers via frontend Drops the TTL-based gate on the chat-adapter's lazy-create path so every code-execution container the user ever sees in the picker has a friendly English-word name. The backend's container_auto fallback stays as a safety net (used only if the POST /v1/containers call fails); in practice that branch should be rare. --- .../src/features/chat/api/chat-adapter.ts | 69 ++++++++++--------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/studio/frontend/src/features/chat/api/chat-adapter.ts b/studio/frontend/src/features/chat/api/chat-adapter.ts index d091c14a90..b39cb4ed83 100644 --- a/studio/frontend/src/features/chat/api/chat-adapter.ts +++ b/studio/frontend/src/features/chat/api/chat-adapter.ts @@ -1037,44 +1037,47 @@ export function createOpenAIStreamAdapter(): ChatModelAdapter { /* fall through to lazy-create below */ } } - // Lazy pre-create when the user has configured a non- - // default TTL and there's no inherited container: we - // POST /v1/containers ourselves with that TTL so the - // auto-create-per-thread path actually honors the - // user's preference. The default 20-min container_auto - // path stays as-is (no extra round trip) when TTL is - // unset or matches OpenAI's default. + // Lazy pre-create when there's no inherited container. + // We always POST /v1/containers ourselves (rather than + // letting the backend send container_auto) so every + // container shows up in the picker with a friendly + // English-word name and the user's configured TTL. + // Falls back to container_auto only if the POST fails + // — keeps the chat moving in that case. if ( !openaiCodeExecContainerId && externalProvider.providerType === "openai" ) { const ttl = externalProvider.openaiContainerTtlMinutes; - if (typeof ttl === "number" && ttl >= 1 && ttl !== 20) { - try { - const created = await createOpenAIContainer( - { - apiKey: externalApiKey, - baseUrl: externalProvider.baseUrl || null, - }, - { - // Friendly English-word name so the container - // is human-readable in the picker list (e.g. - // "kestrel-3f9c") instead of a thread-id slug. - name: pickFriendlyContainerName(), - ttlMinutes: ttl, - }, - ); - openaiCodeExecContainerId = created.id; - void db.threads - .update(resolvedThreadId, { - openaiCodeExecContainerId: created.id, - }) - .catch(() => {}); - } catch { - // Fall back to container_auto on failure — keeps - // the chat moving; the next turn can retry. - openaiCodeExecContainerId = null; - } + const ttlToUse = + typeof ttl === "number" && ttl >= 1 ? ttl : 20; + try { + const created = await createOpenAIContainer( + { + apiKey: externalApiKey, + baseUrl: externalProvider.baseUrl || null, + }, + { + // Friendly English-word name so the container + // is human-readable in the picker list (e.g. + // "kestrel-3f9c") instead of a thread-id slug + // or OpenAI's default blank name. + name: pickFriendlyContainerName(), + ttlMinutes: ttlToUse, + }, + ); + openaiCodeExecContainerId = created.id; + void db.threads + .update(resolvedThreadId, { + openaiCodeExecContainerId: created.id, + }) + .catch(() => {}); + } catch { + // Fall back to backend's container_auto path on + // failure — keeps the chat moving; the next turn + // can retry. The auto-created container will be + // unnamed, but the chat doesn't break. + openaiCodeExecContainerId = null; } } }