@xiaoso/dsh-tool-plus 0.1.5 → 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.
Files changed (120) hide show
  1. package/README.md +1 -1
  2. package/THIRD_PARTY_NOTICES.md +9 -3
  3. package/lib/{abort-Cwwm4Err.mjs → abort-Caqff3M6.mjs} +2 -2
  4. package/lib/alibaba-coding-plan-DTupMiAi.mjs +73 -0
  5. package/lib/alibaba-token-plan-CHGyWOfX.mjs +46 -0
  6. package/lib/alibaba-token-plan-Dj3OZhEE.mjs +82 -0
  7. package/lib/{amazon-bedrock-TVMpUTRG.mjs → amazon-bedrock-DbFSYXfJ.mjs} +117 -38
  8. package/lib/{anthropic-BL6LFDQS.mjs → anthropic-CTJ3IQVa.mjs} +675 -166
  9. package/lib/anthropic-CXfWlp-x.mjs +105 -0
  10. package/lib/{aws-credentials-B20dliS7.mjs → anthropic-wire-CKuhDwZ1.mjs} +74 -14
  11. package/lib/{api-key-login-CIDnXeYd.mjs → api-key-validation-CGCJFbFr.mjs} +27 -68
  12. package/lib/{azure-openai-responses-BkhsLmN3.mjs → azure-openai-responses-ChFbWaGj.mjs} +27 -16
  13. package/lib/{browser-render-CmgvSNte.mjs → browser-render-9o0Rknop.mjs} +4 -4
  14. package/lib/bun-shim.mjs +71 -2
  15. package/lib/{bundled-references-ChZSPDFw.mjs → bundled-references-DY3EJxZV.mjs} +6 -5
  16. package/lib/cline-pass-Bwg3esu9.mjs +44 -0
  17. package/lib/cloudflare-ai-gateway-BupNXyKK.mjs +35 -0
  18. package/lib/cloudflare-ai-gateway-EWo0VkP5.mjs +44 -0
  19. package/lib/collapse-DOR8sOGf.mjs +2304 -0
  20. package/lib/coreweave-C82HrLpb.mjs +31 -0
  21. package/lib/coreweave-Ct8cF-da.mjs +14 -0
  22. package/lib/{cursor-B6HcmplF.mjs → cursor-B95LzVWV.mjs} +11 -3
  23. package/lib/{cursor-CRpLpaZ3.mjs → cursor-DJV_dcgB.mjs} +887 -1784
  24. package/lib/{cursor-B8m6SqAH.mjs → cursor-LKGjucn2.mjs} +48 -38
  25. package/lib/cursor-proto-B8Wj8bv9.mjs +10513 -0
  26. package/lib/{deterministic-id-D-yIV_eI.mjs → deterministic-id-CUEIMSqR.mjs} +1 -1
  27. package/lib/devin-BMTdx_hx.mjs +316 -0
  28. package/lib/{devin-DUAfvBsW.mjs → devin-DSp0Rw_E.mjs} +172 -86
  29. package/lib/devin-ExGIghmx.mjs +69 -0
  30. package/lib/devin-proto-Br8fdyNl.mjs +2888 -0
  31. package/lib/{dom-CawWi8fa.mjs → dom-DG3sPESc.mjs} +8 -8
  32. package/lib/effort-BdtQMN-_.mjs +23 -0
  33. package/lib/{error-C-f_Wnw4.mjs → error-CORgGg5a.mjs} +275 -154
  34. package/lib/{event-stream-Dh2guZxS.mjs → event-stream-ulcDenZD.mjs} +20 -4
  35. package/lib/{gemini-headers-DKUShltF.mjs → gemini-headers-Co9cVvex.mjs} +2 -2
  36. package/lib/{github-copilot-suDymKrx.mjs → github-copilot-Dstq1D3s.mjs} +69 -29
  37. package/lib/github-copilot-headers-DOh1gt_w.mjs +312 -0
  38. package/lib/gitlab-duo-DSCMrU0m.mjs +11 -0
  39. package/lib/google-CtsKkOQK.mjs +38 -0
  40. package/lib/google-antigravity-z-5KsEci.mjs +252 -0
  41. package/lib/{google-auth-DYJLM792.mjs → google-auth-ieLBaneO.mjs} +4 -4
  42. package/lib/{google-gemini-cli-8BT513Ul.mjs → google-gemini-cli-C6NE5mWz.mjs} +28 -54
  43. package/lib/{google-gemini-cli-D6cSmfvB.mjs → google-gemini-cli-CAIPSl7e.mjs} +23 -29
  44. package/lib/google-oauth-shared-DhMllAkt.mjs +53 -0
  45. package/lib/{google-shared-CVbHK5vZ.mjs → google-shared-B0aNCYEH.mjs} +140 -44
  46. package/lib/{google-validation-Cgbn3tWJ.mjs → google-validation-BEkNs-Bx.mjs} +1 -1
  47. package/lib/{google-vertex-Bui-ypAe.mjs → google-vertex-Bbd1tYNc.mjs} +8 -8
  48. package/lib/hosts-00rjRzUD.mjs +203 -0
  49. package/lib/id-AL5obQzR.mjs +71 -0
  50. package/lib/{idle-iterator-CYAxUkSD.mjs → idle-iterator-DlUkEfzW.mjs} +3 -3
  51. package/lib/index.mjs +587 -5266
  52. package/lib/kilo-ChJL54wq.mjs +81 -0
  53. package/lib/kimi-C2c_Zq8A.mjs +67 -0
  54. package/lib/{launch-BmgEUycu.mjs → launch-DKDH71En.mjs} +1 -1
  55. package/lib/markit-CmRfm4E2.mjs +9885 -0
  56. package/lib/models-DnXMYGcJ.mjs +381604 -0
  57. package/lib/muse-code-Di1VZmB1.mjs +143 -0
  58. package/lib/{ollama-Df9ce-Cp.mjs → ollama-B8ic3sEp.mjs} +15 -30
  59. package/lib/{openai-codex-CAVI3Me-.mjs → openai-codex-DuJNC99x.mjs} +29 -99
  60. package/lib/{openai-codex-responses-BcnOotRB.mjs → openai-codex-responses-BL29nh9K.mjs} +204 -116
  61. package/lib/{openai-completions-Bq4WT47M.mjs → openai-completions-BK2f2dBv.mjs} +152 -82
  62. package/lib/openai-configuration-update-xMYUjaK_.mjs +150 -0
  63. package/lib/{openai-reasoning-fallback-DXsfiSXO.mjs → openai-reasoning-fallback-BdB3RCbj.mjs} +106 -12
  64. package/lib/{openai-responses-Mq_-PjvE.mjs → openai-responses-CGQPlIIy.mjs} +76 -82
  65. package/lib/{perplexity-XgLF73E7.mjs → perplexity-TBjz3VMB.mjs} +52 -9
  66. package/lib/{pkce-BlQikGPu.mjs → pkce-BYjmugmw.mjs} +1 -1
  67. package/lib/protobuf-aab1UGVn.mjs +717 -0
  68. package/lib/{provider-response-C6vcbQyO.mjs → provider-response-SqKSkkUc.mjs} +1 -1
  69. package/lib/{proxy-D9lm7ONA.mjs → proxy-5nWqRL1f.mjs} +45 -5
  70. package/lib/{readability-Cpm-ocau.mjs → readability-uGhqb4GC.mjs} +2 -2
  71. package/lib/reference-CtvM4zLU.mjs +114 -0
  72. package/lib/{request-debug-HJMoJncL.mjs → request-debug-NQN0BjHH.mjs} +1 -1
  73. package/lib/{sanitize-text-CfcXzw5X.mjs → sanitize-text-BCf5KmCf.mjs} +1 -1
  74. package/lib/{scrapers-CE_qK1yk.mjs → scrapers-D8oWspgW.mjs} +12 -12
  75. package/lib/{src-BcD0_rQR.mjs → src-BwW51vA5.mjs} +979 -388
  76. package/lib/{sse-debug-CYdjOC96.mjs → sse-debug-B-tkLCPW.mjs} +1 -1
  77. package/lib/{stream-Bjq8wjfr.mjs → stream-B_7qN-bA.mjs} +3802 -2623
  78. package/lib/stream-markup-healing-DKT1lnkW.mjs +267 -0
  79. package/lib/{strict-tool-validation-imVLUcbI.mjs → strict-tool-validation-CBTz1dAA.mjs} +2 -2
  80. package/lib/taxonomy-DSIM99rS.mjs +15392 -0
  81. package/lib/{stream-markup-healing-DZ6bVDxH.mjs → thinking-CiLa2LFB.mjs} +31 -186
  82. package/lib/{turndown-DN7ByzEI.mjs → turndown-DrX1M4WG.mjs} +4 -4
  83. package/lib/{type-guards-B9VVjRDK.mjs → type-guards-CttAANEx.mjs} +1 -1
  84. package/lib/{types-DX_bvuus.mjs → types-PVueGi9S.mjs} +2 -2
  85. package/lib/{utils-APrc-TBB.mjs → utils-CCfhUQen.mjs} +2364 -2676
  86. package/lib/{utils-Cp2Mxf_U.mjs → utils-CUPhpw9A.mjs} +413 -134
  87. package/lib/{utils-CQHPEQ3W.mjs → utils-DeWqNWV8.mjs} +2 -2
  88. package/lib/{vision-guard-mBmtAHx0.mjs → vision-guard-_XwsL1DF.mjs} +14 -29
  89. package/lib/xai-oauth-CXhnz0gO.mjs +210 -0
  90. package/lib/{xiaomi-7mE345KX.mjs → xiaomi-psoUItal.mjs} +8 -37
  91. package/lib/{zai-CeNpMV3W.mjs → zai-ApJ8HBgT.mjs} +8 -71
  92. package/lib/{zip-BK7UHCwX.mjs → zip-Kd602XNe.mjs} +1 -1
  93. package/package.json +43 -41
  94. package/presets/package.json +1 -1
  95. package/presets/tool-plus-ptc/agent.cordis.yml +13 -4
  96. package/presets/tool-plus-standard/agent.cordis.yml +11 -3
  97. package/lib/agent_pb-Rizyt9Zg.mjs +0 -805
  98. package/lib/anthropic-CDmj476p.mjs +0 -262
  99. package/lib/api_server_pb-CDZgLMta.mjs +0 -252
  100. package/lib/callback-server-CFJK-jvK.mjs +0 -398
  101. package/lib/codex-P1dGpX7G.mjs +0 -54
  102. package/lib/device-code-CuXTWYwY.mjs +0 -51
  103. package/lib/devin-BcQwht1W.mjs +0 -114
  104. package/lib/devin-BvMfGevz.mjs +0 -95
  105. package/lib/github-copilot-B3kQl0g0.mjs +0 -104
  106. package/lib/gitlab-duo-BriUTP8k.mjs +0 -155
  107. package/lib/gitlab-duo-workflow-wK5Ljzmc.mjs +0 -91
  108. package/lib/google-CE5tFDod.mjs +0 -30
  109. package/lib/google-antigravity-C1jgNljz.mjs +0 -198
  110. package/lib/google-oauth-shared-BLVTvokk.mjs +0 -147
  111. package/lib/grammar-D-NqNUxQ.mjs +0 -49
  112. package/lib/identity-HNO1Oe9B.mjs +0 -219
  113. package/lib/kimi-DgcUpPtK.mjs +0 -236
  114. package/lib/markit-DtGoRE6M.mjs +0 -1417
  115. package/lib/minimax-code-Y3h5li9N.mjs +0 -53
  116. package/lib/models-DRA2c_8U.mjs +0 -104660
  117. package/lib/opencode-BsVw9rCD.mjs +0 -38
  118. package/lib/to-binary-B1BEBIPC.mjs +0 -6002
  119. package/lib/wafer-BlhWLweO.mjs +0 -17
  120. package/lib/xai-oauth-5pORHUrg.mjs +0 -446
@@ -1,16 +1,117 @@
1
1
  import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
2
  __installBunShim();
3
- import { o as readSseJson } from "./src-BcD0_rQR.mjs";
4
- import { R as GoogleApiError, l as finalize, r as ValidationError, s as ProviderResponseError, t as ConfigurationError, v as AbortError } from "./error-C-f_Wnw4.mjs";
5
- import { M as normalizeSchemaForCCA, N as normalizeSchemaForGoogle, a as normalizeSystemPrompts, k as toolWireSchema, m as transformMessages, w as renderDemotedThinking } from "./utils-Cp2Mxf_U.mjs";
6
- import { t as calculateCost } from "./models-DRA2c_8U.mjs";
7
- import { o as shouldSendServiceTier, t as NON_VISION_IMAGE_PLACEHOLDER } from "./vision-guard-mBmtAHx0.mjs";
8
- import { t as AssistantMessageEventStream } from "./event-stream-Dh2guZxS.mjs";
3
+ import { o as readSseJson } from "./src-BwW51vA5.mjs";
4
+ import { R as GoogleApiError, _ as AbortError, c as finalize, r as ValidationError, s as ProviderResponseError, t as ConfigurationError } from "./error-CORgGg5a.mjs";
5
+ import { A as toolWireSchema, N as normalizeSchemaForCCA, P as normalizeSchemaForGoogle, T as renderDemotedThinking, h as transformMessages, o as normalizeSystemPrompts } from "./utils-CUPhpw9A.mjs";
6
+ import { t as calculateCost } from "./models-DnXMYGcJ.mjs";
7
+ import { o as shouldSendServiceTier, t as NON_VISION_IMAGE_PLACEHOLDER } from "./vision-guard-_XwsL1DF.mjs";
8
+ import { t as AssistantMessageEventStream } from "./event-stream-ulcDenZD.mjs";
9
9
  import { scheduler } from "node:timers/promises";
10
- //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/providers/google-shared.ts
10
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/dialect/thinking-fence-strip.ts
11
+ /**
12
+ * Strip self-referential reasoning-fence delimiters that a provider leaks
13
+ * *inside* a structured thinking part.
14
+ *
15
+ * The visible-channel healers ({@link ../utils/leaked-thinking-stream},
16
+ * {@link ./fenced-thinking}) split leaked ` ```thinking ` fences out of the
17
+ * *text* stream. They never run over parts a provider already flags as
18
+ * thinking, so when a model (observed on Gemini thought summaries — issue
19
+ * #8719) emits a bare ` ```thinking ` / ` ``````thinking ` opener line between
20
+ * summaries, that delimiter reaches display and persistence verbatim as fence
21
+ * spam inside the reasoning block.
22
+ *
23
+ * This stripper removes only a *standalone* reasoning-fence opener line — a line
24
+ * that is nothing but a run of ≥3 backticks immediately followed by the info
25
+ * string `thinking` or `reasoning`. Such a line is always redundant inside an
26
+ * already-structured thinking block and never carries content. Inline mentions
27
+ * (prose on the same line), language-tagged code fences (` ```rs `), and bare
28
+ * closers (` ``` `) are left untouched so legitimate fenced code inside the
29
+ * reasoning survives.
30
+ *
31
+ * Streaming-safe: deltas may split a line anywhere. A trailing partial line is
32
+ * held only while it remains a viable opener prefix; the moment it cannot be an
33
+ * opener it is flushed and the rest of the line passes through character-level.
34
+ * Correctness never depends on the prefix heuristic — every held line is
35
+ * classified strictly on its newline (or on {@link ThinkingFenceStripper.flush})
36
+ * before it is dropped.
37
+ */
38
+ /**
39
+ * A complete standalone reasoning-fence opener: ≤3 lead spaces, ≥3 backticks,
40
+ * `thinking`/`reasoning`, optional trailing spaces, tolerating a trailing CR
41
+ * from a CRLF newline.
42
+ */
43
+ const OPENER_LINE = /^ {0,3}`{3,}(?:thinking|reasoning)[ \t]*\r?$/i;
44
+ /** Could `line` (a partial, newline-not-yet-seen) still grow into {@link OPENER_LINE}? */
45
+ function couldBeOpenerPrefix(line) {
46
+ const s = line.endsWith("\r") ? line.slice(0, -1) : line;
47
+ const m = /^ {0,3}(`*)([\s\S]*)$/.exec(s);
48
+ if (!m) return false;
49
+ const ticks = m[1].length;
50
+ const rest = m[2];
51
+ if (rest === "") return true;
52
+ if (ticks < 3) return false;
53
+ const word = rest.replace(/[ \t]+$/, "").toLowerCase();
54
+ return "thinking".startsWith(word) || "reasoning".startsWith(word);
55
+ }
56
+ /**
57
+ * Stateful, line-oriented stripper for leaked reasoning-fence openers in one
58
+ * structured thinking block. One instance per thinking block; feed every
59
+ * thinking delta through {@link push} and drain the tail with {@link flush}.
60
+ */
61
+ var ThinkingFenceStripper = class {
62
+ /** Buffered content of the current line still being classified. */
63
+ #carry = "";
64
+ /** True once the current line is known not to be an opener; passes through until newline. */
65
+ #passthrough = false;
66
+ /** Consume one thinking delta; returns the sanitized text to emit (may be empty). */
67
+ push(chunk) {
68
+ let out = "";
69
+ for (const ch of chunk) {
70
+ if (this.#passthrough) {
71
+ out += ch;
72
+ if (ch === "\n") this.#passthrough = false;
73
+ continue;
74
+ }
75
+ if (ch === "\n") {
76
+ if (!OPENER_LINE.test(this.#carry)) out += `${this.#carry}\n`;
77
+ this.#carry = "";
78
+ continue;
79
+ }
80
+ this.#carry += ch;
81
+ if (!couldBeOpenerPrefix(this.#carry)) {
82
+ out += this.#carry;
83
+ this.#carry = "";
84
+ this.#passthrough = true;
85
+ }
86
+ }
87
+ return out;
88
+ }
89
+ /** Drain any held partial line at block end; returns text to emit (may be empty). */
90
+ flush() {
91
+ const carry = this.#carry;
92
+ this.#carry = "";
93
+ this.#passthrough = false;
94
+ return OPENER_LINE.test(carry) ? "" : carry;
95
+ }
96
+ };
97
+ //#endregion
98
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/providers/google-shared.ts
11
99
  /**
12
100
  * Shared utilities for Google Generative AI and Google Cloud Code Assist providers.
13
101
  */
102
+ function convertGoogleImagePart(image) {
103
+ if (image.providerFile?.provider === "google" && image.providerFile.uri) return { fileData: {
104
+ fileUri: image.providerFile.uri,
105
+ mimeType: image.mimeType
106
+ } };
107
+ return image.url ? { fileData: {
108
+ fileUri: image.url,
109
+ mimeType: image.mimeType
110
+ } } : { inlineData: {
111
+ mimeType: image.mimeType,
112
+ data: image.data
113
+ } };
114
+ }
14
115
  /**
15
116
  * Determines whether a streamed Gemini `Part` should be treated as "thinking".
16
117
  *
@@ -55,23 +156,6 @@ function isValidThoughtSignature(signature) {
55
156
  function resolveThoughtSignature(isSameProviderAndModel, signature) {
56
157
  return isSameProviderAndModel && isValidThoughtSignature(signature) ? signature : void 0;
57
158
  }
58
- function supportsFunctionPartId(model) {
59
- if (model.api === "google-vertex") return false;
60
- return model.id.startsWith("claude-") || model.api === "google-generative-ai" && isGemini3Model(model.id);
61
- }
62
- function getGeminiMajorVersion(modelId) {
63
- const match = modelId.toLowerCase().match(/^gemini(?:-live)?-(\d+)/);
64
- if (!match) return void 0;
65
- return Number.parseInt(match[1], 10);
66
- }
67
- function supportsMultimodalFunctionResponse(modelId) {
68
- const geminiMajorVersion = getGeminiMajorVersion(modelId);
69
- if (geminiMajorVersion !== void 0) return geminiMajorVersion >= 3;
70
- return true;
71
- }
72
- function isGemini3Model(modelId) {
73
- return modelId.includes("gemini-3");
74
- }
75
159
  /**
76
160
  * Convert internal messages to Gemini Content[] format.
77
161
  */
@@ -108,10 +192,7 @@ function convertMessages(model, context) {
108
192
  const text = item.text.toWellFormed();
109
193
  if (text.trim().length === 0) continue;
110
194
  parts.push({ text });
111
- } else if (supportsImages) parts.push({ inlineData: {
112
- mimeType: item.mimeType,
113
- data: item.data
114
- } });
195
+ } else if (supportsImages) parts.push(convertGoogleImagePart(item));
115
196
  else omittedImages = true;
116
197
  if (omittedImages) parts.push({ text: NON_VISION_IMAGE_PLACEHOLDER });
117
198
  if (parts.length === 0) continue;
@@ -123,7 +204,8 @@ function convertMessages(model, context) {
123
204
  } else if (msg.role === "assistant") {
124
205
  const parts = [];
125
206
  const isSameProviderAndModel = msg.provider === model.provider && msg.model === model.id;
126
- const dropsUnsignedThinking = model.provider === "google-antigravity" && model.id.toLowerCase().includes("claude");
207
+ const dropsUnsignedThinking = model.compat.dropUnsignedThinking;
208
+ let isFirstToolCall = true;
127
209
  for (const block of msg.content) if (block.type === "text") {
128
210
  if (!block.text || block.text.trim() === "") continue;
129
211
  const thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.textSignature);
@@ -143,13 +225,15 @@ function convertMessages(model, context) {
143
225
  else parts.push({ text: renderDemotedThinking(model.id, block.thinking) });
144
226
  } else if (block.type === "toolCall") {
145
227
  emittedToolCallNames.set(block.id, block.name);
146
- const effectiveSignature = resolveThoughtSignature(isSameProviderAndModel, block.thoughtSignature) || (isGemini3Model(model.id) ? SKIP_THOUGHT_SIGNATURE : void 0);
228
+ const thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thoughtSignature);
229
+ const requiresFallback = model.compat.requiresSkipThoughtSignature || isFirstToolCall && model.compat.requiresSkipThoughtSignatureOnFirstFunctionCall;
230
+ const effectiveSignature = thoughtSignature || (requiresFallback ? SKIP_THOUGHT_SIGNATURE : void 0);
231
+ isFirstToolCall = false;
147
232
  const part = { functionCall: {
148
233
  name: block.name,
149
234
  args: block.arguments ?? {},
150
- ...supportsFunctionPartId(model) ? { id: block.id } : {}
235
+ ...model.compat.supportsFunctionPartId ? { id: block.id } : {}
151
236
  } };
152
- if (model.provider === "google-vertex" && part?.functionCall?.id) delete part.functionCall.id;
153
237
  if (effectiveSignature) part.thoughtSignature = effectiveSignature;
154
238
  parts.push(part);
155
239
  }
@@ -165,20 +249,16 @@ function convertMessages(model, context) {
165
249
  const omittedImages = !supportsImages && msg.content.some((c) => c.type === "image");
166
250
  const hasText = textResult.length > 0;
167
251
  const hasImages = imageContent.length > 0;
168
- const modelSupportsMultimodalFunctionResponse = supportsMultimodalFunctionResponse(model.id);
252
+ const modelSupportsMultimodalFunctionResponse = model.compat.multimodalFunctionResponse;
169
253
  const responseValue = omittedImages ? [hasText ? textResult.toWellFormed() : "", NON_VISION_IMAGE_PLACEHOLDER].filter(Boolean).join("\n") : hasText ? textResult.toWellFormed() : hasImages ? "(see attached image)" : "";
170
- const imageParts = imageContent.map((imageBlock) => ({ inlineData: {
171
- mimeType: imageBlock.mimeType,
172
- data: imageBlock.data
173
- } }));
174
- const includeId = supportsFunctionPartId(model);
254
+ const imageParts = imageContent.map(convertGoogleImagePart);
255
+ const includeId = model.compat.supportsFunctionPartId;
175
256
  const functionResponsePart = { functionResponse: {
176
257
  name: emittedToolCallNames.get(msg.toolCallId) ?? msg.toolName,
177
258
  response: msg.isError ? { error: responseValue } : { output: responseValue },
178
259
  ...hasImages && modelSupportsMultimodalFunctionResponse && { parts: imageParts },
179
260
  ...includeId ? { id: msg.toolCallId } : {}
180
261
  } };
181
- if (model.provider === "google-vertex" && functionResponsePart.functionResponse?.id) delete functionResponsePart.functionResponse.id;
182
262
  const lastContent = contents[contents.length - 1];
183
263
  if (lastContent?.role === "user" && lastContent.parts?.some((p) => p.functionResponse)) lastContent.parts.push(functionResponsePart);
184
264
  else contents.push({
@@ -206,7 +286,7 @@ function convertTools(tools, model) {
206
286
  * Claude models on Cloud Code Assist need the legacy `parameters` field;
207
287
  * the API translates it into Anthropic's `input_schema`.
208
288
  */
209
- const useParameters = model.id.startsWith("claude-");
289
+ const useParameters = model.compat.ccaLegacyParametersSchema;
210
290
  return [{ functionDeclarations: tools.map((tool) => ({
211
291
  name: tool.name,
212
292
  description: tool.description || "",
@@ -391,10 +471,24 @@ async function consumeGoogleStream(args) {
391
471
  const blocks = output.content;
392
472
  const blockIndex = () => blocks.length - 1;
393
473
  let currentBlock = null;
474
+ let thinkingStripper = null;
394
475
  let firstTokenSeen = false;
395
476
  let sawFinishReason = false;
396
477
  const flushCurrent = () => {
397
478
  if (!currentBlock) return;
479
+ if (currentBlock.type === "thinking" && thinkingStripper) {
480
+ const tail = thinkingStripper.flush();
481
+ if (tail) {
482
+ currentBlock.thinking += tail;
483
+ stream.push({
484
+ type: "thinking_delta",
485
+ contentIndex: blockIndex(),
486
+ delta: tail,
487
+ partial: output
488
+ });
489
+ }
490
+ }
491
+ thinkingStripper = null;
398
492
  pushBlockEndEvent(currentBlock, blockIndex(), output, stream);
399
493
  };
400
494
  for await (const chunk of googleStream) {
@@ -425,12 +519,14 @@ async function consumeGoogleStream(args) {
425
519
  currentBlock = startTextOrThinkingBlock(isThinking, output, stream);
426
520
  }
427
521
  if (currentBlock.type === "thinking") {
428
- currentBlock.thinking += part.text;
522
+ thinkingStripper ??= new ThinkingFenceStripper();
523
+ const cleaned = thinkingStripper.push(part.text);
524
+ currentBlock.thinking += cleaned;
429
525
  currentBlock.thinkingSignature = retainThoughtSignature(currentBlock.thinkingSignature, part.thoughtSignature);
430
- stream.push({
526
+ if (cleaned) stream.push({
431
527
  type: "thinking_delta",
432
528
  contentIndex: blockIndex(),
433
- delta: part.text,
529
+ delta: cleaned,
434
530
  partial: output
435
531
  });
436
532
  } else {
@@ -491,7 +587,7 @@ async function consumeGoogleStream(args) {
491
587
  total: 0
492
588
  }
493
589
  };
494
- calculateCost(model, output.usage);
590
+ calculateCost(model, output.usage, output.timestamp);
495
591
  }
496
592
  }
497
593
  flushCurrent();
@@ -1,6 +1,6 @@
1
1
  import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
2
  __installBunShim();
3
- //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/utils/google-validation.ts
3
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/utils/google-validation.ts
4
4
  function extractGoogleValidationUrl(errorBody) {
5
5
  if (!errorBody.includes("VALIDATION_REQUIRED")) return void 0;
6
6
  const start = errorBody.indexOf("{");
@@ -1,11 +1,11 @@
1
1
  import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
2
  __installBunShim();
3
- import { P as $env } from "./src-BcD0_rQR.mjs";
4
- import { t as ConfigurationError } from "./error-C-f_Wnw4.mjs";
5
- import { P as resolveVertexEndpointHost } from "./models-DRA2c_8U.mjs";
6
- import { t as getVertexAccessToken } from "./google-auth-DYJLM792.mjs";
7
- import { p as streamGoogleGenAI, t as buildGoogleGenerateContentParams } from "./google-shared-CVbHK5vZ.mjs";
8
- //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/providers/google-vertex.ts
3
+ import { N as $env } from "./src-BwW51vA5.mjs";
4
+ import { t as ConfigurationError } from "./error-CORgGg5a.mjs";
5
+ import { i as resolveVertexEndpointHost } from "./hosts-00rjRzUD.mjs";
6
+ import { t as getVertexAccessToken } from "./google-auth-ieLBaneO.mjs";
7
+ import { p as streamGoogleGenAI, t as buildGoogleGenerateContentParams } from "./google-shared-B0aNCYEH.mjs";
8
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/providers/google-vertex.ts
9
9
  const API_VERSION = "v1";
10
10
  const streamGoogleVertex = (model, context, options) => {
11
11
  return streamGoogleGenAI({
@@ -36,8 +36,8 @@ const streamGoogleVertex = (model, context, options) => {
36
36
  }
37
37
  ];
38
38
  const baseHeaders = {
39
- ...model.headers ?? {},
40
- ...options?.headers ?? {}
39
+ ...model.headers,
40
+ ...options?.headers
41
41
  };
42
42
  if (options?.serviceTier === "priority") baseHeaders["X-Vertex-AI-LLM-Shared-Request-Type"] = "priority";
43
43
  if (apiKey) {
@@ -0,0 +1,203 @@
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/hosts.ts
4
+ const KNOWN_HOSTS = {
5
+ openai: {
6
+ providers: ["openai"],
7
+ urlMarkers: ["api.openai.com"]
8
+ },
9
+ azureOpenAI: {
10
+ providers: ["azure"],
11
+ urlMarkers: [
12
+ ".openai.azure.com",
13
+ "azure.com/openai",
14
+ "models.inference.ai.azure.com"
15
+ ]
16
+ },
17
+ openrouter: {
18
+ providers: ["openrouter"],
19
+ urlMarkers: ["openrouter.ai"]
20
+ },
21
+ vercelAIGateway: {
22
+ providers: ["vercel-ai-gateway"],
23
+ urlMarkers: ["ai-gateway.vercel.sh"]
24
+ },
25
+ githubCopilot: {
26
+ providers: ["github-copilot"],
27
+ urlMarkers: ["githubcopilot.com", "copilot-api."]
28
+ },
29
+ anthropic: {
30
+ providers: ["anthropic"],
31
+ urlMarkers: ["api.anthropic.com"]
32
+ },
33
+ /** DeepSeek's first-party API only — gates direct-API quirks (max_tokens field, thinking extraBody). */
34
+ deepseekDirect: {
35
+ providers: ["deepseek"],
36
+ urlMarkers: ["api.deepseek.com"]
37
+ },
38
+ /** Any DeepSeek-operated host (first-party API, web-chat fronts). Wider than `deepseekDirect` on purpose. */
39
+ deepseekFamily: {
40
+ providers: ["deepseek"],
41
+ urlMarkers: ["deepseek.com"]
42
+ },
43
+ cerebras: {
44
+ providers: ["cerebras"],
45
+ urlMarkers: ["cerebras.ai"]
46
+ },
47
+ zai: {
48
+ providers: ["zai"],
49
+ urlMarkers: ["api.z.ai"]
50
+ },
51
+ zhipu: {
52
+ providers: ["zhipu-coding-plan"],
53
+ urlMarkers: ["open.bigmodel.cn"]
54
+ },
55
+ kilo: {
56
+ providers: ["kilo"],
57
+ urlMarkers: ["api.kilo.ai"]
58
+ },
59
+ alibabaDashscope: {
60
+ providers: ["alibaba-coding-plan", "alibaba-token-plan"],
61
+ urlMarkers: ["dashscope", "token-plan."]
62
+ },
63
+ umans: {
64
+ providers: ["umans"],
65
+ urlMarkers: ["api.code.umans.ai"]
66
+ },
67
+ xiaomi: {
68
+ providers: ["xiaomi"],
69
+ providerPrefixes: ["xiaomi-token-plan-"],
70
+ urlMarkers: ["xiaomimimo.com"]
71
+ },
72
+ xai: {
73
+ providers: ["xai", "xai-oauth"],
74
+ urlMarkers: ["api.x.ai"]
75
+ },
76
+ mistral: {
77
+ providers: ["mistral"],
78
+ urlMarkers: ["mistral.ai"]
79
+ },
80
+ together: {
81
+ providers: ["together"],
82
+ urlMarkers: ["api.together.xyz"]
83
+ },
84
+ baseten: {
85
+ providers: ["baseten"],
86
+ urlMarkers: ["baseten.co"]
87
+ },
88
+ /** URL-only on purpose: the `fireworks`/`firepass` providers route per-model and not every model is Fireworks-shaped. */
89
+ fireworks: { urlMarkers: ["fireworks.ai"] },
90
+ groq: {
91
+ providers: ["groq"],
92
+ urlMarkers: ["api.groq.com"]
93
+ },
94
+ minimax: {
95
+ providers: [
96
+ "minimax",
97
+ "minimax-code",
98
+ "minimax-code-cn"
99
+ ],
100
+ urlMarkers: ["api.minimax.io", "api.minimaxi.com"]
101
+ },
102
+ qwenPortal: {
103
+ providers: ["qwen-portal"],
104
+ urlMarkers: ["portal.qwen.ai"]
105
+ },
106
+ /** NVIDIA NIM (`integrate.api.nvidia.com`). Qwen NIM endpoints take `chat_template_kwargs.enable_thinking`, never top-level `enable_thinking`. */
107
+ nvidia: {
108
+ providers: ["nvidia"],
109
+ urlMarkers: ["integrate.api.nvidia.com"]
110
+ },
111
+ /** Venice AI (`api.venice.ai`). OpenAI-compatible; drives reasoning via top-level `reasoning_effort` (and `venice_parameters.disable_thinking`), and rejects DashScope's top-level `enable_thinking` with a 400 (`additionalProperties: false` request schema). */
112
+ venice: {
113
+ providers: ["venice"],
114
+ urlMarkers: ["api.venice.ai"]
115
+ },
116
+ moonshotNative: {
117
+ providers: ["moonshot", "kimi-code"],
118
+ urlMarkers: ["api.moonshot.ai", "api.kimi.com"]
119
+ },
120
+ /** Google AI Studio's OpenAI-compatible shim (`/v1beta/openai`) — a subset of chat-completions; rejects `store` with a 400. Native Gemini uses `google-generative-ai` api instead. */
121
+ googleAistudio: {
122
+ providers: [],
123
+ urlMarkers: ["generativelanguage.googleapis.com"]
124
+ },
125
+ opencode: {
126
+ providers: ["opencode-go", "opencode-zen"],
127
+ urlMarkers: ["opencode.ai"]
128
+ },
129
+ /** ZenMux's Anthropic-compatible proxy (`zenmux.ai/api/anthropic`) forwards to signature-enforcing Anthropic. */
130
+ zenmux: {
131
+ providers: ["zenmux"],
132
+ urlMarkers: ["zenmux.ai"]
133
+ },
134
+ chutes: { urlMarkers: ["chutes.ai"] }
135
+ };
136
+ const MAX_URL_HOST_MATCHES = 512;
137
+ const urlHostMatches = /* @__PURE__ */ new Map();
138
+ function getUrlHostMatches(baseUrl) {
139
+ let matches = urlHostMatches.get(baseUrl);
140
+ if (matches !== void 0) return matches;
141
+ if (urlHostMatches.size === MAX_URL_HOST_MATCHES) urlHostMatches.clear();
142
+ matches = /* @__PURE__ */ new Map();
143
+ urlHostMatches.set(baseUrl, matches);
144
+ return matches;
145
+ }
146
+ /** URL-only host check (for call sites that have no provider id, e.g. raw env config). */
147
+ function hostMatchesUrl(baseUrl, host) {
148
+ if (!baseUrl) return false;
149
+ const matches = getUrlHostMatches(baseUrl);
150
+ const cached = matches.get(host);
151
+ if (cached !== void 0) return cached;
152
+ const spec = KNOWN_HOSTS[host];
153
+ for (const marker of spec.urlMarkers) if (includesAsciiCaseInsensitive(baseUrl, marker)) {
154
+ matches.set(host, true);
155
+ return true;
156
+ }
157
+ matches.set(host, false);
158
+ return false;
159
+ }
160
+ /** Provider-or-URL host check — the canonical `provider === id || baseUrl.includes(marker)` idiom. */
161
+ function modelMatchesHost(model, host) {
162
+ const spec = KNOWN_HOSTS[host];
163
+ if (spec.providers) {
164
+ for (const provider of spec.providers) if (model.provider === provider) return true;
165
+ }
166
+ if (spec.providerPrefixes) {
167
+ for (const prefix of spec.providerPrefixes) if (model.provider.startsWith(prefix)) return true;
168
+ }
169
+ return hostMatchesUrl(model.baseUrl, host);
170
+ }
171
+ function includesAsciiCaseInsensitive(value, lowerNeedle) {
172
+ const needleLength = lowerNeedle.length;
173
+ const end = value.length - needleLength;
174
+ for (let start = 0; start <= end; start++) {
175
+ let offset = 0;
176
+ for (; offset < needleLength; offset++) if ((value.charCodeAt(start + offset) | 32) !== lowerNeedle.charCodeAt(offset)) break;
177
+ if (offset === needleLength) return true;
178
+ }
179
+ return false;
180
+ }
181
+ /**
182
+ * Hostname for a Vertex AI GenerateContent / rawPredict / OpenAI-compat
183
+ * request for the given location.
184
+ *
185
+ * - `global` → global endpoint (`aiplatform.googleapis.com`)
186
+ * - `eu` / `us` multi-regions → REP endpoints (`aiplatform.{eu|us}.rep.googleapis.com`)
187
+ * - every other location → regional (`{location}-aiplatform.googleapis.com`)
188
+ *
189
+ * Multi-region codes do NOT follow the regional `{location}-aiplatform` pattern;
190
+ * interpolating them that way yields hosts like `eu-aiplatform.googleapis.com`
191
+ * that 404.
192
+ */
193
+ function resolveVertexEndpointHost(location) {
194
+ if (location === "global") return "aiplatform.googleapis.com";
195
+ if (location === "eu" || location === "us") return `aiplatform.${location}.rep.googleapis.com`;
196
+ return `${location}-aiplatform.googleapis.com`;
197
+ }
198
+ /** Vertex AI Anthropic raw-predict endpoints (`:streamRawPredict` / `:rawPredict`). */
199
+ function isVertexRawPredictUrl(baseUrl) {
200
+ return baseUrl.includes(":streamRawPredict") || baseUrl.includes(":rawPredict");
201
+ }
202
+ //#endregion
203
+ export { resolveVertexEndpointHost as i, isVertexRawPredictUrl as n, modelMatchesHost as r, hostMatchesUrl as t };
@@ -0,0 +1,71 @@
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/identity/id.ts
4
+ const LEADING_BRACKETED_AFFIX_PATTERN = /^(?:\s*(?:\[|【)[^\]】]+(?:\]|】)\s*)+/u;
5
+ const TRAILING_BRACKETED_AFFIX_PATTERN = /(?:\s*(?:\[|【)[^\]】]+(?:\]|】)\s*)+$/u;
6
+ /** Strip a provider namespace prefix (`openai/gpt-5.4` → `gpt-5.4`). */
7
+ const bareModelIdCache = /* @__PURE__ */ new Map();
8
+ function bareModelId(modelId) {
9
+ const cached = bareModelIdCache.get(modelId);
10
+ if (cached !== void 0) return cached;
11
+ const separator = modelId.lastIndexOf("/");
12
+ const result = separator === -1 ? modelId : modelId.slice(separator + 1);
13
+ bareModelIdCache.set(modelId, result);
14
+ return result;
15
+ }
16
+ const MODEL_ID_SEGMENT_PATTERN = /[a-z0-9.:-]+/g;
17
+ const MODEL_FAMILY_PREFIX_PATTERN = /^(claude|gemini|gpt|grok|glm|qwen|deepseek|kimi|mimo|doubao|ernie|gpt-oss|gemma|minimax|step|command|jamba|llama|o[1345])/i;
18
+ function normalizeModelIdWhitespace(value) {
19
+ return value.trim().replace(/\s+/g, " ");
20
+ }
21
+ /** Ordering for model-like segments: longest first, ties broken lexicographically. */
22
+ function compareSegmentPreference(left, right) {
23
+ return left.length !== right.length ? right.length - left.length : left.localeCompare(right);
24
+ }
25
+ function getModelLikeIdSegments(modelId) {
26
+ const matches = normalizeModelIdWhitespace(modelId).toLowerCase().match(MODEL_ID_SEGMENT_PATTERN);
27
+ if (!matches) return [];
28
+ const segments = /* @__PURE__ */ new Set();
29
+ for (const segment of matches) if (MODEL_FAMILY_PREFIX_PATTERN.test(segment) && /\d/.test(segment)) segments.add(segment);
30
+ return [...segments].sort(compareSegmentPreference);
31
+ }
32
+ function getLongestModelLikeIdSegment(modelId) {
33
+ const matches = normalizeModelIdWhitespace(modelId).toLowerCase().match(MODEL_ID_SEGMENT_PATTERN);
34
+ if (!matches) return void 0;
35
+ let best;
36
+ for (const segment of matches) if (MODEL_FAMILY_PREFIX_PATTERN.test(segment) && /\d/.test(segment) && (best === void 0 || compareSegmentPreference(segment, best) < 0)) best = segment;
37
+ return best;
38
+ }
39
+ function hasBracketAffixMarker(value) {
40
+ for (let index = 0; index < value.length; index++) {
41
+ const code = value.charCodeAt(index);
42
+ if (code === 91 || code === 93 || code === 12304 || code === 12305) return true;
43
+ }
44
+ return false;
45
+ }
46
+ /**
47
+ * Strip reseller / wrapper tags that are injected as bracketed affixes around an
48
+ * upstream model id, e.g.
49
+ * "[Kiro] claude-opus-4-8" -> "claude-opus-4-8"
50
+ * "[gcli转] gemini-3.1-pro-preview [假流]" -> "gemini-3.1-pro-preview"
51
+ *
52
+ * Candidates are returned most-stripped first: both ends, then leading-only, then trailing-only.
53
+ */
54
+ function getBracketStrippedModelIdCandidates(modelId) {
55
+ if (!hasBracketAffixMarker(modelId)) return [];
56
+ const normalized = normalizeModelIdWhitespace(modelId);
57
+ if (!normalized) return [];
58
+ const strippedLeading = normalized.replace(LEADING_BRACKETED_AFFIX_PATTERN, "");
59
+ const withoutLeading = normalizeModelIdWhitespace(strippedLeading);
60
+ const withoutTrailing = normalizeModelIdWhitespace(normalized.replace(TRAILING_BRACKETED_AFFIX_PATTERN, ""));
61
+ const withoutBoth = normalizeModelIdWhitespace(strippedLeading.replace(TRAILING_BRACKETED_AFFIX_PATTERN, ""));
62
+ const candidates = /* @__PURE__ */ new Set();
63
+ for (const candidate of [
64
+ withoutBoth,
65
+ withoutLeading,
66
+ withoutTrailing
67
+ ]) if (candidate && candidate !== normalized) candidates.add(candidate);
68
+ return [...candidates];
69
+ }
70
+ //#endregion
71
+ export { getModelLikeIdSegments as i, getBracketStrippedModelIdCandidates as n, getLongestModelLikeIdSegment as r, bareModelId as t };
@@ -1,8 +1,8 @@
1
1
  import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
2
  __installBunShim();
3
- import { P as $env } from "./src-BcD0_rQR.mjs";
4
- import { n as StreamTimeoutError, v as AbortError } from "./error-C-f_Wnw4.mjs";
5
- //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/utils/idle-iterator.ts
3
+ import { N as $env } from "./src-BwW51vA5.mjs";
4
+ import { _ as AbortError, n as StreamTimeoutError } from "./error-CORgGg5a.mjs";
5
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/utils/idle-iterator.ts
6
6
  const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 3e5;
7
7
  const DEFAULT_STREAM_FIRST_EVENT_TIMEOUT_MS = 3e5;
8
8
  /** Re-mint persistent race promises every N iterations (see hoisted-racer comment). */