@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.
Files changed (119) hide show
  1. package/THIRD_PARTY_NOTICES.md +9 -3
  2. package/lib/{abort-Cwwm4Err.mjs → abort-Caqff3M6.mjs} +2 -2
  3. package/lib/alibaba-coding-plan-DTupMiAi.mjs +73 -0
  4. package/lib/alibaba-token-plan-CHGyWOfX.mjs +46 -0
  5. package/lib/alibaba-token-plan-Dj3OZhEE.mjs +82 -0
  6. package/lib/{amazon-bedrock-TVMpUTRG.mjs → amazon-bedrock-DbFSYXfJ.mjs} +117 -38
  7. package/lib/{anthropic-BL6LFDQS.mjs → anthropic-CTJ3IQVa.mjs} +675 -166
  8. package/lib/anthropic-CXfWlp-x.mjs +105 -0
  9. package/lib/{aws-credentials-B20dliS7.mjs → anthropic-wire-CKuhDwZ1.mjs} +74 -14
  10. package/lib/{api-key-login-CIDnXeYd.mjs → api-key-validation-CGCJFbFr.mjs} +27 -68
  11. package/lib/{azure-openai-responses-BkhsLmN3.mjs → azure-openai-responses-ChFbWaGj.mjs} +27 -16
  12. package/lib/{browser-render-CmgvSNte.mjs → browser-render-9o0Rknop.mjs} +4 -4
  13. package/lib/bun-shim.mjs +71 -2
  14. package/lib/{bundled-references-ChZSPDFw.mjs → bundled-references-DY3EJxZV.mjs} +6 -5
  15. package/lib/cline-pass-Bwg3esu9.mjs +44 -0
  16. package/lib/cloudflare-ai-gateway-BupNXyKK.mjs +35 -0
  17. package/lib/cloudflare-ai-gateway-EWo0VkP5.mjs +44 -0
  18. package/lib/collapse-DOR8sOGf.mjs +2304 -0
  19. package/lib/coreweave-C82HrLpb.mjs +31 -0
  20. package/lib/coreweave-Ct8cF-da.mjs +14 -0
  21. package/lib/{cursor-B6HcmplF.mjs → cursor-B95LzVWV.mjs} +11 -3
  22. package/lib/{cursor-CRpLpaZ3.mjs → cursor-DJV_dcgB.mjs} +887 -1784
  23. package/lib/{cursor-B8m6SqAH.mjs → cursor-LKGjucn2.mjs} +48 -38
  24. package/lib/cursor-proto-B8Wj8bv9.mjs +10513 -0
  25. package/lib/{deterministic-id-D-yIV_eI.mjs → deterministic-id-CUEIMSqR.mjs} +1 -1
  26. package/lib/devin-BMTdx_hx.mjs +316 -0
  27. package/lib/{devin-DUAfvBsW.mjs → devin-DSp0Rw_E.mjs} +172 -86
  28. package/lib/devin-ExGIghmx.mjs +69 -0
  29. package/lib/devin-proto-Br8fdyNl.mjs +2888 -0
  30. package/lib/{dom-CawWi8fa.mjs → dom-DG3sPESc.mjs} +8 -8
  31. package/lib/effort-BdtQMN-_.mjs +23 -0
  32. package/lib/{error-C-f_Wnw4.mjs → error-CORgGg5a.mjs} +275 -154
  33. package/lib/{event-stream-Dh2guZxS.mjs → event-stream-ulcDenZD.mjs} +20 -4
  34. package/lib/{gemini-headers-DKUShltF.mjs → gemini-headers-Co9cVvex.mjs} +2 -2
  35. package/lib/{github-copilot-suDymKrx.mjs → github-copilot-Dstq1D3s.mjs} +69 -29
  36. package/lib/github-copilot-headers-DOh1gt_w.mjs +312 -0
  37. package/lib/gitlab-duo-DSCMrU0m.mjs +11 -0
  38. package/lib/google-CtsKkOQK.mjs +38 -0
  39. package/lib/google-antigravity-z-5KsEci.mjs +252 -0
  40. package/lib/{google-auth-DYJLM792.mjs → google-auth-ieLBaneO.mjs} +4 -4
  41. package/lib/{google-gemini-cli-8BT513Ul.mjs → google-gemini-cli-C6NE5mWz.mjs} +28 -54
  42. package/lib/{google-gemini-cli-D6cSmfvB.mjs → google-gemini-cli-CAIPSl7e.mjs} +23 -29
  43. package/lib/google-oauth-shared-DhMllAkt.mjs +53 -0
  44. package/lib/{google-shared-CVbHK5vZ.mjs → google-shared-B0aNCYEH.mjs} +140 -44
  45. package/lib/{google-validation-Cgbn3tWJ.mjs → google-validation-BEkNs-Bx.mjs} +1 -1
  46. package/lib/{google-vertex-Bui-ypAe.mjs → google-vertex-Bbd1tYNc.mjs} +8 -8
  47. package/lib/hosts-00rjRzUD.mjs +203 -0
  48. package/lib/id-AL5obQzR.mjs +71 -0
  49. package/lib/{idle-iterator-CYAxUkSD.mjs → idle-iterator-DlUkEfzW.mjs} +3 -3
  50. package/lib/index.mjs +587 -5266
  51. package/lib/kilo-ChJL54wq.mjs +81 -0
  52. package/lib/kimi-C2c_Zq8A.mjs +67 -0
  53. package/lib/{launch-BmgEUycu.mjs → launch-DKDH71En.mjs} +1 -1
  54. package/lib/markit-CmRfm4E2.mjs +9885 -0
  55. package/lib/models-DnXMYGcJ.mjs +381604 -0
  56. package/lib/muse-code-Di1VZmB1.mjs +143 -0
  57. package/lib/{ollama-Df9ce-Cp.mjs → ollama-B8ic3sEp.mjs} +15 -30
  58. package/lib/{openai-codex-CAVI3Me-.mjs → openai-codex-DuJNC99x.mjs} +29 -99
  59. package/lib/{openai-codex-responses-BcnOotRB.mjs → openai-codex-responses-BL29nh9K.mjs} +204 -116
  60. package/lib/{openai-completions-Bq4WT47M.mjs → openai-completions-BK2f2dBv.mjs} +152 -82
  61. package/lib/openai-configuration-update-xMYUjaK_.mjs +150 -0
  62. package/lib/{openai-reasoning-fallback-DXsfiSXO.mjs → openai-reasoning-fallback-BdB3RCbj.mjs} +106 -12
  63. package/lib/{openai-responses-Mq_-PjvE.mjs → openai-responses-CGQPlIIy.mjs} +76 -82
  64. package/lib/{perplexity-XgLF73E7.mjs → perplexity-TBjz3VMB.mjs} +52 -9
  65. package/lib/{pkce-BlQikGPu.mjs → pkce-BYjmugmw.mjs} +1 -1
  66. package/lib/protobuf-aab1UGVn.mjs +717 -0
  67. package/lib/{provider-response-C6vcbQyO.mjs → provider-response-SqKSkkUc.mjs} +1 -1
  68. package/lib/{proxy-D9lm7ONA.mjs → proxy-5nWqRL1f.mjs} +45 -5
  69. package/lib/{readability-Cpm-ocau.mjs → readability-uGhqb4GC.mjs} +2 -2
  70. package/lib/reference-CtvM4zLU.mjs +114 -0
  71. package/lib/{request-debug-HJMoJncL.mjs → request-debug-NQN0BjHH.mjs} +1 -1
  72. package/lib/{sanitize-text-CfcXzw5X.mjs → sanitize-text-BCf5KmCf.mjs} +1 -1
  73. package/lib/{scrapers-Cg5w77td.mjs → scrapers-D8oWspgW.mjs} +12 -12
  74. package/lib/{src-BcD0_rQR.mjs → src-BwW51vA5.mjs} +979 -388
  75. package/lib/{sse-debug-CYdjOC96.mjs → sse-debug-B-tkLCPW.mjs} +1 -1
  76. package/lib/{stream-Bjq8wjfr.mjs → stream-B_7qN-bA.mjs} +3802 -2623
  77. package/lib/stream-markup-healing-DKT1lnkW.mjs +267 -0
  78. package/lib/{strict-tool-validation-imVLUcbI.mjs → strict-tool-validation-CBTz1dAA.mjs} +2 -2
  79. package/lib/taxonomy-DSIM99rS.mjs +15392 -0
  80. package/lib/{stream-markup-healing-DZ6bVDxH.mjs → thinking-CiLa2LFB.mjs} +31 -186
  81. package/lib/{turndown-DN7ByzEI.mjs → turndown-DrX1M4WG.mjs} +4 -4
  82. package/lib/{type-guards-B9VVjRDK.mjs → type-guards-CttAANEx.mjs} +1 -1
  83. package/lib/{types-DX_bvuus.mjs → types-PVueGi9S.mjs} +2 -2
  84. package/lib/{utils-C-dSORPa.mjs → utils-CCfhUQen.mjs} +2364 -2676
  85. package/lib/{utils-Cp2Mxf_U.mjs → utils-CUPhpw9A.mjs} +413 -134
  86. package/lib/{utils-CQHPEQ3W.mjs → utils-DeWqNWV8.mjs} +2 -2
  87. package/lib/{vision-guard-mBmtAHx0.mjs → vision-guard-_XwsL1DF.mjs} +14 -29
  88. package/lib/xai-oauth-CXhnz0gO.mjs +210 -0
  89. package/lib/{xiaomi-7mE345KX.mjs → xiaomi-psoUItal.mjs} +8 -37
  90. package/lib/{zai-CeNpMV3W.mjs → zai-ApJ8HBgT.mjs} +8 -71
  91. package/lib/{zip-BK7UHCwX.mjs → zip-Kd602XNe.mjs} +1 -1
  92. package/package.json +11 -11
  93. package/presets/package.json +1 -1
  94. package/presets/tool-plus-ptc/agent.cordis.yml +1 -1
  95. package/presets/tool-plus-standard/agent.cordis.yml +1 -1
  96. package/lib/agent_pb-Rizyt9Zg.mjs +0 -805
  97. package/lib/anthropic-CDmj476p.mjs +0 -262
  98. package/lib/api_server_pb-CDZgLMta.mjs +0 -252
  99. package/lib/callback-server-CFJK-jvK.mjs +0 -398
  100. package/lib/codex-P1dGpX7G.mjs +0 -54
  101. package/lib/device-code-CuXTWYwY.mjs +0 -51
  102. package/lib/devin-BcQwht1W.mjs +0 -114
  103. package/lib/devin-BvMfGevz.mjs +0 -95
  104. package/lib/github-copilot-B3kQl0g0.mjs +0 -104
  105. package/lib/gitlab-duo-BriUTP8k.mjs +0 -155
  106. package/lib/gitlab-duo-workflow-wK5Ljzmc.mjs +0 -91
  107. package/lib/google-CE5tFDod.mjs +0 -30
  108. package/lib/google-antigravity-C1jgNljz.mjs +0 -198
  109. package/lib/google-oauth-shared-BLVTvokk.mjs +0 -147
  110. package/lib/grammar-D-NqNUxQ.mjs +0 -49
  111. package/lib/identity-HNO1Oe9B.mjs +0 -219
  112. package/lib/kimi-DgcUpPtK.mjs +0 -236
  113. package/lib/markit-DtGoRE6M.mjs +0 -1417
  114. package/lib/minimax-code-Y3h5li9N.mjs +0 -53
  115. package/lib/models-DRA2c_8U.mjs +0 -104660
  116. package/lib/opencode-BsVw9rCD.mjs +0 -38
  117. package/lib/to-binary-B1BEBIPC.mjs +0 -6002
  118. package/lib/wafer-BlhWLweO.mjs +0 -17
  119. package/lib/xai-oauth-5pORHUrg.mjs +0 -446
@@ -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/deterministic-id.ts
3
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/utils/deterministic-id.ts
4
4
  /**
5
5
  * Format the leading 128 bits of `seed`'s SHA-256 digest as a v4-shape UUID
6
6
  * (8-4-4-4-12 hex groups).
@@ -0,0 +1,316 @@
1
+ import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
+ __installBunShim();
3
+ import { C as warn } from "./src-BwW51vA5.mjs";
4
+ import { n as discoveryFetch } from "./utils-DeWqNWV8.mjs";
5
+ import { n as THINKING_EFFORTS } from "./effort-BdtQMN-_.mjs";
6
+ import { t as collapseVariants } from "./collapse-DOR8sOGf.mjs";
7
+ import { r as devinDiscoveryMetadata } from "./devin-ExGIghmx.mjs";
8
+ import { o as toBinary, t as create } from "./protobuf-aab1UGVn.mjs";
9
+ import { d as GetCliModelConfigsRequestSchema, f as GetCliModelConfigsResponseSchema, t as decodeDevinUnaryMessage, v as MetadataSchema } from "./devin-proto-Br8fdyNl.mjs";
10
+ //#region node_modules/.pnpm/@oh-my-pi+pi-catalog@18.1.17/node_modules/@oh-my-pi/pi-catalog/src/discovery/devin.ts
11
+ const DEVIN_GET_CLI_MODEL_CONFIGS_PATH = "/exa.api_server_pb.ApiServerService/GetCliModelConfigs";
12
+ const DEFAULT_CONTEXT_WINDOW = 2e5;
13
+ const DEFAULT_MAX_TOKENS = 64e3;
14
+ /**
15
+ * `DISPLAY_OPTION_INTERNAL_DEFAULT` — display slot for configs the server only
16
+ * reveals to clients that opt in, used for internal default/eval models.
17
+ *
18
+ * The vendored descriptor predates display options 6-8, so the generated
19
+ * `DisplayOption` enum stops at `QUICK_REVIEW` (4). Wire display options are
20
+ * plain int32, so the extra values decode and re-encode faithfully; casting
21
+ * here keeps the generated code untouched.
22
+ */
23
+ const DEVIN_DISPLAY_OPTION_INTERNAL_DEFAULT = 6;
24
+ /**
25
+ * Display slots the native client advertises. `UNSPECIFIED` (0) is implicit —
26
+ * it is the default for configs with no display opinion. Asking for the
27
+ * internal slots is what makes the server return its full catalog; the
28
+ * internal ones are filtered client-side, exactly as native does.
29
+ */
30
+ const DEVIN_SUPPORTED_MODEL_DISPLAYS = [
31
+ 3,
32
+ 4,
33
+ DEVIN_DISPLAY_OPTION_INTERNAL_DEFAULT,
34
+ 7,
35
+ 8
36
+ ];
37
+ /** Display slots requested but never surfaced: quick-review and internal defaults. */
38
+ const DEVIN_INTERNAL_MODEL_DISPLAYS = /* @__PURE__ */ new Set([4, DEVIN_DISPLAY_OPTION_INTERNAL_DEFAULT]);
39
+ /** Best-effort match for labels whose wording implies a thinking / reasoning-effort variant. */
40
+ const REASONING_LABEL_PATTERN = /think|thinking|minimal|high|medium|low|xhigh|max|reasoning/i;
41
+ const NO_REASONING_LABEL_PATTERN = /\bno thinking\b/i;
42
+ /**
43
+ * Server model features are authoritative for reasoning support; the label
44
+ * heuristic only covers configs that ship no `modelFeatures` at all.
45
+ */
46
+ function supportsDevinThinking(config) {
47
+ const features = config.modelInfo?.modelFeatures;
48
+ if (features !== void 0) return features.supportsThinking;
49
+ if (NO_REASONING_LABEL_PATTERN.test(config.label)) return false;
50
+ return REASONING_LABEL_PATTERN.test(config.label);
51
+ }
52
+ /** Cost `modelDimensions` labels, normalized, mapped onto catalog token rates. */
53
+ const DEVIN_COST_LABEL_INPUT = "input";
54
+ const DEVIN_COST_LABEL_CACHE_READ = "cached input";
55
+ const DEVIN_COST_LABEL_OUTPUT = "output";
56
+ /** Leading token count of a cost denominator ("1M tokens", "1K tokens"). */
57
+ const DEVIN_COST_DENOMINATOR_PATTERN = /(\d+(?:\.\d+)?)\s*([kmb])?/i;
58
+ const DEVIN_COST_DENOMINATOR_SCALE = {
59
+ k: 1e3,
60
+ m: 1e6,
61
+ b: 1e9
62
+ };
63
+ /**
64
+ * Tokens covered by one cost dimension. Native prices per `1M tokens`; the
65
+ * scale is parsed instead of assumed so a future `1K` denominator still
66
+ * normalizes to catalog per-million rates.
67
+ */
68
+ function devinCostDenominatorTokens(denominator) {
69
+ const match = DEVIN_COST_DENOMINATOR_PATTERN.exec(denominator);
70
+ if (match === null) return 1e6;
71
+ const suffix = match[2];
72
+ const scale = suffix === void 0 ? 1 : DEVIN_COST_DENOMINATOR_SCALE[suffix.toLowerCase()] ?? 1;
73
+ const tokens = Number(match[1]) * scale;
74
+ return tokens > 0 ? tokens : 1e6;
75
+ }
76
+ /**
77
+ * Per-million-token rates from the config's cost dimensions. `COST_FUZZY` marks
78
+ * an estimated rate, not a different unit, so both kinds are read. `cacheWrite`
79
+ * has no Cascade dimension — Devin bills cache writes at the input rate — and
80
+ * stays 0.
81
+ */
82
+ function devinModelCost(config) {
83
+ const cost = {
84
+ input: 0,
85
+ output: 0,
86
+ cacheRead: 0,
87
+ cacheWrite: 0
88
+ };
89
+ for (const dimension of config.modelDimensions) {
90
+ if (dimension.kind !== 1 && dimension.kind !== 2) continue;
91
+ const perMillion = Math.round(dimension.value * 1e6 / devinCostDenominatorTokens(dimension.denominator) * 1e6) / 1e6;
92
+ switch (dimension.label.trim().toLowerCase()) {
93
+ case DEVIN_COST_LABEL_INPUT:
94
+ cost.input = perMillion;
95
+ break;
96
+ case DEVIN_COST_LABEL_CACHE_READ:
97
+ cost.cacheRead = perMillion;
98
+ break;
99
+ case DEVIN_COST_LABEL_OUTPUT: cost.output = perMillion;
100
+ }
101
+ }
102
+ return cost;
103
+ }
104
+ /** `modelFamilyMetadata` entry keys that carry the family's effort axis. */
105
+ const DEVIN_FAMILY_EFFORT_KEYS = {
106
+ effort: true,
107
+ "reasoning effort": true
108
+ };
109
+ /** `modelFamilyMetadata` entry key for the service-tier axis; order 1 is the fast lane. */
110
+ const DEVIN_FAMILY_FAST_KEY = "fast mode";
111
+ const DEVIN_FAMILY_FAST_ORDER = 1;
112
+ /** Boolean reasoning axis used by Claude families whose effort name alone is ambiguous. */
113
+ const DEVIN_FAMILY_THINKING_KEY = "thinking";
114
+ const DEVIN_FAMILY_THINKING_ORDER = 1;
115
+ /** Context-window axis; order 1 selects the separate 1M-context lane. */
116
+ const DEVIN_FAMILY_CONTEXT_1M_KEY = "1m context";
117
+ const DEVIN_FAMILY_CONTEXT_1M_ORDER = 1;
118
+ /** Effort-entry display names, normalized to a space-free token, mapped onto pi efforts. */
119
+ const DEVIN_FAMILY_EFFORT_BY_NAME = {
120
+ none: "off",
121
+ nothinking: "off",
122
+ minimal: "minimal",
123
+ low: "low",
124
+ medium: "medium",
125
+ high: "high",
126
+ xhigh: "xhigh",
127
+ max: "max"
128
+ };
129
+ /**
130
+ * File `config` under its server-declared family lane. Configs with no family
131
+ * metadata, or whose family carries no effort axis, are left alone and stay
132
+ * standalone specs.
133
+ */
134
+ function collectDevinFamilyLane(lanes, config, uid) {
135
+ const metadata = config.modelFamilyMetadata;
136
+ if (metadata === void 0) return;
137
+ const label = metadata.modelFamilyLabel.trim();
138
+ if (!label) return;
139
+ let effort;
140
+ let thinking;
141
+ let fast = false;
142
+ let oneMillionContext = false;
143
+ for (const entry of metadata.entries) {
144
+ const value = entry.value;
145
+ if (value === void 0) continue;
146
+ const key = entry.key.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
147
+ if (key === DEVIN_FAMILY_FAST_KEY) {
148
+ fast = value.order === DEVIN_FAMILY_FAST_ORDER;
149
+ continue;
150
+ }
151
+ if (key === DEVIN_FAMILY_THINKING_KEY) {
152
+ thinking = value.order === DEVIN_FAMILY_THINKING_ORDER;
153
+ continue;
154
+ }
155
+ if (key === DEVIN_FAMILY_CONTEXT_1M_KEY) {
156
+ oneMillionContext = value.order === DEVIN_FAMILY_CONTEXT_1M_ORDER;
157
+ continue;
158
+ }
159
+ if (DEVIN_FAMILY_EFFORT_KEYS[key]) effort = DEVIN_FAMILY_EFFORT_BY_NAME[value.name.toLowerCase().replace(/[^a-z0-9]+/g, "")];
160
+ }
161
+ if (thinking === false) effort = "off";
162
+ const baseId = label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
163
+ if (!baseId) return;
164
+ const laneId = `${baseId}${oneMillionContext ? "-1m" : ""}${fast ? "-fast" : ""}`;
165
+ let lane = lanes.get(laneId);
166
+ if (lane === void 0) {
167
+ lane = {
168
+ id: laneId,
169
+ name: `${label}${oneMillionContext ? " 1M" : ""}${fast ? " Fast" : ""}`,
170
+ members: [],
171
+ routing: {}
172
+ };
173
+ lanes.set(laneId, lane);
174
+ }
175
+ lane.members.push(uid);
176
+ if (lane.defaultMember === void 0 && (config.isDefaultModelInFamily || metadata.isDefaultModelInFamily)) lane.defaultMember = uid;
177
+ if (effort !== void 0 && lane.routing[effort] === void 0) lane.routing[effort] = uid;
178
+ }
179
+ /**
180
+ * Collapse families for the lanes that declare an effort ladder. The server
181
+ * default wire uid is hoisted to the front of `members` so collapsing adopts it
182
+ * as the logical model's default `requestModelId`.
183
+ *
184
+ * A lane with no non-`off` effort route has nothing to route: its members stay
185
+ * standalone rather than collapsing into a family with an empty effort list.
186
+ */
187
+ function devinDynamicFamilies(lanes) {
188
+ const families = [];
189
+ for (const lane of lanes) {
190
+ const efforts = THINKING_EFFORTS.filter((effort) => lane.routing[effort] !== void 0);
191
+ if (efforts.length === 0) continue;
192
+ const defaultMember = lane.defaultMember;
193
+ const members = defaultMember === void 0 ? lane.members : [defaultMember, ...lane.members.filter((uid) => uid !== defaultMember)];
194
+ const defaultLevel = defaultMember === void 0 ? void 0 : efforts.find((effort) => lane.routing[effort] === defaultMember);
195
+ families.push({
196
+ id: lane.id,
197
+ name: lane.name,
198
+ members,
199
+ routing: lane.routing,
200
+ ...defaultMember !== void 0 ? { defaultMember } : {},
201
+ thinking: {
202
+ mode: "effort",
203
+ efforts,
204
+ ...defaultLevel !== void 0 ? { defaultLevel } : {},
205
+ ...lane.routing.off === void 0 ? { requiresEffort: true } : {}
206
+ }
207
+ });
208
+ }
209
+ return families;
210
+ }
211
+ /**
212
+ * Fetches Devin models through the `GetCliModelConfigs` unary Connect RPC and
213
+ * normalizes them into canonical model entries.
214
+ *
215
+ * Returns `null` on request/decode failures.
216
+ * Returns `[]` only when the endpoint responds successfully with no usable models.
217
+ */
218
+ async function fetchDevinModels(options) {
219
+ const timeoutMs = options.timeoutMs ?? 5e3;
220
+ const requestUrl = `${(options.baseUrl ?? "https://server.codeium.com").replace(/\/+$/, "")}${DEVIN_GET_CLI_MODEL_CONFIGS_PATH}`;
221
+ const controller = new AbortController();
222
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
223
+ const signal = options.signal ? AbortSignal.any([controller.signal, options.signal]) : controller.signal;
224
+ try {
225
+ const request = create(GetCliModelConfigsRequestSchema, { metadata: create(MetadataSchema, {
226
+ ...devinDiscoveryMetadata(options.apiKey),
227
+ supportedModelDisplays: [...DEVIN_SUPPORTED_MODEL_DISPLAYS]
228
+ }) });
229
+ const body = toBinary(GetCliModelConfigsRequestSchema, request);
230
+ const response = await discoveryFetch(options.fetch)(requestUrl, {
231
+ method: "POST",
232
+ headers: {
233
+ "content-type": "application/proto",
234
+ "connect-protocol-version": "1",
235
+ accept: "*/*"
236
+ },
237
+ body,
238
+ signal
239
+ });
240
+ if (!response.ok) return null;
241
+ const decoded = decodeDevinUnaryMessage(GetCliModelConfigsResponseSchema, new Uint8Array(await response.arrayBuffer()));
242
+ if (!decoded) return null;
243
+ const models = normalizeDevinModels(decoded.clientModelConfigs, options.baseUrl);
244
+ if (models.length === 0) {
245
+ warn("Devin returned an empty native model catalog; the pinned CLI identity may be stale", { metadata: devinDiscoveryMetadata(void 0) });
246
+ return null;
247
+ }
248
+ return models;
249
+ } catch {
250
+ return null;
251
+ } finally {
252
+ clearTimeout(timer);
253
+ }
254
+ }
255
+ /**
256
+ * Wire uids whose configs advertise `supports_images` but whose backend
257
+ * silently drops the `ChatMessagePrompt.images` field. Verified live
258
+ * (2026-08-14, native CLI identity): SWE-1.6 and SWE-1.6 Fast answer as if no
259
+ * image was attached, while SWE-1.7, SWE-1.7 Lightning, and every proxied
260
+ * frontier model (Claude/Gemini/GPT/Kimi) read the same field correctly.
261
+ * Declaring text-only lets clients use their image fallback path instead of
262
+ * silently losing attachments ([#6072](https://github.com/can1357/oh-my-pi/issues/6072)).
263
+ * Remove entries if Devin ever wires SWE-1.6 vision up.
264
+ */
265
+ const DEVIN_IMAGE_BLIND_UIDS = /* @__PURE__ */ new Set(["swe-1-6", "swe-1-6-fast"]);
266
+ /** One config as a raw (pre-collapse) spec keyed on its wire uid. */
267
+ function devinModelSpec(config, uid, baseUrl, isRouter) {
268
+ const features = config.modelInfo?.modelFeatures;
269
+ const input = (features !== void 0 ? features.supportsImages : config.supportsImages) && !DEVIN_IMAGE_BLIND_UIDS.has(uid) ? ["text", "image"] : ["text"];
270
+ const compat = {};
271
+ if (isRouter) compat.modelRouter = true;
272
+ if (features?.supportsParallelToolCalls === true) compat.supportsParallelToolCalls = true;
273
+ const maxOutputTokens = config.modelInfo?.maxOutputTokens ?? 0;
274
+ const spec = {
275
+ id: uid,
276
+ name: config.label.trim() || uid,
277
+ api: "devin-agent",
278
+ provider: "devin",
279
+ baseUrl,
280
+ reasoning: supportsDevinThinking(config),
281
+ input,
282
+ supportsTools: features !== void 0 ? features.supportsToolCalls : true,
283
+ cost: devinModelCost(config),
284
+ contextWindow: config.maxTokens > 0 ? config.maxTokens : DEFAULT_CONTEXT_WINDOW,
285
+ maxTokens: maxOutputTokens > 0 ? maxOutputTokens : DEFAULT_MAX_TOKENS,
286
+ ...Object.keys(compat).length > 0 ? { compat } : {}
287
+ };
288
+ const description = config.description?.trim();
289
+ if (description) spec.description = description;
290
+ if (config.isNew) spec.isNew = true;
291
+ if (config.isBeta) spec.isBeta = true;
292
+ if (config.isRecommended) spec.isRecommended = true;
293
+ return spec;
294
+ }
295
+ function normalizeDevinModels(configs, baseUrlOverride) {
296
+ const baseUrl = baseUrlOverride ?? "https://server.codeium.com";
297
+ const specs = [];
298
+ const seen = /* @__PURE__ */ new Set();
299
+ const lanes = /* @__PURE__ */ new Map();
300
+ for (const config of configs) {
301
+ if (config.disabled) continue;
302
+ const displayOption = config.modelInfo?.displayOption ?? 0;
303
+ if (DEVIN_INTERNAL_MODEL_DISPLAYS.has(displayOption)) continue;
304
+ const uid = config.modelUid.trim();
305
+ if (!uid || seen.has(uid)) continue;
306
+ seen.add(uid);
307
+ const isRouter = displayOption === 3 || config.modelInfo?.isModelRouter === true;
308
+ specs.push(devinModelSpec(config, uid, baseUrl, isRouter));
309
+ if (!isRouter) collectDevinFamilyLane(lanes, config, uid);
310
+ }
311
+ const families = devinDynamicFamilies(lanes.values());
312
+ const dynamic = families.length > 0 ? collapseVariants(specs, { table: { families } }) : specs;
313
+ return collapseVariants(dynamic).sort((a, b) => a.id.localeCompare(b.id));
314
+ }
315
+ //#endregion
316
+ export { fetchDevinModels };