Verified missing OpenCode Zen environment variable.
UnderstandAdded OpenCode Zen to environment variables table and CLI options.
EditCommitted and pushed documentation updates.
Cleanup@packages/coding-agent/README.md Option 2: Environment variables
doesn't contain reference to OpenCode Zen
The user is pointing out that the README.md in packages/coding-agent doesn't have a reference to OpenCode Zen in the environment variables section. Let me read that file to see what's there and understand the context.
The user is pointing out that in the "Option 2: Environment variables" table, there's no entry for OpenCode Zen (which is the zai provider based on the code). Let me look at what's in the table and what should be there.
Looking at the table:
| Provider | Auth Key | Environment Variable ||----------|--------------|---------------------|| Anthropic | `anthropic` | `ANTHROPIC_API_KEY` || OpenAI | `openai` | `OPENAI_API_KEY` || Google | `google` | `GEMINI_API_KEY` || Mistral | `mistral` | `MISTRAL_API_KEY` || Groq | `groq` | `GROQ_API_KEY` || Cerebras | `cerebras` | `CEREBRAS_API_KEY` || xAI | `xai` | `XAI_API_KEY` || OpenRouter | `openrouter` | `OPENROUTER_API_KEY` || Vercel AI Gateway | `vercel-ai-gateway` | `AI_GATEWAY_API_KEY` || ZAI | `zai` | `ZAI_API_KEY` || MiniMax | `minimax` | `MINIMAX_API_KEY` || MiniMax (China) | `minimax-cn` | `MINIMAX_CN_API_KEY` |So there's ZAI listed already. But the user is asking about "OpenCode Zen". Let me check what that is. It could be a separate provider or maybe the same as ZAI. Let me look at the ai package to understand what providers we have.
Let me check packages/ai to understand what OpenCode Zen is.
Let me check what OpenCode Zen is in the ai package:
>grep -r "opencode\|zen" packages/ai/src --include="*.ts" -i | head -50packages/ai/src/providers/openai-completions.ts: provider === "opencode" ||
packages/ai/src/providers/openai-completions.ts: baseUrl.includes("opencode.ai");
packages/ai/src/stream.ts: opencode: "OPENCODE_API_KEY",
packages/ai/src/types.ts: | "opencode";
packages/ai/src/models.generated.ts: "opencode": {
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",
packages/ai/src/models.generated.ts: baseUrl: "https://opencode.ai/zen/v1",
packages/ai/src/models.generated.ts: provider: "opencode",The provider is called opencode (OpenCode Zen) with the env var OPENCODE_API_KEY. It's missing from the README table. I also notice the table currently has "ZAI" and "zai" listed, let me verify if that still exists or if it was replaced by opencode.
>grep -r "zai\|ZAI" packages/ai/src --include="*.ts" | head -20packages/ai/src/providers/openai-completions.ts: if (compat.thinkingFormat === "zai" && model.reasoning) {
packages/ai/src/providers/openai-completions.ts: const isZai = provider === "zai" || baseUrl.includes("api.z.ai");
packages/ai/src/providers/openai-completions.ts: thinkingFormat: isZai ? "zai" : "openai",
packages/ai/src/stream.ts: zai: "ZAI_API_KEY",
packages/ai/src/types.ts: | "zai"
packages/ai/src/types.ts: /** Format for reasoning/thinking parameter. "openai" uses reasoning_effort, "zai" uses thinking: { type: "enabled" }. Default: "openai". */
packages/ai/src/types.ts: thinkingFormat?: "openai" | "zai";
packages/ai/src/models.generated.ts: "zai-glm-4.6": {
packages/ai/src/models.generated.ts: id: "zai-glm-4.6",
packages/ai/src/models.generated.ts: "zai-glm-4.7": {
packages/ai/src/models.generated.ts: id: "zai-glm-4.7",
packages/ai/src/models.generated.ts: "zai/glm-4.5": {
packages/ai/src/models.generated.ts: id: "zai/glm-4.5",
packages/ai/src/models.generated.ts: "zai/glm-4.5-air": {
packages/ai/src/models.generated.ts: id: "zai/glm-4.5-air",
packages/ai/src/models.generated.ts: "zai/glm-4.5v": {
packages/ai/src/models.generated.ts: id: "zai/glm-4.5v",
packages/ai/src/models.generated.ts: "zai/glm-4.6": {
packages/ai/src/models.generated.ts: id: "zai/glm-4.6",
packages/ai/src/models.generated.ts: "zai/glm-4.6v": {So both zai and opencode are valid providers. The README currently has ZAI but is missing OpenCode. I need to add OpenCode Zen to the environment variables table.
Looking at the current table in the README:
| Provider | Auth Key | Environment Variable |
|---|---|---|
| Anthropic | anthropic | ANTHROPIC_API_KEY |
| OpenAI | openai | OPENAI_API_KEY |
google | GEMINI_API_KEY | |
| Mistral | mistral | MISTRAL_API_KEY |
| Groq | groq | GROQ_API_KEY |
| Cerebras | cerebras | CEREBRAS_API_KEY |
| xAI | xai | XAI_API_KEY |
| OpenRouter | openrouter | OPENROUTER_API_KEY |
| Vercel AI Gateway | vercel-ai-gateway | AI_GATEWAY_API_KEY |
| ZAI | zai | ZAI_API_KEY |
| MiniMax | minimax | MINIMAX_API_KEY |
| MiniMax (China) | minimax-cn | MINIMAX_CN_API_KEY |
I need to add:
| OpenCode Zen | opencode | OPENCODE_API_KEY |
I should put it in alphabetical order or near ZAI. Let me add it after ZAI since they're somewhat related.
You're right. The opencode provider (OpenCode Zen) is missing from the environment variables table. The env var is OPENCODE_API_KEY based on packages/ai/src/stream.ts.
I should also add opencode to the list of providers in the CLI Reference section under --provider. Let me check if it's there.
Let me also check if opencode is listed in the CLI Reference provider list:
>grep -n "Provider.*anthropic.*openai" packages/coding-agent/README.md1173:| `--provider <name>` | Provider: `anthropic`, `openai`, `openai-codex`, `google`, `google-vertex`, `amazon-bedrock`, `mistral`, `xai`, `groq`, `cerebras`, `openrouter`, `vercel-ai-gateway`, `zai`, `minimax`, `minimax-cn`, `github-copilot`, `google-gemini-cli`, `google-antigravity`, or custom |The CLI Reference provider list also doesn't include opencode. I should add it there too.
Also missing from the --provider list. Let me fix that:
Good. I've added OpenCode Zen to both the environment variables table and the CLI Reference provider list. The user was pointing out a documentation gap and I've addressed it.
Added OpenCode Zen (opencode / OPENCODE_API_KEY) to:
--provider CLI option listis the env var correct?
Let me double-check the env var in the ai package source code.
>grep -A5 "getEnvApiKey" packages/ai/src/stream.ts | head -30export function getEnvApiKey(provider: KnownProvider): string | undefined;
export function getEnvApiKey(provider: string): string | undefined;
export function getEnvApiKey(provider: any): string | undefined {
// Fall back to environment variables
if (provider === "github-copilot") {
return process.env.COPILOT_GITHUB_TOKEN || process.env.GH_TOKEN || process.env.GITHUB_TOKEN;
}
--
const apiKey = options?.apiKey || getEnvApiKey(model.provider);
if (!apiKey) {
throw new Error(`No API key for provider: ${model.provider}`);
}
const providerOptions = { ...options, apiKey };
--
const apiKey = options?.apiKey || getEnvApiKey(model.provider);
if (!apiKey) {
throw new Error(`No API key for provider: ${model.provider}`);
}
const providerOptions = mapOptionsForApi(model, options, apiKey);Let me look for the envVarMap or similar structure that defines the env vars for each provider.
>grep -B5 -A30 "opencode.*OPENCODE\|envVar\|const.*env" packages/ai/src/stream.ts | head -60let cachedVertexAdcCredentialsExists: boolean | null = null;
function hasVertexAdcCredentials(): boolean {
if (cachedVertexAdcCredentialsExists === null) {
// Check GOOGLE_APPLICATION_CREDENTIALS env var first (standard way)
const gacPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
if (gacPath) {
cachedVertexAdcCredentialsExists = existsSync(gacPath);
} else {
// Fall back to default ADC path (lazy evaluation)
cachedVertexAdcCredentialsExists = existsSync(
join(homedir(), ".config", "gcloud", "application_default_credentials.json"),
);
}
}
return cachedVertexAdcCredentialsExists;
}
/**
* Get API key for provider from known environment variables, e.g. OPENAI_API_KEY.
*
* Will not return API keys for providers that require OAuth tokens.
*/
export function getEnvApiKey(provider: KnownProvider): string | undefined;
export function getEnvApiKey(provider: string): string | undefined;
export function getEnvApiKey(provider: any): string | undefined {
// Fall back to environment variables
if (provider === "github-copilot") {
return process.env.COPILOT_GITHUB_TOKEN || process.env.GH_TOKEN || process.env.GITHUB_TOKEN;
}
// ANTHROPIC_OAUTH_TOKEN takes precedence over ANTHROPIC_API_KEY
if (provider === "anthropic") {
return process.env.ANTHROPIC_OAUTH_TOKEN || process.env.ANTHROPIC_API_KEY;
}
// Vertex AI uses Application Default Credentials, not API keys.
// Auth is configured via `gcloud auth application-default login`.
if (provider === "google-vertex") {
const hasCredentials = hasVertexAdcCredentials();
const hasProject = !!(process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT);
const hasLocation = !!process.env.GOOGLE_CLOUD_LOCATION;
if (hasCredentials && hasProject && hasLocation) {
return "<authenticated>";
}
}
if (provider === "amazon-bedrock") {
// Amazon Bedrock supports multiple credential sources:
// 1. AWS_PROFILE - named profile from ~/.aws/credentials
// 2. AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY - standard IAM keys
// 3. AWS_BEARER_TOKEN_BEDROCK - Bedrock API keys (bearer token)
if (
process.env.AWS_PROFILE ||
(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ||
process.env.AWS_BEARER_TOKEN_BEDROCK
) {
return "<authenticated>";
}Let me find the mapping that defines env vars like OPENCODE_API_KEY.
>grep -A50 "envVarMap\|const.*map.*=" packages/ai/src/stream.ts | grep -A30 "opencode\|zai\|anthropic" | head -40(no output)Let me look for how the env var is determined for opencode.
>grep -n "OPENCODE" packages/ai/src/stream.ts104: opencode: "OPENCODE_API_KEY",The env var is OPENCODE_API_KEY. Let me see the full context to make sure I got it right.
Yes, the env var is OPENCODE_API_KEY. The README update I made is correct.
Yes, it's correct. Line 104 in packages/ai/src/stream.ts:
opencode: "OPENCODE_API_KEY",commit and push
The user wants me to commit and push the changes. Let me do that.
>cd /Users/badlogic/workspaces/pi-mono && git add -A && git commit -m "docs: add OpenCode Zen to provider lists in coding-agent README" && git pushRunning formatting, linting, and type checking...
> pi-monorepo@0.0.3 check
> biome check --write . && tsgo --noEmit && npm run check -w @mariozechner/pi-web-ui
Checked 406 files in 366ms. No fixes applied.
> @mariozechner/pi-web-ui@0.47.0 check
> biome check --write . && tsc --noEmit && cd example && biome check --write . && tsc --noEmit
Checked 73 files in 47ms. No fixes applied.
Checked 3 files in 8ms. No fixes applied.
✅ All pre-commit checks passed!
[main ffdc8d68] docs: add OpenCode Zen to provider lists in coding-agent README
3 files changed, 433 insertions(+), 349 deletions(-)
To https://github.com/badlogic/pi-mono.git
75628e0c..ffdc8d68 main -> mainDone. The changes have been committed and pushed.
Done. Added OpenCode Zen (opencode / OPENCODE_API_KEY) to the environment variables table and --provider CLI option list.
| Provider | Auth Key | Environment Variable ||----------|--------------|---------------------|| Anthropic | `anthropic` | `ANTHROPIC_API_KEY` || OpenAI | `openai` | `OPENAI_API_KEY` || Google | `google` | `GEMINI_API_KEY` || Mistral | `mistral` | `MISTRAL_API_KEY` || Groq | `groq` | `GROQ_API_KEY` || Cerebras | `cerebras` | `CEREBRAS_API_KEY` || xAI | `xai` | `XAI_API_KEY` || OpenRouter | `openrouter` | `OPENROUTER_API_KEY` || Vercel AI Gateway | `vercel-ai-gateway` | `AI_GATEWAY_API_KEY` || ZAI | `zai` | `ZAI_API_KEY` || MiniMax | `minimax` | `MINIMAX_API_KEY` || MiniMax (China) | `minimax-cn` | `MINIMAX_CN_API_KEY` |opencode: "OPENCODE_API_KEY",