pi-cliproxyapi-native 0.3.2 → 0.3.4

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/README.md CHANGED
@@ -31,15 +31,15 @@ Chat uses Pi's native API adapters and model metadata, with availability from yo
31
31
 
32
32
  ## Install
33
33
 
34
- The extension targets Pi 1.4.0 and CLIProxyAPI 8.0.48, with Node.js 22.19 or newer. Run CLIProxyAPI with your upstream accounts configured before connecting Pi. The extension uses Pi's host-provided packages, adds no runtime dependencies, and needs no compilation.
34
+ The extension targets Pi 1.5.0 and CLIProxyAPI 8.0.51, with Node.js 22.19 or newer. Run CLIProxyAPI with your upstream accounts configured before connecting Pi. The extension uses Pi's host-provided packages, adds no runtime dependencies, and needs no compilation.
35
35
 
36
36
  If you installed `pi-cliproxy-native`, remove it before installing the renamed package. Both register the same `cliproxyapi` provider.
37
37
 
38
38
  ```sh
39
- pi install npm:pi-cliproxyapi-native@0.3.2
39
+ pi install npm:pi-cliproxyapi-native@0.3.4
40
40
  ```
41
41
 
42
- For Git installation, use `pi install git:github.com/hawkff/pi-cliproxyapi-native@v0.3.2`. For a local checkout, use `pi install /path/to/pi-cliproxyapi-native`.
42
+ For Git installation, use `pi install git:github.com/hawkff/pi-cliproxyapi-native@v0.3.4`. For a local checkout, use `pi install /path/to/pi-cliproxyapi-native`.
43
43
 
44
44
  The default proxy address is `http://localhost:8317`. For another address, set the [connection](#connection) before logging in. Restart Pi, then run:
45
45
 
@@ -129,12 +129,12 @@ Invalid or disabled saved selections block automatic fallback until you clear or
129
129
 
130
130
  Pass output controls for each generation, or omit them to keep the backend defaults. `cliproxyapi_media_models` lists each model's `controls.size`, `controls.resolution`, and `controls.aspect_ratio`. Empty lists mean the control is unsupported; `size_limits` describes custom pixel sizes beyond the listed presets.
131
131
 
132
- | Models | Controls |
133
- | ------------- | ------------------------------------------------------------------------------------------------------------- |
134
- | OpenAI images | `size`: `auto` or `WIDTHxHEIGHT`. No separate `resolution` or `aspect_ratio`. |
135
- | Gemini images | `aspect_ratio` and model-specific `resolution` tiers. |
136
- | xAI images | `resolution`: `1k` or `2k`, plus `aspect_ratio`. |
137
- | xAI videos | `resolution`: `480p` or `720p`, plus `aspect_ratio`. The 1.5 model and its preview alias also accept `1080p`. |
132
+ | Models | Controls |
133
+ | ------------- | ------------------------------------------------------------------------------------------------------------------------ |
134
+ | OpenAI images | `size`: `auto` or `WIDTHxHEIGHT`. No separate `resolution` or `aspect_ratio`. |
135
+ | Gemini images | `aspect_ratio` and model-specific `resolution` tiers. |
136
+ | xAI images | `resolution`: `1k` or `2k`, plus `aspect_ratio`. |
137
+ | xAI videos | `resolution`: `480p` or `720p`, plus `aspect_ratio`. The 1.5 model, its preview alias, and 1.5 Lite also accept `1080p`. |
138
138
 
139
139
  GPT Image 1.5 accepts `auto`, `1024x1024`, `1536x1024`, and `1024x1536`. GPT Image 2 and 2.5 also accept custom dimensions: both edges must be multiples of 16 and at most 3840 pixels. The longer edge cannot exceed three times the shorter one. Total pixels must be between 655,360 and 8,294,400. OpenAI marks resolutions above `2560x1440` as experimental.
140
140
 
@@ -196,11 +196,11 @@ These calls send the prompt with backend defaults. Pi's image interface has no s
196
196
 
197
197
  Your proxy must advertise the exact ID for a model to be available.
198
198
 
199
- | Provider | Models |
200
- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
201
- | OpenAI models | `gpt-image-2.5-flare`, `gpt-image-2.5-sunburst`, `gpt-image-2.5`, `gpt-image-2`, `gpt-image-1.5` |
202
- | Google models | `gemini-2.5-flash-image`, `gemini-3.1-flash-image`, `gemini-3-pro-image`, `gemini-3.1-flash-lite-image` |
203
- | xAI models | `grok-imagine-image`, `grok-imagine-image-quality`, `grok-imagine-image-2.0`, `grok-imagine-video`, `grok-imagine-video-1.5`, `grok-imagine-video-1.5-preview` |
199
+ | Provider | Models |
200
+ | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
201
+ | OpenAI models | `gpt-image-2.5-flare`, `gpt-image-2.5-sunburst`, `gpt-image-2.5`, `gpt-image-2`, `gpt-image-1.5` |
202
+ | Google models | `gemini-2.5-flash-image`, `gemini-3.1-flash-image`, `gemini-3-pro-image`, `gemini-3.1-flash-lite-image` |
203
+ | xAI models | `grok-imagine-image`, `grok-imagine-image-quality`, `grok-imagine-image-2.0`, `grok-imagine-video`, `grok-imagine-video-1.5`, `grok-imagine-video-1.5-lite`, `grok-imagine-video-1.5-preview` |
204
204
 
205
205
  Supported media IDs can also use advertised `api/` and `oauth/` credential routes. OpenAI's API has no plain `gpt-image-2.5`, so the picker disables `api/gpt-image-2.5` and points to Sunburst or Flare; subscription routes keep it. Gemini image models also support `vertex/` and `antigravity/` backend routes. Those backend prefixes do not enable OpenAI or xAI media execution; the picker shows those entries as disabled. Other prefixes, nested prefixes, media aliases, unknown media IDs, Google Veo, and non-OpenAI editing are unsupported.
206
206
 
@@ -376,7 +376,13 @@ Run `/reload` after changing settings and `/cliproxyapi-refresh` before starting
376
376
 
377
377
  ## Protocol notes
378
378
 
379
- Claude uses the legacy fine-grained tool-streaming header in place of eager tool fields. The extension disables unverified deferred-tool and strict-tool capabilities. Responses function tools use `strict: null` when Pi omits strictness, so optional arguments remain optional. Explicit payload hooks retain final control.
379
+ Claude uses the legacy fine-grained tool-streaming header in place of eager tool fields.
380
+
381
+ GPT models keep Pi's OpenAI Responses capabilities when the proxy lists them as owned by OpenAI. These capabilities are strict tools, grammar tools such as codemode, tool declarations added mid-conversation, tool search, and instructions placed mid-conversation. Each passed live checks through CLIProxyAPI 8.0.48 with an OpenAI API key and with a ChatGPT subscription. OpenAI-compatible providers and other model families keep these capabilities off.
382
+
383
+ On `api/` routes, Pi can send thinking effort as a `configuration_update` item. ChatGPT subscriptions ignore that item, so unprefixed and `oauth/` routes send the effort as a request field.
384
+
385
+ When Pi omits strictness in the top-level Responses tool list, the extension sends `strict: null`, so optional arguments remain optional. Tools declared inside the conversation keep Pi's strictness values. Explicit payload hooks retain final control.
380
386
 
381
387
  OpenAI images POST `model`, `prompt`, `n`, and supplied controls to `/v1/images/generations`, without `response_format`. Editing uses `/v1/images/edits` with JSON `images` and optional `mask` data URLs. A nonzero `partial_images` adds `stream: true`, and the extension reads server-sent events. Each `*.partial_image` frame becomes a progress preview, and the `*.completed` frame carries the final image and usage. xAI uses the same route with `response_format: "b64_json"`. Gemini uses `/v1beta/models/{id}:generateContent`. Media generation sends the prompt and generation options without chat history, system instructions, or tools.
382
388
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-cliproxyapi-native",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "CLIProxyAPI chat discovery, image generation and editing, and video generation with Pi's native adapters",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -39,15 +39,17 @@
39
39
  },
40
40
  "devDependencies": {
41
41
  "@biomejs/biome": "^2.6.4",
42
- "@earendil-works/pi-ai": "^1.4.0",
43
- "@earendil-works/pi-coding-agent": "^1.4.0",
44
- "@earendil-works/pi-tui": "^1.4.0",
42
+ "@earendil-works/pi-ai": "^1.5.0",
43
+ "@earendil-works/pi-coding-agent": "^1.5.0",
44
+ "@earendil-works/pi-tui": "^1.5.0",
45
45
  "@types/node": "^24.19.2",
46
+ "typebox": "1.3.27",
46
47
  "typescript": "7.0.2"
47
48
  },
48
49
  "peerDependencies": {
49
50
  "@earendil-works/pi-ai": "*",
50
51
  "@earendil-works/pi-coding-agent": "*",
51
- "@earendil-works/pi-tui": "*"
52
+ "@earendil-works/pi-tui": "*",
53
+ "typebox": "*"
52
54
  }
53
55
  }
package/src/catalog.ts CHANGED
@@ -134,6 +134,7 @@ const mediaModels = new Map<
134
134
  ["grok-imagine-image-2.0", { name: "Grok Imagine Image 2.0", purpose: "image", route: "xai" }],
135
135
  ["grok-imagine-video", { name: "Grok Imagine Video", purpose: "video", route: "xai" }],
136
136
  ["grok-imagine-video-1.5", { name: "Grok Imagine Video 1.5", purpose: "video", route: "xai" }],
137
+ ["grok-imagine-video-1.5-lite", { name: "Grok Imagine Video 1.5 Lite", purpose: "video", route: "xai" }],
137
138
  [
138
139
  "grok-imagine-video-1.5-preview",
139
140
  { name: "Grok Imagine Video 1.5 Preview", purpose: "video", route: "xai" },
@@ -332,6 +333,16 @@ export function mapCatalog(value: unknown, config: Config, known: readonly Model
332
333
  skipped.add(entry.id);
333
334
  continue;
334
335
  }
336
+ // CLIProxyAPI 8.0.48 forwards strict and grammar tools, additional_tools, tool search, and
337
+ // mid-conversation instructions to OpenAI API keys and ChatGPT subscriptions (live-checked).
338
+ // Other owners stay conservative. If an OpenAI-compatible provider shares a bare ID, the proxy
339
+ // lists one owner, and its Chat translator converts these items for that provider.
340
+ const openai =
341
+ api === "openai-responses" &&
342
+ !metadataId.includes("/") &&
343
+ (!prefix || prefix === "api" || prefix === "oauth") &&
344
+ (preferred === "openai" || preferred === "openai-codex") &&
345
+ (reference.provider === "openai" || reference.provider === "openai-codex");
335
346
  const model: Model<CpaApi> = {
336
347
  ...structuredClone(reference),
337
348
  id: entry.id,
@@ -353,15 +364,19 @@ export function mapCatalog(value: unknown, config: Config, known: readonly Model
353
364
  }
354
365
  : api === "google-generative-ai"
355
366
  ? reference.compat
356
- : {
357
- ...reference.compat,
358
- supportsStrictMode: false,
359
- supportsMidConvoSystemMessages: false,
360
- supportsMidConvoToolAdditions: false,
361
- supportsOpenAIGrammarTools: false,
362
- supportsToolSearch: false,
363
- supportsAdditionalTools: false,
364
- },
367
+ : openai
368
+ ? // ChatGPT subscriptions ignore configuration_update effort items; only API keys apply them.
369
+ { ...reference.compat, ...(prefix === "api" ? {} : { supportsMidConvoEffort: false }) }
370
+ : {
371
+ ...reference.compat,
372
+ supportsStrictMode: false,
373
+ supportsMidConvoSystemMessages: false,
374
+ supportsMidConvoToolAdditions: false,
375
+ supportsOpenAIGrammarTools: false,
376
+ supportsToolSearch: false,
377
+ supportsAdditionalTools: false,
378
+ supportsMidConvoEffort: false,
379
+ },
365
380
  };
366
381
  models.set(model.id, model);
367
382
  skipped.delete(model.id);
package/src/media.ts CHANGED
@@ -4,19 +4,18 @@ import * as http from "node:http";
4
4
  import * as https from "node:https";
5
5
  import { join, resolve } from "node:path";
6
6
  import { addAbortSignal, Readable } from "node:stream";
7
- import {
8
- type AssistantImages,
9
- type ImageApi,
10
- type ImageContent,
11
- type ImageModel,
12
- type ImagesContext,
13
- type ImagesOptions,
14
- type Static,
15
- type TextContent,
16
- Type,
17
- type Usage,
7
+ import type {
8
+ AssistantImages,
9
+ ImageApi,
10
+ ImageContent,
11
+ ImageModel,
12
+ ImagesContext,
13
+ ImagesOptions,
14
+ TextContent,
15
+ Usage,
18
16
  } from "@earendil-works/pi-ai";
19
17
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
18
+ import { type Static, Type } from "typebox";
20
19
  import { fetchCatalog, mapMediaCatalog, mediaCapability, mediaControls } from "./catalog.ts";
21
20
  import { type Config, deadline, isRecord, PROVIDER_ID, validateKey } from "./config.ts";
22
21
  import { type DefaultsContext, effectiveMediaDefaults, resolveMediaModel } from "./media-defaults.ts";