@oh-my-pi/pi-ai 13.3.6 → 13.3.8

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/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [13.3.8] - 2026-02-28
6
+ ### Fixed
7
+
8
+ - Fixed response body reuse error when handling 429 rate limit responses with retry logic
9
+
10
+ ## [13.3.7] - 2026-02-27
11
+ ### Added
12
+
13
+ - Added `tryEnforceStrictSchema` function that gracefully downgrades to non-strict mode when schema enforcement fails, enabling better compatibility with malformed or circular schemas
14
+ - Added `sanitizeSchemaForStrictMode` function to normalize JSON schemas by stripping non-structural keywords, converting `const` to `enum`, and expanding type arrays into `anyOf` variants
15
+ - Added Kilo Gateway provider support with OpenAI-compatible model discovery, OAuth `/login kilo`, and `KILO_API_KEY` environment variable support ([#193](https://github.com/can1357/oh-my-pi/issues/193))
16
+
17
+ ### Changed
18
+
19
+ - Changed strict mode handling in OpenAI providers to use `tryEnforceStrictSchema` for safer schema enforcement with automatic fallback to non-strict mode
20
+ - Enhanced `enforceStrictSchema` to properly handle schemas with type arrays containing `object` (e.g., `type: ["object", "null"]`)
21
+
22
+ ### Fixed
23
+
24
+ - Fixed `enforceStrictSchema` to properly handle malformed object schemas with required keys but missing properties
25
+ - Fixed `enforceStrictSchema` to correctly process nested object schemas within `anyOf`, `allOf`, and `oneOf` combinators
26
+
5
27
  ## [13.3.1] - 2026-02-26
6
28
  ### Added
7
29
 
package/README.md CHANGED
@@ -63,6 +63,7 @@ Unified LLM API with automatic model discovery, provider configuration, token an
63
63
  - **xAI**
64
64
  - **Venice** (requires `VENICE_API_KEY`)
65
65
  - **OpenRouter**
66
+ - **Kilo Gateway** (supports OAuth `/login kilo` or `KILO_API_KEY`)
66
67
  - **LiteLLM** (requires `LITELLM_API_KEY`)
67
68
  - **zAI** (requires `ZAI_API_KEY`)
68
69
  - **MiniMax Coding Plan** (requires `MINIMAX_CODE_API_KEY` or `MINIMAX_CODE_CN_API_KEY`)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-ai",
4
- "version": "13.3.6",
4
+ "version": "13.3.8",
5
5
  "description": "Unified LLM API with automatic model discovery and provider configuration",
6
6
  "homepage": "https://github.com/can1357/oh-my-pi",
7
7
  "author": "Can Boluk",
@@ -40,20 +40,15 @@
40
40
  "@anthropic-ai/sdk": "^0.78",
41
41
  "@aws-sdk/client-bedrock-runtime": "^3.998",
42
42
  "@bufbuild/protobuf": "^2.11",
43
- "@connectrpc/connect": "^2.1",
44
- "@connectrpc/connect-node": "^2.1",
45
43
  "@google/genai": "^1.43",
46
- "@mistralai/mistralai": "^1.14",
47
- "@oh-my-pi/pi-utils": "13.3.6",
44
+ "@oh-my-pi/pi-utils": "13.3.8",
48
45
  "@sinclair/typebox": "^0.34",
49
46
  "@smithy/node-http-handler": "^4.4",
50
47
  "ajv": "^8.18",
51
48
  "ajv-formats": "^3.0",
52
- "chalk": "^5.6",
53
49
  "openai": "^6.25",
54
50
  "partial-json": "^0.1",
55
- "zod": "^4.3",
56
- "zod-to-json-schema": "^3.25"
51
+ "zod": "^4.3"
57
52
  },
58
53
  "devDependencies": {
59
54
  "@types/bun": "^1.3"
@@ -41,6 +41,7 @@ import { loginGitLabDuo } from "./utils/oauth/gitlab-duo";
41
41
  import { loginAntigravity } from "./utils/oauth/google-antigravity";
42
42
  import { loginGeminiCli } from "./utils/oauth/google-gemini-cli";
43
43
  import { loginHuggingface } from "./utils/oauth/huggingface";
44
+ import { loginKilo } from "./utils/oauth/kilo";
44
45
  import { loginKimi } from "./utils/oauth/kimi";
45
46
  import { loginLiteLLM } from "./utils/oauth/litellm";
46
47
  import { loginMiniMaxCode, loginMiniMaxCodeCn } from "./utils/oauth/minimax-code";
@@ -379,7 +380,13 @@ export class AuthStorage {
379
380
  }
380
381
  }
381
382
 
382
- #dedupeOAuthCredentials(credentials: AuthCredential[]): AuthCredential[] {
383
+ #resolveOAuthDedupeIdentifiers(provider: string, credential: OAuthCredential): string[] {
384
+ const identifiers = this.#getOAuthIdentifiers(credential);
385
+ if (provider !== "openai-codex") return identifiers;
386
+ return identifiers.filter(identifier => identifier.startsWith("email:"));
387
+ }
388
+
389
+ #dedupeOAuthCredentials(provider: string, credentials: AuthCredential[]): AuthCredential[] {
383
390
  const seen = new Set<string>();
384
391
  const deduped: AuthCredential[] = [];
385
392
  for (let index = credentials.length - 1; index >= 0; index -= 1) {
@@ -388,7 +395,7 @@ export class AuthStorage {
388
395
  deduped.push(credential);
389
396
  continue;
390
397
  }
391
- const identifiers = this.#getOAuthIdentifiers(credential);
398
+ const identifiers = this.#resolveOAuthDedupeIdentifiers(provider, credential);
392
399
  if (identifiers.length === 0) {
393
400
  deduped.push(credential);
394
401
  continue;
@@ -415,7 +422,7 @@ export class AuthStorage {
415
422
  kept.push(entry);
416
423
  continue;
417
424
  }
418
- const identifiers = this.#getOAuthIdentifiers(credential);
425
+ const identifiers = this.#resolveOAuthDedupeIdentifiers(provider, credential);
419
426
  if (identifiers.length === 0) {
420
427
  kept.push(entry);
421
428
  continue;
@@ -627,7 +634,7 @@ export class AuthStorage {
627
634
  */
628
635
  async set(provider: string, credential: AuthCredentialEntry): Promise<void> {
629
636
  const normalized = Array.isArray(credential) ? credential : [credential];
630
- const deduped = this.#dedupeOAuthCredentials(normalized);
637
+ const deduped = this.#dedupeOAuthCredentials(provider, normalized);
631
638
  const stored = this.#store.replaceAuthCredentialsForProvider(provider, deduped);
632
639
  this.#setStoredCredentials(
633
640
  provider,
@@ -773,6 +780,9 @@ export class AuthStorage {
773
780
  case "kimi-code":
774
781
  credentials = await loginKimi(ctrl);
775
782
  break;
783
+ case "kilo":
784
+ credentials = await loginKilo(ctrl);
785
+ break;
776
786
  case "cursor":
777
787
  credentials = await loginCursor(
778
788
  url => ctrl.onAuth({ url }),
@@ -955,6 +965,9 @@ export class AuthStorage {
955
965
  const identifiers: string[] = [];
956
966
  const email = this.#getUsageReportMetadataValue(report, "email");
957
967
  if (email) identifiers.push(`email:${email.toLowerCase()}`);
968
+ if (report.provider === "openai-codex") {
969
+ return identifiers.map(identifier => `${report.provider}:${identifier.toLowerCase()}`);
970
+ }
958
971
  const accountId = this.#getUsageReportMetadataValue(report, "accountId");
959
972
  if (accountId) identifiers.push(`account:${accountId}`);
960
973
  const account = this.#getUsageReportMetadataValue(report, "account");
package/src/cli.ts CHANGED
@@ -7,6 +7,7 @@ import { loginCursor } from "./utils/oauth/cursor";
7
7
  import { loginGitHubCopilot } from "./utils/oauth/github-copilot";
8
8
  import { loginAntigravity } from "./utils/oauth/google-antigravity";
9
9
  import { loginGeminiCli } from "./utils/oauth/google-gemini-cli";
10
+ import { loginKilo } from "./utils/oauth/kilo";
10
11
  import { loginKimi } from "./utils/oauth/kimi";
11
12
  import { loginMiniMaxCode, loginMiniMaxCodeCn } from "./utils/oauth/minimax-code";
12
13
  import { loginNanoGPT } from "./utils/oauth/nanogpt";
@@ -146,6 +147,16 @@ async function login(provider: OAuthProvider): Promise<void> {
146
147
  },
147
148
  });
148
149
  break;
150
+ case "kilo":
151
+ credentials = await loginKilo({
152
+ onAuth(info) {
153
+ const { url, instructions } = info;
154
+ console.log(`\nOpen this URL in your browser:\n${url}`);
155
+ if (instructions) console.log(instructions);
156
+ console.log();
157
+ },
158
+ });
159
+ break;
149
160
 
150
161
  case "cursor":
151
162
  credentials = await loginCursor(
@@ -259,6 +270,7 @@ Providers:
259
270
  google-antigravity Antigravity (Gemini 3, Claude, GPT-OSS)
260
271
  openai-codex OpenAI Codex (ChatGPT Plus/Pro)
261
272
  kimi-code Kimi Code
273
+ kilo Kilo Gateway
262
274
  zai Z.AI (GLM Coding Plan)
263
275
  nanogpt NanoGPT
264
276
  minimax-code MiniMax Coding Plan (International)