@oh-my-pi/pi-ai 9.2.0 → 9.2.2

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": "@oh-my-pi/pi-ai",
3
- "version": "9.2.0",
3
+ "version": "9.2.2",
4
4
  "description": "Unified LLM API with automatic model discovery and provider configuration",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -63,7 +63,7 @@
63
63
  "@connectrpc/connect-node": "^2.1.1",
64
64
  "@google/genai": "^1.38.0",
65
65
  "@mistralai/mistralai": "^1.13.0",
66
- "@oh-my-pi/pi-utils": "9.2.0",
66
+ "@oh-my-pi/pi-utils": "9.2.2",
67
67
  "@sinclair/typebox": "^0.34.48",
68
68
  "@smithy/node-http-handler": "^4.4.8",
69
69
  "ajv": "^8.17.1",
@@ -3102,8 +3102,8 @@ export const MODELS = {
3102
3102
  reasoning: false,
3103
3103
  input: ["text"],
3104
3104
  cost: {
3105
- input: 0,
3106
- output: 0,
3105
+ input: 0.4,
3106
+ output: 2,
3107
3107
  cacheRead: 0,
3108
3108
  cacheWrite: 0,
3109
3109
  },
@@ -4357,6 +4357,23 @@ export const MODELS = {
4357
4357
  contextWindow: 204800,
4358
4358
  maxTokens: 131072,
4359
4359
  } satisfies Model<"openai-completions">,
4360
+ "glm-4.7-free": {
4361
+ id: "glm-4.7-free",
4362
+ name: "GLM-4.7 Free",
4363
+ api: "openai-completions",
4364
+ provider: "opencode",
4365
+ baseUrl: "https://opencode.ai/zen/v1",
4366
+ reasoning: true,
4367
+ input: ["text"],
4368
+ cost: {
4369
+ input: 0,
4370
+ output: 0,
4371
+ cacheRead: 0,
4372
+ cacheWrite: 0,
4373
+ },
4374
+ contextWindow: 204800,
4375
+ maxTokens: 131072,
4376
+ } satisfies Model<"openai-completions">,
4360
4377
  "gpt-5": {
4361
4378
  id: "gpt-5",
4362
4379
  name: "GPT-5",
@@ -4555,7 +4572,24 @@ export const MODELS = {
4555
4572
  cost: {
4556
4573
  input: 0.6,
4557
4574
  output: 3,
4558
- cacheRead: 0.1,
4575
+ cacheRead: 0.08,
4576
+ cacheWrite: 0,
4577
+ },
4578
+ contextWindow: 262144,
4579
+ maxTokens: 262144,
4580
+ } satisfies Model<"openai-completions">,
4581
+ "kimi-k2.5-free": {
4582
+ id: "kimi-k2.5-free",
4583
+ name: "Kimi K2.5 Free",
4584
+ api: "openai-completions",
4585
+ provider: "opencode",
4586
+ baseUrl: "https://opencode.ai/zen/v1",
4587
+ reasoning: true,
4588
+ input: ["text", "image"],
4589
+ cost: {
4590
+ input: 0,
4591
+ output: 0,
4592
+ cacheRead: 0,
4559
4593
  cacheWrite: 0,
4560
4594
  },
4561
4595
  contextWindow: 262144,
@@ -4578,6 +4612,23 @@ export const MODELS = {
4578
4612
  contextWindow: 204800,
4579
4613
  maxTokens: 131072,
4580
4614
  } satisfies Model<"openai-completions">,
4615
+ "minimax-m2.1-free": {
4616
+ id: "minimax-m2.1-free",
4617
+ name: "MiniMax M2.1 Free",
4618
+ api: "anthropic-messages",
4619
+ provider: "opencode",
4620
+ baseUrl: "https://opencode.ai/zen",
4621
+ reasoning: true,
4622
+ input: ["text"],
4623
+ cost: {
4624
+ input: 0,
4625
+ output: 0,
4626
+ cacheRead: 0,
4627
+ cacheWrite: 0,
4628
+ },
4629
+ contextWindow: 204800,
4630
+ maxTokens: 131072,
4631
+ } satisfies Model<"anthropic-messages">,
4581
4632
  "qwen3-coder": {
4582
4633
  id: "qwen3-coder",
4583
4634
  name: "Qwen3 Coder",
@@ -4595,6 +4646,23 @@ export const MODELS = {
4595
4646
  contextWindow: 262144,
4596
4647
  maxTokens: 65536,
4597
4648
  } satisfies Model<"openai-completions">,
4649
+ "trinity-large-preview-free": {
4650
+ id: "trinity-large-preview-free",
4651
+ name: "Trinity Large Preview",
4652
+ api: "openai-completions",
4653
+ provider: "opencode",
4654
+ baseUrl: "https://opencode.ai/zen/v1",
4655
+ reasoning: false,
4656
+ input: ["text"],
4657
+ cost: {
4658
+ input: 0,
4659
+ output: 0,
4660
+ cacheRead: 0,
4661
+ cacheWrite: 0,
4662
+ },
4663
+ contextWindow: 131072,
4664
+ maxTokens: 131072,
4665
+ } satisfies Model<"openai-completions">,
4598
4666
  },
4599
4667
  "openrouter": {
4600
4668
  "ai21/jamba-large-1.7": {
@@ -5350,23 +5418,6 @@ export const MODELS = {
5350
5418
  contextWindow: 1048576,
5351
5419
  maxTokens: 8192,
5352
5420
  } satisfies Model<"openai-completions">,
5353
- "google/gemini-2.0-flash-exp:free": {
5354
- id: "google/gemini-2.0-flash-exp:free",
5355
- name: "Google: Gemini 2.0 Flash Experimental (free)",
5356
- api: "openai-completions",
5357
- provider: "openrouter",
5358
- baseUrl: "https://openrouter.ai/api/v1",
5359
- reasoning: false,
5360
- input: ["text", "image"],
5361
- cost: {
5362
- input: 0,
5363
- output: 0,
5364
- cacheRead: 0,
5365
- cacheWrite: 0,
5366
- },
5367
- contextWindow: 1048576,
5368
- maxTokens: 8192,
5369
- } satisfies Model<"openai-completions">,
5370
5421
  "google/gemini-2.0-flash-lite-001": {
5371
5422
  id: "google/gemini-2.0-flash-lite-001",
5372
5423
  name: "Google: Gemini 2.0 Flash Lite",
@@ -6362,13 +6413,13 @@ export const MODELS = {
6362
6413
  reasoning: true,
6363
6414
  input: ["text", "image"],
6364
6415
  cost: {
6365
- input: 0.6,
6366
- output: 3,
6416
+ input: 0.5,
6417
+ output: 2.8,
6367
6418
  cacheRead: 0,
6368
6419
  cacheWrite: 0,
6369
6420
  },
6370
6421
  contextWindow: 262144,
6371
- maxTokens: 262144,
6422
+ maxTokens: 4096,
6372
6423
  } satisfies Model<"openai-completions">,
6373
6424
  "nex-agi/deepseek-v3.1-nex-n1": {
6374
6425
  id: "nex-agi/deepseek-v3.1-nex-n1",
@@ -6464,13 +6515,13 @@ export const MODELS = {
6464
6515
  reasoning: true,
6465
6516
  input: ["text"],
6466
6517
  cost: {
6467
- input: 0.06,
6468
- output: 0.24,
6518
+ input: 0.049999999999999996,
6519
+ output: 0.19999999999999998,
6469
6520
  cacheRead: 0,
6470
6521
  cacheWrite: 0,
6471
6522
  },
6472
6523
  contextWindow: 262144,
6473
- maxTokens: 262144,
6524
+ maxTokens: 4096,
6474
6525
  } satisfies Model<"openai-completions">,
6475
6526
  "nvidia/nemotron-3-nano-30b-a3b:free": {
6476
6527
  id: "nvidia/nemotron-3-nano-30b-a3b:free",
@@ -8699,7 +8750,7 @@ export const MODELS = {
8699
8750
  cacheWrite: 0,
8700
8751
  },
8701
8752
  contextWindow: 256000,
8702
- maxTokens: 256000,
8753
+ maxTokens: 65536,
8703
8754
  } satisfies Model<"anthropic-messages">,
8704
8755
  "anthropic/claude-3-haiku": {
8705
8756
  id: "anthropic/claude-3-haiku",
@@ -9611,9 +9662,9 @@ export const MODELS = {
9611
9662
  reasoning: true,
9612
9663
  input: ["text", "image"],
9613
9664
  cost: {
9614
- input: 1.2,
9615
- output: 1.2,
9616
- cacheRead: 0.6,
9665
+ input: 0.6,
9666
+ output: 3,
9667
+ cacheRead: 0.09999999999999999,
9617
9668
  cacheWrite: 0,
9618
9669
  },
9619
9670
  contextWindow: 256000,
@@ -9732,7 +9783,7 @@ export const MODELS = {
9732
9783
  cost: {
9733
9784
  input: 0.09999999999999999,
9734
9785
  output: 0.39999999999999997,
9735
- cacheRead: 0.024999999999999998,
9786
+ cacheRead: 0.03,
9736
9787
  cacheWrite: 0,
9737
9788
  },
9738
9789
  contextWindow: 1047576,
@@ -9936,7 +9987,7 @@ export const MODELS = {
9936
9987
  cost: {
9937
9988
  input: 1.25,
9938
9989
  output: 10,
9939
- cacheRead: 0.125,
9990
+ cacheRead: 0.13,
9940
9991
  cacheWrite: 0,
9941
9992
  },
9942
9993
  contextWindow: 128000,
@@ -9953,7 +10004,7 @@ export const MODELS = {
9953
10004
  cost: {
9954
10005
  input: 1.25,
9955
10006
  output: 10,
9956
- cacheRead: 0.125,
10007
+ cacheRead: 0.13,
9957
10008
  cacheWrite: 0,
9958
10009
  },
9959
10010
  contextWindow: 400000,
@@ -9961,7 +10012,7 @@ export const MODELS = {
9961
10012
  } satisfies Model<"anthropic-messages">,
9962
10013
  "openai/gpt-5.2": {
9963
10014
  id: "openai/gpt-5.2",
9964
- name: "GPT-5.2",
10015
+ name: "GPT 5.2",
9965
10016
  api: "anthropic-messages",
9966
10017
  provider: "vercel-ai-gateway",
9967
10018
  baseUrl: "https://ai-gateway.vercel.sh",
@@ -9970,7 +10021,7 @@ export const MODELS = {
9970
10021
  cost: {
9971
10022
  input: 1.75,
9972
10023
  output: 14,
9973
- cacheRead: 0.175,
10024
+ cacheRead: 0.18,
9974
10025
  cacheWrite: 0,
9975
10026
  },
9976
10027
  contextWindow: 400000,
@@ -10231,40 +10282,6 @@ export const MODELS = {
10231
10282
  contextWindow: 131072,
10232
10283
  maxTokens: 131072,
10233
10284
  } satisfies Model<"anthropic-messages">,
10234
- "stealth/sonoma-dusk-alpha": {
10235
- id: "stealth/sonoma-dusk-alpha",
10236
- name: "Sonoma Dusk Alpha",
10237
- api: "anthropic-messages",
10238
- provider: "vercel-ai-gateway",
10239
- baseUrl: "https://ai-gateway.vercel.sh",
10240
- reasoning: false,
10241
- input: ["text", "image"],
10242
- cost: {
10243
- input: 0.19999999999999998,
10244
- output: 0.5,
10245
- cacheRead: 0.049999999999999996,
10246
- cacheWrite: 0,
10247
- },
10248
- contextWindow: 2000000,
10249
- maxTokens: 131072,
10250
- } satisfies Model<"anthropic-messages">,
10251
- "stealth/sonoma-sky-alpha": {
10252
- id: "stealth/sonoma-sky-alpha",
10253
- name: "Sonoma Sky Alpha",
10254
- api: "anthropic-messages",
10255
- provider: "vercel-ai-gateway",
10256
- baseUrl: "https://ai-gateway.vercel.sh",
10257
- reasoning: false,
10258
- input: ["text", "image"],
10259
- cost: {
10260
- input: 0.19999999999999998,
10261
- output: 0.5,
10262
- cacheRead: 0.049999999999999996,
10263
- cacheWrite: 0,
10264
- },
10265
- contextWindow: 2000000,
10266
- maxTokens: 131072,
10267
- } satisfies Model<"anthropic-messages">,
10268
10285
  "vercel/v0-1.0-md": {
10269
10286
  id: "vercel/v0-1.0-md",
10270
10287
  name: "v0-1.0-md",
@@ -10552,7 +10569,7 @@ export const MODELS = {
10552
10569
  cacheWrite: 0,
10553
10570
  },
10554
10571
  contextWindow: 65536,
10555
- maxTokens: 66000,
10572
+ maxTokens: 16384,
10556
10573
  } satisfies Model<"anthropic-messages">,
10557
10574
  "zai/glm-4.6": {
10558
10575
  id: "zai/glm-4.6",
@@ -11143,5 +11160,23 @@ export const MODELS = {
11143
11160
  contextWindow: 204800,
11144
11161
  maxTokens: 131072,
11145
11162
  } satisfies Model<"openai-completions">,
11163
+ "glm-4.7-flash": {
11164
+ id: "glm-4.7-flash",
11165
+ name: "GLM-4.7-Flash",
11166
+ api: "openai-completions",
11167
+ provider: "zai",
11168
+ baseUrl: "https://api.z.ai/api/coding/paas/v4",
11169
+ compat: {"supportsDeveloperRole":false,"thinkingFormat":"zai"},
11170
+ reasoning: true,
11171
+ input: ["text"],
11172
+ cost: {
11173
+ input: 0,
11174
+ output: 0,
11175
+ cacheRead: 0,
11176
+ cacheWrite: 0,
11177
+ },
11178
+ contextWindow: 200000,
11179
+ maxTokens: 131072,
11180
+ } satisfies Model<"openai-completions">,
11146
11181
  },
11147
11182
  } as const;
@@ -48,6 +48,8 @@ export { loginKimi, refreshKimiToken } from "./kimi";
48
48
  export type { OpenAICodexLoginOptions } from "./openai-codex";
49
49
  // OpenAI Codex (ChatGPT OAuth)
50
50
  export { loginOpenAICodex, refreshOpenAICodexToken } from "./openai-codex";
51
+ // OpenCode (API key)
52
+ export { loginOpenCode } from "./opencode";
51
53
 
52
54
  export * from "./types";
53
55
 
@@ -93,6 +95,10 @@ export async function refreshOAuthToken(
93
95
  case "cursor":
94
96
  newCredentials = await refreshCursorToken(credentials.refresh);
95
97
  break;
98
+ case "opencode":
99
+ // API keys don't expire, return as-is
100
+ newCredentials = credentials;
101
+ break;
96
102
  default:
97
103
  throw new Error(`Unknown OAuth provider: ${provider}`);
98
104
  }
@@ -173,5 +179,10 @@ export function getOAuthProviders(): OAuthProviderInfo[] {
173
179
  name: "Cursor (Claude, GPT, etc.)",
174
180
  available: true,
175
181
  },
182
+ {
183
+ id: "opencode",
184
+ name: "OpenCode Zen",
185
+ available: true,
186
+ },
176
187
  ];
177
188
  }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * OpenCode Zen login flow.
3
+ *
4
+ * OpenCode Zen is a subscription service that provides access to various AI models
5
+ * (GPT-5.x, Claude 4.x, Gemini 3, etc.) through a unified API at opencode.ai/zen.
6
+ *
7
+ * This is not OAuth - it's a simple API key flow:
8
+ * 1. Open browser to https://opencode.ai/auth
9
+ * 2. User logs in and copies their API key
10
+ * 3. User pastes the API key back into the CLI
11
+ */
12
+
13
+ import type { OAuthController } from "./types";
14
+
15
+ const AUTH_URL = "https://opencode.ai/auth";
16
+
17
+ /**
18
+ * Login to OpenCode Zen.
19
+ *
20
+ * Opens browser to auth page, prompts user to paste their API key.
21
+ * Returns the API key directly (not OAuthCredentials - this isn't OAuth).
22
+ */
23
+ export async function loginOpenCode(options: OAuthController): Promise<string> {
24
+ if (!options.onPrompt) {
25
+ throw new Error("OpenCode Zen login requires onPrompt callback");
26
+ }
27
+
28
+ // Open browser to auth page
29
+ options.onAuth?.({
30
+ url: AUTH_URL,
31
+ instructions: "Log in and copy your API key",
32
+ });
33
+
34
+ // Prompt user to paste their API key
35
+ const apiKey = await options.onPrompt({
36
+ message: "Paste your OpenCode Zen API key",
37
+ placeholder: "sk-...",
38
+ });
39
+
40
+ if (options.signal?.aborted) {
41
+ throw new Error("Login cancelled");
42
+ }
43
+
44
+ const trimmed = apiKey.trim();
45
+ if (!trimmed) {
46
+ throw new Error("API key is required");
47
+ }
48
+
49
+ return trimmed;
50
+ }
@@ -15,6 +15,7 @@ export type OAuthProvider =
15
15
  | "google-antigravity"
16
16
  | "kimi-code"
17
17
  | "openai-codex"
18
+ | "opencode"
18
19
  | "cursor";
19
20
 
20
21
  export type OAuthPrompt = {