@xiaoso/dsh-tool-plus 0.1.6 → 0.1.7-beta.0
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/THIRD_PARTY_NOTICES.md +9 -3
- package/lib/{abort-Cwwm4Err.mjs → abort-Caqff3M6.mjs} +2 -2
- package/lib/alibaba-coding-plan-DTupMiAi.mjs +73 -0
- package/lib/alibaba-token-plan-CHGyWOfX.mjs +46 -0
- package/lib/alibaba-token-plan-Dj3OZhEE.mjs +82 -0
- package/lib/{amazon-bedrock-TVMpUTRG.mjs → amazon-bedrock-DbFSYXfJ.mjs} +117 -38
- package/lib/{anthropic-BL6LFDQS.mjs → anthropic-CTJ3IQVa.mjs} +675 -166
- package/lib/anthropic-CXfWlp-x.mjs +105 -0
- package/lib/{aws-credentials-B20dliS7.mjs → anthropic-wire-CKuhDwZ1.mjs} +74 -14
- package/lib/{api-key-login-CIDnXeYd.mjs → api-key-validation-CGCJFbFr.mjs} +27 -68
- package/lib/{azure-openai-responses-BkhsLmN3.mjs → azure-openai-responses-ChFbWaGj.mjs} +27 -16
- package/lib/{browser-render-CmgvSNte.mjs → browser-render-9o0Rknop.mjs} +4 -4
- package/lib/bun-shim.mjs +71 -2
- package/lib/{bundled-references-ChZSPDFw.mjs → bundled-references-DY3EJxZV.mjs} +6 -5
- package/lib/cline-pass-Bwg3esu9.mjs +44 -0
- package/lib/cloudflare-ai-gateway-BupNXyKK.mjs +35 -0
- package/lib/cloudflare-ai-gateway-EWo0VkP5.mjs +44 -0
- package/lib/collapse-DOR8sOGf.mjs +2304 -0
- package/lib/coreweave-C82HrLpb.mjs +31 -0
- package/lib/coreweave-Ct8cF-da.mjs +14 -0
- package/lib/{cursor-B6HcmplF.mjs → cursor-B95LzVWV.mjs} +11 -3
- package/lib/{cursor-CRpLpaZ3.mjs → cursor-DJV_dcgB.mjs} +887 -1784
- package/lib/{cursor-B8m6SqAH.mjs → cursor-LKGjucn2.mjs} +48 -38
- package/lib/cursor-proto-B8Wj8bv9.mjs +10513 -0
- package/lib/{deterministic-id-D-yIV_eI.mjs → deterministic-id-CUEIMSqR.mjs} +1 -1
- package/lib/devin-BMTdx_hx.mjs +316 -0
- package/lib/{devin-DUAfvBsW.mjs → devin-DSp0Rw_E.mjs} +172 -86
- package/lib/devin-ExGIghmx.mjs +69 -0
- package/lib/devin-proto-Br8fdyNl.mjs +2888 -0
- package/lib/{dom-CawWi8fa.mjs → dom-DG3sPESc.mjs} +8 -8
- package/lib/effort-BdtQMN-_.mjs +23 -0
- package/lib/{error-C-f_Wnw4.mjs → error-CORgGg5a.mjs} +275 -154
- package/lib/{event-stream-Dh2guZxS.mjs → event-stream-ulcDenZD.mjs} +20 -4
- package/lib/{gemini-headers-DKUShltF.mjs → gemini-headers-Co9cVvex.mjs} +2 -2
- package/lib/{github-copilot-suDymKrx.mjs → github-copilot-Dstq1D3s.mjs} +69 -29
- package/lib/github-copilot-headers-DOh1gt_w.mjs +312 -0
- package/lib/gitlab-duo-DSCMrU0m.mjs +11 -0
- package/lib/google-CtsKkOQK.mjs +38 -0
- package/lib/google-antigravity-z-5KsEci.mjs +252 -0
- package/lib/{google-auth-DYJLM792.mjs → google-auth-ieLBaneO.mjs} +4 -4
- package/lib/{google-gemini-cli-8BT513Ul.mjs → google-gemini-cli-C6NE5mWz.mjs} +28 -54
- package/lib/{google-gemini-cli-D6cSmfvB.mjs → google-gemini-cli-CAIPSl7e.mjs} +23 -29
- package/lib/google-oauth-shared-DhMllAkt.mjs +53 -0
- package/lib/{google-shared-CVbHK5vZ.mjs → google-shared-B0aNCYEH.mjs} +140 -44
- package/lib/{google-validation-Cgbn3tWJ.mjs → google-validation-BEkNs-Bx.mjs} +1 -1
- package/lib/{google-vertex-Bui-ypAe.mjs → google-vertex-Bbd1tYNc.mjs} +8 -8
- package/lib/hosts-00rjRzUD.mjs +203 -0
- package/lib/id-AL5obQzR.mjs +71 -0
- package/lib/{idle-iterator-CYAxUkSD.mjs → idle-iterator-DlUkEfzW.mjs} +3 -3
- package/lib/index.mjs +587 -5266
- package/lib/kilo-ChJL54wq.mjs +81 -0
- package/lib/kimi-C2c_Zq8A.mjs +67 -0
- package/lib/{launch-BmgEUycu.mjs → launch-DKDH71En.mjs} +1 -1
- package/lib/markit-CmRfm4E2.mjs +9885 -0
- package/lib/models-DnXMYGcJ.mjs +381604 -0
- package/lib/muse-code-Di1VZmB1.mjs +143 -0
- package/lib/{ollama-Df9ce-Cp.mjs → ollama-B8ic3sEp.mjs} +15 -30
- package/lib/{openai-codex-CAVI3Me-.mjs → openai-codex-DuJNC99x.mjs} +29 -99
- package/lib/{openai-codex-responses-BcnOotRB.mjs → openai-codex-responses-BL29nh9K.mjs} +204 -116
- package/lib/{openai-completions-Bq4WT47M.mjs → openai-completions-BK2f2dBv.mjs} +152 -82
- package/lib/openai-configuration-update-xMYUjaK_.mjs +150 -0
- package/lib/{openai-reasoning-fallback-DXsfiSXO.mjs → openai-reasoning-fallback-BdB3RCbj.mjs} +106 -12
- package/lib/{openai-responses-Mq_-PjvE.mjs → openai-responses-CGQPlIIy.mjs} +76 -82
- package/lib/{perplexity-XgLF73E7.mjs → perplexity-TBjz3VMB.mjs} +52 -9
- package/lib/{pkce-BlQikGPu.mjs → pkce-BYjmugmw.mjs} +1 -1
- package/lib/protobuf-aab1UGVn.mjs +717 -0
- package/lib/{provider-response-C6vcbQyO.mjs → provider-response-SqKSkkUc.mjs} +1 -1
- package/lib/{proxy-D9lm7ONA.mjs → proxy-5nWqRL1f.mjs} +45 -5
- package/lib/{readability-Cpm-ocau.mjs → readability-uGhqb4GC.mjs} +2 -2
- package/lib/reference-CtvM4zLU.mjs +114 -0
- package/lib/{request-debug-HJMoJncL.mjs → request-debug-NQN0BjHH.mjs} +1 -1
- package/lib/{sanitize-text-CfcXzw5X.mjs → sanitize-text-BCf5KmCf.mjs} +1 -1
- package/lib/{scrapers-Cg5w77td.mjs → scrapers-D8oWspgW.mjs} +12 -12
- package/lib/{src-BcD0_rQR.mjs → src-BwW51vA5.mjs} +979 -388
- package/lib/{sse-debug-CYdjOC96.mjs → sse-debug-B-tkLCPW.mjs} +1 -1
- package/lib/{stream-Bjq8wjfr.mjs → stream-B_7qN-bA.mjs} +3802 -2623
- package/lib/stream-markup-healing-DKT1lnkW.mjs +267 -0
- package/lib/{strict-tool-validation-imVLUcbI.mjs → strict-tool-validation-CBTz1dAA.mjs} +2 -2
- package/lib/taxonomy-DSIM99rS.mjs +15392 -0
- package/lib/{stream-markup-healing-DZ6bVDxH.mjs → thinking-CiLa2LFB.mjs} +31 -186
- package/lib/{turndown-DN7ByzEI.mjs → turndown-DrX1M4WG.mjs} +4 -4
- package/lib/{type-guards-B9VVjRDK.mjs → type-guards-CttAANEx.mjs} +1 -1
- package/lib/{types-DX_bvuus.mjs → types-PVueGi9S.mjs} +2 -2
- package/lib/{utils-C-dSORPa.mjs → utils-CCfhUQen.mjs} +2364 -2676
- package/lib/{utils-Cp2Mxf_U.mjs → utils-CUPhpw9A.mjs} +413 -134
- package/lib/{utils-CQHPEQ3W.mjs → utils-DeWqNWV8.mjs} +2 -2
- package/lib/{vision-guard-mBmtAHx0.mjs → vision-guard-_XwsL1DF.mjs} +14 -29
- package/lib/xai-oauth-CXhnz0gO.mjs +210 -0
- package/lib/{xiaomi-7mE345KX.mjs → xiaomi-psoUItal.mjs} +8 -37
- package/lib/{zai-CeNpMV3W.mjs → zai-ApJ8HBgT.mjs} +8 -71
- package/lib/{zip-BK7UHCwX.mjs → zip-Kd602XNe.mjs} +1 -1
- package/package.json +11 -11
- package/presets/package.json +1 -1
- package/presets/tool-plus-ptc/agent.cordis.yml +1 -1
- package/presets/tool-plus-standard/agent.cordis.yml +1 -1
- package/lib/agent_pb-Rizyt9Zg.mjs +0 -805
- package/lib/anthropic-CDmj476p.mjs +0 -262
- package/lib/api_server_pb-CDZgLMta.mjs +0 -252
- package/lib/callback-server-CFJK-jvK.mjs +0 -398
- package/lib/codex-P1dGpX7G.mjs +0 -54
- package/lib/device-code-CuXTWYwY.mjs +0 -51
- package/lib/devin-BcQwht1W.mjs +0 -114
- package/lib/devin-BvMfGevz.mjs +0 -95
- package/lib/github-copilot-B3kQl0g0.mjs +0 -104
- package/lib/gitlab-duo-BriUTP8k.mjs +0 -155
- package/lib/gitlab-duo-workflow-wK5Ljzmc.mjs +0 -91
- package/lib/google-CE5tFDod.mjs +0 -30
- package/lib/google-antigravity-C1jgNljz.mjs +0 -198
- package/lib/google-oauth-shared-BLVTvokk.mjs +0 -147
- package/lib/grammar-D-NqNUxQ.mjs +0 -49
- package/lib/identity-HNO1Oe9B.mjs +0 -219
- package/lib/kimi-DgcUpPtK.mjs +0 -236
- package/lib/markit-DtGoRE6M.mjs +0 -1417
- package/lib/minimax-code-Y3h5li9N.mjs +0 -53
- package/lib/models-DRA2c_8U.mjs +0 -104660
- package/lib/opencode-BsVw9rCD.mjs +0 -38
- package/lib/to-binary-B1BEBIPC.mjs +0 -6002
- package/lib/wafer-BlhWLweO.mjs +0 -17
- package/lib/xai-oauth-5pORHUrg.mjs +0 -446
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -7,9 +7,15 @@ Scope of ported upstream code:
|
|
|
7
7
|
|
|
8
8
|
- from **oh-my-pi** (MIT, notice below): the tool suite sources under
|
|
9
9
|
`src/tools/` (bash runtime, read, write, edit, grep, glob, plus the OMP
|
|
10
|
-
`omp/` engine sources they wrap), and the hashline
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
`omp/` engine sources they wrap), and the thin hashline adapter at
|
|
11
|
+
`src/tools/hashline/native/` (`diff-preview.ts` is a verbatim port of the
|
|
12
|
+
former upstream TypeScript engine). The hashline engine itself is no longer
|
|
13
|
+
vendored: since oh-my-pi 18.x it lives in Rust (`crates/pi-edit`) and reaches
|
|
14
|
+
this plugin through the `@oh-my-pi/pi-natives` dependency, which ships
|
|
15
|
+
upstream's compiled binary.
|
|
16
|
+
- upstream hashline **test fixtures** vendored for regression testing under
|
|
17
|
+
`src/tools/hashline/test/fixtures/` (copied from
|
|
18
|
+
`crates/pi-edit/tests/fixtures/hashline/`), MIT, same notice below.
|
|
13
19
|
|
|
14
20
|
---
|
|
15
21
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
2
|
__installBunShim();
|
|
3
|
-
import {
|
|
4
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@
|
|
3
|
+
import { _ as AbortError } from "./error-CORgGg5a.mjs";
|
|
4
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/utils/abort.ts
|
|
5
5
|
/**
|
|
6
6
|
* Tracks whether a merged request signal was aborted by the caller or by provider-local logic.
|
|
7
7
|
*
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
+
__installBunShim();
|
|
3
|
+
import { g as OnPromptRequiredError, m as LoginCancelledError, p as ApiKeyRequiredError, t as ConfigurationError } from "./error-CORgGg5a.mjs";
|
|
4
|
+
import { n as validateApiKeyAgainstModelsEndpoint, r as validateOpenAICompatibleApiKey } from "./api-key-validation-CGCJFbFr.mjs";
|
|
5
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/registry/oauth/alibaba-coding-plan.ts
|
|
6
|
+
const DEFAULT_AUTH_URL = "https://modelstudio.console.alibabacloud.com/";
|
|
7
|
+
const CHINA_AUTH_URL = "https://bailian.console.aliyun.com/?tab=model#/api-key";
|
|
8
|
+
const DEFAULT_API_BASE_URL = "https://coding-intl.dashscope.aliyuncs.com/v1";
|
|
9
|
+
const CHINA_API_BASE_URL = "https://coding.dashscope.aliyuncs.com/v1";
|
|
10
|
+
const VALIDATION_MODEL = "qwen3.5-plus";
|
|
11
|
+
async function loginAlibabaCodingPlan(options) {
|
|
12
|
+
if (!options.onPrompt) throw new OnPromptRequiredError("Alibaba Coding Plan");
|
|
13
|
+
const endpointChoice = await options.onPrompt({
|
|
14
|
+
message: "Select Alibaba Coding Plan endpoint: 1=International (default), 2=China, 3=Custom — enter 1, 2, or 3",
|
|
15
|
+
placeholder: "1"
|
|
16
|
+
});
|
|
17
|
+
if (options.signal?.aborted) throw new LoginCancelledError();
|
|
18
|
+
const choice = endpointChoice.trim();
|
|
19
|
+
let baseUrl;
|
|
20
|
+
let authUrl;
|
|
21
|
+
let instructions;
|
|
22
|
+
if (choice === "2") {
|
|
23
|
+
baseUrl = CHINA_API_BASE_URL;
|
|
24
|
+
authUrl = CHINA_AUTH_URL;
|
|
25
|
+
instructions = "Copy your API key from the Alibaba Cloud Bailian console (China mainland)";
|
|
26
|
+
} else if (choice === "3") {
|
|
27
|
+
const trimmedUrl = (await options.onPrompt({
|
|
28
|
+
message: "Enter custom base URL",
|
|
29
|
+
placeholder: "https://your-proxy.com/v1"
|
|
30
|
+
})).trim().replace(/\/+$/, "");
|
|
31
|
+
if (!trimmedUrl) throw new ConfigurationError("Custom URL is required for option 3");
|
|
32
|
+
baseUrl = trimmedUrl;
|
|
33
|
+
authUrl = DEFAULT_AUTH_URL;
|
|
34
|
+
instructions = "Copy your API key from the Alibaba Cloud DashScope console";
|
|
35
|
+
} else {
|
|
36
|
+
baseUrl = DEFAULT_API_BASE_URL;
|
|
37
|
+
authUrl = DEFAULT_AUTH_URL;
|
|
38
|
+
instructions = "Copy your API key from the Alibaba Cloud DashScope console (International)";
|
|
39
|
+
}
|
|
40
|
+
options.onAuth?.({
|
|
41
|
+
url: authUrl,
|
|
42
|
+
instructions
|
|
43
|
+
});
|
|
44
|
+
const apiKey = await options.onPrompt({
|
|
45
|
+
message: "Paste your Alibaba Coding Plan API key",
|
|
46
|
+
placeholder: "sk-..."
|
|
47
|
+
});
|
|
48
|
+
if (options.signal?.aborted) throw new LoginCancelledError();
|
|
49
|
+
const trimmed = apiKey.trim();
|
|
50
|
+
if (!trimmed) throw new ApiKeyRequiredError();
|
|
51
|
+
options.onProgress?.("Validating API key...");
|
|
52
|
+
if (choice === "3") await validateApiKeyAgainstModelsEndpoint({
|
|
53
|
+
provider: "Alibaba Coding Plan",
|
|
54
|
+
apiKey: trimmed,
|
|
55
|
+
modelsUrl: `${baseUrl}/models`,
|
|
56
|
+
signal: options.signal
|
|
57
|
+
});
|
|
58
|
+
else await validateOpenAICompatibleApiKey({
|
|
59
|
+
provider: "Alibaba Coding Plan",
|
|
60
|
+
apiKey: trimmed,
|
|
61
|
+
baseUrl,
|
|
62
|
+
model: VALIDATION_MODEL,
|
|
63
|
+
signal: options.signal
|
|
64
|
+
});
|
|
65
|
+
return {
|
|
66
|
+
access: trimmed,
|
|
67
|
+
refresh: trimmed,
|
|
68
|
+
expires: Number.MAX_SAFE_INTEGER,
|
|
69
|
+
enterpriseUrl: baseUrl
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
export { loginAlibabaCodingPlan };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
+
__installBunShim();
|
|
3
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-catalog@18.1.17/node_modules/@oh-my-pi/pi-catalog/src/wire/alibaba-token-plan.ts
|
|
4
|
+
/**
|
|
5
|
+
* International (Singapore) Token Plan endpoint. Default region; keys issued by
|
|
6
|
+
* the international product authenticate only here.
|
|
7
|
+
*/
|
|
8
|
+
const ALIBABA_TOKEN_PLAN_BASE_URL = "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1";
|
|
9
|
+
/**
|
|
10
|
+
* China (Beijing) Token Plan endpoint (百炼 Token Plan). Keys are region-locked:
|
|
11
|
+
* a Beijing-issued key is rejected by the international endpoint with
|
|
12
|
+
* `invalid_api_key`, and vice versa (#6682).
|
|
13
|
+
*/
|
|
14
|
+
const ALIBABA_TOKEN_PLAN_CN_BASE_URL = "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1";
|
|
15
|
+
const TOKEN_PATTERN = /^sk-[A-Za-z0-9._~+/-]+={0,2}$/;
|
|
16
|
+
function parseAlibabaTokenPlanCredential(value) {
|
|
17
|
+
const trimmed = value.trim();
|
|
18
|
+
if (!trimmed) return null;
|
|
19
|
+
if (!trimmed.startsWith("{")) return TOKEN_PATTERN.test(trimmed) ? { token: trimmed } : null;
|
|
20
|
+
try {
|
|
21
|
+
const parsed = JSON.parse(trimmed);
|
|
22
|
+
if (typeof parsed.token !== "string" || !TOKEN_PATTERN.test(parsed.token.trim())) return null;
|
|
23
|
+
if (parsed.cookie !== void 0 && typeof parsed.cookie !== "string") return null;
|
|
24
|
+
if (parsed.baseUrl !== void 0 && typeof parsed.baseUrl !== "string") return null;
|
|
25
|
+
const token = parsed.token.trim();
|
|
26
|
+
const cookie = parsed.cookie?.trim();
|
|
27
|
+
const baseUrl = parsed.baseUrl?.trim();
|
|
28
|
+
const credential = { token };
|
|
29
|
+
if (cookie) credential.cookie = cookie;
|
|
30
|
+
if (baseUrl) credential.baseUrl = baseUrl;
|
|
31
|
+
return credential;
|
|
32
|
+
} catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function serializeAlibabaTokenPlanCredential(token, cookie, baseUrl) {
|
|
37
|
+
const trimmedCookie = cookie.trim();
|
|
38
|
+
const trimmedBaseUrl = baseUrl?.trim();
|
|
39
|
+
if (!trimmedCookie && !trimmedBaseUrl) return token;
|
|
40
|
+
const payload = { token };
|
|
41
|
+
if (trimmedCookie) payload.cookie = trimmedCookie;
|
|
42
|
+
if (trimmedBaseUrl) payload.baseUrl = trimmedBaseUrl;
|
|
43
|
+
return JSON.stringify(payload);
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { serializeAlibabaTokenPlanCredential as i, ALIBABA_TOKEN_PLAN_CN_BASE_URL as n, parseAlibabaTokenPlanCredential as r, ALIBABA_TOKEN_PLAN_BASE_URL as t };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
+
__installBunShim();
|
|
3
|
+
import { g as OnPromptRequiredError, m as LoginCancelledError, p as ApiKeyRequiredError, t as ConfigurationError } from "./error-CORgGg5a.mjs";
|
|
4
|
+
import { i as serializeAlibabaTokenPlanCredential, n as ALIBABA_TOKEN_PLAN_CN_BASE_URL, t as ALIBABA_TOKEN_PLAN_BASE_URL } from "./alibaba-token-plan-CHGyWOfX.mjs";
|
|
5
|
+
import { n as validateApiKeyAgainstModelsEndpoint } from "./api-key-validation-CGCJFbFr.mjs";
|
|
6
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/registry/oauth/alibaba-token-plan.ts
|
|
7
|
+
const INTERNATIONAL_AUTH_URL = "https://home.qwencloud.com/billing/subscription/token-plan-individual";
|
|
8
|
+
const CHINA_AUTH_URL = "https://www.aliyun.com/benefit/scene/tokenplan";
|
|
9
|
+
/**
|
|
10
|
+
* Log in to the QwenCloud Token Plan provider.
|
|
11
|
+
*
|
|
12
|
+
* The Token Plan ships as two regionally separate products with
|
|
13
|
+
* non-interchangeable keys — International (Singapore) and China (Beijing) —
|
|
14
|
+
* so login first selects the region (or a custom base URL) before pasting the
|
|
15
|
+
* key, mirroring {@link loginAlibabaCodingPlan}. The chosen region is validated
|
|
16
|
+
* against its own `/models` endpoint and, when it diverges from the default
|
|
17
|
+
* international endpoint, stored in the credential so inference and discovery
|
|
18
|
+
* both target it (#6682).
|
|
19
|
+
*/
|
|
20
|
+
async function loginAlibabaTokenPlan(options) {
|
|
21
|
+
if (!options.onPrompt) throw new OnPromptRequiredError("QwenCloud Token Plan");
|
|
22
|
+
const endpointChoice = await options.onPrompt({
|
|
23
|
+
message: "Select QwenCloud Token Plan region: 1=International (default), 2=China (Beijing), 3=Custom — enter 1, 2, or 3",
|
|
24
|
+
placeholder: "1"
|
|
25
|
+
});
|
|
26
|
+
if (options.signal?.aborted) throw new LoginCancelledError();
|
|
27
|
+
const choice = endpointChoice.trim();
|
|
28
|
+
let baseUrl;
|
|
29
|
+
let authUrl;
|
|
30
|
+
let instructions;
|
|
31
|
+
if (choice === "2") {
|
|
32
|
+
baseUrl = ALIBABA_TOKEN_PLAN_CN_BASE_URL;
|
|
33
|
+
authUrl = CHINA_AUTH_URL;
|
|
34
|
+
instructions = "Subscribe to the China (Beijing) 百炼 Token Plan and copy its dedicated API key";
|
|
35
|
+
} else if (choice === "3") {
|
|
36
|
+
const trimmedUrl = (await options.onPrompt({
|
|
37
|
+
message: "Enter custom Token Plan base URL",
|
|
38
|
+
placeholder: "https://token-plan.<region>.maas.aliyuncs.com/compatible-mode/v1"
|
|
39
|
+
})).trim().replace(/\/+$/, "");
|
|
40
|
+
if (!trimmedUrl) throw new ConfigurationError("Custom URL is required for option 3");
|
|
41
|
+
baseUrl = trimmedUrl;
|
|
42
|
+
authUrl = INTERNATIONAL_AUTH_URL;
|
|
43
|
+
instructions = "Copy your Token Plan API key for the custom endpoint";
|
|
44
|
+
} else {
|
|
45
|
+
baseUrl = ALIBABA_TOKEN_PLAN_BASE_URL;
|
|
46
|
+
authUrl = INTERNATIONAL_AUTH_URL;
|
|
47
|
+
instructions = "Subscribe to Token Plan Individual and copy its dedicated API key. Keep this page open; the next prompt explains how to enable optional quota reporting.";
|
|
48
|
+
}
|
|
49
|
+
options.onAuth?.({
|
|
50
|
+
url: authUrl,
|
|
51
|
+
instructions
|
|
52
|
+
});
|
|
53
|
+
const apiKeyInput = await options.onPrompt({
|
|
54
|
+
message: "Paste your QwenCloud Token Plan API key",
|
|
55
|
+
placeholder: "sk-sp-..."
|
|
56
|
+
});
|
|
57
|
+
if (options.signal?.aborted) throw new LoginCancelledError();
|
|
58
|
+
const apiKey = apiKeyInput.trim();
|
|
59
|
+
if (!apiKey) throw new ApiKeyRequiredError();
|
|
60
|
+
options.onProgress?.("Validating API key...");
|
|
61
|
+
await validateApiKeyAgainstModelsEndpoint({
|
|
62
|
+
provider: "QwenCloud Token Plan",
|
|
63
|
+
apiKey,
|
|
64
|
+
modelsUrl: `${baseUrl}/models`,
|
|
65
|
+
signal: options.signal,
|
|
66
|
+
fetch: options.fetch
|
|
67
|
+
});
|
|
68
|
+
const cookieRequestHost = baseUrl === "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1" ? "bailian-cs.console.aliyun.com" : "cs-data.qwencloud.com";
|
|
69
|
+
const cookie = (await options.onPrompt({
|
|
70
|
+
message: baseUrl === "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1" ? "Optional quota reporting: open browser DevTools → Network, reload the Token Plan page, filter for api.json, and select the bailian-cs.console.aliyun.com/data/api.json request whose api query ends in /tokenplan/personal/api/v2/usage. Copy Request Headers → Cookie, then paste the complete name=value; ... value here, or press Enter to skip." : "Optional quota reporting: open browser DevTools → Network, reload the Token Plan page, filter for api.json, and select the cs-data.qwencloud.com/data/api.json request whose api query ends in /tokenplan/personal/api/v2/usage. Copy Request Headers → Cookie, then paste the complete name=value; ... value here, or press Enter to skip.",
|
|
71
|
+
placeholder: "name=value; name=value; ...",
|
|
72
|
+
allowEmpty: true
|
|
73
|
+
})).trim().replace(/^Cookie:\s*/i, "").trim();
|
|
74
|
+
if (options.signal?.aborted) throw new LoginCancelledError();
|
|
75
|
+
if (cookie && !cookie.split(";").some((segment) => {
|
|
76
|
+
const separator = segment.indexOf("=");
|
|
77
|
+
return separator > 0 && Boolean(segment.slice(0, separator).trim() && segment.slice(separator + 1).trim());
|
|
78
|
+
})) throw new ConfigurationError(`Invalid QwenCloud Cookie header. Copy the complete Cookie request header from the ${cookieRequestHost} usage request, not a single cookie value.`);
|
|
79
|
+
return serializeAlibabaTokenPlanCredential(apiKey, cookie, baseUrl === "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1" ? void 0 : baseUrl);
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { loginAlibabaTokenPlan };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
2
|
__installBunShim();
|
|
3
|
-
import {
|
|
4
|
-
import { G as fetchWithRetry, I as BedrockApiError, U as EventStreamFrameError,
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { t as
|
|
9
|
-
import {
|
|
10
|
-
|
|
3
|
+
import { B as USER_AGENT, C as warn, F as $flag, _ as parseStreamingJson, v as parseStreamingJsonThrottled } from "./src-BwW51vA5.mjs";
|
|
4
|
+
import { G as fetchWithRetry, I as BedrockApiError, U as EventStreamFrameError, _ as AbortError, c as finalize, r as ValidationError } from "./error-CORgGg5a.mjs";
|
|
5
|
+
import { A as toolWireSchema, C as kStreamingLastParseLen, T as renderDemotedThinking, b as kStreamingBlockIndex, c as resolveCacheRetention, g as clearStreamingPartialJson, h as transformMessages, o as normalizeSystemPrompts, s as normalizeToolCallId, w as kStreamingPartialJson } from "./utils-CUPhpw9A.mjs";
|
|
6
|
+
import { n as isRecord } from "./type-guards-CttAANEx.mjs";
|
|
7
|
+
import { a as mapEffortToAnthropicAdaptiveEffort, c as invalidateAwsCredentialCache, d as resolveAwsBearerToken, l as resolveAwsCredentials, m as resolveAwsAmbientRegion, o as requireSupportedEffort, r as parseAnthropicInputTransformations, t as THINKING_BINDING_CONTROLS_BETA, u as signRequest } from "./anthropic-wire-CKuhDwZ1.mjs";
|
|
8
|
+
import { t as calculateCost } from "./models-DnXMYGcJ.mjs";
|
|
9
|
+
import { t as AssistantMessageEventStream } from "./event-stream-ulcDenZD.mjs";
|
|
10
|
+
import { i as getStreamFirstEventTimeoutMs, t as armPreResponseTimeout } from "./idle-iterator-DlUkEfzW.mjs";
|
|
11
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/providers/aws-eventstream.ts
|
|
11
12
|
/**
|
|
12
13
|
* `application/vnd.amazon.eventstream` decoder.
|
|
13
14
|
*
|
|
@@ -162,7 +163,7 @@ async function* decodeEventStream(source) {
|
|
|
162
163
|
}
|
|
163
164
|
}
|
|
164
165
|
//#endregion
|
|
165
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@
|
|
166
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/providers/amazon-bedrock.ts
|
|
166
167
|
/**
|
|
167
168
|
* Headers SigV4 generates for itself. A caller cannot be allowed to supply these:
|
|
168
169
|
* `signRequest` would sign the caller's value but return its own, so the signature
|
|
@@ -229,24 +230,27 @@ function regionServesGeo(region, geo) {
|
|
|
229
230
|
}
|
|
230
231
|
/**
|
|
231
232
|
* Resolve the Bedrock runtime region for a request. An explicit per-request
|
|
232
|
-
* region and an ARN-embedded region win outright. Otherwise, for a
|
|
233
|
-
* cross-region inference profile (`us.`/`eu.`/`apac.`/`au.`/`jp
|
|
234
|
-
* ambient region (`AWS_REGION` / `AWS_DEFAULT_REGION`) is
|
|
235
|
-
* can serve the profile's geo
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
* ambient region (or
|
|
233
|
+
* region and an ARN-embedded model region win outright. Otherwise, for a
|
|
234
|
+
* geo-prefixed cross-region inference profile (`us.`/`eu.`/`apac.`/`au.`/`jp.`/
|
|
235
|
+
* `us-gov.`), an ambient region (`AWS_REGION` / `AWS_DEFAULT_REGION`) is
|
|
236
|
+
* honored only when it can serve the profile's geo. If the ambient region is
|
|
237
|
+
* absent or mismatched, a same-geo guardrail ARN region is used when available;
|
|
238
|
+
* otherwise the geo default is used. `global.` profiles have no geo entry, so
|
|
239
|
+
* the ambient region (or, when absent, a guardrail ARN's region or
|
|
240
|
+
* `us-east-1`) is used unchanged.
|
|
239
241
|
*/
|
|
240
242
|
function resolveBedrockRegion(modelId, options) {
|
|
241
243
|
const explicit = options.region || inferRegionFromBedrockArn(modelId);
|
|
242
244
|
if (explicit) return explicit;
|
|
243
245
|
const ambient = resolveAwsAmbientRegion(options.profile);
|
|
246
|
+
const guardrailRegion = inferRegionFromBedrockArn(options.guardrailIdentifier ?? "");
|
|
244
247
|
const geo = inferenceProfileGeo(modelId);
|
|
245
248
|
if (geo) {
|
|
246
249
|
if (ambient && regionServesGeo(ambient, geo)) return ambient;
|
|
250
|
+
if (guardrailRegion && regionServesGeo(guardrailRegion, geo)) return guardrailRegion;
|
|
247
251
|
return INFERENCE_PROFILE_GEO_DEFAULT_REGION[geo];
|
|
248
252
|
}
|
|
249
|
-
return ambient || "us-east-1";
|
|
253
|
+
return ambient || guardrailRegion || "us-east-1";
|
|
250
254
|
}
|
|
251
255
|
/**
|
|
252
256
|
* Bedrock validates that requests carrying any `toolUse`/`toolResult` history
|
|
@@ -264,6 +268,31 @@ const NO_TOOLS_SENTINEL = { toolSpec: {
|
|
|
264
268
|
properties: {}
|
|
265
269
|
} }
|
|
266
270
|
} };
|
|
271
|
+
const REQUEST_METADATA_PATTERN = /^[a-zA-Z0-9\s:_@$#=/+,\-.]*$/;
|
|
272
|
+
const REQUEST_METADATA_MAX_ENTRIES = 16;
|
|
273
|
+
const REQUEST_METADATA_MAX_LENGTH = 256;
|
|
274
|
+
/**
|
|
275
|
+
* Bedrock rejects the whole invocation on a malformed `requestMetadata` entry.
|
|
276
|
+
* Attribution tags must never cost a turn, so invalid and excess entries are
|
|
277
|
+
* dropped with a warning instead of failing the request. Returns `undefined`
|
|
278
|
+
* for an empty result so the field is omitted from the body entirely.
|
|
279
|
+
*/
|
|
280
|
+
function sanitizeRequestMetadata(raw) {
|
|
281
|
+
if (!isRecord(raw)) return void 0;
|
|
282
|
+
const out = {};
|
|
283
|
+
const dropped = [];
|
|
284
|
+
let kept = 0;
|
|
285
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
286
|
+
if (typeof value !== "string" || key.length < 1 || key.length > REQUEST_METADATA_MAX_LENGTH || !REQUEST_METADATA_PATTERN.test(key) || value.length > REQUEST_METADATA_MAX_LENGTH || !REQUEST_METADATA_PATTERN.test(value) || kept >= REQUEST_METADATA_MAX_ENTRIES) {
|
|
287
|
+
dropped.push(key);
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
out[key] = value;
|
|
291
|
+
kept++;
|
|
292
|
+
}
|
|
293
|
+
if (dropped.length > 0) warn("Bedrock requestMetadata entries dropped", { keys: dropped });
|
|
294
|
+
return kept > 0 ? out : void 0;
|
|
295
|
+
}
|
|
267
296
|
const streamBedrock = (model, context, options) => {
|
|
268
297
|
const stream = new AssistantMessageEventStream();
|
|
269
298
|
(async () => {
|
|
@@ -299,14 +328,22 @@ const streamBedrock = (model, context, options) => {
|
|
|
299
328
|
const promptCachePolicy = resolvePromptCachePolicy(model, resolveCacheRetention(options.cacheRetention));
|
|
300
329
|
const convertedMessages = convertMessages(context, model, promptCachePolicy);
|
|
301
330
|
const toolPlan = planToolConfig(context.tools, options.toolChoice, convertedMessages);
|
|
302
|
-
|
|
331
|
+
let toolConfig = toolPlan.toolConfig;
|
|
303
332
|
const sentinelInjected = toolPlan.sentinelInjected;
|
|
304
333
|
let additionalModelRequestFields = buildAdditionalModelRequestFields(model, options);
|
|
334
|
+
const prefixMismatchBehavior = model.thinking?.prefixBinding ? options.anthropicPrefixMismatchBehavior ?? "drop_block" : void 0;
|
|
305
335
|
if (toolConfig?.toolChoice && additionalModelRequestFields) {
|
|
306
336
|
const tc = toolConfig.toolChoice;
|
|
307
|
-
if (tc.any || tc.tool)
|
|
337
|
+
if (tc.any || tc.tool) {
|
|
338
|
+
if (prefixMismatchBehavior) toolConfig = {
|
|
339
|
+
...toolConfig,
|
|
340
|
+
toolChoice: { auto: {} }
|
|
341
|
+
};
|
|
342
|
+
else additionalModelRequestFields = void 0;
|
|
343
|
+
}
|
|
308
344
|
}
|
|
309
|
-
|
|
345
|
+
if (prefixMismatchBehavior) additionalModelRequestFields = applyBedrockThinkingBinding(additionalModelRequestFields, prefixMismatchBehavior);
|
|
346
|
+
let commandInput = {
|
|
310
347
|
messages: convertedMessages,
|
|
311
348
|
system: buildSystemPrompt(context.systemPrompt, promptCachePolicy),
|
|
312
349
|
inferenceConfig: {
|
|
@@ -315,9 +352,20 @@ const streamBedrock = (model, context, options) => {
|
|
|
315
352
|
topP: options.topP
|
|
316
353
|
},
|
|
317
354
|
toolConfig,
|
|
318
|
-
|
|
355
|
+
guardrailConfig: buildGuardrailConfig(options),
|
|
356
|
+
additionalModelRequestFields,
|
|
357
|
+
requestMetadata: model.requestMetadata || options.requestMetadata ? {
|
|
358
|
+
...model.requestMetadata,
|
|
359
|
+
...options.requestMetadata
|
|
360
|
+
} : void 0,
|
|
361
|
+
...prefixMismatchBehavior ? { additionalModelResponseFieldPaths: ["/input_transformations"] } : {}
|
|
362
|
+
};
|
|
363
|
+
const replacementInput = await options?.onPayload?.(commandInput, model);
|
|
364
|
+
if (replacementInput !== void 0) commandInput = replacementInput;
|
|
365
|
+
commandInput = {
|
|
366
|
+
...commandInput,
|
|
367
|
+
requestMetadata: sanitizeRequestMetadata(commandInput.requestMetadata)
|
|
319
368
|
};
|
|
320
|
-
options?.onPayload?.(commandInput, model);
|
|
321
369
|
const host = `bedrock-runtime.${region}.amazonaws.com`;
|
|
322
370
|
const url = `https://${host}/model/${encodeURIComponent(model.id)}/converse-stream`;
|
|
323
371
|
const urlPath = `/model/${encodeURIComponent(model.id)}/converse-stream`;
|
|
@@ -332,11 +380,12 @@ const streamBedrock = (model, context, options) => {
|
|
|
332
380
|
const bodyText = JSON.stringify(commandInput);
|
|
333
381
|
const body = new TextEncoder().encode(bodyText);
|
|
334
382
|
const callerHeaders = {};
|
|
335
|
-
for (const [name, value] of Object.entries(
|
|
383
|
+
for (const source of [model.headers, options?.headers]) for (const [name, value] of Object.entries(source ?? {})) {
|
|
336
384
|
const field = name.toLowerCase();
|
|
337
385
|
if (SIGNER_OWNED_HEADERS.has(field) || BEDROCK_RESERVED_HEADERS.has(field)) continue;
|
|
338
386
|
callerHeaders[field] = value;
|
|
339
387
|
}
|
|
388
|
+
callerHeaders["user-agent"] ??= USER_AGENT;
|
|
340
389
|
const baseHeaders = {
|
|
341
390
|
...callerHeaders,
|
|
342
391
|
"content-type": "application/json",
|
|
@@ -436,8 +485,20 @@ const streamBedrock = (model, context, options) => {
|
|
|
436
485
|
break;
|
|
437
486
|
case "messageStop": {
|
|
438
487
|
const ev = payload;
|
|
488
|
+
const responseFields = isRecord(ev.additionalModelResponseFields) ? ev.additionalModelResponseFields : void 0;
|
|
489
|
+
const transformations = parseAnthropicInputTransformations(responseFields?.input_transformations);
|
|
490
|
+
if (transformations.length > 0) {
|
|
491
|
+
output.inputTransformations = transformations;
|
|
492
|
+
for (const transformation of transformations) {
|
|
493
|
+
if (transformation.reason !== "prefix_binding_mismatch") continue;
|
|
494
|
+
warn("bedrock: dropped thinking block after conversation prefix changed", {
|
|
495
|
+
model: model.id,
|
|
496
|
+
path: transformation.path
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
}
|
|
439
500
|
output.stopReason = sentinelInjected && ev.stopReason === "tool_use" ? "stop" : mapStopReason(ev.stopReason);
|
|
440
|
-
if (output.stopReason === "error") output.errorMessage = `Generation failed with stop reason: ${ev.stopReason ?? "unknown"}`;
|
|
501
|
+
if (output.stopReason === "error") output.errorMessage = ev.stopReason === "guardrail_intervened" ? `Response blocked by Amazon Bedrock guardrail (stop reason: ${ev.stopReason}).` : ev.stopReason === "content_filtered" ? `Response filtered by Amazon Bedrock content filters (stop reason: ${ev.stopReason}).` : `Generation failed with stop reason: ${ev.stopReason ?? "unknown"}`;
|
|
441
502
|
break;
|
|
442
503
|
}
|
|
443
504
|
case "metadata": handleMetadata(payload, model, output);
|
|
@@ -605,7 +666,7 @@ function handleMetadata(event, model, output) {
|
|
|
605
666
|
output.usage.cacheRead = event.usage.cacheReadInputTokens || 0;
|
|
606
667
|
output.usage.cacheWrite = event.usage.cacheWriteInputTokens || 0;
|
|
607
668
|
output.usage.totalTokens = event.usage.totalTokens || output.usage.input + output.usage.output;
|
|
608
|
-
calculateCost(model, output.usage);
|
|
669
|
+
calculateCost(model, output.usage, output.timestamp);
|
|
609
670
|
}
|
|
610
671
|
}
|
|
611
672
|
function handleContentBlockStop(event, blocks, output, stream) {
|
|
@@ -671,16 +732,6 @@ function takeCachePoint(policy) {
|
|
|
671
732
|
...policy.ttl ? { ttl: policy.ttl } : {}
|
|
672
733
|
} };
|
|
673
734
|
}
|
|
674
|
-
/**
|
|
675
|
-
* Check if the model supports thinking signatures in reasoningContent.
|
|
676
|
-
* Only Anthropic Claude models support the signature field.
|
|
677
|
-
* Other models (Nova, Titan, Mistral, Llama, etc.) reject it with:
|
|
678
|
-
* "This model doesn't support the reasoningContent.reasoningText.signature field"
|
|
679
|
-
*/
|
|
680
|
-
function supportsThinkingSignature(model) {
|
|
681
|
-
const id = model.id.toLowerCase();
|
|
682
|
-
return id.includes("anthropic.claude") || id.includes("anthropic/claude");
|
|
683
|
-
}
|
|
684
735
|
function buildSystemPrompt(systemPrompt, promptCachePolicy) {
|
|
685
736
|
const prompts = normalizeSystemPrompts(systemPrompt);
|
|
686
737
|
if (prompts.length === 0) return void 0;
|
|
@@ -740,12 +791,11 @@ function convertMessages(context, model, promptCachePolicy) {
|
|
|
740
791
|
} });
|
|
741
792
|
break;
|
|
742
793
|
case "thinking":
|
|
743
|
-
if (c.thinking.trim().length === 0) continue;
|
|
794
|
+
if (c.thinking.trim().length === 0 && !c.thinkingSignature) continue;
|
|
744
795
|
if (c.thinkingSignature) contentBlocks.push({ reasoningContent: { reasoningText: {
|
|
745
796
|
text: c.thinking.toWellFormed(),
|
|
746
797
|
signature: c.thinkingSignature
|
|
747
798
|
} } });
|
|
748
|
-
else if (!supportsThinkingSignature(model)) contentBlocks.push({ reasoningContent: { reasoningText: { text: c.thinking.toWellFormed() } } });
|
|
749
799
|
else contentBlocks.push({ text: renderDemotedThinking(model.id, c.thinking) });
|
|
750
800
|
break;
|
|
751
801
|
default: throw new ValidationError("Unknown assistant content type");
|
|
@@ -858,10 +908,35 @@ function mapStopReason(reason) {
|
|
|
858
908
|
default: return "error";
|
|
859
909
|
}
|
|
860
910
|
}
|
|
911
|
+
/**
|
|
912
|
+
* Build the Converse `guardrailConfig` block when a guardrail identifier is set.
|
|
913
|
+
* The version defaults to `"DRAFT"` (Bedrock's editable working draft) and the
|
|
914
|
+
* trace is passed through untouched — leaving it undefined keeps Bedrock's own
|
|
915
|
+
* default rather than forcing a value.
|
|
916
|
+
*/
|
|
917
|
+
function buildGuardrailConfig(options) {
|
|
918
|
+
if (!options.guardrailIdentifier) return void 0;
|
|
919
|
+
return {
|
|
920
|
+
guardrailIdentifier: options.guardrailIdentifier,
|
|
921
|
+
guardrailVersion: options.guardrailVersion ?? "DRAFT",
|
|
922
|
+
...options.guardrailTrace === void 0 ? {} : { trace: options.guardrailTrace }
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
function applyBedrockThinkingBinding(fields, behavior) {
|
|
926
|
+
const result = { ...fields };
|
|
927
|
+
const thinking = isRecord(result.thinking) ? { ...result.thinking } : { type: "adaptive" };
|
|
928
|
+
thinking.block_binding = { prefix_mismatch_behavior: behavior };
|
|
929
|
+
result.thinking = thinking;
|
|
930
|
+
const betas = Array.isArray(result.anthropic_beta) ? result.anthropic_beta.filter((beta) => typeof beta === "string") : [];
|
|
931
|
+
if (!betas.includes("thinking-binding-controls-2026-08-01")) betas.push(THINKING_BINDING_CONTROLS_BETA);
|
|
932
|
+
result.anthropic_beta = betas;
|
|
933
|
+
return result;
|
|
934
|
+
}
|
|
861
935
|
function buildAdditionalModelRequestFields(model, options) {
|
|
862
936
|
const reasoning = options.reasoning;
|
|
863
937
|
if (!reasoning || !model.reasoning) return void 0;
|
|
864
|
-
|
|
938
|
+
const mode = model.thinking?.mode;
|
|
939
|
+
if (mode === "anthropic-adaptive") {
|
|
865
940
|
const effort = mapEffortToAnthropicAdaptiveEffort(model, reasoning);
|
|
866
941
|
const adaptive = { type: "adaptive" };
|
|
867
942
|
if (model.thinking?.supportsDisplay) adaptive.display = options.thinkingDisplay ?? "summarized";
|
|
@@ -870,6 +945,10 @@ function buildAdditionalModelRequestFields(model, options) {
|
|
|
870
945
|
output_config: { effort }
|
|
871
946
|
};
|
|
872
947
|
}
|
|
948
|
+
if (mode === "effort") {
|
|
949
|
+
const level = requireSupportedEffort(model, reasoning);
|
|
950
|
+
return { reasoning: { effort: model.thinking?.effortMap?.[level] ?? level } };
|
|
951
|
+
}
|
|
873
952
|
const level = requireSupportedEffort(model, reasoning);
|
|
874
953
|
const result = { thinking: {
|
|
875
954
|
type: "enabled",
|