@henryqw/pi-multi-codex 1.0.3 → 1.0.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 +11 -15
- package/extensions/multi-codex.ts +3 -14
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -13,11 +13,11 @@ pi install npm:@henryqw/pi-multi-codex
|
|
|
13
13
|
|
|
14
14
|
## Works with
|
|
15
15
|
|
|
16
|
-
| Package |
|
|
17
|
-
| --- | --- |
|
|
18
|
-
| [`@henryqw/pi-footer`](https://pi.henry.wang/extensions/pi-footer) | Improves
|
|
19
|
-
| [`@henryqw/pi-subagent`](https://pi.henry.wang/extensions/pi-subagent) | Improves
|
|
20
|
-
| [`@henryqw/pi-task-models`](https://pi.henry.wang/extensions/pi-task-models) | Improves
|
|
16
|
+
| Package | Relationship | Purpose |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| [`@henryqw/pi-footer`](https://pi.henry.wang/extensions/pi-footer) | Improves | Shows the active slot's quota or five-hour block in the footer. |
|
|
19
|
+
| [`@henryqw/pi-subagent`](https://pi.henry.wang/extensions/pi-subagent) | Improves | Isolated children keep Main's active Codex slot. |
|
|
20
|
+
| [`@henryqw/pi-task-models`](https://pi.henry.wang/extensions/pi-task-models) | Improves | Numbered slots share one profile route. |
|
|
21
21
|
|
|
22
22
|
## Use
|
|
23
23
|
|
|
@@ -47,24 +47,20 @@ A numbered slot is one Codex account position in Pi.
|
|
|
47
47
|
|
|
48
48
|
## Config
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
Package-owned: `~/.pi/agent/config/pi-multi-codex/config.json`
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
```
|
|
52
|
+
| Name | Description | Values | Default |
|
|
53
|
+
| --- | --- | --- | --- |
|
|
54
|
+
| `autoSwitchOn429` | Switches to another eligible slot after an HTTP 429. | Boolean. | `true` |
|
|
57
55
|
|
|
58
|
-
The config must contain only
|
|
56
|
+
Set `autoSwitchOn429` to `false` to disable automatic switching. The config must contain only this field as a boolean. Invalid config is preserved and disables automatic switching.
|
|
59
57
|
|
|
60
58
|
## State and storage
|
|
61
59
|
|
|
62
60
|
The extension maintains a generated, credential-free quota cache at `~/.pi/agent/config/pi-multi-codex/usage.json`.
|
|
63
61
|
|
|
64
|
-
##
|
|
62
|
+
## Limits and recovery
|
|
65
63
|
|
|
66
64
|
The extension reads `auth.json`. It never writes or refreshes credentials.
|
|
67
65
|
|
|
68
|
-
## Limits and recovery
|
|
69
|
-
|
|
70
66
|
Scoped sessions can switch only to exact scoped aliases.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
|
-
import {
|
|
3
|
+
import { mkdir, readFile } from "node:fs/promises";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { setTimeout as delay } from "node:timers/promises";
|
|
6
|
-
import { createConfigStore, extensionConfigDir } from "@henryqw/pi-config-store";
|
|
6
|
+
import { createConfigStore, extensionConfigDir, writePrivateTextFileAtomically } from "@henryqw/pi-config-store";
|
|
7
7
|
import { lock } from "proper-lockfile";
|
|
8
8
|
import {
|
|
9
9
|
createAssistantMessageEventStream,
|
|
@@ -258,22 +258,11 @@ async function saveState(state: UsageState, signal?: AbortSignal): Promise<void>
|
|
|
258
258
|
signal?.throwIfAborted();
|
|
259
259
|
if (state.untrusted) return;
|
|
260
260
|
const file = cachePath();
|
|
261
|
-
const directory = extensionConfigDir("pi-multi-codex");
|
|
262
|
-
await mkdir(directory, { recursive: true, mode: 0o700 });
|
|
263
261
|
const data = `${JSON.stringify({
|
|
264
262
|
slots: [...state.slots.values()].sort((a, b) => a.slot - b.slot),
|
|
265
263
|
locks: [...state.locks.values()].sort((a, b) => a.slot - b.slot),
|
|
266
264
|
})}\n`;
|
|
267
|
-
|
|
268
|
-
try {
|
|
269
|
-
await writeFile(temporary, data, { encoding: "utf8", mode: 0o600, flag: "wx", signal });
|
|
270
|
-
signal?.throwIfAborted();
|
|
271
|
-
await rename(temporary, file);
|
|
272
|
-
signal?.throwIfAborted();
|
|
273
|
-
await chmod(file, 0o600);
|
|
274
|
-
} finally {
|
|
275
|
-
await rm(temporary, { force: true }).catch(() => undefined);
|
|
276
|
-
}
|
|
265
|
+
await writePrivateTextFileAtomically(file, data, { signal });
|
|
277
266
|
}
|
|
278
267
|
|
|
279
268
|
async function withCacheMutex<T>(operation: (signal: AbortSignal) => Promise<T>, signal?: AbortSignal): Promise<T> {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@henryqw/pi-multi-codex",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Use multiple ChatGPT Codex OAuth accounts in Pi.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"image": "https://raw.githubusercontent.com/HenryQW/pi-harness/main/extensions/pi-multi-codex/example.png"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@henryqw/pi-config-store": "^1.
|
|
49
|
+
"@henryqw/pi-config-store": "^1.1.0",
|
|
50
50
|
"proper-lockfile": "^4.1.2"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|