pi-cliproxyapi-native 0.1.3 → 0.1.5

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
@@ -6,15 +6,15 @@ Chat uses Pi's native API adapters and model metadata, with availability from yo
6
6
 
7
7
  ## Install
8
8
 
9
- You need Pi 0.87.x and Node.js 22.19 or newer. Run CLIProxyAPI with your upstream accounts configured before connecting Pi. This release targets CLIProxyAPI 7.3.11. The extension adds no runtime dependencies and needs no compilation.
9
+ This release targets Pi 1.0.0 and CLIProxyAPI 8.0.7, 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.
10
10
 
11
11
  If you installed `pi-cliproxy-native`, remove it before installing the renamed package. Both register the same `cliproxyapi` provider.
12
12
 
13
13
  ```sh
14
- pi install npm:pi-cliproxyapi-native@0.1.3
14
+ pi install npm:pi-cliproxyapi-native@0.1.5
15
15
  ```
16
16
 
17
- For Git installation, use `pi install git:github.com/hawkff/pi-cliproxyapi-native@v0.1.3`. For a local checkout, use `pi install /path/to/pi-cliproxyapi-native`.
17
+ For Git installation, use `pi install git:github.com/hawkff/pi-cliproxyapi-native@v0.1.5`. For a local checkout, use `pi install /path/to/pi-cliproxyapi-native`.
18
18
 
19
19
  The default proxy address is `http://localhost:8317`. For another address, set the [connection](#connection) before logging in. Restart Pi, then run:
20
20
 
@@ -112,7 +112,7 @@ GPT Image 1.5 accepts `auto`, `1024x1024`, `1536x1024`, and `1024x1536`. GPT Ima
112
112
 
113
113
  Gemini 3 Pro Image supports `1K`, `2K`, and `4K`. Gemini 3.1 Flash Image also supports `512`. Flash Lite Image supports `1K` only. Gemini 2.5 Flash Image has no resolution selector. Use the exact case shown in discovery, including uppercase `K` for Gemini and lowercase `k` for xAI.
114
114
 
115
- Aspect ratios vary by model and proxy route. For example, CLIProxyAPI 7.3.11 accepts `20:9` for xAI images but drops xAI's `21:9` and `auto` values. The extension rejects unsupported controls before authentication or network access instead of substituting another size or shape.
115
+ Aspect ratios vary by model and proxy route. For example, CLIProxyAPI 8.0.7 accepts `20:9` for xAI images but drops xAI's `21:9` and `auto` values. The extension rejects unsupported controls before authentication or network access instead of substituting another size or shape.
116
116
 
117
117
  ```text
118
118
  Generate an image with gpt-image-2.5-sunburst at size 2048x2048.
@@ -207,7 +207,7 @@ Keep the full advertised ID when selecting a backend, for example:
207
207
 
208
208
  These examples select media defaults. Chat routes belong in Pi's built-in `/model` picker.
209
209
 
210
- Set the CLIProxyAPI auth record's top-level `prefix` to `vertex` or `antigravity` to advertise those routes. With `force-model-prefix: false`, the proxy retains bare IDs too. This extension does not change proxy configuration or restart it.
210
+ Set the CLIProxyAPI auth record's top-level `prefix` to `vertex` or `antigravity` to advertise those routes. With `routing.force-model-prefix: false` in CLIProxyAPI 8, the proxy retains bare IDs too. Legacy configurations use the top-level `force-model-prefix` setting. This extension does not change proxy configuration or restart it.
211
211
 
212
212
  ## Thinking and child sessions
213
213
 
@@ -237,7 +237,7 @@ Claude uses the legacy fine-grained tool-streaming header in place of eager tool
237
237
 
238
238
  OpenAI images POST `model`, `prompt`, and `n=1` to `/v1/images/generations`, without `response_format`. 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.
239
239
 
240
- OpenAI image POSTs use a dedicated HTTP connection so shorter transport timeouts do not interrupt the ten-minute deadline. They request identity encoding and reject compressed responses.
240
+ OpenAI image POSTs use a dedicated HTTP connection and preserve Node's configured proxy routing. They disable socket timeouts so the ten-minute deadline controls the request, request identity encoding, and reject compressed responses.
241
241
 
242
242
  The implementation follows CLIProxyAPI v7.3.1's [OpenAI image handler](https://github.com/router-for-me/CLIProxyAPI/blob/v7.3.1/sdk/api/handlers/openai/openai_images_handlers.go) and [Codex image executor](https://github.com/router-for-me/CLIProxyAPI/blob/v7.3.1/internal/runtime/executor/codex_openai_images.go). The xAI and Google routes follow v7.2.158's [video handler](https://github.com/router-for-me/CLIProxyAPI/blob/v7.2.158/sdk/api/handlers/openai/openai_videos_handlers.go), [Gemini handler](https://github.com/router-for-me/CLIProxyAPI/blob/v7.2.158/sdk/api/handlers/gemini/gemini_handlers.go), and [Vertex executor](https://github.com/router-for-me/CLIProxyAPI/blob/v7.2.158/internal/runtime/executor/gemini_vertex_executor.go). See [xAI's video documentation](https://docs.x.ai/developers/model-capabilities/video/generation) for duration and status semantics.
243
243
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-cliproxyapi-native",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "CLIProxyAPI chat discovery and image/video generation with Pi's native adapters",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -12,7 +12,8 @@
12
12
  },
13
13
  "keywords": [
14
14
  "pi-package",
15
- "CLIProxyAPI"
15
+ "pi-extension",
16
+ "cliproxyapi"
16
17
  ],
17
18
  "repository": {
18
19
  "type": "git",
@@ -38,15 +39,15 @@
38
39
  },
39
40
  "devDependencies": {
40
41
  "@biomejs/biome": "^2.5.13",
41
- "@earendil-works/pi-ai": "^0.87.0",
42
- "@earendil-works/pi-coding-agent": "^0.87.0",
43
- "@earendil-works/pi-tui": "^0.87.0",
42
+ "@earendil-works/pi-ai": "^1.0.0",
43
+ "@earendil-works/pi-coding-agent": "^1.0.0",
44
+ "@earendil-works/pi-tui": "^1.0.0",
44
45
  "@types/node": "^24.13.4",
45
46
  "typescript": "5.9.3"
46
47
  },
47
48
  "peerDependencies": {
48
- "@earendil-works/pi-ai": "^0.87.0",
49
- "@earendil-works/pi-coding-agent": "^0.87.0",
50
- "@earendil-works/pi-tui": "^0.87.0"
49
+ "@earendil-works/pi-ai": "*",
50
+ "@earendil-works/pi-coding-agent": "*",
51
+ "@earendil-works/pi-tui": "*"
51
52
  }
52
53
  }
package/src/catalog.ts CHANGED
@@ -124,7 +124,7 @@ export function mediaControls(id: string) {
124
124
  aspect_ratio = commonRatios;
125
125
  if (capability.purpose === "image") {
126
126
  resolution = ["1k", "2k"];
127
- // CLIProxyAPI 7.3.11 drops other xAI image ratios, including auto.
127
+ // CLIProxyAPI 8.0.7 drops other xAI image ratios, including auto.
128
128
  aspect_ratio.push("9:20", "20:9");
129
129
  } else {
130
130
  resolution = ["480p", "720p"];
package/src/media.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
2
- import { request as httpRequest } from "node:http";
3
- import { request as httpsRequest } from "node:https";
2
+ import * as http from "node:http";
3
+ import * as https from "node:https";
4
4
  import { join } from "node:path";
5
5
  import { addAbortSignal, Readable } from "node:stream";
6
6
  import { type ImageContent, type Static, type TextContent, Type } from "@earendil-works/pi-ai";
@@ -133,12 +133,25 @@ function openaiImageResponse(config: Config, key: string, body: object, signal:
133
133
  return new Promise<{ ok: boolean; status: number; body: ReturnType<typeof Readable.toWeb> | null }>(
134
134
  (resolve, reject) => {
135
135
  const url = new URL(`${config.baseUrl}/v1/images/generations`);
136
- // A private agent and no socket timeout leave the overall signal in control of long image waits.
137
- const request = (url.protocol === "https:" ? httpsRequest : httpRequest)(
136
+ const transport = url.protocol === "https:" ? https : http;
137
+ const options = "options" in transport.globalAgent ? transport.globalAgent.options : undefined;
138
+ // Preserve configured proxies without inheriting the global agent's socket timeout.
139
+ const agent = new transport.Agent({
140
+ ...(isRecord(options) ? options : {}),
141
+ keepAlive: false,
142
+ timeout: 0,
143
+ });
144
+ const connect = agent.createConnection.bind(agent);
145
+ agent.createConnection = (connectionOptions, callback) => {
146
+ // Node assigns HTTPS proxy sockets to the request only after CONNECT completes.
147
+ const socket = connect(connectionOptions, callback);
148
+ return socket ? addAbortSignal(signal, socket) : socket;
149
+ };
150
+ const request = transport.request(
138
151
  url,
139
152
  {
140
153
  method: "POST",
141
- agent: false,
154
+ agent,
142
155
  timeout: 0,
143
156
  signal,
144
157
  headers: {
package/src/provider.ts CHANGED
@@ -146,8 +146,11 @@ function route(streams: ProviderStreams, baseUrl: string): ProviderStreams {
146
146
  ...options,
147
147
  onPayload,
148
148
  onResponse: options?.onResponse ? (response) => options.onResponse?.(response, model) : undefined,
149
+ onProviderStreamEvent: options?.onProviderStreamEvent
150
+ ? (event) => options.onProviderStreamEvent?.(event, model)
151
+ : undefined,
149
152
  });
150
- if (!backend) return run();
153
+ if (!google) return run();
151
154
  return lazyStream(model, async () => ({
152
155
  async *[Symbol.asyncIterator]() {
153
156
  for await (const event of run()) {