From e234e8d18f1610dfffd78bec4735fb81a008237d Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Wed, 24 Dec 2025 01:52:59 +0100 Subject: [PATCH] Allow startup without API keys, fixes #288 --- packages/coding-agent/CHANGELOG.md | 1 + .../coding-agent/src/core/agent-session.ts | 3 +- packages/coding-agent/src/core/sdk.ts | 19 +++++----- unset-env.sh | 37 +++++++++++++++++++ 4 files changed, 48 insertions(+), 12 deletions(-) create mode 100755 unset-env.sh diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index a5005565..1c7c7f55 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fixed +- **Allow startup without API keys**: Interactive mode no longer throws when no API keys are configured. Users can now start the agent and use `/login` to authenticate. ([#288](https://github.com/badlogic/pi-mono/issues/288)) - **`--system-prompt` file path support**: The `--system-prompt` argument now correctly resolves file paths (like `--append-system-prompt` already did). ([#287](https://github.com/badlogic/pi-mono/pull/287) by [@scutifer](https://github.com/scutifer)) ## [0.27.2] - 2025-12-23 diff --git a/packages/coding-agent/src/core/agent-session.ts b/packages/coding-agent/src/core/agent-session.ts index 3fa1617e..883b27ad 100644 --- a/packages/coding-agent/src/core/agent-session.ts +++ b/packages/coding-agent/src/core/agent-session.ts @@ -422,8 +422,7 @@ export class AgentSession { if (!this.model) { throw new Error( "No model selected.\n\n" + - "Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.)\n" + - `or create ${getModelsPath()}\n\n` + + `Use /login, set an API key environment variable or create ${getModelsPath()}\n\n` + "Then use /model to select a model.", ); } diff --git a/packages/coding-agent/src/core/sdk.ts b/packages/coding-agent/src/core/sdk.ts index 9d13786b..2bbb6e81 100644 --- a/packages/coding-agent/src/core/sdk.ts +++ b/packages/coding-agent/src/core/sdk.ts @@ -517,15 +517,14 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {} if (!model) { const available = await discoverAvailableModels(); time("discoverAvailableModels"); - if (available.length === 0) { - throw new Error( - "No models available. Set an API key environment variable " + - "(ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.) or provide a model explicitly.", - ); - } - model = available[0]; - if (modelFallbackMessage) { - modelFallbackMessage += `. Using ${model.provider}/${model.id}`; + if (available.length > 0) { + model = available[0]; + if (modelFallbackMessage) { + modelFallbackMessage += `. Using ${model.provider}/${model.id}`; + } + } else { + // No models available - set message so user knows to /login or configure keys + modelFallbackMessage = "No models available. Use /login or set an API key environment variable."; } } @@ -542,7 +541,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {} } // Clamp to model capabilities - if (!model.reasoning) { + if (!model || !model.reasoning) { thinkingLevel = "off"; } diff --git a/unset-env.sh b/unset-env.sh new file mode 100755 index 00000000..ea4a11a6 --- /dev/null +++ b/unset-env.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# Unset all provider API keys + +unset OPENAI_API_KEY +unset OPENAI_KEY +unset ANTHROPIC_API_KEY +unset ANTHROPIC_OAUTH_TOKEN +unset GROQ_API_KEY +unset OPENROUTER_API_KEY +unset GEMINI_API_KEY +unset CEREBRAS_API_KEY +unset HF_TOKEN +unset XAI_API_KEY +unset ZAI_API_KEY +unset EXA_API_KEY +unset MINIMAX_API_KEY +unset MISTRAL_API_KEY +unset ELEVENLABS_API_KEY +unset BRAVE_API_KEY + +echo "Unset the following provider API keys:" +echo " OPENAI_API_KEY" +echo " OPENAI_KEY" +echo " ANTHROPIC_API_KEY" +echo " ANTHROPIC_OAUTH_TOKEN" +echo " GROQ_API_KEY" +echo " OPENROUTER_API_KEY" +echo " GEMINI_API_KEY" +echo " CEREBRAS_API_KEY" +echo " HF_TOKEN" +echo " XAI_API_KEY" +echo " ZAI_API_KEY" +echo " EXA_API_KEY" +echo " MINIMAX_API_KEY" +echo " MISTRAL_API_KEY" +echo " ELEVENLABS_API_KEY" +echo " BRAVE_API_KEY"