pi-cliproxyapi-native 0.1.4 → 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
- This release targets Pi 0.99.2 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.
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.4
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.4`. 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
 
@@ -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.4",
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"
@@ -39,9 +39,9 @@
39
39
  },
40
40
  "devDependencies": {
41
41
  "@biomejs/biome": "^2.5.13",
42
- "@earendil-works/pi-ai": "^0.99.2",
43
- "@earendil-works/pi-coding-agent": "^0.99.2",
44
- "@earendil-works/pi-tui": "^0.99.2",
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",
45
45
  "@types/node": "^24.13.4",
46
46
  "typescript": "5.9.3"
47
47
  },
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
@@ -150,7 +150,7 @@ function route(streams: ProviderStreams, baseUrl: string): ProviderStreams {
150
150
  ? (event) => options.onProviderStreamEvent?.(event, model)
151
151
  : undefined,
152
152
  });
153
- if (!backend) return run();
153
+ if (!google) return run();
154
154
  return lazyStream(model, async () => ({
155
155
  async *[Symbol.asyncIterator]() {
156
156
  for await (const event of run()) {