pleumrouter 0.5.40 → 0.5.41

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pleumrouter",
3
- "version": "0.5.40",
3
+ "version": "0.5.41",
4
4
  "description": "Official PleumRouter terminal CLI — launch any coding agent against PleumRouter.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -284,6 +284,9 @@ export const ES = {
284
284
  "Anthropic official models": "Continuar con modelos oficiales de Anthropic",
285
285
  "OpenAI official models": "Continuar con modelos oficiales de OpenAI",
286
286
  "Antigravity default models": "Continuar con modelos predeterminados de Antigravity",
287
+ "Gemini official models": "Continuar con modelos oficiales de Gemini",
288
+ "Qwen official models": "Continuar con modelos oficiales de Qwen",
289
+ "Copilot official models": "Continuar con modelos oficiales de Copilot",
287
290
  "Choose models inside the agent": "Elegir modelo dentro del agente",
288
291
  "Choose my model (beta)": "Elegir mi modelo (beta)",
289
292
  "Select a PleumRouter coding model": "Elegir un modelo de código de PleumRouter",
@@ -284,6 +284,9 @@ export const JA = {
284
284
  "Anthropic official models": "Anthropic 公式モデルで続行",
285
285
  "OpenAI official models": "OpenAI 公式モデルで続行",
286
286
  "Antigravity default models": "Antigravity 標準モデルで続行",
287
+ "Gemini official models": "Gemini 公式モデルで続行",
288
+ "Qwen official models": "Qwen 公式モデルで続行",
289
+ "Copilot official models": "Copilot 公式モデルで続行",
287
290
  "Choose models inside the agent": "エージェント内でモデルを選択",
288
291
  "Choose my model (beta)": "モデルを自分で選ぶ (beta)",
289
292
  "Select a PleumRouter coding model": "PleumRouter のコーディングモデルを選択",
@@ -343,6 +343,9 @@ export const KO = {
343
343
  "Anthropic official models": "Anthropic 공식 모델로 진행",
344
344
  "OpenAI official models": "OpenAI 공식 모델로 진행",
345
345
  "Antigravity default models": "Antigravity 기본 모델로 진행",
346
+ "Gemini official models": "Gemini 공식 모델로 진행",
347
+ "Qwen official models": "Qwen 공식 모델로 진행",
348
+ "Copilot official models": "Copilot 공식 모델로 진행",
346
349
  "Choose models inside the agent": "에이전트 안에서 모델 선택",
347
350
  "Choose my model (beta)": "모델 내가 custom하기(beta)",
348
351
  "Select a PleumRouter coding model": "PleumRouter 코딩 모델 선택",
@@ -284,6 +284,9 @@ export const ZH = {
284
284
  "Anthropic official models": "使用 Anthropic 官方模型",
285
285
  "OpenAI official models": "使用 OpenAI 官方模型",
286
286
  "Antigravity default models": "使用 Antigravity 默认模型",
287
+ "Gemini official models": "使用 Gemini 官方模型",
288
+ "Qwen official models": "使用 Qwen 官方模型",
289
+ "Copilot official models": "使用 Copilot 官方模型",
287
290
  "Choose models inside the agent": "在代理中选择模型",
288
291
  "Choose my model (beta)": "自选模型 (beta)",
289
292
  "Select a PleumRouter coding model": "选择 PleumRouter 编程模型",
package/src/menu.mjs CHANGED
@@ -19,6 +19,16 @@ import { parseInstallCommand, runInstallCommand, printManualInstall } from "./in
19
19
  // 값은 t() 키(영어 원문)만 담는다 — 여기서 t()를 호출하면 모듈 로드 시점(import 1회)에
20
20
  // 번역이 확정돼, 같은 프로세스 안에서 언어를 바꿔도(Settings) 이 설명들만 예전 언어로 남는다.
21
21
  // 실제 번역은 소비 지점(buildAgentItems)에서 매번 t()를 호출해 얻는다.
22
+ const AGENT_MODE_TOOLS = new Set(["claude", "codex", "agy", "gemini", "qwen", "copilot"]);
23
+ const NATIVE_MODE_LABEL = {
24
+ claude: "Anthropic official models",
25
+ codex: "OpenAI official models",
26
+ agy: "Antigravity default models",
27
+ gemini: "Gemini official models",
28
+ qwen: "Qwen official models",
29
+ copilot: "Copilot official models",
30
+ };
31
+
22
32
  const AGENT_DESC = {
23
33
  claude: "Anthropic's coding agent — supports subagents",
24
34
  codex: "OpenAI's coding agent",
@@ -193,10 +203,8 @@ export async function pickModelFor(item, defaultModel, { supported = () => true,
193
203
  }
194
204
 
195
205
  export function agentModeItems(tool) {
196
- const native = tool === "claude" ? "Anthropic official models"
197
- : tool === "codex" ? "OpenAI official models" : "Antigravity default models";
198
206
  return [
199
- { id: "native", title: t(native), desc: t("Choose models inside the agent") },
207
+ { id: "native", title: t(NATIVE_MODE_LABEL[tool]), desc: t("Choose models inside the agent") },
200
208
  { id: "custom", title: t("Choose my model (beta)"), desc: t("Select a PleumRouter coding model") },
201
209
  ];
202
210
  }
@@ -363,7 +371,7 @@ export async function runList(items, { header, footer, initialCursor = 0 } = {})
363
371
  else if (key.type === "down" || (key.type === "char" && key.value === "j")) move(1);
364
372
  else if (key.type === "right" || (key.type === "char" && key.value === "l")) {
365
373
  const it = items[cursor];
366
- if (!it.tool || it.manual || ["claude", "codex", "agy", "opencode"].includes(it.tool)) continue;
374
+ if (!it.tool || it.manual || it.tool === "opencode" || AGENT_MODE_TOOLS.has(it.tool)) continue;
367
375
  return void (await configure(it));
368
376
  } else continue;
369
377
  dirty = true;
@@ -432,7 +440,7 @@ export async function runAgentMenu({ loop = false } = {}) {
432
440
  }
433
441
 
434
442
  let model = agentPicked.model;
435
- if (["claude", "codex", "agy"].includes(agentItem.tool)) {
443
+ if (AGENT_MODE_TOOLS.has(agentItem.tool)) {
436
444
  const mode = await select(agentModeItems(agentItem.tool), {
437
445
  message: agentItem.title,
438
446
  formatItem: (x) => `${x.title} ${style.dim(x.desc)}`,
package/src/recipes.mjs CHANGED
@@ -2,6 +2,17 @@ import { ROOT, V1 } from "./config.mjs";
2
2
 
3
3
  export const DEFAULT_MODEL = "deepseek-ai/DeepSeek-V4.1-Flash";
4
4
 
5
+ // 미지정은 공식/기본 모드. 문자열·custom 객체만 모델 하나를 고정한다.
6
+ function chosenModel(selection) {
7
+ if (selection == null || (typeof selection === "object" && selection.mode === "native")) return undefined;
8
+ const raw = typeof selection === "object" ? selection.model : selection;
9
+ return raw ? String(raw) : undefined;
10
+ }
11
+
12
+ const nativeOrCustom = (explicit) => explicit && typeof explicit === "object"
13
+ ? explicit
14
+ : explicit ? { mode: "custom", model: explicit } : { mode: "native" };
15
+
5
16
  export const CORE_MODELS = [
6
17
  "deepseek-ai/DeepSeek-V4.1-Flash",
7
18
  "claude-sonnet-5",
@@ -35,9 +46,7 @@ export const RECIPES = {
35
46
  bin: "claude",
36
47
  type: "env",
37
48
  unsetEnv: ["ANTHROPIC_API_KEY", "ANTHROPIC_CUSTOM_MODEL_OPTION", "ANTHROPIC_CUSTOM_MODEL_OPTION_NAME", "ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION"],
38
- resolveModel: (explicit) => explicit && typeof explicit === "object"
39
- ? explicit
40
- : explicit ? { mode: "custom", model: explicit } : { mode: "native" },
49
+ resolveModel: nativeOrCustom,
41
50
  install: "npm i -g @anthropic-ai/claude-code",
42
51
  // 앱 랭킹 귀속 메타 — 백엔드 featured_agents / UA fallback과 동기화.
43
52
  attribution: {
@@ -117,9 +126,7 @@ export const RECIPES = {
117
126
  label: "Antigravity CLI",
118
127
  bin: "agy",
119
128
  type: "agy-settings",
120
- resolveModel: (explicit) => explicit && typeof explicit === "object"
121
- ? explicit
122
- : explicit ? { mode: "custom", model: explicit } : { mode: "native" },
129
+ resolveModel: nativeOrCustom,
123
130
  install: "https://antigravity.google/cli/install.sh",
124
131
  note: "Writes modelProvider=gemini into ~/.gemini/antigravity-cli/settings.json. Supported Gemini models route via PleumRouter.",
125
132
  attribution: {
@@ -141,7 +148,7 @@ export const RECIPES = {
141
148
  label: "opencode",
142
149
  bin: "opencode",
143
150
  type: "env",
144
- defaultModel: "gpt-6-sol",
151
+ defaultModel: DEFAULT_MODEL,
145
152
  install: "npm i -g opencode-ai@latest",
146
153
  // opencode는 커스텀 엔드포인트를 opencode.json provider 블록으로만 읽는다.
147
154
  // OpenCode는 openai 공급자 ID에만 Responses용 getModel을 등록한다.
@@ -153,12 +160,14 @@ export const RECIPES = {
153
160
  referer: "https://opencode.ai",
154
161
  },
155
162
  env: (key, model, catalog = []) => {
156
- const active = model || "gpt-6-sol";
163
+ // OpenCode 2는 루트 `--model`을 거절한다. 시작 모델은 이번 실행 설정에만 둔다.
164
+ const active = (chosenModel(model) || DEFAULT_MODEL).split("@")[0];
157
165
  const models = Object.fromEntries(catalog.map(({ id }) => [id, {}]));
158
166
  models[active] = {};
159
167
  return {
160
168
  PLEUM_API_KEY: key,
161
169
  OPENCODE_CONFIG_CONTENT: JSON.stringify({
170
+ model: `openai/${active}`,
162
171
  enabled_providers: ["openai"],
163
172
  disabled_providers: [],
164
173
  provider: {
@@ -173,7 +182,7 @@ export const RECIPES = {
173
182
  }),
174
183
  };
175
184
  },
176
- args: (m) => ["--model", `openai/${m || "gpt-6-sol"}`],
185
+ args: () => [],
177
186
  },
178
187
  aider: {
179
188
  label: "Aider",
@@ -250,7 +259,13 @@ export const RECIPES = {
250
259
  title: "Qwen Code",
251
260
  referer: "https://github.com/QwenLM/qwen-code",
252
261
  },
253
- env: (key, model) => ({ OPENAI_BASE_URL: V1, OPENAI_API_KEY: key, OPENAI_MODEL: model || DEFAULT_MODEL }),
262
+ resolveModel: nativeOrCustom,
263
+ // 모델이 없으면 비대화형 실행이 OpenAI 호환 인증을 고르지 못한다. 정규 모드는 Qwen 모델로 시작한다.
264
+ env: (key, selection) => ({
265
+ OPENAI_BASE_URL: V1,
266
+ OPENAI_API_KEY: key,
267
+ OPENAI_MODEL: chosenModel(selection) || "qwen3.8-max",
268
+ }),
254
269
  args: () => [],
255
270
  },
256
271
  copilot: {
@@ -263,12 +278,16 @@ export const RECIPES = {
263
278
  title: "GitHub Copilot CLI",
264
279
  referer: "https://docs.github.com/en/copilot/how-tos/use-copilot-agents/use-copilot-cli",
265
280
  },
266
- env: (key, model) => ({
267
- COPILOT_PROVIDER_BASE_URL: V1,
268
- COPILOT_PROVIDER_TYPE: "openai",
269
- COPILOT_PROVIDER_API_KEY: key,
270
- COPILOT_MODEL: model || DEFAULT_MODEL,
271
- }),
281
+ resolveModel: nativeOrCustom,
282
+ env: (key, selection) => {
283
+ const model = chosenModel(selection);
284
+ return {
285
+ COPILOT_PROVIDER_BASE_URL: V1,
286
+ COPILOT_PROVIDER_TYPE: "openai",
287
+ COPILOT_PROVIDER_API_KEY: key,
288
+ COPILOT_MODEL: model || DEFAULT_MODEL,
289
+ };
290
+ },
272
291
  args: () => [],
273
292
  },
274
293
  gemini: {
@@ -284,12 +303,17 @@ export const RECIPES = {
284
303
  title: "Gemini CLI",
285
304
  referer: "https://github.com/google-gemini/gemini-cli",
286
305
  },
306
+ resolveModel: nativeOrCustom,
287
307
  env: (key) => ({
288
308
  GOOGLE_GEMINI_BASE_URL: ROOT,
289
309
  GEMINI_API_KEY: key,
290
310
  GOOGLE_API_KEY: key,
291
311
  }),
292
- args: (m) => ["--model", (m || DEFAULT_MODEL).startsWith("google/") ? (m || DEFAULT_MODEL) : `google/${m || DEFAULT_MODEL}`],
312
+ args: (selection) => {
313
+ const model = chosenModel(selection);
314
+ if (!model) return [];
315
+ return ["--model", model.startsWith("google/") ? model : `google/${model}`];
316
+ },
293
317
  },
294
318
  pi: {
295
319
  label: "Pi",