From 1713b57d75c491ebc4c130f331e78be4157d8022 Mon Sep 17 00:00:00 2001 From: James Olds <12104969+oldsj@users.noreply.github.com> Date: Fri, 16 Jan 2026 12:34:40 -0500 Subject: [PATCH] Improve session spawning UX and dev environment - Update main thread prompt to acknowledge and spawn sessions immediately (no more asking for confirmation) - Configure dev to use opus for main thread, haiku for background agents - Add CLAUDE_WORKER_MODEL env var to test config for consistency - Fix dev-reset to clean up mainloop-session-* namespaces Co-Authored-By: Claude Opus 4.5 --- backend/src/mainloop/services/chat_handler.py | 15 ++++++--------- k8s/apps/mainloop/overlays/dev/backend-patch.yaml | 4 +++- .../mainloop/overlays/test/backend-patch.yaml | 2 ++ scripts/kind/reset-data.sh | 8 +++++++- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/backend/src/mainloop/services/chat_handler.py b/backend/src/mainloop/services/chat_handler.py index 2fb7133..74d6c1b 100644 --- a/backend/src/mainloop/services/chat_handler.py +++ b/backend/src/mainloop/services/chat_handler.py @@ -48,11 +48,10 @@ def build_chat_system_prompt(recent_repos: list[str] | None = None) -> str: - Planning or brainstorming that needs multiple steps - Any work that can run in the background -Usage: -1. For code work: suggest a recent repo or ask for the GitHub repository URL -2. Always get explicit confirmation before spawning a session -3. Call spawn_session with just a title (and repo_url for code work) - - The session automatically receives the user's original request from the conversation +IMPORTANT - When spawning a session: +1. IMMEDIATELY acknowledge and spawn - don't ask for confirmation +2. Respond with a brief acknowledgment like "On it - spawning a session to [task summary]" +3. Then call spawn_session with the title (and repo_url for code work) Do NOT use spawn_session for: - Answering simple questions @@ -66,14 +65,12 @@ def build_chat_system_prompt(recent_repos: list[str] | None = None) -> str: The user has recently worked with these repositories: {repos_list} -If the request involves code work, suggest using one of these repos. For example: -"I can spawn a session to work on this. Should I use {recent_repos[0]}?" +If the request involves code work and includes a repo URL, use it. Otherwise use the most relevant recent repo. """ else: base_prompt += """ -If the request involves code work, ask for the GitHub repo URL like: -"I can spawn a session to work on this. Would you like me to proceed? Please provide the GitHub repo URL." +If the request involves code work but no repo is provided, ask for the GitHub repo URL. """ return base_prompt diff --git a/k8s/apps/mainloop/overlays/dev/backend-patch.yaml b/k8s/apps/mainloop/overlays/dev/backend-patch.yaml index 3b86aff..31bd1b2 100644 --- a/k8s/apps/mainloop/overlays/dev/backend-patch.yaml +++ b/k8s/apps/mainloop/overlays/dev/backend-patch.yaml @@ -42,8 +42,10 @@ spec: env: - name: IS_TEST_ENV value: 'true' - # Use cheapest/fastest model for dev + # Use opus for main thread, haiku for background agents - name: CLAUDE_MODEL + value: opus + - name: CLAUDE_WORKER_MODEL value: haiku # Mock GitHub API - name: USE_MOCK_GITHUB diff --git a/k8s/apps/mainloop/overlays/test/backend-patch.yaml b/k8s/apps/mainloop/overlays/test/backend-patch.yaml index 2851e87..c9414f2 100644 --- a/k8s/apps/mainloop/overlays/test/backend-patch.yaml +++ b/k8s/apps/mainloop/overlays/test/backend-patch.yaml @@ -20,6 +20,8 @@ spec: # Use cheapest/fastest model for tests - name: CLAUDE_MODEL value: haiku + - name: CLAUDE_WORKER_MODEL + value: haiku # Mock GitHub API (no real GitHub calls in tests) - name: USE_MOCK_GITHUB value: 'true' diff --git a/scripts/kind/reset-data.sh b/scripts/kind/reset-data.sh index 457298f..fe992c2 100755 --- a/scripts/kind/reset-data.sh +++ b/scripts/kind/reset-data.sh @@ -8,12 +8,18 @@ CONTEXT="kind-${CLUSTER_NAME}" echo "=== Using context: ${CONTEXT} ===" echo "=== Cleaning up k8s task namespaces ===" -# Delete all task-* namespaces (created by worker workflows) +# Delete all task-* namespaces (legacy worker workflows) for ns in $(kubectl --context "${CONTEXT}" get ns -o name 2>/dev/null | grep "^namespace/task-" | cut -d/ -f2); do echo "Deleting namespace: ${ns}" kubectl --context "${CONTEXT}" delete ns "${ns}" --wait=false 2>/dev/null || true done +# Delete all mainloop-session-* namespaces (session workers) +for ns in $(kubectl --context "${CONTEXT}" get ns -o name 2>/dev/null | grep "^namespace/mainloop-session-" | cut -d/ -f2); do + echo "Deleting namespace: ${ns}" + kubectl --context "${CONTEXT}" delete ns "${ns}" --wait=false 2>/dev/null || true +done + echo "=== Resetting database ===" # Drop both public and dbos schemas to fully reset state kubectl --context "${CONTEXT}" exec -n mainloop postgres-0 -- psql -U mainloop -d mainloop -c "