swixter 0.1.10 → 0.1.12
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/dist/cli/index.js +509 -87
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -14021,7 +14021,7 @@ var CONFIG_VERSION = "2.0.0", EXPORT_VERSION = "1.0.0";
|
|
|
14021
14021
|
var init_versions2 = () => {};
|
|
14022
14022
|
|
|
14023
14023
|
// src/constants/meta.ts
|
|
14024
|
-
var APP_VERSION = "0.1.
|
|
14024
|
+
var APP_VERSION = "0.1.12";
|
|
14025
14025
|
var init_meta = () => {};
|
|
14026
14026
|
|
|
14027
14027
|
// src/constants/install.ts
|
|
@@ -14459,6 +14459,7 @@ var init_presets = __esm(() => {
|
|
|
14459
14459
|
name: "MiniMax CN",
|
|
14460
14460
|
displayName: "MiniMax (CN)",
|
|
14461
14461
|
baseURL: "https://api.minimaxi.com/anthropic",
|
|
14462
|
+
baseURLChat: "https://api.minimaxi.com/v1",
|
|
14462
14463
|
defaultModels: [
|
|
14463
14464
|
"MiniMax-M2.7"
|
|
14464
14465
|
],
|
|
@@ -14474,6 +14475,7 @@ var init_presets = __esm(() => {
|
|
|
14474
14475
|
name: "MiniMax Global",
|
|
14475
14476
|
displayName: "MiniMax (Global)",
|
|
14476
14477
|
baseURL: "https://api.minimax.io/anthropic",
|
|
14478
|
+
baseURLChat: "https://api.minimax.io/v1",
|
|
14477
14479
|
defaultModels: [
|
|
14478
14480
|
"MiniMax-M2.7"
|
|
14479
14481
|
],
|
|
@@ -18986,10 +18988,12 @@ import { join as join3, dirname as dirname4 } from "node:path";
|
|
|
18986
18988
|
class CodexAdapter {
|
|
18987
18989
|
name = "codex";
|
|
18988
18990
|
configPath;
|
|
18989
|
-
authPath;
|
|
18990
18991
|
constructor() {
|
|
18991
|
-
|
|
18992
|
-
this.
|
|
18992
|
+
const codexHome = join3(homedir2(), ".codex");
|
|
18993
|
+
this.configPath = join3(codexHome, "config.toml");
|
|
18994
|
+
}
|
|
18995
|
+
getProfileFilePath(profileName) {
|
|
18996
|
+
return join3(dirname4(this.configPath), `swixter-${profileName}.config.toml`);
|
|
18993
18997
|
}
|
|
18994
18998
|
async apply(profile) {
|
|
18995
18999
|
try {
|
|
@@ -19019,15 +19023,17 @@ class CodexAdapter {
|
|
|
19019
19023
|
config2.model_providers = {};
|
|
19020
19024
|
}
|
|
19021
19025
|
config2.model_providers[providerName] = await this.createProviderTable(profile, preset);
|
|
19022
|
-
if (!config2.profiles) {
|
|
19023
|
-
config2.profiles = {};
|
|
19024
|
-
}
|
|
19025
|
-
config2.profiles[profileName] = await this.createProfileTable(profile, providerName);
|
|
19026
|
-
config2.profile = profileName;
|
|
19027
19026
|
config2.model_provider = providerName;
|
|
19027
|
+
delete config2.profile;
|
|
19028
|
+
if (config2.profiles) {
|
|
19029
|
+
delete config2.profiles[profileName];
|
|
19030
|
+
if (Object.keys(config2.profiles).length === 0) {
|
|
19031
|
+
delete config2.profiles;
|
|
19032
|
+
}
|
|
19033
|
+
}
|
|
19028
19034
|
const tomlContent = stringify(config2);
|
|
19029
19035
|
await writeFile4(this.configPath, tomlContent, "utf-8");
|
|
19030
|
-
await this.
|
|
19036
|
+
await this.writeProfileFile(profile, providerName);
|
|
19031
19037
|
} catch (error46) {
|
|
19032
19038
|
throw new Error(`Failed to apply Codex configuration: ${error46 instanceof Error ? error46.message : String(error46)}`);
|
|
19033
19039
|
}
|
|
@@ -19039,32 +19045,24 @@ class CodexAdapter {
|
|
|
19039
19045
|
}
|
|
19040
19046
|
const content = await readFile4(this.configPath, "utf-8");
|
|
19041
19047
|
const config2 = parse5(content);
|
|
19042
|
-
const
|
|
19043
|
-
if (config2.
|
|
19048
|
+
const providerName = `swixter-${profile.name}`;
|
|
19049
|
+
if (config2.model_provider !== providerName) {
|
|
19044
19050
|
return false;
|
|
19045
19051
|
}
|
|
19046
|
-
if (!config2.
|
|
19052
|
+
if (!config2.model_providers || !config2.model_providers[providerName]) {
|
|
19047
19053
|
return false;
|
|
19048
19054
|
}
|
|
19049
|
-
const
|
|
19050
|
-
if (!
|
|
19055
|
+
const profileFilePath = this.getProfileFilePath(profile.name);
|
|
19056
|
+
if (!existsSync4(profileFilePath)) {
|
|
19051
19057
|
return false;
|
|
19052
19058
|
}
|
|
19053
|
-
|
|
19054
|
-
const
|
|
19055
|
-
if (
|
|
19056
|
-
try {
|
|
19057
|
-
const authContent = await readFile4(this.authPath, "utf-8");
|
|
19058
|
-
const auth = JSON.parse(authContent);
|
|
19059
|
-
if (auth[envKey] !== profile.apiKey) {
|
|
19060
|
-
return false;
|
|
19061
|
-
}
|
|
19062
|
-
} catch {
|
|
19063
|
-
return false;
|
|
19064
|
-
}
|
|
19065
|
-
} else {
|
|
19059
|
+
try {
|
|
19060
|
+
const profileFile = parse5(await readFile4(profileFilePath, "utf-8"));
|
|
19061
|
+
if (profileFile.model_provider !== providerName) {
|
|
19066
19062
|
return false;
|
|
19067
19063
|
}
|
|
19064
|
+
} catch {
|
|
19065
|
+
return false;
|
|
19068
19066
|
}
|
|
19069
19067
|
return true;
|
|
19070
19068
|
} catch (error46) {
|
|
@@ -19076,8 +19074,7 @@ class CodexAdapter {
|
|
|
19076
19074
|
const providerTable = {
|
|
19077
19075
|
name: preset.displayName,
|
|
19078
19076
|
base_url: profile.baseURL || baseUrl,
|
|
19079
|
-
wire_api: "responses"
|
|
19080
|
-
requires_openai_auth: true
|
|
19077
|
+
wire_api: "responses"
|
|
19081
19078
|
};
|
|
19082
19079
|
providerTable.env_key = await getEnvKey(profile);
|
|
19083
19080
|
if (preset.headers) {
|
|
@@ -19085,45 +19082,21 @@ class CodexAdapter {
|
|
|
19085
19082
|
}
|
|
19086
19083
|
return providerTable;
|
|
19087
19084
|
}
|
|
19088
|
-
async
|
|
19089
|
-
const
|
|
19085
|
+
async writeProfileFile(profile, providerName) {
|
|
19086
|
+
const profileContent = {
|
|
19090
19087
|
model_provider: providerName
|
|
19091
19088
|
};
|
|
19092
19089
|
const modelValue = getOpenAIModel(profile);
|
|
19093
19090
|
if (modelValue) {
|
|
19094
|
-
|
|
19091
|
+
profileContent.model = modelValue;
|
|
19095
19092
|
} else {
|
|
19096
19093
|
const preset = await getPresetByIdAsync(profile.providerId);
|
|
19097
19094
|
if (preset && preset.defaultModels && preset.defaultModels.length > 0) {
|
|
19098
|
-
|
|
19095
|
+
profileContent.model = preset.defaultModels[0];
|
|
19099
19096
|
}
|
|
19100
19097
|
}
|
|
19101
|
-
|
|
19102
|
-
|
|
19103
|
-
async writeAuthJson(profile) {
|
|
19104
|
-
const envKey = await getEnvKey(profile);
|
|
19105
|
-
let auth = {};
|
|
19106
|
-
if (existsSync4(this.authPath)) {
|
|
19107
|
-
try {
|
|
19108
|
-
const content = await readFile4(this.authPath, "utf-8");
|
|
19109
|
-
const parsed = JSON.parse(content);
|
|
19110
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
19111
|
-
auth = parsed;
|
|
19112
|
-
}
|
|
19113
|
-
} catch {
|
|
19114
|
-
auth = {};
|
|
19115
|
-
}
|
|
19116
|
-
}
|
|
19117
|
-
if (profile.apiKey) {
|
|
19118
|
-
auth[envKey] = profile.apiKey;
|
|
19119
|
-
} else {
|
|
19120
|
-
delete auth[envKey];
|
|
19121
|
-
}
|
|
19122
|
-
if (Object.keys(auth).length > 0) {
|
|
19123
|
-
await writeFile4(this.authPath, JSON.stringify(auth, null, 2), "utf-8");
|
|
19124
|
-
} else if (existsSync4(this.authPath)) {
|
|
19125
|
-
await unlink(this.authPath);
|
|
19126
|
-
}
|
|
19098
|
+
const profileFilePath = this.getProfileFilePath(profile.name);
|
|
19099
|
+
await writeFile4(profileFilePath, stringify(profileContent), "utf-8");
|
|
19127
19100
|
}
|
|
19128
19101
|
async getEnvExportCommands(profile) {
|
|
19129
19102
|
const commands = await getEnvExportCommands(profile);
|
|
@@ -19134,6 +19107,12 @@ class CodexAdapter {
|
|
|
19134
19107
|
return commands;
|
|
19135
19108
|
}
|
|
19136
19109
|
async remove(profileName) {
|
|
19110
|
+
const profileFilePath = this.getProfileFilePath(profileName);
|
|
19111
|
+
if (existsSync4(profileFilePath)) {
|
|
19112
|
+
try {
|
|
19113
|
+
await unlink(profileFilePath);
|
|
19114
|
+
} catch {}
|
|
19115
|
+
}
|
|
19137
19116
|
if (!existsSync4(this.configPath)) {
|
|
19138
19117
|
return;
|
|
19139
19118
|
}
|
|
@@ -19141,20 +19120,23 @@ class CodexAdapter {
|
|
|
19141
19120
|
const content = await readFile4(this.configPath, "utf-8");
|
|
19142
19121
|
const config2 = parse5(content);
|
|
19143
19122
|
const providerKey = `swixter-${profileName}`;
|
|
19144
|
-
const profileKey = `swixter-${profileName}`;
|
|
19145
19123
|
let modified = false;
|
|
19146
|
-
let envKeyToRemove;
|
|
19147
19124
|
if (config2.model_providers && config2.model_providers[providerKey]) {
|
|
19148
|
-
envKeyToRemove = config2.model_providers[providerKey].env_key;
|
|
19149
19125
|
delete config2.model_providers[providerKey];
|
|
19150
19126
|
modified = true;
|
|
19151
19127
|
}
|
|
19152
|
-
if (config2.profiles && config2.profiles[
|
|
19153
|
-
delete config2.profiles[
|
|
19128
|
+
if (config2.profiles && config2.profiles[providerKey]) {
|
|
19129
|
+
delete config2.profiles[providerKey];
|
|
19130
|
+
if (Object.keys(config2.profiles).length === 0) {
|
|
19131
|
+
delete config2.profiles;
|
|
19132
|
+
}
|
|
19154
19133
|
modified = true;
|
|
19155
19134
|
}
|
|
19156
|
-
if (config2.profile ===
|
|
19135
|
+
if (config2.profile === providerKey) {
|
|
19157
19136
|
delete config2.profile;
|
|
19137
|
+
modified = true;
|
|
19138
|
+
}
|
|
19139
|
+
if (config2.model_provider === providerKey) {
|
|
19158
19140
|
delete config2.model_provider;
|
|
19159
19141
|
modified = true;
|
|
19160
19142
|
}
|
|
@@ -19162,14 +19144,6 @@ class CodexAdapter {
|
|
|
19162
19144
|
const tomlContent = stringify(config2);
|
|
19163
19145
|
await writeFile4(this.configPath, tomlContent, "utf-8");
|
|
19164
19146
|
}
|
|
19165
|
-
if (envKeyToRemove && existsSync4(this.authPath)) {
|
|
19166
|
-
try {
|
|
19167
|
-
const authContent = await readFile4(this.authPath, "utf-8");
|
|
19168
|
-
const auth = JSON.parse(authContent);
|
|
19169
|
-
delete auth[envKeyToRemove];
|
|
19170
|
-
await writeFile4(this.authPath, JSON.stringify(auth, null, 2), "utf-8");
|
|
19171
|
-
} catch {}
|
|
19172
|
-
}
|
|
19173
19147
|
} catch (error46) {
|
|
19174
19148
|
console.warn(`Failed to remove profile from Codex config: ${error46}`);
|
|
19175
19149
|
}
|
|
@@ -19180,6 +19154,7 @@ var init_codex = __esm(() => {
|
|
|
19180
19154
|
init_presets();
|
|
19181
19155
|
init_model_helper();
|
|
19182
19156
|
init_env_key_helper();
|
|
19157
|
+
init_env_key_helper();
|
|
19183
19158
|
});
|
|
19184
19159
|
|
|
19185
19160
|
// src/adapters/index.ts
|
|
@@ -25718,19 +25693,23 @@ function parseSSEEvents(chunk) {
|
|
|
25718
25693
|
if (currentDataLines.length > 0) {
|
|
25719
25694
|
const dataStr = currentDataLines.join(`
|
|
25720
25695
|
`);
|
|
25721
|
-
|
|
25722
|
-
|
|
25723
|
-
|
|
25724
|
-
|
|
25696
|
+
if (dataStr === "[DONE]") {
|
|
25697
|
+
events.push({ event: currentEvent, data: "[DONE]" });
|
|
25698
|
+
} else {
|
|
25699
|
+
try {
|
|
25700
|
+
const data = JSON.parse(dataStr);
|
|
25701
|
+
events.push({ event: currentEvent, data });
|
|
25702
|
+
} catch {}
|
|
25703
|
+
}
|
|
25725
25704
|
}
|
|
25726
25705
|
currentEvent = "";
|
|
25727
25706
|
currentDataLines = [];
|
|
25728
25707
|
}
|
|
25729
25708
|
for (const line of lines) {
|
|
25730
|
-
if (line.startsWith("event:
|
|
25731
|
-
currentEvent = line.slice("event:
|
|
25732
|
-
} else if (line.startsWith("data:
|
|
25733
|
-
currentDataLines.push(line.slice("data:
|
|
25709
|
+
if (line.startsWith("event:")) {
|
|
25710
|
+
currentEvent = line.slice("event:".length).replace(/^ /, "");
|
|
25711
|
+
} else if (line.startsWith("data:")) {
|
|
25712
|
+
currentDataLines.push(line.slice("data:".length).replace(/^ /, ""));
|
|
25734
25713
|
} else if (line === "") {
|
|
25735
25714
|
flushEvent();
|
|
25736
25715
|
}
|
|
@@ -25889,7 +25868,7 @@ function inferClientFormat(endpoint) {
|
|
|
25889
25868
|
return "openai_chat";
|
|
25890
25869
|
}
|
|
25891
25870
|
if (endpoint.includes("/v1/responses")) {
|
|
25892
|
-
return "
|
|
25871
|
+
return "openai_responses";
|
|
25893
25872
|
}
|
|
25894
25873
|
if (endpoint.includes("/anthropic/") || endpoint.includes("/v1/messages")) {
|
|
25895
25874
|
return "anthropic_messages";
|
|
@@ -26412,6 +26391,446 @@ var init_openai_chat_to_anthropic2 = __esm(() => {
|
|
|
26412
26391
|
});
|
|
26413
26392
|
});
|
|
26414
26393
|
|
|
26394
|
+
// src/proxy/transform/request/openai-responses-to-openai-chat.ts
|
|
26395
|
+
function openaiResponsesToOpenAIChatRequest(body, _ctx) {
|
|
26396
|
+
const r2 = body;
|
|
26397
|
+
const chatBody = { model: r2.model };
|
|
26398
|
+
const messages2 = [];
|
|
26399
|
+
if (typeof r2.instructions === "string" && r2.instructions.length > 0) {
|
|
26400
|
+
messages2.push({ role: "system", content: r2.instructions });
|
|
26401
|
+
}
|
|
26402
|
+
if (Array.isArray(r2.input)) {
|
|
26403
|
+
for (const item of r2.input) {
|
|
26404
|
+
const converted = convertInputItem(item);
|
|
26405
|
+
if (Array.isArray(converted))
|
|
26406
|
+
messages2.push(...converted);
|
|
26407
|
+
else if (converted)
|
|
26408
|
+
messages2.push(converted);
|
|
26409
|
+
}
|
|
26410
|
+
} else if (typeof r2.input === "string" && r2.input.length > 0) {
|
|
26411
|
+
messages2.push({ role: "user", content: r2.input });
|
|
26412
|
+
}
|
|
26413
|
+
chatBody.messages = messages2;
|
|
26414
|
+
if (r2.max_output_tokens !== undefined)
|
|
26415
|
+
chatBody.max_tokens = r2.max_output_tokens;
|
|
26416
|
+
if (r2.temperature !== undefined)
|
|
26417
|
+
chatBody.temperature = r2.temperature;
|
|
26418
|
+
if (r2.top_p !== undefined)
|
|
26419
|
+
chatBody.top_p = r2.top_p;
|
|
26420
|
+
if (r2.stream !== undefined)
|
|
26421
|
+
chatBody.stream = r2.stream;
|
|
26422
|
+
if (r2.parallel_tool_calls !== undefined)
|
|
26423
|
+
chatBody.parallel_tool_calls = r2.parallel_tool_calls;
|
|
26424
|
+
if (Array.isArray(r2.tools)) {
|
|
26425
|
+
chatBody.tools = r2.tools.filter((t) => {
|
|
26426
|
+
const name = t.name;
|
|
26427
|
+
if (typeof name !== "string" || name.length === 0)
|
|
26428
|
+
return false;
|
|
26429
|
+
return TOOL_NAME_RE.test(name);
|
|
26430
|
+
}).map((t) => ({
|
|
26431
|
+
type: "function",
|
|
26432
|
+
function: {
|
|
26433
|
+
name: t.name,
|
|
26434
|
+
description: t.description,
|
|
26435
|
+
parameters: t.parameters && typeof t.parameters === "object" ? t.parameters : { type: "object", properties: {} }
|
|
26436
|
+
}
|
|
26437
|
+
}));
|
|
26438
|
+
}
|
|
26439
|
+
if (r2.tool_choice !== undefined)
|
|
26440
|
+
chatBody.tool_choice = convertToolChoice2(r2.tool_choice);
|
|
26441
|
+
const effort = r2.reasoning?.effort;
|
|
26442
|
+
if (typeof effort === "string")
|
|
26443
|
+
chatBody.reasoning_effort = effort;
|
|
26444
|
+
return { body: chatBody, targetEndpoint: "/v1/chat/completions" };
|
|
26445
|
+
}
|
|
26446
|
+
function convertInputItem(item) {
|
|
26447
|
+
switch (item.type) {
|
|
26448
|
+
case "message": {
|
|
26449
|
+
const role = item.role === "developer" ? "system" : item.role;
|
|
26450
|
+
return { role, content: flattenText(item.content) };
|
|
26451
|
+
}
|
|
26452
|
+
case "function_call": {
|
|
26453
|
+
return {
|
|
26454
|
+
role: "assistant",
|
|
26455
|
+
content: null,
|
|
26456
|
+
tool_calls: [{ id: item.call_id, type: "function", function: { name: item.name, arguments: item.arguments ?? "" } }]
|
|
26457
|
+
};
|
|
26458
|
+
}
|
|
26459
|
+
case "function_call_output": {
|
|
26460
|
+
return {
|
|
26461
|
+
role: "tool",
|
|
26462
|
+
tool_call_id: item.call_id,
|
|
26463
|
+
content: typeof item.output === "string" ? item.output : JSON.stringify(item.output ?? "")
|
|
26464
|
+
};
|
|
26465
|
+
}
|
|
26466
|
+
default:
|
|
26467
|
+
return null;
|
|
26468
|
+
}
|
|
26469
|
+
}
|
|
26470
|
+
function flattenText(content) {
|
|
26471
|
+
if (typeof content === "string")
|
|
26472
|
+
return content;
|
|
26473
|
+
if (!Array.isArray(content))
|
|
26474
|
+
return content;
|
|
26475
|
+
const parts = [];
|
|
26476
|
+
for (const part of content) {
|
|
26477
|
+
if (part.type === "input_text" || part.type === "output_text" || part.type === "text") {
|
|
26478
|
+
parts.push({ type: "text", text: part.text });
|
|
26479
|
+
} else {
|
|
26480
|
+
throw new Error(`openai_responses→openai_chat: unsupported content part type "${part.type}"`);
|
|
26481
|
+
}
|
|
26482
|
+
}
|
|
26483
|
+
if (parts.length === 1 && parts[0].type === "text") {
|
|
26484
|
+
return parts[0].text;
|
|
26485
|
+
}
|
|
26486
|
+
return parts;
|
|
26487
|
+
}
|
|
26488
|
+
function convertToolChoice2(tc) {
|
|
26489
|
+
if (typeof tc === "string")
|
|
26490
|
+
return tc;
|
|
26491
|
+
if (tc && typeof tc === "object") {
|
|
26492
|
+
const t = tc;
|
|
26493
|
+
if (t.type === "function" && t.name) {
|
|
26494
|
+
return { type: "function", function: { name: t.name } };
|
|
26495
|
+
}
|
|
26496
|
+
}
|
|
26497
|
+
return tc;
|
|
26498
|
+
}
|
|
26499
|
+
var TOOL_NAME_RE;
|
|
26500
|
+
var init_openai_responses_to_openai_chat = __esm(() => {
|
|
26501
|
+
TOOL_NAME_RE = /^(?!.*__)[a-zA-Z][a-zA-Z0-9_-]{0,63}$/;
|
|
26502
|
+
});
|
|
26503
|
+
|
|
26504
|
+
// src/proxy/transform/response/openai-chat-to-openai-responses.ts
|
|
26505
|
+
function openAIChatToOpenAIResponsesResponse(body, _ctx) {
|
|
26506
|
+
const chat = body;
|
|
26507
|
+
const choices = chat.choices;
|
|
26508
|
+
const choice = choices?.[0];
|
|
26509
|
+
const message = choice?.message;
|
|
26510
|
+
const output = [];
|
|
26511
|
+
if (message) {
|
|
26512
|
+
if (typeof message.content === "string" && message.content.length > 0) {
|
|
26513
|
+
output.push({
|
|
26514
|
+
type: "message",
|
|
26515
|
+
id: "msg_0",
|
|
26516
|
+
status: "completed",
|
|
26517
|
+
role: "assistant",
|
|
26518
|
+
content: [{ type: "output_text", text: message.content, annotations: [] }]
|
|
26519
|
+
});
|
|
26520
|
+
}
|
|
26521
|
+
if (Array.isArray(message.tool_calls)) {
|
|
26522
|
+
message.tool_calls.forEach((tc, i2) => {
|
|
26523
|
+
const fn = tc.function || {};
|
|
26524
|
+
output.push({
|
|
26525
|
+
type: "function_call",
|
|
26526
|
+
id: `fc_${i2}`,
|
|
26527
|
+
call_id: tc.id,
|
|
26528
|
+
name: fn.name,
|
|
26529
|
+
arguments: typeof fn.arguments === "string" ? fn.arguments : JSON.stringify(fn.arguments ?? ""),
|
|
26530
|
+
status: "completed"
|
|
26531
|
+
});
|
|
26532
|
+
});
|
|
26533
|
+
}
|
|
26534
|
+
}
|
|
26535
|
+
const usage = chat.usage;
|
|
26536
|
+
const inputTokens = usage?.prompt_tokens ?? 0;
|
|
26537
|
+
const outputTokens = usage?.completion_tokens ?? 0;
|
|
26538
|
+
const base = chat.id ? `resp_${chat.id}` : "";
|
|
26539
|
+
const id = base && base !== "resp_" ? base : `resp_${Date.now()}`;
|
|
26540
|
+
return {
|
|
26541
|
+
id,
|
|
26542
|
+
object: "response",
|
|
26543
|
+
status: mapStatus(choice?.finish_reason),
|
|
26544
|
+
model: chat.model ?? "unknown",
|
|
26545
|
+
output,
|
|
26546
|
+
usage: {
|
|
26547
|
+
input_tokens: inputTokens,
|
|
26548
|
+
output_tokens: outputTokens,
|
|
26549
|
+
total_tokens: usage?.total_tokens ?? inputTokens + outputTokens
|
|
26550
|
+
}
|
|
26551
|
+
};
|
|
26552
|
+
}
|
|
26553
|
+
function mapStatus(finishReason) {
|
|
26554
|
+
if (finishReason === "length")
|
|
26555
|
+
return "incomplete";
|
|
26556
|
+
return "completed";
|
|
26557
|
+
}
|
|
26558
|
+
|
|
26559
|
+
// src/proxy/transform/streaming/openai-chat-to-openai-responses.ts
|
|
26560
|
+
function createOpenAIChatToOpenAIResponsesStream(source, ctx) {
|
|
26561
|
+
const stream = source instanceof Uint8Array ? new ReadableStream({
|
|
26562
|
+
start(controller) {
|
|
26563
|
+
controller.enqueue(source);
|
|
26564
|
+
controller.close();
|
|
26565
|
+
}
|
|
26566
|
+
}) : source;
|
|
26567
|
+
return stream.pipeThrough(createSSETransformStream(new OpenAIChatToOpenAIResponsesStreamTransformer(ctx)));
|
|
26568
|
+
}
|
|
26569
|
+
var OpenAIChatToOpenAIResponsesStreamTransformer;
|
|
26570
|
+
var init_openai_chat_to_openai_responses = __esm(() => {
|
|
26571
|
+
init_base();
|
|
26572
|
+
init_transform();
|
|
26573
|
+
init_openai_responses_to_openai_chat();
|
|
26574
|
+
OpenAIChatToOpenAIResponsesStreamTransformer = class OpenAIChatToOpenAIResponsesStreamTransformer extends SSEStreamTransformer {
|
|
26575
|
+
responseId = "";
|
|
26576
|
+
model = "";
|
|
26577
|
+
created = false;
|
|
26578
|
+
textOutputIndex = -1;
|
|
26579
|
+
textStarted = false;
|
|
26580
|
+
textBuf = "";
|
|
26581
|
+
tools = new Map;
|
|
26582
|
+
nextOutputIndex = 0;
|
|
26583
|
+
usage = null;
|
|
26584
|
+
finished = false;
|
|
26585
|
+
convertEvent(event) {
|
|
26586
|
+
if (event.data === "[DONE]")
|
|
26587
|
+
return null;
|
|
26588
|
+
const data = event.data;
|
|
26589
|
+
if (data && data.id)
|
|
26590
|
+
this.responseId = `resp_${data.id}`;
|
|
26591
|
+
if (data && data.model)
|
|
26592
|
+
this.model = data.model;
|
|
26593
|
+
if (data && data.usage)
|
|
26594
|
+
this.usage = data.usage;
|
|
26595
|
+
const choices = data?.choices;
|
|
26596
|
+
const choice = choices?.[0];
|
|
26597
|
+
if (!choice)
|
|
26598
|
+
return null;
|
|
26599
|
+
const out = [];
|
|
26600
|
+
if (!this.created) {
|
|
26601
|
+
this.created = true;
|
|
26602
|
+
out.push({
|
|
26603
|
+
event: "response.created",
|
|
26604
|
+
data: { type: "response.created", response: this.responseShell("in_progress") }
|
|
26605
|
+
});
|
|
26606
|
+
}
|
|
26607
|
+
const delta = choice.delta;
|
|
26608
|
+
if (delta?.content && typeof delta.content === "string") {
|
|
26609
|
+
out.push(...this.handleText(delta.content));
|
|
26610
|
+
}
|
|
26611
|
+
if (Array.isArray(delta?.tool_calls)) {
|
|
26612
|
+
for (const tc of delta.tool_calls)
|
|
26613
|
+
out.push(...this.handleTool(tc));
|
|
26614
|
+
}
|
|
26615
|
+
if (choice.finish_reason && !this.finished) {
|
|
26616
|
+
out.push(...this.finish(choice.finish_reason));
|
|
26617
|
+
}
|
|
26618
|
+
return out;
|
|
26619
|
+
}
|
|
26620
|
+
responseShell(status) {
|
|
26621
|
+
return { id: this.responseId, object: "response", status, model: this.model, output: [] };
|
|
26622
|
+
}
|
|
26623
|
+
handleText(text) {
|
|
26624
|
+
this.textBuf += text;
|
|
26625
|
+
const out = [];
|
|
26626
|
+
if (this.textOutputIndex < 0)
|
|
26627
|
+
this.textOutputIndex = this.nextOutputIndex++;
|
|
26628
|
+
if (!this.textStarted) {
|
|
26629
|
+
this.textStarted = true;
|
|
26630
|
+
out.push({
|
|
26631
|
+
event: "response.output_item.added",
|
|
26632
|
+
data: {
|
|
26633
|
+
type: "response.output_item.added",
|
|
26634
|
+
output_index: this.textOutputIndex,
|
|
26635
|
+
item: { type: "message", id: "msg_0", status: "in_progress", role: "assistant", content: [] }
|
|
26636
|
+
}
|
|
26637
|
+
});
|
|
26638
|
+
out.push({
|
|
26639
|
+
event: "response.content_part.added",
|
|
26640
|
+
data: {
|
|
26641
|
+
type: "response.content_part.added",
|
|
26642
|
+
item_id: "msg_0",
|
|
26643
|
+
output_index: this.textOutputIndex,
|
|
26644
|
+
content_index: 0,
|
|
26645
|
+
part: { type: "output_text", text: "", annotations: [] }
|
|
26646
|
+
}
|
|
26647
|
+
});
|
|
26648
|
+
}
|
|
26649
|
+
out.push({
|
|
26650
|
+
event: "response.output_text.delta",
|
|
26651
|
+
data: {
|
|
26652
|
+
type: "response.output_text.delta",
|
|
26653
|
+
item_id: "msg_0",
|
|
26654
|
+
output_index: this.textOutputIndex,
|
|
26655
|
+
content_index: 0,
|
|
26656
|
+
delta: text
|
|
26657
|
+
}
|
|
26658
|
+
});
|
|
26659
|
+
return out;
|
|
26660
|
+
}
|
|
26661
|
+
handleTool(tc) {
|
|
26662
|
+
const idx = tc.index ?? 0;
|
|
26663
|
+
let st = this.tools.get(idx);
|
|
26664
|
+
if (!st) {
|
|
26665
|
+
st = {
|
|
26666
|
+
outputIndex: this.nextOutputIndex++,
|
|
26667
|
+
itemId: `fc_${idx}`,
|
|
26668
|
+
callId: tc.id ?? `call_${idx}`,
|
|
26669
|
+
name: "",
|
|
26670
|
+
argsBuf: "",
|
|
26671
|
+
announced: false
|
|
26672
|
+
};
|
|
26673
|
+
this.tools.set(idx, st);
|
|
26674
|
+
}
|
|
26675
|
+
if (tc.id)
|
|
26676
|
+
st.callId = tc.id;
|
|
26677
|
+
if (tc.function?.name)
|
|
26678
|
+
st.name = tc.function.name;
|
|
26679
|
+
const out = [];
|
|
26680
|
+
if (!st.announced && st.name) {
|
|
26681
|
+
st.announced = true;
|
|
26682
|
+
out.push({
|
|
26683
|
+
event: "response.output_item.added",
|
|
26684
|
+
data: {
|
|
26685
|
+
type: "response.output_item.added",
|
|
26686
|
+
output_index: st.outputIndex,
|
|
26687
|
+
item: {
|
|
26688
|
+
type: "function_call",
|
|
26689
|
+
id: st.itemId,
|
|
26690
|
+
call_id: st.callId,
|
|
26691
|
+
name: st.name,
|
|
26692
|
+
arguments: "",
|
|
26693
|
+
status: "in_progress"
|
|
26694
|
+
}
|
|
26695
|
+
}
|
|
26696
|
+
});
|
|
26697
|
+
}
|
|
26698
|
+
if (tc.function?.arguments) {
|
|
26699
|
+
st.argsBuf += tc.function.arguments;
|
|
26700
|
+
if (st.announced) {
|
|
26701
|
+
out.push({
|
|
26702
|
+
event: "response.function_call_arguments.delta",
|
|
26703
|
+
data: {
|
|
26704
|
+
type: "response.function_call_arguments.delta",
|
|
26705
|
+
item_id: st.itemId,
|
|
26706
|
+
output_index: st.outputIndex,
|
|
26707
|
+
delta: tc.function.arguments
|
|
26708
|
+
}
|
|
26709
|
+
});
|
|
26710
|
+
}
|
|
26711
|
+
}
|
|
26712
|
+
return out;
|
|
26713
|
+
}
|
|
26714
|
+
finish(_finishReason) {
|
|
26715
|
+
if (this.finished)
|
|
26716
|
+
return [];
|
|
26717
|
+
this.finished = true;
|
|
26718
|
+
const out = [];
|
|
26719
|
+
if (this.textStarted) {
|
|
26720
|
+
out.push({
|
|
26721
|
+
event: "response.output_text.done",
|
|
26722
|
+
data: {
|
|
26723
|
+
type: "response.output_text.done",
|
|
26724
|
+
item_id: "msg_0",
|
|
26725
|
+
output_index: this.textOutputIndex,
|
|
26726
|
+
content_index: 0,
|
|
26727
|
+
text: this.textBuf
|
|
26728
|
+
}
|
|
26729
|
+
});
|
|
26730
|
+
out.push({
|
|
26731
|
+
event: "response.content_part.done",
|
|
26732
|
+
data: {
|
|
26733
|
+
type: "response.content_part.done",
|
|
26734
|
+
item_id: "msg_0",
|
|
26735
|
+
output_index: this.textOutputIndex,
|
|
26736
|
+
content_index: 0,
|
|
26737
|
+
part: { type: "output_text", text: this.textBuf, annotations: [] }
|
|
26738
|
+
}
|
|
26739
|
+
});
|
|
26740
|
+
out.push({
|
|
26741
|
+
event: "response.output_item.done",
|
|
26742
|
+
data: {
|
|
26743
|
+
type: "response.output_item.done",
|
|
26744
|
+
output_index: this.textOutputIndex,
|
|
26745
|
+
item: {
|
|
26746
|
+
type: "message",
|
|
26747
|
+
id: "msg_0",
|
|
26748
|
+
status: "completed",
|
|
26749
|
+
role: "assistant",
|
|
26750
|
+
content: [{ type: "output_text", text: this.textBuf, annotations: [] }]
|
|
26751
|
+
}
|
|
26752
|
+
}
|
|
26753
|
+
});
|
|
26754
|
+
}
|
|
26755
|
+
const outputItems = [];
|
|
26756
|
+
if (this.textStarted) {
|
|
26757
|
+
outputItems.push({
|
|
26758
|
+
type: "message",
|
|
26759
|
+
id: "msg_0",
|
|
26760
|
+
status: "completed",
|
|
26761
|
+
role: "assistant",
|
|
26762
|
+
content: [{ type: "output_text", text: this.textBuf, annotations: [] }]
|
|
26763
|
+
});
|
|
26764
|
+
}
|
|
26765
|
+
for (const st of this.tools.values()) {
|
|
26766
|
+
if (!st.announced)
|
|
26767
|
+
continue;
|
|
26768
|
+
out.push({
|
|
26769
|
+
event: "response.function_call_arguments.done",
|
|
26770
|
+
data: {
|
|
26771
|
+
type: "response.function_call_arguments.done",
|
|
26772
|
+
item_id: st.itemId,
|
|
26773
|
+
output_index: st.outputIndex,
|
|
26774
|
+
arguments: st.argsBuf
|
|
26775
|
+
}
|
|
26776
|
+
});
|
|
26777
|
+
out.push({
|
|
26778
|
+
event: "response.output_item.done",
|
|
26779
|
+
data: {
|
|
26780
|
+
type: "response.output_item.done",
|
|
26781
|
+
output_index: st.outputIndex,
|
|
26782
|
+
item: {
|
|
26783
|
+
type: "function_call",
|
|
26784
|
+
id: st.itemId,
|
|
26785
|
+
call_id: st.callId,
|
|
26786
|
+
name: st.name,
|
|
26787
|
+
arguments: st.argsBuf,
|
|
26788
|
+
status: "completed"
|
|
26789
|
+
}
|
|
26790
|
+
}
|
|
26791
|
+
});
|
|
26792
|
+
outputItems.push({
|
|
26793
|
+
type: "function_call",
|
|
26794
|
+
id: st.itemId,
|
|
26795
|
+
call_id: st.callId,
|
|
26796
|
+
name: st.name,
|
|
26797
|
+
arguments: st.argsBuf,
|
|
26798
|
+
status: "completed"
|
|
26799
|
+
});
|
|
26800
|
+
}
|
|
26801
|
+
const u2 = this.usage ?? {};
|
|
26802
|
+
const inputTokens = u2.prompt_tokens ?? 0;
|
|
26803
|
+
const outputTokens = u2.completion_tokens ?? 0;
|
|
26804
|
+
out.push({
|
|
26805
|
+
event: "response.completed",
|
|
26806
|
+
data: {
|
|
26807
|
+
type: "response.completed",
|
|
26808
|
+
response: {
|
|
26809
|
+
id: this.responseId,
|
|
26810
|
+
object: "response",
|
|
26811
|
+
status: "completed",
|
|
26812
|
+
model: this.model,
|
|
26813
|
+
output: outputItems,
|
|
26814
|
+
usage: {
|
|
26815
|
+
input_tokens: inputTokens,
|
|
26816
|
+
output_tokens: outputTokens,
|
|
26817
|
+
total_tokens: u2.total_tokens ?? inputTokens + outputTokens
|
|
26818
|
+
}
|
|
26819
|
+
}
|
|
26820
|
+
}
|
|
26821
|
+
});
|
|
26822
|
+
return out;
|
|
26823
|
+
}
|
|
26824
|
+
};
|
|
26825
|
+
registerTransformer({
|
|
26826
|
+
clientFormat: "openai_responses",
|
|
26827
|
+
targetFormat: "openai_chat",
|
|
26828
|
+
requestTransform: openaiResponsesToOpenAIChatRequest,
|
|
26829
|
+
responseTransform: openAIChatToOpenAIResponsesResponse,
|
|
26830
|
+
streamTransform: (stream, ctx) => createOpenAIChatToOpenAIResponsesStream(stream, ctx)
|
|
26831
|
+
});
|
|
26832
|
+
});
|
|
26833
|
+
|
|
26415
26834
|
// src/proxy/router.ts
|
|
26416
26835
|
class ProxyRouter {
|
|
26417
26836
|
routes = [];
|
|
@@ -26497,8 +26916,9 @@ class ProxyForwarder {
|
|
|
26497
26916
|
defaultTimeout = 3000000;
|
|
26498
26917
|
async forward(request, profile, timeoutMs) {
|
|
26499
26918
|
const preset = await getPresetByIdAsync(profile.providerId);
|
|
26500
|
-
const baseURL = profile.baseURL || preset?.baseURL || "";
|
|
26501
|
-
const
|
|
26919
|
+
const baseURL = (profile.baseURL || preset?.baseURL || "").replace(/\/+$/, "");
|
|
26920
|
+
const path = baseURL.endsWith("/v1") && request.path.startsWith("/v1/") ? request.path.slice(3) : request.path;
|
|
26921
|
+
const url2 = `${baseURL}${path}`;
|
|
26502
26922
|
const timeout = timeoutMs || this.defaultTimeout;
|
|
26503
26923
|
const headers = Object.fromEntries(Object.entries(request.headers).filter(([key]) => {
|
|
26504
26924
|
const normalizedKey = key.toLowerCase();
|
|
@@ -27124,6 +27544,7 @@ class ProxyHandler {
|
|
|
27124
27544
|
}
|
|
27125
27545
|
var init_handler = __esm(() => {
|
|
27126
27546
|
init_openai_chat_to_anthropic2();
|
|
27547
|
+
init_openai_chat_to_openai_responses();
|
|
27127
27548
|
init_model_helper();
|
|
27128
27549
|
init_forwarder();
|
|
27129
27550
|
init_manager2();
|
|
@@ -30341,9 +30762,10 @@ async function cmdApply3() {
|
|
|
30341
30762
|
console.log(` Provider: ${import_picocolors10.default.yellow(preset?.displayName)}`);
|
|
30342
30763
|
console.log(` Config file: ${import_picocolors10.default.dim(adapter.configPath)}`);
|
|
30343
30764
|
console.log();
|
|
30344
|
-
console.log(import_picocolors10.default.bold("Run Codex now: ") + import_picocolors10.default.cyan("codex"));
|
|
30765
|
+
console.log(import_picocolors10.default.bold("Run Codex now: ") + import_picocolors10.default.cyan("swixter codex run"));
|
|
30345
30766
|
console.log();
|
|
30346
|
-
|
|
30767
|
+
const envKey = profile.envKey || preset?.env_key || "OPENAI_API_KEY";
|
|
30768
|
+
console.log(import_picocolors10.default.dim(`Or export your key first: export ${envKey}=<your-key> then run codex`));
|
|
30347
30769
|
console.log();
|
|
30348
30770
|
} else {
|
|
30349
30771
|
console.log(import_picocolors10.default.yellow("⚠ Profile written, but verification failed"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swixter",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "CLI tool for managing AI coding assistant configurations - easily switch between providers (Claude Code, Codex, Continue) with Anthropic, Ollama, or custom APIs",
|
|
5
5
|
"main": "dist/cli/index.js",
|
|
6
6
|
"module": "dist/cli/index.js",
|