@minniexcode/codex-switch 0.1.1 → 0.1.3
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.CN.md +6 -4
- package/README.md +15 -4
- package/dist/app/add-provider.js +1 -0
- package/dist/app/bridge.js +2 -1
- package/dist/app/switch-provider.js +2 -1
- package/dist/commands/handlers.js +1 -0
- package/dist/domain/config.js +45 -1
- package/dist/domain/providers.js +1 -0
- package/dist/runtime/copilot-adapter.js +346 -70
- package/dist/runtime/copilot-bridge-worker.js +27 -2
- package/dist/runtime/copilot-bridge.js +192 -10
- package/dist/runtime/copilot-cli.js +22 -0
- package/dist/runtime/copilot-installer.js +59 -1
- package/dist/runtime/copilot-sdk-loader.js +4 -1
- package/docs/Design/codex-switch-v0.1.0-design.md +32 -152
- package/docs/Design/codex-switch-v0.1.1-design.md +15 -26
- package/docs/Design/codex-switch-v0.1.2-design.md +65 -0
- package/docs/Design/codex-switch-v0.1.3-design.md +10 -0
- package/docs/PRD/codex-switch-prd-v0.1.0.md +65 -217
- package/docs/PRD/codex-switch-prd-v0.1.1.md +26 -0
- package/docs/PRD/codex-switch-prd-v0.1.2.md +41 -0
- package/docs/PRD/codex-switch-prd-v0.1.3.md +22 -0
- package/docs/Tests/testing.md +1 -1
- package/docs/cli-usage.md +14 -4
- package/docs/codex-switch-command-design.md +1 -1
- package/docs/codex-switch-product-overview.md +7 -3
- package/docs/codex-switch-product-research.md +2 -2
- package/docs/codex-switch-technical-architecture.md +86 -1115
- package/package.json +1 -1
- package/docs/Design/codex-switch-copilot-integration-design.md +0 -517
- package/docs/Design/codex-switch-v0.0.10-design.md +0 -669
- package/docs/Design/codex-switch-v0.0.11-design.md +0 -824
- package/docs/Design/codex-switch-v0.0.12-design.md +0 -343
- package/docs/Design/codex-switch-v0.0.4-design.md +0 -874
- package/docs/Design/codex-switch-v0.0.5-design.md +0 -932
- package/docs/Design/codex-switch-v0.0.6-design.md +0 -708
- package/docs/Design/codex-switch-v0.0.7-design.md +0 -862
- package/docs/Design/codex-switch-v0.0.8-design.md +0 -132
- package/docs/Design/codex-switch-v0.0.9-design.md +0 -182
- package/docs/Design/codex-switch-v0.0.9-to-v0.0.12-roadmap.md +0 -413
- package/docs/PRD/codex-switch-prd-v0.0.10.md +0 -406
- package/docs/PRD/codex-switch-prd-v0.0.11.md +0 -577
- package/docs/PRD/codex-switch-prd-v0.0.12.md +0 -279
- package/docs/PRD/codex-switch-prd-v0.0.5-to-v0.1.0.md +0 -446
- package/docs/PRD/codex-switch-prd-v0.0.8.md +0 -62
- package/docs/PRD/codex-switch-prd-v0.0.9.md +0 -166
- package/docs/PRD/codex-switch-prd.md +0 -650
- package/docs/Tests/test-report-0.0.5.md +0 -163
- package/docs/Tests/test-report-0.0.7.md +0 -118
- package/docs/Tests/testing-bridge-v0.0.9.md +0 -367
package/README.CN.md
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
## 版本定位
|
|
8
8
|
|
|
9
|
-
当前包版本:`0.1.
|
|
9
|
+
当前包版本:`0.1.2`
|
|
10
10
|
|
|
11
|
-
这是当前稳定发布线。`0.1.
|
|
11
|
+
这是当前稳定发布线。`0.1.2` 是 Copilot runtime 修复版本,包含受管 SDK 固定版本与 Copilot 专用的 `stream_idle_timeout_ms = 300000` 投影,用于避免长 prompt 的空闲超时。
|
|
12
12
|
|
|
13
13
|
## 安装
|
|
14
14
|
|
|
@@ -205,8 +205,10 @@ npm pack --dry-run
|
|
|
205
205
|
- [详细 CLI 文档](./docs/cli-usage.md)
|
|
206
206
|
- [产品概览](./docs/codex-switch-product-overview.md)
|
|
207
207
|
- [测试说明](./docs/Tests/testing.md)
|
|
208
|
-
- [
|
|
209
|
-
- [
|
|
208
|
+
- [PRD 0.1.1](./docs/PRD/codex-switch-prd-v0.1.1.md)
|
|
209
|
+
- [Design 0.1.1](./docs/Design/codex-switch-v0.1.1-design.md)
|
|
210
|
+
- [PRD 0.1.2](./docs/PRD/codex-switch-prd-v0.1.2.md)
|
|
211
|
+
- [Design 0.1.2](./docs/Design/codex-switch-v0.1.2-design.md)
|
|
210
212
|
|
|
211
213
|
## License
|
|
212
214
|
|
package/README.md
CHANGED
|
@@ -8,9 +8,9 @@ Chinese version: [README.CN.md](./README.CN.md)
|
|
|
8
8
|
|
|
9
9
|
## Version
|
|
10
10
|
|
|
11
|
-
Current package version: `0.1.
|
|
11
|
+
Current package version: `0.1.3`
|
|
12
12
|
|
|
13
|
-
This is the current stable
|
|
13
|
+
This is the current stable documentation line. `0.1.3` is the Copilot login hotfix release, repairing the managed SDK client construction against the current official Copilot SDK runtime while keeping the `stream_idle_timeout_ms = 300000` Copilot projection unchanged.
|
|
14
14
|
|
|
15
15
|
## Install
|
|
16
16
|
|
|
@@ -58,6 +58,7 @@ Notes:
|
|
|
58
58
|
- `init` prepares the `codex-switch` tool home and managed state.
|
|
59
59
|
- `login copilot` handles upstream Copilot onboarding and auth readiness.
|
|
60
60
|
- `add --copilot` does not perform login for you; it assumes Copilot login is already ready.
|
|
61
|
+
- Copilot support is an experimental local bridge. The managed installer defaults to `@github/copilot-sdk@1.0.2`, Copilot runtime paths require Node.js `>=20`, and runtime checks separately reject older or prerelease SDK installs while validating API shape when the client or session is used.
|
|
61
62
|
- `switch` projects the selected provider into the target Codex runtime as top-level `model` plus `model_provider`.
|
|
62
63
|
- `status` is the main read command after switching.
|
|
63
64
|
- `doctor` is the main repair-oriented diagnostic command.
|
|
@@ -95,6 +96,12 @@ wire_api = "responses"
|
|
|
95
96
|
requires_openai_auth = true
|
|
96
97
|
```
|
|
97
98
|
|
|
99
|
+
Managed Copilot projection additionally writes:
|
|
100
|
+
|
|
101
|
+
```toml
|
|
102
|
+
stream_idle_timeout_ms = 300000
|
|
103
|
+
```
|
|
104
|
+
|
|
98
105
|
## Advanced Adopt Workflow
|
|
99
106
|
|
|
100
107
|
Use `migrate` only when you already have Codex runtime state that should be adopted into managed `providers.json` state:
|
|
@@ -207,8 +214,12 @@ npm pack --dry-run
|
|
|
207
214
|
- [Detailed CLI Usage](./docs/cli-usage.md)
|
|
208
215
|
- [Testing Guide](./docs/Tests/testing.md)
|
|
209
216
|
- [Product Overview](./docs/codex-switch-product-overview.md)
|
|
210
|
-
- [
|
|
211
|
-
- [
|
|
217
|
+
- [PRD 0.1.0](./docs/PRD/codex-switch-prd-v0.1.0.md)
|
|
218
|
+
- [PRD 0.1.1](./docs/PRD/codex-switch-prd-v0.1.1.md)
|
|
219
|
+
- [PRD 0.1.2](./docs/PRD/codex-switch-prd-v0.1.2.md)
|
|
220
|
+
- [PRD 0.1.3](./docs/PRD/codex-switch-prd-v0.1.3.md)
|
|
221
|
+
- [Design 0.1.2](./docs/Design/codex-switch-v0.1.2-design.md)
|
|
222
|
+
- [Design 0.1.3](./docs/Design/codex-switch-v0.1.3-design.md)
|
|
212
223
|
|
|
213
224
|
## License
|
|
214
225
|
|
package/dist/app/add-provider.js
CHANGED
|
@@ -67,6 +67,7 @@ async function addProvider(args) {
|
|
|
67
67
|
}
|
|
68
68
|
: undefined;
|
|
69
69
|
if (args.copilot) {
|
|
70
|
+
(0, copilot_installer_1.assertCopilotNodeRuntimeSupported)();
|
|
70
71
|
const installStatus = (0, copilot_installer_1.probeCopilotSdkInstall)(args.runtimesDir);
|
|
71
72
|
if (!installStatus.installed) {
|
|
72
73
|
throw (0, errors_1.cliError)("COPILOT_SDK_MISSING", "The optional Copilot SDK runtime is not installed. Run `codexs login copilot` first.", {
|
package/dist/app/bridge.js
CHANGED
|
@@ -29,7 +29,7 @@ async function startBridge(args) {
|
|
|
29
29
|
preferRuntimeState: false,
|
|
30
30
|
});
|
|
31
31
|
await requireBridgeRuntimeReadiness(args.runtimesDir);
|
|
32
|
-
const bridge = await (0, copilot_bridge_1.ensureCopilotBridge)(target.providerName, target.provider, args.runtimeDir);
|
|
32
|
+
const bridge = await (0, copilot_bridge_1.ensureCopilotBridge)(target.providerName, target.provider, args.runtimeDir, args.runtimesDir);
|
|
33
33
|
const nextProvider = bridge.portChanged ? rewriteBridgeProviderPort(target.provider, bridge.port) : target.provider;
|
|
34
34
|
if (bridge.portChanged) {
|
|
35
35
|
try {
|
|
@@ -242,6 +242,7 @@ async function promptForCopilotBridgeSelection(runtime, targets, commandName) {
|
|
|
242
242
|
* Verifies that the local Copilot bridge prerequisites are available before startup.
|
|
243
243
|
*/
|
|
244
244
|
async function requireBridgeRuntimeReadiness(runtimesDir) {
|
|
245
|
+
(0, copilot_installer_1.assertCopilotNodeRuntimeSupported)();
|
|
245
246
|
const installStatus = (0, copilot_installer_1.probeCopilotSdkInstall)(runtimesDir);
|
|
246
247
|
if (!installStatus.installed) {
|
|
247
248
|
throw (0, errors_1.cliError)("COPILOT_SDK_MISSING", "The optional Copilot SDK runtime is not installed.", {
|
|
@@ -31,6 +31,7 @@ async function switchProvider(args) {
|
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
if ((0, providers_1.isCopilotBridgeProvider)(provider)) {
|
|
34
|
+
(0, copilot_installer_1.assertCopilotNodeRuntimeSupported)();
|
|
34
35
|
const installStatus = (0, copilot_installer_1.probeCopilotSdkInstall)(args.runtimesDir);
|
|
35
36
|
if (!installStatus.installed) {
|
|
36
37
|
throw (0, errors_1.cliError)("COPILOT_SDK_MISSING", "The optional Copilot SDK runtime is not installed.", {
|
|
@@ -39,7 +40,7 @@ async function switchProvider(args) {
|
|
|
39
40
|
});
|
|
40
41
|
}
|
|
41
42
|
await (0, copilot_adapter_1.readCopilotAuthState)(args.runtimesDir);
|
|
42
|
-
const bridge = await (0, copilot_bridge_1.ensureCopilotBridge)(args.providerName, provider, args.runtimeDir);
|
|
43
|
+
const bridge = await (0, copilot_bridge_1.ensureCopilotBridge)(args.providerName, provider, args.runtimeDir, args.runtimesDir);
|
|
43
44
|
const nextProvider = bridge.portChanged
|
|
44
45
|
? (0, providers_1.cleanProviderRecord)({
|
|
45
46
|
...provider,
|
|
@@ -156,6 +156,7 @@ async function handleRegisteredCommand(ctx, parsed, runtime = (0, prompt_1.creat
|
|
|
156
156
|
supportedUpstreams: ["copilot", "github-copilot"],
|
|
157
157
|
});
|
|
158
158
|
}
|
|
159
|
+
(0, copilot_installer_1.assertCopilotNodeRuntimeSupported)();
|
|
159
160
|
const installed = (0, copilot_installer_1.probeCopilotSdkInstall)(paths.runtimesDir);
|
|
160
161
|
let installedNow = false;
|
|
161
162
|
if (!installed.installed) {
|
package/dist/domain/config.js
CHANGED
|
@@ -133,6 +133,8 @@ function parseStructuredConfig(configContent) {
|
|
|
133
133
|
requiresOpenAiAuth: null,
|
|
134
134
|
wireApiValueRange: null,
|
|
135
135
|
wireApi: null,
|
|
136
|
+
streamIdleTimeoutMsValueRange: null,
|
|
137
|
+
streamIdleTimeoutMs: null,
|
|
136
138
|
envKeyValueRange: null,
|
|
137
139
|
envKey: null,
|
|
138
140
|
envKeyInstructionsValueRange: null,
|
|
@@ -209,6 +211,11 @@ function parseStructuredConfig(configContent) {
|
|
|
209
211
|
currentModelProviderSection.wireApi = wireApiMatch.value;
|
|
210
212
|
currentModelProviderSection.wireApiValueRange = toAbsoluteRange(line.start, wireApiMatch.valueStart, wireApiMatch.valueEnd);
|
|
211
213
|
}
|
|
214
|
+
const streamIdleTimeoutMsMatch = matchNumberKeyValueLine(line.content, "stream_idle_timeout_ms");
|
|
215
|
+
if (streamIdleTimeoutMsMatch) {
|
|
216
|
+
currentModelProviderSection.streamIdleTimeoutMs = streamIdleTimeoutMsMatch.value;
|
|
217
|
+
currentModelProviderSection.streamIdleTimeoutMsValueRange = toAbsoluteRange(line.start, streamIdleTimeoutMsMatch.valueStart, streamIdleTimeoutMsMatch.valueEnd);
|
|
218
|
+
}
|
|
212
219
|
const envKeyMatch = matchKeyValueLine(line.content, "env_key");
|
|
213
220
|
if (envKeyMatch) {
|
|
214
221
|
currentModelProviderSection.envKey = envKeyMatch.value;
|
|
@@ -481,7 +488,10 @@ function planConfigMutation(document, args) {
|
|
|
481
488
|
`base_url = ${JSON.stringify(normalizedFields.baseUrl)}${document.lineEnding}` +
|
|
482
489
|
`name = ${JSON.stringify(normalizedFields.name)}${document.lineEnding}` +
|
|
483
490
|
`requires_openai_auth = ${String(normalizedFields.requiresOpenAiAuth)}${document.lineEnding}` +
|
|
484
|
-
`wire_api = ${JSON.stringify(normalizedFields.wireApi)}${document.lineEnding}
|
|
491
|
+
`wire_api = ${JSON.stringify(normalizedFields.wireApi)}${document.lineEnding}` +
|
|
492
|
+
(normalizedFields.streamIdleTimeoutMs !== undefined
|
|
493
|
+
? `stream_idle_timeout_ms = ${String(normalizedFields.streamIdleTimeoutMs)}${document.lineEnding}`
|
|
494
|
+
: ""),
|
|
485
495
|
});
|
|
486
496
|
createdModelProviderSections.push(profileName);
|
|
487
497
|
continue;
|
|
@@ -597,6 +607,7 @@ function planModelProviderFieldMutation(document, section, fields, operations) {
|
|
|
597
607
|
const nameText = JSON.stringify(fields.name);
|
|
598
608
|
const requiresOpenAiAuthText = String(fields.requiresOpenAiAuth);
|
|
599
609
|
const wireApiText = JSON.stringify(fields.wireApi);
|
|
610
|
+
const streamIdleTimeoutMsText = fields.streamIdleTimeoutMs !== undefined ? String(fields.streamIdleTimeoutMs) : null;
|
|
600
611
|
const inserts = [];
|
|
601
612
|
if (section.baseUrlValueRange) {
|
|
602
613
|
if (section.baseUrl !== fields.baseUrl) {
|
|
@@ -658,6 +669,23 @@ function planModelProviderFieldMutation(document, section, fields, operations) {
|
|
|
658
669
|
inserts.push(`wire_api = ${wireApiText}`);
|
|
659
670
|
updated = true;
|
|
660
671
|
}
|
|
672
|
+
if (streamIdleTimeoutMsText !== null) {
|
|
673
|
+
if (section.streamIdleTimeoutMsValueRange) {
|
|
674
|
+
if (section.streamIdleTimeoutMs !== fields.streamIdleTimeoutMs) {
|
|
675
|
+
operations.push({
|
|
676
|
+
kind: "replace-range",
|
|
677
|
+
start: section.streamIdleTimeoutMsValueRange.start,
|
|
678
|
+
end: section.streamIdleTimeoutMsValueRange.end,
|
|
679
|
+
text: streamIdleTimeoutMsText,
|
|
680
|
+
});
|
|
681
|
+
updated = true;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
inserts.push(`stream_idle_timeout_ms = ${streamIdleTimeoutMsText}`);
|
|
686
|
+
updated = true;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
661
689
|
if (inserts.length > 0) {
|
|
662
690
|
operations.push({
|
|
663
691
|
kind: "insert-at",
|
|
@@ -713,6 +741,7 @@ function normalizeManagedModelProviderFields(profileName, fields) {
|
|
|
713
741
|
name: fields.name?.trim() || profileName,
|
|
714
742
|
requiresOpenAiAuth: fields.requiresOpenAiAuth ?? true,
|
|
715
743
|
wireApi: fields.wireApi?.trim() || "responses",
|
|
744
|
+
streamIdleTimeoutMs: fields.streamIdleTimeoutMs,
|
|
716
745
|
};
|
|
717
746
|
}
|
|
718
747
|
function splitWithOffsets(value) {
|
|
@@ -773,6 +802,21 @@ function matchBooleanKeyValueLine(line, key) {
|
|
|
773
802
|
valueEnd,
|
|
774
803
|
};
|
|
775
804
|
}
|
|
805
|
+
function matchNumberKeyValueLine(line, key) {
|
|
806
|
+
const match = line.match(new RegExp(`^\\s*${escapeRegExp(key)}\\s*=\\s*(\\d+)\\s*(#.*)?$`));
|
|
807
|
+
if (!match || match.index === undefined) {
|
|
808
|
+
return null;
|
|
809
|
+
}
|
|
810
|
+
const valueStart = line.indexOf(match[1], match.index);
|
|
811
|
+
if (valueStart === -1) {
|
|
812
|
+
return null;
|
|
813
|
+
}
|
|
814
|
+
return {
|
|
815
|
+
value: Number(match[1]),
|
|
816
|
+
valueStart,
|
|
817
|
+
valueEnd: valueStart + match[1].length,
|
|
818
|
+
};
|
|
819
|
+
}
|
|
776
820
|
function findManagedFieldInsertIndex(rawText, sectionStart, sectionEnd) {
|
|
777
821
|
const sectionText = rawText.slice(sectionStart, sectionEnd);
|
|
778
822
|
const lines = splitWithOffsets(sectionText);
|