From 9bcfab386368501d57ca2175f7a5985d017dc11d Mon Sep 17 00:00:00 2001 From: Rony Kelner Date: Mon, 29 Dec 2025 11:54:09 +0900 Subject: [PATCH] make mom fetch apiKey from `authStorage` instead of env vars --- packages/mom/README.md | 23 +++++++++++++++++++---- packages/mom/src/agent.ts | 22 +++++++++++++--------- packages/mom/src/main.ts | 6 ++---- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/packages/mom/README.md b/packages/mom/README.md index 63d3488e..2515b019 100644 --- a/packages/mom/README.md +++ b/packages/mom/README.md @@ -64,8 +64,7 @@ export MOM_SLACK_APP_TOKEN=xapp-... export MOM_SLACK_BOT_TOKEN=xoxb-... # Option 1: Anthropic API key export ANTHROPIC_API_KEY=sk-ant-... -# Option 2: Anthropic Pro/Max (use `claude setup-token`) -export ANTHROPIC_OAUTH_TOKEN=sk-ant-... +# Option 2: use /login command in pi agent, then copy/link auth.json to ~/.pi/mom/ # Create Docker sandbox (recommended) docker run -d \ @@ -96,8 +95,24 @@ Options: |----------|-------------| | `MOM_SLACK_APP_TOKEN` | Slack app-level token (xapp-...) | | `MOM_SLACK_BOT_TOKEN` | Slack bot token (xoxb-...) | -| `ANTHROPIC_API_KEY` | Anthropic API key | -| `ANTHROPIC_OAUTH_TOKEN` | Alternative: Anthropic OAuth token | +| `ANTHROPIC_API_KEY` | (Optional) Anthropic API key | + +## Authentication + +Mom needs credentials for Anthropic API. The options to set it are: + +1. **Environment Variable** +```bash +export ANTHROPIC_API_KEY=sk-ant-... +``` + +2. **OAuth Login via coding agent command** (Recommended for Claude Pro/Max) + +- run interactive coding agent session: `npx @mariozechner/pi-coding-agent` +- enter `/login` command + - choose "Anthropic" provider + - follow instructions in the browser +- link `auth.json` to mom: `ln -s ~/.pi/agent/auth.json ~/.pi/mom/auth.json` ## How Mom Works diff --git a/packages/mom/src/agent.ts b/packages/mom/src/agent.ts index 848cb870..b5cb6333 100644 --- a/packages/mom/src/agent.ts +++ b/packages/mom/src/agent.ts @@ -39,10 +39,14 @@ export interface AgentRunner { abort(): void; } -function getAnthropicApiKey(): string { - const key = process.env.ANTHROPIC_OAUTH_TOKEN || process.env.ANTHROPIC_API_KEY; +async function getAnthropicApiKey(authStorage: AuthStorage): Promise { + const key = await authStorage.getApiKey("anthropic"); if (!key) { - throw new Error("ANTHROPIC_OAUTH_TOKEN or ANTHROPIC_API_KEY must be set"); + throw new Error( + "No API key found for anthropic.\n\n" + + "Set an API key environment variable, or use /login with Anthropic and link to auth.json from " + + join(homedir(), ".pi", "mom", "auth.json"), + ); } return key; } @@ -417,6 +421,11 @@ function createRunner(sandboxConfig: SandboxConfig, channelId: string, channelDi const sessionManager = new MomSessionManager(channelDir); const settingsManager = new MomSettingsManager(join(channelDir, "..")); + // Create AuthStorage and ModelRegistry + // Auth stored outside workspace so agent can't access it + const authStorage = new AuthStorage(join(homedir(), ".pi", "mom", "auth.json")); + const modelRegistry = new ModelRegistry(authStorage); + // Create agent const agent = new Agent({ initialState: { @@ -427,7 +436,7 @@ function createRunner(sandboxConfig: SandboxConfig, channelId: string, channelDi }, messageTransformer, transport: new ProviderTransport({ - getApiKey: async () => getAnthropicApiKey(), + getApiKey: async () => getAnthropicApiKey(authStorage), }), }); @@ -438,11 +447,6 @@ function createRunner(sandboxConfig: SandboxConfig, channelId: string, channelDi log.logInfo(`[${channelId}] Loaded ${loadedSession.messages.length} messages from context.jsonl`); } - // Create AuthStorage and ModelRegistry for AgentSession - // Auth stored outside workspace so agent can't access it - const authStorage = new AuthStorage(join(homedir(), ".pi", "mom", "auth.json")); - const modelRegistry = new ModelRegistry(authStorage); - // Create AgentSession wrapper const session = new AgentSession({ agent, diff --git a/packages/mom/src/main.ts b/packages/mom/src/main.ts index 1e97867c..292d31e3 100644 --- a/packages/mom/src/main.ts +++ b/packages/mom/src/main.ts @@ -16,8 +16,6 @@ import { ChannelStore } from "./store.js"; const MOM_SLACK_APP_TOKEN = process.env.MOM_SLACK_APP_TOKEN; const MOM_SLACK_BOT_TOKEN = process.env.MOM_SLACK_BOT_TOKEN; -const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; -const ANTHROPIC_OAUTH_TOKEN = process.env.ANTHROPIC_OAUTH_TOKEN; interface ParsedArgs { workingDir?: string; @@ -74,8 +72,8 @@ if (!parsedArgs.workingDir) { const { workingDir, sandbox } = { workingDir: parsedArgs.workingDir, sandbox: parsedArgs.sandbox }; -if (!MOM_SLACK_APP_TOKEN || !MOM_SLACK_BOT_TOKEN || (!ANTHROPIC_API_KEY && !ANTHROPIC_OAUTH_TOKEN)) { - console.error("Missing env: MOM_SLACK_APP_TOKEN, MOM_SLACK_BOT_TOKEN, ANTHROPIC_API_KEY or ANTHROPIC_OAUTH_TOKEN"); +if (!MOM_SLACK_APP_TOKEN || !MOM_SLACK_BOT_TOKEN) { + console.error("Missing env: MOM_SLACK_APP_TOKEN, MOM_SLACK_BOT_TOKEN"); process.exit(1); }