@armadra/agent 0.6.1 → 0.6.2
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/CHANGELOG.md +17 -0
- package/CHANGELOG.zh-CN.md +12 -0
- package/dist/agent/session-settings.d.ts +4 -1
- package/dist/agent/session-settings.js +7 -2
- package/dist/ai/apis/chatgpt-backend.d.ts +7 -2
- package/dist/ai/apis/chatgpt-backend.js +12 -4
- package/dist/ai/providers/discovered-cache.d.ts +22 -11
- package/dist/ai/providers/discovered-cache.js +56 -12
- package/dist/ai/providers/registry.js +7 -6
- package/dist/ai/types.d.ts +5 -0
- package/dist/auth/chatgpt/backend-client.d.ts +11 -2
- package/dist/auth/chatgpt/backend-client.js +38 -6
- package/dist/auth/chatgpt/cli.d.ts +2 -1
- package/dist/auth/chatgpt/cli.js +14 -7
- package/dist/auth/chatgpt/follow.d.ts +16 -0
- package/dist/auth/chatgpt/follow.js +51 -0
- package/dist/auth/chatgpt/presets.d.ts +8 -0
- package/dist/auth/chatgpt/presets.js +12 -0
- package/dist/auth/testing/fake-oauth.d.ts +4 -1
- package/dist/auth/testing/fake-oauth.js +24 -1
- package/dist/bundle/ama.cjs +341 -180
- package/dist/cli/compose-providers.d.ts +2 -1
- package/dist/cli/compose-providers.js +6 -3
- package/dist/cli/startup-steps.js +4 -1
- package/dist/cli/subcommands/models-discover.d.ts +4 -2
- package/dist/cli/subcommands/models-discover.js +40 -8
- package/dist/config/json-schema.js +1 -0
- package/dist/config/key-docs.js +7 -1
- package/dist/config/schema-w6.d.ts +1 -1
- package/dist/config/schema-w6.js +2 -1
- package/dist/config/types-w6.d.ts +5 -0
- package/dist/i18n/catalog.d.ts +7 -0
- package/dist/i18n/messages/auth.d.ts +12 -0
- package/dist/i18n/messages/auth.js +20 -0
- package/dist/i18n/messages/config-keys.d.ts +2 -0
- package/dist/i18n/messages/config-keys.js +2 -0
- package/dist/i18n/messages/config.d.ts +2 -0
- package/docs/en/providers.md +8 -4
- package/docs/providers.md +25 -10
- package/package.json +1 -1
package/dist/bundle/ama.cjs
CHANGED
|
@@ -41,7 +41,7 @@ var AMA_VERSION;
|
|
|
41
41
|
var init_version = __esm({
|
|
42
42
|
"src/version.ts"() {
|
|
43
43
|
"use strict";
|
|
44
|
-
AMA_VERSION = true ? "0.6.
|
|
44
|
+
AMA_VERSION = true ? "0.6.2" : readPackageVersion();
|
|
45
45
|
}
|
|
46
46
|
});
|
|
47
47
|
|
|
@@ -3622,6 +3622,7 @@ var init_config_keys = __esm({
|
|
|
3622
3622
|
"auth.chatgpt.clientId": "OAuth client id",
|
|
3623
3623
|
"auth.chatgpt.issuer": "Authorization server (override with AMA_CHATGPT_ISSUER for tests)",
|
|
3624
3624
|
"auth.chatgpt.originator": "originator request header for the codex flavor",
|
|
3625
|
+
"auth.chatgpt.codexClientVersion": "Codex CLI version sent as client_version when listing codex-flavor models (the backend hides models newer than it); AMA_CHATGPT_CODEX_CLIENT_VERSION overrides",
|
|
3625
3626
|
"auth.chatgpt.redirectPorts": "Local callback ports, tried in order; 0 = any free port",
|
|
3626
3627
|
skills: "Skills",
|
|
3627
3628
|
"skills.dirs": "Extra skill directories; accumulated across levels",
|
|
@@ -3740,6 +3741,7 @@ var init_config_keys = __esm({
|
|
|
3740
3741
|
"auth.chatgpt.clientId": "OAuth 客户端 id",
|
|
3741
3742
|
"auth.chatgpt.issuer": "授权服务器(测试用 AMA_CHATGPT_ISSUER 覆盖)",
|
|
3742
3743
|
"auth.chatgpt.originator": "codex flavor 的 originator 请求头",
|
|
3744
|
+
"auth.chatgpt.codexClientVersion": "codex flavor 列模型时作为 client_version 发送的 Codex CLI 版本号(后端不给比它新的模型);AMA_CHATGPT_CODEX_CLIENT_VERSION 优先",
|
|
3743
3745
|
"auth.chatgpt.redirectPorts": "本地回调端口,依次尝试;0 = 任意空闲端口",
|
|
3744
3746
|
skills: "Skill",
|
|
3745
3747
|
"skills.dirs": "追加的 Skill 目录;各层累加",
|
|
@@ -5114,7 +5116,13 @@ Then paste the full URL from the address bar (http://127.0.0.1:…/auth/callback
|
|
|
5114
5116
|
siwcLimitHint: "Tip: set a weekly limit for ama in ChatGPT → Settings → Usage → App limits. For personal use only; never share one sign-in between several people.",
|
|
5115
5117
|
freePlanHint: (plan2) => `Note: the "${plan2}" plan may not include subscription usage for ama.`,
|
|
5116
5118
|
modelHint: "Use it with --model chatgpt/<model>; list the models your account can use with ama models discover chatgpt.",
|
|
5117
|
-
modelsCached: (count2) => `Your account can use ${count2} model(s); pick one with /model or --model chatgpt/<model
|
|
5119
|
+
modelsCached: (count2) => `Your account can use ${count2} model(s); pick one with /model or --model chatgpt/<model>.`,
|
|
5120
|
+
siwcEligibilityHint: "Whether this account can share its plan usage with ama is only confirmed on the first request.",
|
|
5121
|
+
codexNoModels: (version) => `The codex backend returned no models. codexClientVersion (${version}) may be too old: set a newer Codex CLI version with ama config set auth.chatgpt.codexClientVersion <version>, then run ama models discover chatgpt.`
|
|
5122
|
+
},
|
|
5123
|
+
request: {
|
|
5124
|
+
notEligible: "this ChatGPT account cannot share plan usage with ama (403 subscription_sharing_user_not_eligible). Possible causes:\n 1. Plan: plan usage is shared with Plus / Pro only\n 2. Workspace account: Team / Enterprise / Edu workspaces may not offer it\n 3. Region restriction, or not yet rolled out during the preview (most likely when a Pro account still gets this error)\nYou can sign in the other way instead: ama auth login chatgpt --flavor codex",
|
|
5125
|
+
flavorMismatch: (current3, ref, pinned) => `signed in with ${current3}, but ${ref} pins the @${pinned} channel. Drop @${pinned} so the channel follows the sign-in, or run ama auth login chatgpt --flavor ${pinned}`
|
|
5118
5126
|
},
|
|
5119
5127
|
errors: {
|
|
5120
5128
|
portsBusy: (ports, codex) => `callback port ${ports} is in use: finish the other sign-in first, or use --paste${codex ? " / --device" : ""}`,
|
|
@@ -5215,7 +5223,13 @@ Then paste the full URL from the address bar (http://127.0.0.1:…/auth/callback
|
|
|
5215
5223
|
siwcLimitHint: "提示:可在 ChatGPT → 设置 → Usage → App limits 给 ama 设周上限。仅限本人使用,不要让多人共用一个登录。",
|
|
5216
5224
|
freePlanHint: (plan2) => `注意:「${plan2}」计划可能不含给 ama 用的订阅额度。`,
|
|
5217
5225
|
modelHint: "用 --model chatgpt/<模型> 使用;账户可用的模型用 ama models discover chatgpt 查看。",
|
|
5218
|
-
modelsCached: (count2) => `账户可用 ${count2} 个模型,用 /model 或 --model chatgpt/<模型>
|
|
5226
|
+
modelsCached: (count2) => `账户可用 ${count2} 个模型,用 /model 或 --model chatgpt/<模型> 选择。`,
|
|
5227
|
+
siwcEligibilityHint: "这个账户能否把套餐额度共享给 ama,要到首次请求时才能确认。",
|
|
5228
|
+
codexNoModels: (version) => `codex 后端没有返回模型,可能是 codexClientVersion(${version})过旧:用 ama config set auth.chatgpt.codexClientVersion <版本> 设为较新的 Codex CLI 版本,再运行 ama models discover chatgpt。`
|
|
5229
|
+
},
|
|
5230
|
+
request: {
|
|
5231
|
+
notEligible: "这个 ChatGPT 账户不能把套餐额度共享给 ama(403 subscription_sharing_user_not_eligible)。可能的原因:\n 1. 账户套餐:额度共享只对 Plus / Pro 开放\n 2. 工作空间账户:Team / Enterprise / Edu 工作空间可能未开放\n 3. 地区受限,或预览期尚未开放(Pro 账户仍报此错时最可能是这一条)\n可以改用另一种登录方式:ama auth login chatgpt --flavor codex",
|
|
5232
|
+
flavorMismatch: (current3, ref, pinned) => `当前以 ${current3} 方式登录,但 ${ref} 显式指定了 @${pinned} 渠道。去掉 @${pinned} 让渠道跟随登录方式,或运行 ama auth login chatgpt --flavor ${pinned}`
|
|
5219
5233
|
},
|
|
5220
5234
|
errors: {
|
|
5221
5235
|
portsBusy: (ports, codex) => `回调端口 ${ports} 被占用:请先结束其它登录,或用 --paste${codex ? " / --device" : ""}`,
|
|
@@ -6410,7 +6424,8 @@ function validateConfigW6(c, config) {
|
|
|
6410
6424
|
if (chatgpt === void 0 || !c.object(chatgpt, cp)) return;
|
|
6411
6425
|
c.keys(chatgpt, cp, CHATGPT_AUTH_KEYS);
|
|
6412
6426
|
c.oneOf(chatgpt, "flavor", cp, CHATGPT_FLAVORS);
|
|
6413
|
-
for (const key of ["clientId", "issuer", "originator"
|
|
6427
|
+
for (const key of ["clientId", "issuer", "originator", "codexClientVersion"])
|
|
6428
|
+
c.string(chatgpt, key, cp);
|
|
6414
6429
|
checkPorts(c, chatgpt, "redirectPorts", cp);
|
|
6415
6430
|
});
|
|
6416
6431
|
}
|
|
@@ -6477,6 +6492,7 @@ var init_schema_w6 = __esm({
|
|
|
6477
6492
|
"clientId",
|
|
6478
6493
|
"issuer",
|
|
6479
6494
|
"originator",
|
|
6495
|
+
"codexClientVersion",
|
|
6480
6496
|
"redirectPorts"
|
|
6481
6497
|
];
|
|
6482
6498
|
}
|
|
@@ -9695,6 +9711,113 @@ var init_channels = __esm({
|
|
|
9695
9711
|
}
|
|
9696
9712
|
});
|
|
9697
9713
|
|
|
9714
|
+
// src/auth/chatgpt/presets.ts
|
|
9715
|
+
function nonEmpty2(value) {
|
|
9716
|
+
const trimmed = value?.trim();
|
|
9717
|
+
return trimmed === void 0 || trimmed === "" ? void 0 : trimmed;
|
|
9718
|
+
}
|
|
9719
|
+
function chatgptBaseUrl(flavor, env = process.env) {
|
|
9720
|
+
return nonEmpty2(env["AMA_CHATGPT_BASE_URL"]) ?? CHATGPT_BASE_URLS[flavor];
|
|
9721
|
+
}
|
|
9722
|
+
function codexClientVersion(config, env = process.env) {
|
|
9723
|
+
return nonEmpty2(env["AMA_CHATGPT_CODEX_CLIENT_VERSION"]) ?? nonEmpty2(config?.codexClientVersion) ?? DEFAULT_CODEX_CLIENT_VERSION;
|
|
9724
|
+
}
|
|
9725
|
+
function resolveChatGptPreset(flavor, overrides = {}) {
|
|
9726
|
+
const env = overrides.env ?? process.env;
|
|
9727
|
+
const config = overrides.config;
|
|
9728
|
+
const issuer = (nonEmpty2(env["AMA_CHATGPT_ISSUER"]) ?? nonEmpty2(config?.issuer) ?? DEFAULT_ISSUER).replace(/\/+$/, "");
|
|
9729
|
+
const sameFlavor = overrides.entry?.flavor === flavor ? overrides.entry : void 0;
|
|
9730
|
+
const explicitClient = nonEmpty2(env["AMA_CHATGPT_CLIENT_ID"]) ?? nonEmpty2(config?.clientId);
|
|
9731
|
+
const ports = overrides.port !== void 0 ? [overrides.port] : config?.redirectPorts !== void 0 && config.redirectPorts.length > 0 ? [...config.redirectPorts] : void 0;
|
|
9732
|
+
if (flavor === "siwc") {
|
|
9733
|
+
const issued = sameFlavor?.clientId !== SIWC_REGISTRATION_CLIENT_ID ? sameFlavor?.clientId : void 0;
|
|
9734
|
+
const clientId = explicitClient ?? issued ?? SIWC_REGISTRATION_CLIENT_ID;
|
|
9735
|
+
return {
|
|
9736
|
+
flavor,
|
|
9737
|
+
issuer,
|
|
9738
|
+
clientId,
|
|
9739
|
+
registering: clientId === SIWC_REGISTRATION_CLIENT_ID,
|
|
9740
|
+
authorizeUrl: `${issuer}/api/accounts/authorize`,
|
|
9741
|
+
tokenUrl: `${issuer}/api/accounts/oauth/token`,
|
|
9742
|
+
scopes: [
|
|
9743
|
+
"openid",
|
|
9744
|
+
"profile",
|
|
9745
|
+
"email",
|
|
9746
|
+
"offline_access",
|
|
9747
|
+
"resource.invoke",
|
|
9748
|
+
SIWC_REQUIRED_SCOPE
|
|
9749
|
+
],
|
|
9750
|
+
// 端口可变(scheme / host / path 不变):1455 被占用就用任意空闲端口
|
|
9751
|
+
redirectPorts: ports ?? [1455, 0],
|
|
9752
|
+
resource: SIWC_RESOURCE,
|
|
9753
|
+
refreshEncoding: "form",
|
|
9754
|
+
baseUrl: chatgptBaseUrl(flavor, env),
|
|
9755
|
+
verifyIdToken: true,
|
|
9756
|
+
requiredScope: SIWC_REQUIRED_SCOPE,
|
|
9757
|
+
device: false,
|
|
9758
|
+
revoke: true
|
|
9759
|
+
};
|
|
9760
|
+
}
|
|
9761
|
+
return {
|
|
9762
|
+
flavor,
|
|
9763
|
+
issuer,
|
|
9764
|
+
clientId: explicitClient ?? CODEX_CLIENT_ID,
|
|
9765
|
+
registering: false,
|
|
9766
|
+
authorizeUrl: `${issuer}/oauth/authorize`,
|
|
9767
|
+
tokenUrl: `${issuer}/oauth/token`,
|
|
9768
|
+
scopes: ["openid", "profile", "email", "offline_access"],
|
|
9769
|
+
// 公开客户端只登记了这两个端口;被占用不抢占
|
|
9770
|
+
redirectPorts: ports ?? [1455, 1457],
|
|
9771
|
+
refreshEncoding: "json",
|
|
9772
|
+
baseUrl: chatgptBaseUrl(flavor, env),
|
|
9773
|
+
verifyIdToken: false,
|
|
9774
|
+
device: true,
|
|
9775
|
+
revoke: false,
|
|
9776
|
+
originator: nonEmpty2(config?.originator) ?? DEFAULT_ORIGINATOR
|
|
9777
|
+
};
|
|
9778
|
+
}
|
|
9779
|
+
function authorizeUrl(preset, input2) {
|
|
9780
|
+
const params = new URLSearchParams({
|
|
9781
|
+
response_type: "code",
|
|
9782
|
+
client_id: preset.clientId,
|
|
9783
|
+
redirect_uri: input2.redirectUri,
|
|
9784
|
+
scope: preset.scopes.join(" "),
|
|
9785
|
+
code_challenge: input2.challenge,
|
|
9786
|
+
code_challenge_method: "S256",
|
|
9787
|
+
state: input2.state
|
|
9788
|
+
});
|
|
9789
|
+
if (preset.flavor === "siwc") {
|
|
9790
|
+
params.set("nonce", input2.nonce);
|
|
9791
|
+
if (preset.resource !== void 0) params.set("resource", preset.resource);
|
|
9792
|
+
if (input2.hostId !== void 0) params.set("ext_agent_host_id", input2.hostId);
|
|
9793
|
+
if (preset.registering) params.set("agent_name_hint", AGENT_NAME_HINT);
|
|
9794
|
+
} else {
|
|
9795
|
+
params.set("id_token_add_organizations", "true");
|
|
9796
|
+
params.set("codex_cli_simplified_flow", "true");
|
|
9797
|
+
if (preset.originator !== void 0) params.set("originator", preset.originator);
|
|
9798
|
+
}
|
|
9799
|
+
return `${preset.authorizeUrl}?${params.toString()}`;
|
|
9800
|
+
}
|
|
9801
|
+
var CHATGPT_PROVIDER_ID, DEFAULT_ISSUER, SIWC_REGISTRATION_CLIENT_ID, CODEX_CLIENT_ID, SIWC_RESOURCE, SIWC_REQUIRED_SCOPE, AGENT_NAME_HINT, DEFAULT_ORIGINATOR, DEFAULT_CODEX_CLIENT_VERSION, CHATGPT_BASE_URLS;
|
|
9802
|
+
var init_presets = __esm({
|
|
9803
|
+
"src/auth/chatgpt/presets.ts"() {
|
|
9804
|
+
"use strict";
|
|
9805
|
+
CHATGPT_PROVIDER_ID = "chatgpt";
|
|
9806
|
+
DEFAULT_ISSUER = "https://auth.openai.com";
|
|
9807
|
+
SIWC_REGISTRATION_CLIENT_ID = "dynamic_agent_client";
|
|
9808
|
+
CODEX_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
9809
|
+
SIWC_RESOURCE = "https://api.openai.com/v1";
|
|
9810
|
+
SIWC_REQUIRED_SCOPE = "chatgpt.tokens.use.direct";
|
|
9811
|
+
AGENT_NAME_HINT = "ama";
|
|
9812
|
+
DEFAULT_ORIGINATOR = "codex_cli_rs";
|
|
9813
|
+
DEFAULT_CODEX_CLIENT_VERSION = "0.160.0";
|
|
9814
|
+
CHATGPT_BASE_URLS = {
|
|
9815
|
+
siwc: "https://api.openai.com/v1",
|
|
9816
|
+
codex: "https://chatgpt.com/backend-api/codex"
|
|
9817
|
+
};
|
|
9818
|
+
}
|
|
9819
|
+
});
|
|
9820
|
+
|
|
9698
9821
|
// src/ai/providers/catalog-data.ts
|
|
9699
9822
|
var CATALOG_SOURCES;
|
|
9700
9823
|
var init_catalog_data = __esm({
|
|
@@ -11802,11 +11925,12 @@ async function resolveModel(args, registry2, manager, defaultModel, deps, intera
|
|
|
11802
11925
|
} else {
|
|
11803
11926
|
const change = lastEntry(manager, (e) => e.type === "model_change");
|
|
11804
11927
|
if (change?.type === "model_change") {
|
|
11928
|
+
const channel = change.provider === CHATGPT_PROVIDER_ID ? void 0 : change.channel;
|
|
11805
11929
|
const found = registry2.findModel(
|
|
11806
11930
|
formatModelRef({
|
|
11807
11931
|
provider: change.provider,
|
|
11808
11932
|
id: change.modelId,
|
|
11809
|
-
...
|
|
11933
|
+
...channel !== void 0 ? { channel } : {}
|
|
11810
11934
|
})
|
|
11811
11935
|
);
|
|
11812
11936
|
if (found.ok) choice3 = { model: found.model, provider: found.provider };
|
|
@@ -11883,6 +12007,7 @@ var init_startup_steps = __esm({
|
|
|
11883
12007
|
"use strict";
|
|
11884
12008
|
init_suggest();
|
|
11885
12009
|
init_channels();
|
|
12010
|
+
init_presets();
|
|
11886
12011
|
import_node_fs14 = require("node:fs");
|
|
11887
12012
|
import_node_path16 = require("node:path");
|
|
11888
12013
|
init_errors();
|
|
@@ -16579,7 +16704,7 @@ function resolvePreset(input2) {
|
|
|
16579
16704
|
return { preset, codemode, builtin: names.sort(), warnings };
|
|
16580
16705
|
}
|
|
16581
16706
|
var CODEMODE_TOOL, PRESET_TOOLS, PresetToolRegistry;
|
|
16582
|
-
var
|
|
16707
|
+
var init_presets2 = __esm({
|
|
16583
16708
|
"src/tools/presets.ts"() {
|
|
16584
16709
|
"use strict";
|
|
16585
16710
|
init_capability();
|
|
@@ -16939,7 +17064,7 @@ var init_tool_runner = __esm({
|
|
|
16939
17064
|
import_node_path35 = require("node:path");
|
|
16940
17065
|
init_loop_guard();
|
|
16941
17066
|
init_schema2();
|
|
16942
|
-
|
|
17067
|
+
init_presets2();
|
|
16943
17068
|
init_registry();
|
|
16944
17069
|
init_truncate();
|
|
16945
17070
|
ABORTED_TOOL_TEXT = "aborted by user";
|
|
@@ -24127,9 +24252,72 @@ var init_session_extensions = __esm({
|
|
|
24127
24252
|
}
|
|
24128
24253
|
});
|
|
24129
24254
|
|
|
24255
|
+
// src/auth/oauth/live.ts
|
|
24256
|
+
function registerLiveToken(token, context) {
|
|
24257
|
+
live.delete(token);
|
|
24258
|
+
live.set(token, context);
|
|
24259
|
+
while (live.size > MAX_LIVE) {
|
|
24260
|
+
const oldest = live.keys().next().value;
|
|
24261
|
+
if (oldest === void 0) break;
|
|
24262
|
+
live.delete(oldest);
|
|
24263
|
+
}
|
|
24264
|
+
}
|
|
24265
|
+
function liveToken(token) {
|
|
24266
|
+
return token === void 0 ? void 0 : live.get(token);
|
|
24267
|
+
}
|
|
24268
|
+
var MAX_LIVE, live;
|
|
24269
|
+
var init_live = __esm({
|
|
24270
|
+
"src/auth/oauth/live.ts"() {
|
|
24271
|
+
"use strict";
|
|
24272
|
+
MAX_LIVE = 32;
|
|
24273
|
+
live = /* @__PURE__ */ new Map();
|
|
24274
|
+
}
|
|
24275
|
+
});
|
|
24276
|
+
|
|
24277
|
+
// src/auth/chatgpt/follow.ts
|
|
24278
|
+
function backendOf(compat) {
|
|
24279
|
+
if (typeof compat !== "object" || compat === null) return void 0;
|
|
24280
|
+
const value = compat.chatgptBackend;
|
|
24281
|
+
return value === "siwc" || value === "codex" ? value : void 0;
|
|
24282
|
+
}
|
|
24283
|
+
function followChatGptLogin(model, provider, apiKey) {
|
|
24284
|
+
const current3 = backendOf(model.compat);
|
|
24285
|
+
if (current3 === void 0 || model.channelPinned === true) return model;
|
|
24286
|
+
const flavor = liveToken(apiKey)?.flavor;
|
|
24287
|
+
if (flavor === void 0 || flavor === current3) return model;
|
|
24288
|
+
const channels = provider?.channels ?? [];
|
|
24289
|
+
const target = channels.find((c) => backendOf(c.compat) === flavor) ?? channels.find((c) => c.name === flavor);
|
|
24290
|
+
if (target === void 0) return model;
|
|
24291
|
+
const previous = channels.find((c) => c.name === model.channel);
|
|
24292
|
+
const headers2 = { ...model.headers };
|
|
24293
|
+
for (const name of Object.keys(previous?.headers ?? {})) delete headers2[name];
|
|
24294
|
+
Object.assign(headers2, target.headers);
|
|
24295
|
+
const next = {
|
|
24296
|
+
...model,
|
|
24297
|
+
api: target.api,
|
|
24298
|
+
baseUrl: target.baseUrl,
|
|
24299
|
+
channel: target.name,
|
|
24300
|
+
compat: { ...model.compat, ...target.compat, chatgptBackend: flavor }
|
|
24301
|
+
};
|
|
24302
|
+
if (Object.keys(headers2).length > 0) next.headers = headers2;
|
|
24303
|
+
else delete next.headers;
|
|
24304
|
+
return next;
|
|
24305
|
+
}
|
|
24306
|
+
var init_follow = __esm({
|
|
24307
|
+
"src/auth/chatgpt/follow.ts"() {
|
|
24308
|
+
"use strict";
|
|
24309
|
+
init_live();
|
|
24310
|
+
}
|
|
24311
|
+
});
|
|
24312
|
+
|
|
24130
24313
|
// src/agent/session-settings.ts
|
|
24131
24314
|
function providerStream(providers) {
|
|
24132
|
-
return (
|
|
24315
|
+
return (requested, context, streamOptions) => {
|
|
24316
|
+
const model = followChatGptLogin(
|
|
24317
|
+
requested,
|
|
24318
|
+
providers.get(requested.provider),
|
|
24319
|
+
streamOptions.apiKey
|
|
24320
|
+
);
|
|
24133
24321
|
const api = providers.getApi(model.api);
|
|
24134
24322
|
if (api === void 0) {
|
|
24135
24323
|
throw new AmaError("provider_not_found", `no implementation registered for api ${model.api}`);
|
|
@@ -24141,6 +24329,7 @@ var SessionSettings;
|
|
|
24141
24329
|
var init_session_settings = __esm({
|
|
24142
24330
|
"src/agent/session-settings.ts"() {
|
|
24143
24331
|
"use strict";
|
|
24332
|
+
init_follow();
|
|
24144
24333
|
init_errors();
|
|
24145
24334
|
init_session_sync();
|
|
24146
24335
|
SessionSettings = class {
|
|
@@ -33625,7 +33814,7 @@ var init_compose_session = __esm({
|
|
|
33625
33814
|
init_expand();
|
|
33626
33815
|
init_index_prompt();
|
|
33627
33816
|
init_templates();
|
|
33628
|
-
|
|
33817
|
+
init_presets2();
|
|
33629
33818
|
init_compose_store();
|
|
33630
33819
|
init_compose_extensions();
|
|
33631
33820
|
init_compose_memory();
|
|
@@ -34299,10 +34488,20 @@ var init_token_store = __esm({
|
|
|
34299
34488
|
function discoveredCachePath(dataDir, provider) {
|
|
34300
34489
|
return (0, import_node_path66.join)(dataDir, "models", "discovered", `${provider}.json`);
|
|
34301
34490
|
}
|
|
34302
|
-
function
|
|
34303
|
-
if (typeof value !== "object" || value === null) return
|
|
34304
|
-
const
|
|
34305
|
-
|
|
34491
|
+
function toEntry(value) {
|
|
34492
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
34493
|
+
const raw = value;
|
|
34494
|
+
const { id, name, contextWindow, input: input2, reasoningLevels } = raw;
|
|
34495
|
+
if (typeof id !== "string" || id === "") return void 0;
|
|
34496
|
+
const out = { id };
|
|
34497
|
+
if (typeof name === "string" && name !== "") out.name = name;
|
|
34498
|
+
if (typeof contextWindow === "number" && Number.isInteger(contextWindow) && contextWindow > 0)
|
|
34499
|
+
out.contextWindow = contextWindow;
|
|
34500
|
+
if (Array.isArray(input2) && input2.includes("text"))
|
|
34501
|
+
out.input = ["text", "image"].filter((x) => input2.includes(x));
|
|
34502
|
+
if (Array.isArray(reasoningLevels) && reasoningLevels.every((x) => typeof x === "string"))
|
|
34503
|
+
out.reasoningLevels = reasoningLevels;
|
|
34504
|
+
return out;
|
|
34306
34505
|
}
|
|
34307
34506
|
function readDiscoveredCache(dataDir, provider) {
|
|
34308
34507
|
let parsed;
|
|
@@ -34319,7 +34518,7 @@ function readDiscoveredCache(dataDir, provider) {
|
|
|
34319
34518
|
provider,
|
|
34320
34519
|
fetchedAt: typeof file.fetchedAt === "string" ? file.fetchedAt : "",
|
|
34321
34520
|
...typeof file.flavor === "string" ? { flavor: file.flavor } : {},
|
|
34322
|
-
models: file.models.
|
|
34521
|
+
models: file.models.map(toEntry).filter((m) => m !== void 0)
|
|
34323
34522
|
};
|
|
34324
34523
|
}
|
|
34325
34524
|
function writeDiscoveredCache(dataDir, provider, input2, now = Date.now()) {
|
|
@@ -34329,7 +34528,7 @@ function writeDiscoveredCache(dataDir, provider, input2, now = Date.now()) {
|
|
|
34329
34528
|
provider,
|
|
34330
34529
|
fetchedAt: new Date(now).toISOString(),
|
|
34331
34530
|
...input2.flavor !== void 0 ? { flavor: input2.flavor } : {},
|
|
34332
|
-
models: input2.models.map((m) => m
|
|
34531
|
+
models: input2.models.map(toEntry).filter((m) => m !== void 0)
|
|
34333
34532
|
};
|
|
34334
34533
|
(0, import_node_fs44.mkdirSync)((0, import_node_path66.dirname)(path), { recursive: true, mode: 448 });
|
|
34335
34534
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
@@ -34344,10 +34543,32 @@ function clearDiscoveredCache(dataDir, provider) {
|
|
|
34344
34543
|
(0, import_node_fs44.rmSync)(path, { force: true });
|
|
34345
34544
|
return true;
|
|
34346
34545
|
}
|
|
34546
|
+
function thinkingMapOf(levels) {
|
|
34547
|
+
const map = {
|
|
34548
|
+
off: levels.includes("none") ? "none" : null
|
|
34549
|
+
};
|
|
34550
|
+
for (const level of EFFORT_LEVELS) map[level] = levels.includes(level) ? level : null;
|
|
34551
|
+
return map;
|
|
34552
|
+
}
|
|
34553
|
+
function withBackendMetadata(model, cached, matched) {
|
|
34554
|
+
if (model.contextWindow === void 0 && cached.contextWindow !== void 0)
|
|
34555
|
+
model.contextWindow = cached.contextWindow;
|
|
34556
|
+
if (matched) return;
|
|
34557
|
+
if (cached.input !== void 0) model.input = [...cached.input];
|
|
34558
|
+
const efforts = (cached.reasoningLevels ?? []).filter((x) => x !== "none");
|
|
34559
|
+
if (efforts.length > 0) {
|
|
34560
|
+
model.reasoning = true;
|
|
34561
|
+
model.thinkingLevelMap = thinkingMapOf(cached.reasoningLevels ?? []);
|
|
34562
|
+
}
|
|
34563
|
+
}
|
|
34347
34564
|
function discoveredModels(file, provider, modelsDev) {
|
|
34348
34565
|
return file.models.map((m) => {
|
|
34349
|
-
const { entry } = enrichEntry(
|
|
34566
|
+
const { entry, metadata } = enrichEntry(
|
|
34567
|
+
m.name ? { id: m.id, name: m.name } : { id: m.id },
|
|
34568
|
+
modelsDev
|
|
34569
|
+
);
|
|
34350
34570
|
const model = withCustomDefaults(entry, provider.id, provider.api);
|
|
34571
|
+
withBackendMetadata(model, m, metadata.match !== void 0);
|
|
34351
34572
|
const names = (provider.channels ?? []).map((c) => c.name);
|
|
34352
34573
|
if (names.length > 0) {
|
|
34353
34574
|
const own = file.flavor !== void 0 && names.includes(file.flavor) ? file.flavor : void 0;
|
|
@@ -34356,18 +34577,20 @@ function discoveredModels(file, provider, modelsDev) {
|
|
|
34356
34577
|
return model;
|
|
34357
34578
|
});
|
|
34358
34579
|
}
|
|
34359
|
-
function mergeDiscoveredModels(registry2, dataDir, modelsDev) {
|
|
34580
|
+
function mergeDiscoveredModels(registry2, dataDir, modelsDev, loginFlavor = () => void 0) {
|
|
34360
34581
|
const merged = [];
|
|
34361
34582
|
for (const provider of registry2.list()) {
|
|
34362
34583
|
if (provider.models.length > 0 || !provider.requiresApiKey) continue;
|
|
34363
34584
|
const file = readDiscoveredCache(dataDir, provider.id);
|
|
34364
34585
|
if (file === void 0 || file.models.length === 0) continue;
|
|
34586
|
+
const flavor = loginFlavor(provider.id);
|
|
34587
|
+
if (flavor !== void 0 && file.flavor !== void 0 && file.flavor !== flavor) continue;
|
|
34365
34588
|
registry2.addModels(provider.id, discoveredModels(file, provider, modelsDev), "discovered");
|
|
34366
34589
|
merged.push(provider.id);
|
|
34367
34590
|
}
|
|
34368
34591
|
return merged;
|
|
34369
34592
|
}
|
|
34370
|
-
var import_node_fs44, import_node_path66, DISCOVERED_CACHE_VERSION;
|
|
34593
|
+
var import_node_fs44, import_node_path66, DISCOVERED_CACHE_VERSION, EFFORT_LEVELS;
|
|
34371
34594
|
var init_discovered_cache = __esm({
|
|
34372
34595
|
"src/ai/providers/discovered-cache.ts"() {
|
|
34373
34596
|
"use strict";
|
|
@@ -34376,6 +34599,7 @@ var init_discovered_cache = __esm({
|
|
|
34376
34599
|
init_catalog2();
|
|
34377
34600
|
init_enrich();
|
|
34378
34601
|
DISCOVERED_CACHE_VERSION = 1;
|
|
34602
|
+
EFFORT_LEVELS = ["minimal", "low", "medium", "high", "xhigh"];
|
|
34379
34603
|
}
|
|
34380
34604
|
});
|
|
34381
34605
|
|
|
@@ -34464,109 +34688,6 @@ var init_chatgpt_rate_limits = __esm({
|
|
|
34464
34688
|
}
|
|
34465
34689
|
});
|
|
34466
34690
|
|
|
34467
|
-
// src/auth/chatgpt/presets.ts
|
|
34468
|
-
function nonEmpty2(value) {
|
|
34469
|
-
const trimmed = value?.trim();
|
|
34470
|
-
return trimmed === void 0 || trimmed === "" ? void 0 : trimmed;
|
|
34471
|
-
}
|
|
34472
|
-
function chatgptBaseUrl(flavor, env = process.env) {
|
|
34473
|
-
return nonEmpty2(env["AMA_CHATGPT_BASE_URL"]) ?? CHATGPT_BASE_URLS[flavor];
|
|
34474
|
-
}
|
|
34475
|
-
function resolveChatGptPreset(flavor, overrides = {}) {
|
|
34476
|
-
const env = overrides.env ?? process.env;
|
|
34477
|
-
const config = overrides.config;
|
|
34478
|
-
const issuer = (nonEmpty2(env["AMA_CHATGPT_ISSUER"]) ?? nonEmpty2(config?.issuer) ?? DEFAULT_ISSUER).replace(/\/+$/, "");
|
|
34479
|
-
const sameFlavor = overrides.entry?.flavor === flavor ? overrides.entry : void 0;
|
|
34480
|
-
const explicitClient = nonEmpty2(env["AMA_CHATGPT_CLIENT_ID"]) ?? nonEmpty2(config?.clientId);
|
|
34481
|
-
const ports = overrides.port !== void 0 ? [overrides.port] : config?.redirectPorts !== void 0 && config.redirectPorts.length > 0 ? [...config.redirectPorts] : void 0;
|
|
34482
|
-
if (flavor === "siwc") {
|
|
34483
|
-
const issued = sameFlavor?.clientId !== SIWC_REGISTRATION_CLIENT_ID ? sameFlavor?.clientId : void 0;
|
|
34484
|
-
const clientId = explicitClient ?? issued ?? SIWC_REGISTRATION_CLIENT_ID;
|
|
34485
|
-
return {
|
|
34486
|
-
flavor,
|
|
34487
|
-
issuer,
|
|
34488
|
-
clientId,
|
|
34489
|
-
registering: clientId === SIWC_REGISTRATION_CLIENT_ID,
|
|
34490
|
-
authorizeUrl: `${issuer}/api/accounts/authorize`,
|
|
34491
|
-
tokenUrl: `${issuer}/api/accounts/oauth/token`,
|
|
34492
|
-
scopes: [
|
|
34493
|
-
"openid",
|
|
34494
|
-
"profile",
|
|
34495
|
-
"email",
|
|
34496
|
-
"offline_access",
|
|
34497
|
-
"resource.invoke",
|
|
34498
|
-
SIWC_REQUIRED_SCOPE
|
|
34499
|
-
],
|
|
34500
|
-
// 端口可变(scheme / host / path 不变):1455 被占用就用任意空闲端口
|
|
34501
|
-
redirectPorts: ports ?? [1455, 0],
|
|
34502
|
-
resource: SIWC_RESOURCE,
|
|
34503
|
-
refreshEncoding: "form",
|
|
34504
|
-
baseUrl: chatgptBaseUrl(flavor, env),
|
|
34505
|
-
verifyIdToken: true,
|
|
34506
|
-
requiredScope: SIWC_REQUIRED_SCOPE,
|
|
34507
|
-
device: false,
|
|
34508
|
-
revoke: true
|
|
34509
|
-
};
|
|
34510
|
-
}
|
|
34511
|
-
return {
|
|
34512
|
-
flavor,
|
|
34513
|
-
issuer,
|
|
34514
|
-
clientId: explicitClient ?? CODEX_CLIENT_ID,
|
|
34515
|
-
registering: false,
|
|
34516
|
-
authorizeUrl: `${issuer}/oauth/authorize`,
|
|
34517
|
-
tokenUrl: `${issuer}/oauth/token`,
|
|
34518
|
-
scopes: ["openid", "profile", "email", "offline_access"],
|
|
34519
|
-
// 公开客户端只登记了这两个端口;被占用不抢占
|
|
34520
|
-
redirectPorts: ports ?? [1455, 1457],
|
|
34521
|
-
refreshEncoding: "json",
|
|
34522
|
-
baseUrl: chatgptBaseUrl(flavor, env),
|
|
34523
|
-
verifyIdToken: false,
|
|
34524
|
-
device: true,
|
|
34525
|
-
revoke: false,
|
|
34526
|
-
originator: nonEmpty2(config?.originator) ?? DEFAULT_ORIGINATOR
|
|
34527
|
-
};
|
|
34528
|
-
}
|
|
34529
|
-
function authorizeUrl(preset, input2) {
|
|
34530
|
-
const params = new URLSearchParams({
|
|
34531
|
-
response_type: "code",
|
|
34532
|
-
client_id: preset.clientId,
|
|
34533
|
-
redirect_uri: input2.redirectUri,
|
|
34534
|
-
scope: preset.scopes.join(" "),
|
|
34535
|
-
code_challenge: input2.challenge,
|
|
34536
|
-
code_challenge_method: "S256",
|
|
34537
|
-
state: input2.state
|
|
34538
|
-
});
|
|
34539
|
-
if (preset.flavor === "siwc") {
|
|
34540
|
-
params.set("nonce", input2.nonce);
|
|
34541
|
-
if (preset.resource !== void 0) params.set("resource", preset.resource);
|
|
34542
|
-
if (input2.hostId !== void 0) params.set("ext_agent_host_id", input2.hostId);
|
|
34543
|
-
if (preset.registering) params.set("agent_name_hint", AGENT_NAME_HINT);
|
|
34544
|
-
} else {
|
|
34545
|
-
params.set("id_token_add_organizations", "true");
|
|
34546
|
-
params.set("codex_cli_simplified_flow", "true");
|
|
34547
|
-
if (preset.originator !== void 0) params.set("originator", preset.originator);
|
|
34548
|
-
}
|
|
34549
|
-
return `${preset.authorizeUrl}?${params.toString()}`;
|
|
34550
|
-
}
|
|
34551
|
-
var CHATGPT_PROVIDER_ID, DEFAULT_ISSUER, SIWC_REGISTRATION_CLIENT_ID, CODEX_CLIENT_ID, SIWC_RESOURCE, SIWC_REQUIRED_SCOPE, AGENT_NAME_HINT, DEFAULT_ORIGINATOR, CHATGPT_BASE_URLS;
|
|
34552
|
-
var init_presets2 = __esm({
|
|
34553
|
-
"src/auth/chatgpt/presets.ts"() {
|
|
34554
|
-
"use strict";
|
|
34555
|
-
CHATGPT_PROVIDER_ID = "chatgpt";
|
|
34556
|
-
DEFAULT_ISSUER = "https://auth.openai.com";
|
|
34557
|
-
SIWC_REGISTRATION_CLIENT_ID = "dynamic_agent_client";
|
|
34558
|
-
CODEX_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
34559
|
-
SIWC_RESOURCE = "https://api.openai.com/v1";
|
|
34560
|
-
SIWC_REQUIRED_SCOPE = "chatgpt.tokens.use.direct";
|
|
34561
|
-
AGENT_NAME_HINT = "ama";
|
|
34562
|
-
DEFAULT_ORIGINATOR = "codex_cli_rs";
|
|
34563
|
-
CHATGPT_BASE_URLS = {
|
|
34564
|
-
siwc: "https://api.openai.com/v1",
|
|
34565
|
-
codex: "https://chatgpt.com/backend-api/codex"
|
|
34566
|
-
};
|
|
34567
|
-
}
|
|
34568
|
-
});
|
|
34569
|
-
|
|
34570
34691
|
// src/auth/oauth/token-client.ts
|
|
34571
34692
|
function oauthErrorCode(body) {
|
|
34572
34693
|
try {
|
|
@@ -34832,6 +34953,7 @@ var init_key_docs = __esm({
|
|
|
34832
34953
|
"src/config/key-docs.ts"() {
|
|
34833
34954
|
"use strict";
|
|
34834
34955
|
init_http();
|
|
34956
|
+
init_presets();
|
|
34835
34957
|
init_i18n();
|
|
34836
34958
|
init_declarations();
|
|
34837
34959
|
init_merge();
|
|
@@ -34854,7 +34976,12 @@ var init_key_docs = __esm({
|
|
|
34854
34976
|
subagents: "read"
|
|
34855
34977
|
},
|
|
34856
34978
|
auth: {
|
|
34857
|
-
chatgpt: {
|
|
34979
|
+
chatgpt: {
|
|
34980
|
+
flavor: "siwc",
|
|
34981
|
+
issuer: "https://auth.openai.com",
|
|
34982
|
+
originator: "codex_cli_rs",
|
|
34983
|
+
codexClientVersion: DEFAULT_CODEX_CLIENT_VERSION
|
|
34984
|
+
}
|
|
34858
34985
|
},
|
|
34859
34986
|
checkpoints: { ...DEFAULT_CHECKPOINTS_CONFIG },
|
|
34860
34987
|
sandbox: { enabled: "auto", bash: "off", network: "deny", writable: [] },
|
|
@@ -35146,6 +35273,7 @@ function w6Sections() {
|
|
|
35146
35273
|
clientId: str3(),
|
|
35147
35274
|
issuer: str3(),
|
|
35148
35275
|
originator: str3(),
|
|
35276
|
+
codexClientVersion: str3(),
|
|
35149
35277
|
redirectPorts: {
|
|
35150
35278
|
type: "array",
|
|
35151
35279
|
items: { type: "integer", minimum: 0, maximum: 65535 }
|
|
@@ -36168,28 +36296,6 @@ var init_openai_compat = __esm({
|
|
|
36168
36296
|
}
|
|
36169
36297
|
});
|
|
36170
36298
|
|
|
36171
|
-
// src/auth/oauth/live.ts
|
|
36172
|
-
function registerLiveToken(token, context) {
|
|
36173
|
-
live.delete(token);
|
|
36174
|
-
live.set(token, context);
|
|
36175
|
-
while (live.size > MAX_LIVE) {
|
|
36176
|
-
const oldest = live.keys().next().value;
|
|
36177
|
-
if (oldest === void 0) break;
|
|
36178
|
-
live.delete(oldest);
|
|
36179
|
-
}
|
|
36180
|
-
}
|
|
36181
|
-
function liveToken(token) {
|
|
36182
|
-
return token === void 0 ? void 0 : live.get(token);
|
|
36183
|
-
}
|
|
36184
|
-
var MAX_LIVE, live;
|
|
36185
|
-
var init_live = __esm({
|
|
36186
|
-
"src/auth/oauth/live.ts"() {
|
|
36187
|
-
"use strict";
|
|
36188
|
-
MAX_LIVE = 32;
|
|
36189
|
-
live = /* @__PURE__ */ new Map();
|
|
36190
|
-
}
|
|
36191
|
-
});
|
|
36192
|
-
|
|
36193
36299
|
// src/auth/oauth/refresh.ts
|
|
36194
36300
|
function authExpiredError(provider) {
|
|
36195
36301
|
return new AmaError(
|
|
@@ -36288,7 +36394,7 @@ var init_refresh = __esm({
|
|
|
36288
36394
|
"src/auth/oauth/refresh.ts"() {
|
|
36289
36395
|
"use strict";
|
|
36290
36396
|
init_errors();
|
|
36291
|
-
|
|
36397
|
+
init_presets();
|
|
36292
36398
|
init_token_client();
|
|
36293
36399
|
init_token_store();
|
|
36294
36400
|
REFRESH_MARGIN_MS = 5 * 6e4;
|
|
@@ -36342,8 +36448,10 @@ function chatgptPrecheck(model, compat, apiKey) {
|
|
|
36342
36448
|
if (live2 === void 0) return;
|
|
36343
36449
|
if (live2.needsLogin === true) throw authExpiredError(live2.provider);
|
|
36344
36450
|
if (live2.flavor !== compat.chatgptBackend) {
|
|
36451
|
+
const pinned = String(compat.chatgptBackend);
|
|
36452
|
+
const ref = `${model.provider}/${model.id}@${pinned}`;
|
|
36345
36453
|
throw new Error(
|
|
36346
|
-
`chatgpt_flavor_mismatch:
|
|
36454
|
+
`chatgpt_flavor_mismatch: ${msg().auth.request.flavorMismatch(live2.flavor, ref, pinned)}`
|
|
36347
36455
|
);
|
|
36348
36456
|
}
|
|
36349
36457
|
}
|
|
@@ -36427,9 +36535,7 @@ function recoverChatGptError(error2, model, compat, options, apiKey, tried) {
|
|
|
36427
36535
|
if (backend === "siwc" && error2.status === 403 && code === "subscription_sharing_user_not_eligible")
|
|
36428
36536
|
return {
|
|
36429
36537
|
kind: "fail",
|
|
36430
|
-
error: new Error(
|
|
36431
|
-
"not_eligible: this ChatGPT account cannot share plan usage with ama (403 subscription_sharing_user_not_eligible)"
|
|
36432
|
-
)
|
|
36538
|
+
error: new Error(`not_eligible: ${msg().auth.request.notEligible}`)
|
|
36433
36539
|
};
|
|
36434
36540
|
if (backend === "siwc" && error2.status === 400 && code === "subscription_sharing_unsupported_capability" && !tried.has("strip")) {
|
|
36435
36541
|
const param = typeof body["param"] === "string" ? body["param"].split(/[.[]/)[0] : void 0;
|
|
@@ -36455,6 +36561,7 @@ var init_chatgpt_backend = __esm({
|
|
|
36455
36561
|
"use strict";
|
|
36456
36562
|
init_live();
|
|
36457
36563
|
init_refresh();
|
|
36564
|
+
init_i18n();
|
|
36458
36565
|
init_chatgpt_rate_limits();
|
|
36459
36566
|
SIWC_FORBIDDEN_FIELDS = [
|
|
36460
36567
|
"background",
|
|
@@ -38733,8 +38840,8 @@ var init_registry2 = __esm({
|
|
|
38733
38840
|
candidates: available.filter(Boolean).map((c) => `${provider.id}/${model.id}@${c}`)
|
|
38734
38841
|
};
|
|
38735
38842
|
}
|
|
38736
|
-
|
|
38737
|
-
return { ok: true, model:
|
|
38843
|
+
const picked = channel === model.channel ? model : this.materialize(provider, model, channel);
|
|
38844
|
+
return { ok: true, model: { ...picked, channelPinned: true }, provider };
|
|
38738
38845
|
}
|
|
38739
38846
|
/**
|
|
38740
38847
|
* `provider/model`、`provider/model@渠道` 或裸模型 id。`@` 先按渠道解析(id 里本来就带 `@` 且已登记的
|
|
@@ -38763,9 +38870,9 @@ var init_registry2 = __esm({
|
|
|
38763
38870
|
const open2 = this.relayed.has(provider.id) || this.openTables.has(provider.id);
|
|
38764
38871
|
const relayed = provider.models.length === 0 || open2;
|
|
38765
38872
|
if (synthesize && relayed && id.length > 0) {
|
|
38766
|
-
const
|
|
38767
|
-
|
|
38768
|
-
|
|
38873
|
+
const known = provider.channels?.some((c) => c.name === channel) ? channel : void 0;
|
|
38874
|
+
const synthesized = this.synthesize(provider, id, known);
|
|
38875
|
+
if (known) synthesized.channels = [.../* @__PURE__ */ new Set([...synthesized.channels ?? [], known])];
|
|
38769
38876
|
return { ok: true, model: synthesized, provider };
|
|
38770
38877
|
}
|
|
38771
38878
|
return { ok: false, reason: "not_found", candidates: this.similar(id, provider.id) };
|
|
@@ -46723,7 +46830,7 @@ var init_tool = __esm({
|
|
|
46723
46830
|
import_node_fs65 = require("node:fs");
|
|
46724
46831
|
import_node_os13 = require("node:os");
|
|
46725
46832
|
import_node_path88 = require("node:path");
|
|
46726
|
-
|
|
46833
|
+
init_presets2();
|
|
46727
46834
|
init_capability();
|
|
46728
46835
|
init_declarations();
|
|
46729
46836
|
init_host_side();
|
|
@@ -46873,7 +46980,7 @@ var init_codemode_notice = __esm({
|
|
|
46873
46980
|
"use strict";
|
|
46874
46981
|
import_node_fs66 = require("node:fs");
|
|
46875
46982
|
import_node_path89 = require("node:path");
|
|
46876
|
-
|
|
46983
|
+
init_presets2();
|
|
46877
46984
|
init_i18n();
|
|
46878
46985
|
NOTICES_FILE = "notices.json";
|
|
46879
46986
|
KEY = "codemodeNonStrictDefault";
|
|
@@ -46959,12 +47066,15 @@ async function buildProviderRegistry(input2, options = {}) {
|
|
|
46959
47066
|
}
|
|
46960
47067
|
if (provider !== void 0) registry2 = make({ provider, apiKey: cli.apiKey });
|
|
46961
47068
|
}
|
|
46962
|
-
if (dataDir !== void 0)
|
|
47069
|
+
if (dataDir !== void 0) {
|
|
47070
|
+
const flavor = readOAuthEntry(input2.authFile, CHATGPT_PROVIDER_ID)?.flavor;
|
|
46963
47071
|
mergeDiscoveredModels(
|
|
46964
47072
|
registry2,
|
|
46965
47073
|
dataDir,
|
|
46966
|
-
lazyIndex(() => loadModelsDevIndex(dataDir))
|
|
47074
|
+
lazyIndex(() => loadModelsDevIndex(dataDir)),
|
|
47075
|
+
(id) => id === CHATGPT_PROVIDER_ID ? flavor : void 0
|
|
46967
47076
|
);
|
|
47077
|
+
}
|
|
46968
47078
|
const probe = options.probeLocal ?? env[NO_LOCAL_PROBE_ENV] !== "1";
|
|
46969
47079
|
if (probe && config.defaultModel === void 0 && !anyKeyConfigured(registry2)) {
|
|
46970
47080
|
await probeLocalProviders(registry2, options.probeTimeoutMs ?? LOCAL_PROBE_TIMEOUT_MS);
|
|
@@ -46999,7 +47109,7 @@ var init_compose_providers = __esm({
|
|
|
46999
47109
|
init_discovered_cache();
|
|
47000
47110
|
init_enrich();
|
|
47001
47111
|
init_token_store();
|
|
47002
|
-
|
|
47112
|
+
init_presets();
|
|
47003
47113
|
LOCAL_PROBE_TIMEOUT_MS = 300;
|
|
47004
47114
|
NO_LOCAL_PROBE_ENV = "AMA_NO_LOCAL_PROBE";
|
|
47005
47115
|
}
|
|
@@ -47741,7 +47851,7 @@ var init_model_items = __esm({
|
|
|
47741
47851
|
"src/modes/interactive/model-items.ts"() {
|
|
47742
47852
|
"use strict";
|
|
47743
47853
|
init_model_visibility();
|
|
47744
|
-
|
|
47854
|
+
init_presets();
|
|
47745
47855
|
init_i18n();
|
|
47746
47856
|
HINT_PREFIX = "ama:hint:";
|
|
47747
47857
|
}
|
|
@@ -48951,7 +49061,7 @@ var init_startup_screen = __esm({
|
|
|
48951
49061
|
init_builtin3();
|
|
48952
49062
|
import_node_path92 = require("node:path");
|
|
48953
49063
|
init_channels();
|
|
48954
|
-
|
|
49064
|
+
init_presets2();
|
|
48955
49065
|
init_i18n();
|
|
48956
49066
|
init_version();
|
|
48957
49067
|
}
|
|
@@ -54723,7 +54833,7 @@ var init_status_area = __esm({
|
|
|
54723
54833
|
init_info();
|
|
54724
54834
|
init_bash();
|
|
54725
54835
|
init_detect();
|
|
54726
|
-
|
|
54836
|
+
init_presets2();
|
|
54727
54837
|
init_tui2();
|
|
54728
54838
|
init_status_bar();
|
|
54729
54839
|
init_status_line();
|
|
@@ -57271,7 +57381,7 @@ var init_compose2 = __esm({
|
|
|
57271
57381
|
init_bash();
|
|
57272
57382
|
import_node_path99 = require("node:path");
|
|
57273
57383
|
init_paths();
|
|
57274
|
-
|
|
57384
|
+
init_presets2();
|
|
57275
57385
|
init_registry();
|
|
57276
57386
|
init_tool2();
|
|
57277
57387
|
init_codemode_notice();
|
|
@@ -58811,8 +58921,7 @@ init_discovered_cache();
|
|
|
58811
58921
|
|
|
58812
58922
|
// src/auth/chatgpt/backend-client.ts
|
|
58813
58923
|
init_chatgpt_rate_limits();
|
|
58814
|
-
|
|
58815
|
-
init_presets2();
|
|
58924
|
+
init_presets();
|
|
58816
58925
|
var BACKEND_TIMEOUT_MS = 15e3;
|
|
58817
58926
|
function headers(auth) {
|
|
58818
58927
|
const out = {
|
|
@@ -58829,9 +58938,29 @@ function listed(item) {
|
|
|
58829
58938
|
const visibility = item["visibility"];
|
|
58830
58939
|
return visibility === void 0 || visibility === "list";
|
|
58831
58940
|
}
|
|
58941
|
+
function codexMetadata(item) {
|
|
58942
|
+
const out = {};
|
|
58943
|
+
const window2 = item["context_window"];
|
|
58944
|
+
if (typeof window2 === "number" && Number.isInteger(window2) && window2 > 0)
|
|
58945
|
+
out.contextWindow = window2;
|
|
58946
|
+
const modalities = item["input_modalities"];
|
|
58947
|
+
if (Array.isArray(modalities)) {
|
|
58948
|
+
const input2 = ["text", "image"].filter((x) => modalities.includes(x));
|
|
58949
|
+
if (input2.includes("text")) out.input = input2;
|
|
58950
|
+
}
|
|
58951
|
+
const levels = item["supported_reasoning_levels"];
|
|
58952
|
+
if (Array.isArray(levels)) {
|
|
58953
|
+
const efforts = levels.map(
|
|
58954
|
+
(level) => typeof level === "string" ? level : typeof level === "object" && level !== null ? level["effort"] : void 0
|
|
58955
|
+
).filter((x) => typeof x === "string" && x !== "");
|
|
58956
|
+
if (efforts.length > 0) out.reasoningLevels = [...new Set(efforts)];
|
|
58957
|
+
}
|
|
58958
|
+
return out;
|
|
58959
|
+
}
|
|
58832
58960
|
async function listChatGptModels(fetchFn, baseUrl, auth) {
|
|
58833
58961
|
const base4 = baseUrl.replace(/\/+$/, "");
|
|
58834
|
-
const
|
|
58962
|
+
const version = auth.clientVersion ?? DEFAULT_CODEX_CLIENT_VERSION;
|
|
58963
|
+
const url = auth.flavor === "codex" ? `${base4}/models?client_version=${encodeURIComponent(version)}` : `${base4}/models`;
|
|
58835
58964
|
const response = await fetchFn(url, {
|
|
58836
58965
|
headers: headers(auth),
|
|
58837
58966
|
signal: AbortSignal.timeout(BACKEND_TIMEOUT_MS)
|
|
@@ -58846,7 +58975,11 @@ async function listChatGptModels(fetchFn, baseUrl, auth) {
|
|
|
58846
58975
|
if (typeof id !== "string" || id === "" || seen.has(id)) continue;
|
|
58847
58976
|
seen.add(id);
|
|
58848
58977
|
const name = item["display_name"];
|
|
58849
|
-
out.push(
|
|
58978
|
+
out.push({
|
|
58979
|
+
id,
|
|
58980
|
+
...typeof name === "string" && name !== "" ? { name } : {},
|
|
58981
|
+
...auth.flavor === "codex" ? codexMetadata(item) : {}
|
|
58982
|
+
});
|
|
58850
58983
|
}
|
|
58851
58984
|
return out;
|
|
58852
58985
|
}
|
|
@@ -59299,7 +59432,7 @@ function readOrCreateHostId(dataDir) {
|
|
|
59299
59432
|
}
|
|
59300
59433
|
|
|
59301
59434
|
// src/auth/chatgpt/login.ts
|
|
59302
|
-
|
|
59435
|
+
init_presets();
|
|
59303
59436
|
var DEFAULT_ACCESS_TTL_S = 3600;
|
|
59304
59437
|
function flowPreset(preset, hostId) {
|
|
59305
59438
|
return {
|
|
@@ -59412,7 +59545,7 @@ async function revokeChatGpt(fetchFn, entry, overrides = {}) {
|
|
|
59412
59545
|
}
|
|
59413
59546
|
|
|
59414
59547
|
// src/auth/chatgpt/cli.ts
|
|
59415
|
-
|
|
59548
|
+
init_presets();
|
|
59416
59549
|
init_quota_text();
|
|
59417
59550
|
function userAuthConfig(io) {
|
|
59418
59551
|
try {
|
|
@@ -59564,14 +59697,18 @@ async function runLogin(args, io, deps = {}) {
|
|
|
59564
59697
|
if (entry.planType === "free") io.stdout(`${m.freePlanHint(entry.planType)}
|
|
59565
59698
|
`);
|
|
59566
59699
|
if (flavor === "siwc") io.stdout(`${m.siwcLimitHint}
|
|
59700
|
+
${m.siwcEligibilityHint}
|
|
59567
59701
|
`);
|
|
59568
59702
|
const count2 = await cacheModels(io, entry, config, deps);
|
|
59569
|
-
io.
|
|
59703
|
+
const done = count2 === 0 && flavor === "codex" ? m.codexNoModels(codexClientVersion(config, io.env)) : count2 === void 0 || count2 === 0 ? m.modelHint : m.modelsCached(count2);
|
|
59704
|
+
io.stdout(`${done}
|
|
59570
59705
|
`);
|
|
59571
59706
|
return ExitCode.Ok;
|
|
59572
59707
|
}
|
|
59573
59708
|
async function cacheModels(io, entry, config, deps) {
|
|
59709
|
+
const dataDir = resolveDataDir({ env: io.env });
|
|
59574
59710
|
try {
|
|
59711
|
+
clearDiscoveredCache(dataDir, CHATGPT_PROVIDER_ID);
|
|
59575
59712
|
const models = await listChatGptModels(
|
|
59576
59713
|
deps.fetch ?? fetch,
|
|
59577
59714
|
chatgptBaseUrl(entry.flavor, io.env),
|
|
@@ -59579,11 +59716,10 @@ async function cacheModels(io, entry, config, deps) {
|
|
|
59579
59716
|
flavor: entry.flavor,
|
|
59580
59717
|
accessToken: entry.accessToken,
|
|
59581
59718
|
accountId: entry.accountId,
|
|
59582
|
-
originator: config?.originator
|
|
59719
|
+
originator: config?.originator,
|
|
59720
|
+
clientVersion: codexClientVersion(config, io.env)
|
|
59583
59721
|
}
|
|
59584
59722
|
);
|
|
59585
|
-
if (models.length === 0) return void 0;
|
|
59586
|
-
const dataDir = resolveDataDir({ env: io.env });
|
|
59587
59723
|
writeDiscoveredCache(dataDir, CHATGPT_PROVIDER_ID, { models, flavor: entry.flavor });
|
|
59588
59724
|
return models.length;
|
|
59589
59725
|
} catch {
|
|
@@ -59790,7 +59926,7 @@ init_types2();
|
|
|
59790
59926
|
init_capability();
|
|
59791
59927
|
init_registry2();
|
|
59792
59928
|
init_auth_file();
|
|
59793
|
-
|
|
59929
|
+
init_presets2();
|
|
59794
59930
|
init_registry();
|
|
59795
59931
|
init_args();
|
|
59796
59932
|
init_default_model();
|
|
@@ -60424,7 +60560,7 @@ init_types_w6();
|
|
|
60424
60560
|
|
|
60425
60561
|
// src/auth/chatgpt/doctor.ts
|
|
60426
60562
|
init_i18n();
|
|
60427
|
-
|
|
60563
|
+
init_presets();
|
|
60428
60564
|
init_quota_text();
|
|
60429
60565
|
async function oauthDoctorLines(provider, entry, options = {}) {
|
|
60430
60566
|
const m = msg().auth;
|
|
@@ -60891,7 +61027,7 @@ var CACHE_PROBE_ACTION = {
|
|
|
60891
61027
|
|
|
60892
61028
|
// src/cli/subcommands/models-discover.ts
|
|
60893
61029
|
init_http();
|
|
60894
|
-
|
|
61030
|
+
init_presets();
|
|
60895
61031
|
init_live();
|
|
60896
61032
|
init_registry2();
|
|
60897
61033
|
init_discovered_cache();
|
|
@@ -61160,11 +61296,18 @@ async function discoverModels(provider, apiKey, options = {}) {
|
|
|
61160
61296
|
flavor,
|
|
61161
61297
|
accessToken: apiKey,
|
|
61162
61298
|
accountId: live2?.accountId,
|
|
61163
|
-
originator: channel?.headers?.["originator"]
|
|
61299
|
+
originator: channel?.headers?.["originator"],
|
|
61300
|
+
clientVersion: options.codexClientVersion
|
|
61164
61301
|
});
|
|
61165
61302
|
return models.map((m) => {
|
|
61166
61303
|
const model = withCustomDefaults({ id: m.id }, provider.id, provider.api);
|
|
61167
61304
|
if (m.name !== void 0) model.name = m.name;
|
|
61305
|
+
if (m.contextWindow !== void 0) model.contextWindow = m.contextWindow;
|
|
61306
|
+
if (m.input !== void 0) model.input = m.input;
|
|
61307
|
+
if (m.reasoningLevels?.some((x) => x !== "none") === true) {
|
|
61308
|
+
model.reasoning = true;
|
|
61309
|
+
model.thinkingLevelMap = thinkingMapOf(m.reasoningLevels);
|
|
61310
|
+
}
|
|
61168
61311
|
return model;
|
|
61169
61312
|
});
|
|
61170
61313
|
}
|
|
@@ -61279,7 +61422,9 @@ async function run6(ctx) {
|
|
|
61279
61422
|
}
|
|
61280
61423
|
let found;
|
|
61281
61424
|
try {
|
|
61282
|
-
found = await discoverModels(provider, key.apiKey
|
|
61425
|
+
found = await discoverModels(provider, key.apiKey, {
|
|
61426
|
+
codexClientVersion: codexClientVersion(ctx.level.merged.config.auth?.chatgpt, io.env)
|
|
61427
|
+
});
|
|
61283
61428
|
} catch (error2) {
|
|
61284
61429
|
io.stderr(m.listFailed(provider.id, error2.message));
|
|
61285
61430
|
return ExitCode.RuntimeError;
|
|
@@ -61345,14 +61490,30 @@ async function run6(ctx) {
|
|
|
61345
61490
|
}
|
|
61346
61491
|
return ExitCode.Ok;
|
|
61347
61492
|
}
|
|
61493
|
+
function cacheEntry(m) {
|
|
61494
|
+
const entry = { id: m.id };
|
|
61495
|
+
if (m.name !== m.id) entry.name = m.name;
|
|
61496
|
+
if (m.contextWindow !== void 0) entry.contextWindow = m.contextWindow;
|
|
61497
|
+
if (m.input.length !== 1 || m.input[0] !== "text") entry.input = [...m.input];
|
|
61498
|
+
if (m.reasoning && m.thinkingLevelMap !== void 0)
|
|
61499
|
+
entry.reasoningLevels = Object.entries(m.thinkingLevelMap).flatMap(
|
|
61500
|
+
([level, value]) => typeof value !== "string" ? [] : level === "off" ? ["none"] : [level]
|
|
61501
|
+
);
|
|
61502
|
+
return entry;
|
|
61503
|
+
}
|
|
61348
61504
|
function cacheChatGpt(ctx, found, apiKey) {
|
|
61505
|
+
const flavor = liveToken(apiKey)?.flavor;
|
|
61349
61506
|
try {
|
|
61350
|
-
const
|
|
61351
|
-
const models = found.map((m) => ({ id: m.id, ...m.name !== m.id ? { name: m.name } : {} }));
|
|
61507
|
+
const models = found.map(cacheEntry);
|
|
61352
61508
|
const path = writeDiscoveredCache(ctx.level.dataDir, CHATGPT_PROVIDER_ID, { models, flavor });
|
|
61353
61509
|
ctx.io.stdout(msg().subcommands.discover.cached(path));
|
|
61354
61510
|
} catch (error2) {
|
|
61355
61511
|
ctx.io.stderr(`ama: ${error2.message}
|
|
61512
|
+
`);
|
|
61513
|
+
}
|
|
61514
|
+
if (found.length === 0 && flavor === "codex") {
|
|
61515
|
+
const version = codexClientVersion(ctx.level.merged.config.auth?.chatgpt, ctx.io.env);
|
|
61516
|
+
ctx.io.stderr(`${msg().auth.login.codexNoModels(version)}
|
|
61356
61517
|
`);
|
|
61357
61518
|
}
|
|
61358
61519
|
}
|