@exreve/exk 1.0.27 → 1.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -134,16 +134,22 @@ const PROVIDERS = {
134
134
  models: ['glm-5.1', 'glm-4.7', 'glm-4.5-air'],
135
135
  },
136
136
  minimax: {
137
- apiKey: process.env.MINIMAX_API_KEY || '',
137
+ apiKey: '', // Populated from ai-config.json (served by backend)
138
138
  baseUrl: 'https://api.minimax.io/anthropic',
139
139
  models: ['MiniMax-M2.7', 'MiniMax-M2.7-highspeed'],
140
140
  },
141
141
  };
142
142
  /** Resolve which provider to use based on model name or explicit provider ID.
143
- * 1. If explicit providerId is given and has an API key configured, use that provider.
144
- * 2. Else if model name matches one of a provider's model list, use that provider.
145
- * 3. Else fall back to zai (default). */
143
+ * 1. Populate provider API keys from ai-config.json (served by backend).
144
+ * 2. If explicit providerId is given and has an API key configured, use that provider.
145
+ * 3. Else if model name matches one of a provider's model list, use that provider.
146
+ * 4. Else fall back to zai (default). */
146
147
  function resolveProvider(model, providerId) {
148
+ // Populate provider keys from ai-config.json
149
+ const aiConfig = loadAiConfig();
150
+ PROVIDERS.minimax.apiKey = aiConfig.minimaxApiKey || process.env.MINIMAX_API_KEY || '';
151
+ if (!PROVIDERS.zai.apiKey)
152
+ PROVIDERS.zai.apiKey = aiConfig.apiKey || '';
147
153
  // 1. Explicit provider selection
148
154
  if (providerId && PROVIDERS[providerId]?.apiKey) {
149
155
  const provider = PROVIDERS[providerId];
@@ -156,7 +162,6 @@ function resolveProvider(model, providerId) {
156
162
  }
157
163
  }
158
164
  // 3. Fallback: use ai-config.json credentials (z.ai default)
159
- const aiConfig = loadAiConfig();
160
165
  return {
161
166
  provider: 'zai',
162
167
  apiKey: aiConfig.apiKey,
@@ -172,12 +177,18 @@ function loadAiConfig() {
172
177
  const baseUrl = typeof config.baseUrl === 'string' ? config.baseUrl.trim() : '';
173
178
  const model = typeof config.model === 'string' && config.model.trim() ? config.model.trim() : DEFAULT_AI_MODEL;
174
179
  const proxy = typeof config.proxy === 'string' ? config.proxy.trim() : '';
175
- return { apiKey, baseUrl, model, proxy };
180
+ const minimaxApiKey = typeof config.minimaxApiKey === 'string' ? config.minimaxApiKey.trim() : '';
181
+ const openrouterApiKey = typeof config.openrouterApiKey === 'string' ? config.openrouterApiKey.trim() : '';
182
+ return { apiKey, baseUrl, model, proxy, minimaxApiKey, openrouterApiKey };
176
183
  }
177
184
  catch {
178
- return { apiKey: '', baseUrl: '', model: DEFAULT_AI_MODEL, proxy: '' };
185
+ return { apiKey: '', baseUrl: '', model: DEFAULT_AI_MODEL, proxy: '', minimaxApiKey: '', openrouterApiKey: '' };
179
186
  }
180
187
  }
188
+ /** Get OpenRouter API key from ai-config.json (served by backend) */
189
+ export function getOpenrouterApiKey() {
190
+ return loadAiConfig().openrouterApiKey || process.env.OPENROUTER_API_KEY || '';
191
+ }
181
192
  /** Create (or reuse) an empty directory to use as CLAUDE_CONFIG_DIR.
182
193
  * Setting this prevents the spawned Claude CLI from reading ~/.claude/settings.json,
183
194
  * which may contain env.ANTHROPIC_BASE_URL pointing to z.ai and would override our
@@ -10,6 +10,7 @@ import { z } from 'zod';
10
10
  import * as fs from 'fs';
11
11
  import * as path from 'path';
12
12
  import * as os from 'os';
13
+ import { getOpenrouterApiKey } from './agentSession.js';
13
14
  /**
14
15
  * Create a tool for the user-choice module
15
16
  */
@@ -99,7 +100,7 @@ function createAnalyzeImageTool(attachmentDir) {
99
100
  image_path: z.string().describe('Path to the image file to analyze (can be relative to working directory, e.g. "attachments/photo.jpg")'),
100
101
  question: z.string().describe('Question or instruction about the image. Be specific about what you want to know.'),
101
102
  }, async (args) => {
102
- const apiKey = process.env.OPENROUTER_API_KEY || '';
103
+ const apiKey = getOpenrouterApiKey();
103
104
  if (!apiKey) {
104
105
  return { content: [{ type: 'text', text: 'Error: OPENROUTER_API_KEY not configured.' }], isError: true };
105
106
  }
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exreve/exk",
3
- "version": "1.0.27",
3
+ "version": "1.0.29",
4
4
  "description": "exk - Control Claude CLI with voice and programmable interfaces",
5
5
  "type": "module",
6
6
  "bin": {