@xiaoso/dsh-tool-plus 0.1.0-beta.2 → 0.1.0-beta.3

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 (88) hide show
  1. package/README.en.md +122 -0
  2. package/README.md +3 -2
  3. package/THIRD_PARTY_NOTICES.md +4 -35
  4. package/lib/abort-B7izMMna.mjs +51 -0
  5. package/lib/amazon-bedrock-D-shAr1X.mjs +917 -0
  6. package/lib/anthropic-BWsZFzU8.mjs +262 -0
  7. package/lib/anthropic-CMT1Qj1t.mjs +3115 -0
  8. package/lib/api-key-login-CpzSezsi.mjs +157 -0
  9. package/lib/aws-credentials-8Mgn5MAy.mjs +867 -0
  10. package/lib/azure-openai-responses-CNkHiLUh.mjs +274 -0
  11. package/lib/bun-shim.mjs +172 -7
  12. package/lib/bundled-references-CSuBco5p.mjs +55 -0
  13. package/lib/callback-server-BEFNf-jf.mjs +398 -0
  14. package/lib/client.js +110 -40
  15. package/lib/cursor-BIQfBC6V.mjs +135 -0
  16. package/lib/cursor-DNk6eXDd.mjs +5470 -0
  17. package/lib/cursor-MjSm74IJ.mjs +273 -0
  18. package/lib/device-code-OI_tQcmc.mjs +51 -0
  19. package/lib/devin-CldyPD8K.mjs +95 -0
  20. package/lib/devin-CzRpTUOA.mjs +114 -0
  21. package/lib/devin-DXOeNyU7.mjs +542 -0
  22. package/lib/error-B3bevhrs.mjs +1449 -0
  23. package/lib/event-stream-BDPi64mK.mjs +151 -0
  24. package/lib/github-copilot-4GaMtQmg.mjs +208 -0
  25. package/lib/github-copilot-B2HGSIJK.mjs +104 -0
  26. package/lib/gitlab-duo-akICyfeD.mjs +155 -0
  27. package/lib/gitlab-duo-workflow-CSEgYk3N.mjs +91 -0
  28. package/lib/google-antigravity-Dlkdhahq.mjs +198 -0
  29. package/lib/google-auth-DhqpOYrX.mjs +232 -0
  30. package/lib/google-gemini-cli-BG_LRdIV.mjs +850 -0
  31. package/lib/google-gemini-cli-zJhiOcND.mjs +211 -0
  32. package/lib/google-oauth-shared-CwNWYdmR.mjs +147 -0
  33. package/lib/google-shared-DzhCb9b0.mjs +760 -0
  34. package/lib/google-vertex-kscbkyRb.mjs +99 -0
  35. package/lib/google-zyDOG9x7.mjs +30 -0
  36. package/lib/identity-DnB63pS7.mjs +219 -0
  37. package/lib/idle-iterator-C6XbWcuB.mjs +366 -0
  38. package/lib/index.mjs +2865 -2745
  39. package/lib/kimi-DMVI-zrZ.mjs +236 -0
  40. package/lib/markit-M0jhziqU.mjs +1417 -0
  41. package/lib/minimax-code-BK-3eBbz.mjs +53 -0
  42. package/lib/models-CfT4coYT.mjs +104660 -0
  43. package/lib/ollama-BQMGPxtV.mjs +589 -0
  44. package/lib/openai-codex-CQL_kvYL.mjs +255 -0
  45. package/lib/openai-codex-responses-Cz-2qpC7.mjs +3144 -0
  46. package/lib/openai-completions-i8doczAk.mjs +1360 -0
  47. package/lib/openai-reasoning-fallback-DGVVLgd1.mjs +286 -0
  48. package/lib/openai-responses-DTkBiiy-.mjs +867 -0
  49. package/lib/opencode-DaJjcUbf.mjs +38 -0
  50. package/lib/perplexity-9b-RQ0mV.mjs +194 -0
  51. package/lib/proxy-ZtUcl6r5.mjs +190 -0
  52. package/lib/scrapers-CL-WgdU1.mjs +9198 -0
  53. package/lib/scrapers-CipyKyCH.mjs +9198 -0
  54. package/lib/scrapers-DGfrYhtw.mjs +9198 -0
  55. package/lib/scrapers-DSUPYoUF.mjs +9198 -0
  56. package/lib/scrapers-DZ2GXmp7.mjs +9198 -0
  57. package/lib/src-DTid0g4K.mjs +5001 -0
  58. package/lib/stream-C_RAoxJC.mjs +10236 -0
  59. package/lib/stream-markup-healing-2toHXWXM.mjs +491 -0
  60. package/lib/types/client/locales.d.ts +1 -1
  61. package/lib/types/config/fields.d.ts +1 -1
  62. package/lib/types/config/settings.d.ts +16 -2
  63. package/lib/types/tools/omp/sdk.d.ts +6 -0
  64. package/lib/types/tools/omp/tools/fetch.d.ts +2 -0
  65. package/lib/types/tools/omp/tools/read.d.ts +2 -8
  66. package/lib/types/tools/omp/utils/image-loading.d.ts +10 -36
  67. package/lib/types/tools/read/adapter/index.d.ts +4 -1
  68. package/lib/types/tools/read-image/index.d.ts +4 -0
  69. package/lib/types/tools/shared/bun-shim.d.ts +35 -3
  70. package/lib/types/tools/shared/image-bridge.d.ts +98 -0
  71. package/lib/types/tools/shared/omp-prompt.d.ts +4 -2
  72. package/lib/utils-2Wq2eATG.mjs +8119 -0
  73. package/lib/utils-BnX8O3vi.mjs +12303 -0
  74. package/lib/utils-CE8N8P4Q.mjs +12315 -0
  75. package/lib/utils-C_MrQ_0z.mjs +12301 -0
  76. package/lib/utils-D0Z1fyoO.mjs +12299 -0
  77. package/lib/utils-DppGHXQB.mjs +51 -0
  78. package/lib/utils-W8WdSBpX.mjs +12315 -0
  79. package/lib/vision-guard-BDD4OrKo.mjs +92 -0
  80. package/lib/wafer-DRU0EjZX.mjs +17 -0
  81. package/lib/xai-oauth-DPHDXKD7.mjs +446 -0
  82. package/lib/xiaomi-Dd87KSg5.mjs +157 -0
  83. package/lib/zai-CFeOt-53.mjs +203 -0
  84. package/lib/zip-D6QXpvaJ.mjs +1316 -0
  85. package/package.json +14 -10
  86. package/presets/package.json +1 -1
  87. package/presets/tool-plus-ptc/preset.yml +1 -1
  88. package/presets/tool-plus-standard/preset.yml +1 -1
@@ -0,0 +1,542 @@
1
+ import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
+ __installBunShim();
3
+ import { C as error, S as debug, T as warn, _ as parseStreamingJsonThrottled, g as parseStreamingJson } from "./src-DTid0g4K.mjs";
4
+ import { l as finalize, o as DevinApiError, r as ValidationError, s as ProviderResponseError, w as create, x as attach, y as Flag } from "./error-B3bevhrs.mjs";
5
+ import { a as normalizeSystemPrompts, g as isDemotedThinking, k as toolWireSchema, m as transformMessages } from "./utils-2Wq2eATG.mjs";
6
+ import { t as calculateCost } from "./models-CfT4coYT.mjs";
7
+ import { t as AssistantMessageEventStream } from "./event-stream-BDPi64mK.mjs";
8
+ import { E as create$1, c as messageDesc, i as fromBinary, r as fileDesc, t as toBinary } from "./to-binary-B1BEBIPC.mjs";
9
+ import { a as ChatMessagePromptSchema, c as PromptCacheOptionsSchema, d as ImageDataSchema, f as MetadataSchema, l as ChatToolCallSchema, m as file_buf_validate_validate, n as GetChatMessageResponseSchema, o as ChatToolChoiceSchema, p as file_exa_codeium_common_pb_codeium_common, s as ChatToolDefinitionSchema, t as GetChatMessageRequestSchema, u as CompletionConfigurationSchema } from "./api_server_pb-CDZgLMta.mjs";
10
+ import { t as deterministicUuid } from "./deterministic-id-D-yIV_eI.mjs";
11
+ import { gunzipSync, gzipSync } from "node:zlib";
12
+ //#region node_modules/.pnpm/@oh-my-pi+pi-catalog@17.3.5/node_modules/@oh-my-pi/pi-catalog/src/discovery/devin-gen/exa/auth_pb/auth_pb.ts
13
+ /**
14
+ * Describes the file exa/auth_pb/auth.proto.
15
+ */
16
+ const file_exa_auth_pb_auth = /*@__PURE__*/ fileDesc("ChZleGEvYXV0aF9wYi9hdXRoLnByb3RvEgtleGEuYXV0aF9wYiJGChFHZXRVc2VySnd0UmVxdWVzdBIxCghtZXRhZGF0YRgBIAEoCzIfLmV4YS5jb2RlaXVtX2NvbW1vbl9wYi5NZXRhZGF0YSJFChJHZXRVc2VySnd0UmVzcG9uc2USEAoIdXNlcl9qd3QYASABKAkSHQoVY3VzdG9tX2FwaV9zZXJ2ZXJfdXJsGAIgASgJMlwKC0F1dGhTZXJ2aWNlEk0KCkdldFVzZXJKd3QSHi5leGEuYXV0aF9wYi5HZXRVc2VySnd0UmVxdWVzdBofLmV4YS5hdXRoX3BiLkdldFVzZXJKd3RSZXNwb25zZWIGcHJvdG8z", [file_buf_validate_validate, file_exa_codeium_common_pb_codeium_common]);
17
+ /**
18
+ * Describes the message exa.auth_pb.GetUserJwtRequest.
19
+ * Use `create(GetUserJwtRequestSchema)` to create a new message.
20
+ */
21
+ const GetUserJwtRequestSchema = /*@__PURE__*/ messageDesc(file_exa_auth_pb_auth, 0);
22
+ /**
23
+ * Describes the message exa.auth_pb.GetUserJwtResponse.
24
+ * Use `create(GetUserJwtResponseSchema)` to create a new message.
25
+ */
26
+ const GetUserJwtResponseSchema = /*@__PURE__*/ messageDesc(file_exa_auth_pb_auth, 1);
27
+ const CHAT_MESSAGE_PATH = "/exa.api_server_pb.ApiServerService/GetChatMessage";
28
+ const DEVIN_IDE_VERSION = "3.2.23";
29
+ const DEVIN_EXTENSION_VERSION = "1.48.2";
30
+ const DEVIN_SESSION_TOKEN_PREFIX = "devin-session-token$";
31
+ const DEVIN_AUTH_PATH = "/exa.auth_pb.AuthService/GetUserJwt";
32
+ const DEVIN_DEFAULT_STOP_PATTERNS = [
33
+ "<|user|>",
34
+ "<|bot|>",
35
+ "<|context_request|>",
36
+ "<|endoftext|>",
37
+ "<|end_of_turn|>"
38
+ ];
39
+ /** Connect streaming framing: flag byte bit 0x01 = gzip payload, 0x02 = end-of-stream JSON trailers. */
40
+ const CONNECT_COMPRESSED_FLAG = 1;
41
+ const CONNECT_END_STREAM_FLAG = 2;
42
+ /**
43
+ * Hard upper bound on a single Connect frame payload. The 4-byte length prefix
44
+ * is otherwise attacker-controlled (up to `2**32 - 1`), so a malicious or buggy
45
+ * peer could force {@link streamDevin}'s reader to buffer gigabytes via
46
+ * `Buffer.concat` before the idle-timeout wrapper aborts. Well above any
47
+ * legitimate Cascade response but tight enough that a corrupt length prefix
48
+ * fails fast instead of consuming memory.
49
+ */
50
+ const MAX_CONNECT_FRAME_PAYLOAD = 16777216;
51
+ /**
52
+ * Recovery heuristic for opaque Devin `invalid_argument` trailers. This is not
53
+ * asserted to be the backend's hard limit: small requests can hit the same
54
+ * intermittent error, while compactable message history this large is likely
55
+ * to benefit from the existing context-overflow maintenance path.
56
+ */
57
+ const LARGE_HISTORY_RECOVERY_BYTES = 524288;
58
+ const streamDevin = (model, context, options) => {
59
+ const stream = new AssistantMessageEventStream();
60
+ (async () => {
61
+ const startTime = performance.now();
62
+ let firstTokenTime;
63
+ const output = {
64
+ role: "assistant",
65
+ content: [],
66
+ api: "devin-agent",
67
+ provider: model.provider,
68
+ model: model.id,
69
+ usage: {
70
+ input: 0,
71
+ output: 0,
72
+ cacheRead: 0,
73
+ cacheWrite: 0,
74
+ totalTokens: 0,
75
+ cost: {
76
+ input: 0,
77
+ output: 0,
78
+ cacheRead: 0,
79
+ cacheWrite: 0,
80
+ total: 0
81
+ }
82
+ },
83
+ stopReason: "stop",
84
+ timestamp: Date.now()
85
+ };
86
+ let currentTextBlock = null;
87
+ let currentThinkingBlock = null;
88
+ const toolBlocks = /* @__PURE__ */ new Map();
89
+ const toolPartialJson = /* @__PURE__ */ new Map();
90
+ const toolLastParseLen = /* @__PURE__ */ new Map();
91
+ let activeToolCallId;
92
+ let latestStopReason = 0;
93
+ const markFirstToken = () => {
94
+ if (firstTokenTime === void 0) firstTokenTime = performance.now();
95
+ };
96
+ const endTextBlock = () => {
97
+ const block = currentTextBlock;
98
+ if (!block) return;
99
+ currentTextBlock = null;
100
+ stream.push({
101
+ type: "text_end",
102
+ contentIndex: output.content.indexOf(block),
103
+ content: block.text,
104
+ partial: output
105
+ });
106
+ };
107
+ const endThinkingBlock = () => {
108
+ const block = currentThinkingBlock;
109
+ if (!block) return;
110
+ currentThinkingBlock = null;
111
+ stream.push({
112
+ type: "thinking_end",
113
+ contentIndex: output.content.indexOf(block),
114
+ content: block.thinking,
115
+ partial: output
116
+ });
117
+ };
118
+ try {
119
+ const fetchImpl = options?.fetch ?? fetch;
120
+ const baseUrl = (model.baseUrl || "https://server.codeium.com").replace(/\/+$/, "");
121
+ const apiKey = normalizeDevinSessionToken(options?.apiKey);
122
+ const auth = await fetchDevinAuthMetadata(apiKey, baseUrl, fetchImpl, options?.signal);
123
+ const chatBaseUrl = auth.baseUrl ?? baseUrl;
124
+ const request = buildDevinChatRequest(model, context, options, apiKey, auth.userJwt);
125
+ const reqBytes = toBinary(GetChatMessageRequestSchema, request);
126
+ const gz = gzipSync(reqBytes);
127
+ debug("devin: sending chat request", {
128
+ model: model.id,
129
+ tools: context.tools?.length ?? 0,
130
+ requestBytes: reqBytes.byteLength,
131
+ compressedBytes: gz.byteLength
132
+ });
133
+ const frame = Buffer.alloc(5 + gz.length);
134
+ frame[0] = CONNECT_COMPRESSED_FLAG;
135
+ frame.writeUInt32BE(gz.length, 1);
136
+ frame.set(gz, 5);
137
+ const response = await fetchImpl(chatBaseUrl + CHAT_MESSAGE_PATH, {
138
+ method: "POST",
139
+ headers: {
140
+ "content-type": "application/connect+proto",
141
+ "connect-protocol-version": "1",
142
+ "connect-content-encoding": "gzip",
143
+ "accept-encoding": "identity",
144
+ "user-agent": "connect-go/1.18.1 (go1.26.3)",
145
+ "connect-accept-encoding": "gzip",
146
+ ...options?.headers ?? {}
147
+ },
148
+ body: frame,
149
+ signal: options?.signal
150
+ });
151
+ if (!response.ok) {
152
+ const text = await response.text();
153
+ throw new DevinApiError(`Devin API error ${response.status} ${response.statusText}: ${text}`, response.status);
154
+ }
155
+ if (!response.body) throw new ProviderResponseError("Devin API error: response body is empty", {
156
+ provider: model.provider,
157
+ kind: "empty-body"
158
+ });
159
+ const body = response.body;
160
+ stream.push({
161
+ type: "start",
162
+ partial: output
163
+ });
164
+ const reader = body.getReader();
165
+ let pending = Buffer.alloc(0);
166
+ for (;;) {
167
+ const { done, value } = await reader.read();
168
+ if (value && value.length > 0) pending = pending.length === 0 ? Buffer.from(value.buffer, value.byteOffset, value.byteLength) : Buffer.concat([pending, value]);
169
+ while (pending.length >= 5) {
170
+ const flag = pending[0];
171
+ const len = pending.readUInt32BE(1);
172
+ if (len > MAX_CONNECT_FRAME_PAYLOAD) throw new ProviderResponseError(`Devin Connect frame length ${len} exceeds ${MAX_CONNECT_FRAME_PAYLOAD}-byte cap`, {
173
+ provider: model.provider,
174
+ kind: "envelope"
175
+ });
176
+ if (pending.length < 5 + len) break;
177
+ const payload = pending.subarray(5, 5 + len);
178
+ pending = pending.subarray(5 + len);
179
+ if (flag & CONNECT_END_STREAM_FLAG) {
180
+ const trailerError = readConnectTrailerError((flag & CONNECT_COMPRESSED_FLAG ? gunzipSync(payload) : payload).toString("utf8").trim());
181
+ if (trailerError) {
182
+ const error = new ValidationError(trailerError.formatted);
183
+ if (firstTokenTime === void 0 && trailerError.code.toLowerCase() === "invalid_argument" && /\binternal error\b/i.test(trailerError.message)) {
184
+ let activeTailCount = 0;
185
+ const lastRole = context.messages.at(-1)?.role;
186
+ if (lastRole === "user" || lastRole === "developer") {
187
+ activeTailCount = 1;
188
+ if (lastRole === "developer") for (let i = context.messages.length - 2; i >= 0; i--) {
189
+ const role = context.messages[i].role;
190
+ if (role !== "user" && role !== "developer") break;
191
+ activeTailCount++;
192
+ }
193
+ }
194
+ const shrinkablePrompts = activeTailCount > 0 ? request.chatMessagePrompts.slice(0, -activeTailCount) : request.chatMessagePrompts;
195
+ const historyBytes = toBinary(GetChatMessageRequestSchema, create$1(GetChatMessageRequestSchema, { chatMessagePrompts: shrinkablePrompts })).byteLength;
196
+ if (historyBytes >= LARGE_HISTORY_RECOVERY_BYTES) {
197
+ attach(error, create(Flag.ContextOverflow));
198
+ warn("devin: treating large-history invalid_argument as context overflow", {
199
+ model: model.id,
200
+ historyBytes,
201
+ requestBytes: reqBytes.byteLength,
202
+ compressedBytes: gz.byteLength
203
+ });
204
+ }
205
+ }
206
+ throw error;
207
+ }
208
+ continue;
209
+ }
210
+ const raw = flag & CONNECT_COMPRESSED_FLAG ? gunzipSync(payload) : payload;
211
+ const msg = fromBinary(GetChatMessageResponseSchema, raw);
212
+ if (msg.messageId && !output.responseId) output.responseId = msg.messageId;
213
+ if (msg.deltaThinking) {
214
+ markFirstToken();
215
+ const block = currentThinkingBlock ?? {
216
+ type: "thinking",
217
+ thinking: ""
218
+ };
219
+ if (currentThinkingBlock !== block) {
220
+ output.content.push(block);
221
+ currentThinkingBlock = block;
222
+ stream.push({
223
+ type: "thinking_start",
224
+ contentIndex: output.content.length - 1,
225
+ partial: output
226
+ });
227
+ }
228
+ block.thinking += msg.deltaThinking;
229
+ if (msg.deltaSignature) block.thinkingSignature = msg.deltaSignature;
230
+ stream.push({
231
+ type: "thinking_delta",
232
+ contentIndex: output.content.indexOf(block),
233
+ delta: msg.deltaThinking,
234
+ partial: output
235
+ });
236
+ }
237
+ if (msg.deltaText) {
238
+ markFirstToken();
239
+ endThinkingBlock();
240
+ const block = currentTextBlock ?? {
241
+ type: "text",
242
+ text: ""
243
+ };
244
+ if (currentTextBlock !== block) {
245
+ output.content.push(block);
246
+ currentTextBlock = block;
247
+ stream.push({
248
+ type: "text_start",
249
+ contentIndex: output.content.length - 1,
250
+ partial: output
251
+ });
252
+ }
253
+ block.text += msg.deltaText;
254
+ stream.push({
255
+ type: "text_delta",
256
+ contentIndex: output.content.indexOf(block),
257
+ delta: msg.deltaText,
258
+ partial: output
259
+ });
260
+ }
261
+ if (msg.deltaToolCalls.length > 0) {
262
+ markFirstToken();
263
+ endTextBlock();
264
+ endThinkingBlock();
265
+ for (const tc of msg.deltaToolCalls) {
266
+ const toolCallId = tc.id || activeToolCallId;
267
+ if (!toolCallId) continue;
268
+ let block = toolBlocks.get(toolCallId);
269
+ if (!block) {
270
+ block = {
271
+ type: "toolCall",
272
+ id: toolCallId,
273
+ name: tc.name,
274
+ arguments: {}
275
+ };
276
+ output.content.push(block);
277
+ toolBlocks.set(toolCallId, block);
278
+ toolPartialJson.set(toolCallId, "");
279
+ stream.push({
280
+ type: "toolcall_start",
281
+ contentIndex: output.content.length - 1,
282
+ partial: output
283
+ });
284
+ }
285
+ if (tc.name) block.name = tc.name;
286
+ activeToolCallId = toolCallId;
287
+ if (!tc.argumentsJson) continue;
288
+ const previousJson = toolPartialJson.get(toolCallId) ?? "";
289
+ const accumulated = tc.argumentsJson.startsWith(previousJson) ? tc.argumentsJson : previousJson + tc.argumentsJson;
290
+ const delta = accumulated.slice(previousJson.length);
291
+ toolPartialJson.set(toolCallId, accumulated);
292
+ const throttled = parseStreamingJsonThrottled(accumulated, toolLastParseLen.get(toolCallId) ?? 0);
293
+ if (throttled) {
294
+ block.arguments = throttled.value;
295
+ toolLastParseLen.set(toolCallId, throttled.parsedLen);
296
+ }
297
+ stream.push({
298
+ type: "toolcall_delta",
299
+ contentIndex: output.content.indexOf(block),
300
+ delta,
301
+ partial: output
302
+ });
303
+ }
304
+ }
305
+ if (msg.stopReason !== 0) latestStopReason = msg.stopReason;
306
+ if (msg.usage) {
307
+ output.usage.input = Number(msg.usage.inputTokens);
308
+ output.usage.output = Number(msg.usage.outputTokens);
309
+ output.usage.cacheRead = Number(msg.usage.cacheReadTokens);
310
+ output.usage.cacheWrite = Number(msg.usage.cacheWriteTokens);
311
+ output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
312
+ }
313
+ }
314
+ if (done) break;
315
+ }
316
+ endTextBlock();
317
+ endThinkingBlock();
318
+ for (const [id, block] of toolBlocks) {
319
+ block.arguments = parseStreamingJson(toolPartialJson.get(id));
320
+ stream.push({
321
+ type: "toolcall_end",
322
+ contentIndex: output.content.indexOf(block),
323
+ toolCall: block,
324
+ partial: output
325
+ });
326
+ }
327
+ const doneReason = toolBlocks.size > 0 ? "toolUse" : latestStopReason === 3 ? "length" : "stop";
328
+ output.stopReason = doneReason;
329
+ calculateCost(model, output.usage);
330
+ output.duration = performance.now() - startTime;
331
+ if (firstTokenTime) output.ttft = firstTokenTime - startTime;
332
+ stream.push({
333
+ type: "done",
334
+ reason: doneReason,
335
+ message: output
336
+ });
337
+ stream.end();
338
+ } catch (error$1) {
339
+ error("devin: stream failed", { error: String(error$1) });
340
+ const result = await finalize(error$1, {
341
+ api: model.api,
342
+ signal: options?.signal
343
+ });
344
+ output.stopReason = result.stopReason;
345
+ output.errorStatus = result.status;
346
+ output.errorId = result.id;
347
+ output.errorMessage = result.message;
348
+ output.duration = performance.now() - startTime;
349
+ if (firstTokenTime) output.ttft = firstTokenTime - startTime;
350
+ stream.push({
351
+ type: "error",
352
+ reason: result.stopReason,
353
+ error: output
354
+ });
355
+ stream.end();
356
+ }
357
+ })();
358
+ return stream;
359
+ };
360
+ function normalizeDevinSessionToken(apiKey) {
361
+ if (!apiKey) return "";
362
+ return apiKey.startsWith(DEVIN_SESSION_TOKEN_PREFIX) ? apiKey : `${DEVIN_SESSION_TOKEN_PREFIX}${apiKey}`;
363
+ }
364
+ async function fetchDevinAuthMetadata(apiKey, baseUrl, fetchImpl, signal) {
365
+ const request = create$1(GetUserJwtRequestSchema, { metadata: create$1(MetadataSchema, {
366
+ apiKey,
367
+ ideName: "windsurf",
368
+ ideVersion: DEVIN_IDE_VERSION,
369
+ extensionName: "windsurf",
370
+ extensionVersion: DEVIN_EXTENSION_VERSION,
371
+ locale: "en"
372
+ }) });
373
+ const response = await fetchImpl(`${baseUrl}${DEVIN_AUTH_PATH}`, {
374
+ method: "POST",
375
+ headers: {
376
+ "content-type": "application/proto",
377
+ "connect-protocol-version": "1",
378
+ accept: "*/*"
379
+ },
380
+ body: toBinary(GetUserJwtRequestSchema, request),
381
+ signal
382
+ });
383
+ const payload = new Uint8Array(await response.arrayBuffer());
384
+ if (!response.ok) throw new DevinApiError(`Devin auth error ${response.status} ${response.statusText}: ${new TextDecoder().decode(payload)}`, response.status);
385
+ const decoded = decodeDevinUserJwtResponse(payload);
386
+ if (!decoded.userJwt) throw new ProviderResponseError("Devin auth error: GetUserJwt returned an empty user JWT", {
387
+ provider: "devin",
388
+ kind: "runtime"
389
+ });
390
+ const customBaseUrl = decoded.customApiServerUrl.trim();
391
+ return {
392
+ userJwt: decoded.userJwt,
393
+ ...customBaseUrl ? { baseUrl: customBaseUrl.replace(/\/+$/, "") } : void 0
394
+ };
395
+ }
396
+ function decodeDevinUserJwtResponse(payload) {
397
+ try {
398
+ return fromBinary(GetUserJwtResponseSchema, payload);
399
+ } catch {
400
+ return fromBinary(GetUserJwtResponseSchema, gunzipSync(payload));
401
+ }
402
+ }
403
+ /**
404
+ * Build a {@link GetChatMessageRequest} for one Cascade turn. Auth rides inside
405
+ * `Metadata.apiKey`; the system prompt is the flattened `prompt` string and the
406
+ * conversation history maps to `chatMessagePrompts`.
407
+ */
408
+ function buildDevinChatRequest(model, context, options, apiKey, userJwt) {
409
+ const cascadeId = options?.conversationId ?? options?.sessionId ?? crypto.randomUUID();
410
+ const stopPatterns = options?.stopSequences && options.stopSequences.length > 0 ? [...DEVIN_DEFAULT_STOP_PATTERNS, ...options.stopSequences] : DEVIN_DEFAULT_STOP_PATTERNS;
411
+ const messages = transformMessages(context.messages, model);
412
+ return create$1(GetChatMessageRequestSchema, {
413
+ metadata: create$1(MetadataSchema, {
414
+ apiKey,
415
+ userJwt,
416
+ ideName: "windsurf",
417
+ ideVersion: DEVIN_IDE_VERSION,
418
+ extensionName: "windsurf",
419
+ extensionVersion: DEVIN_EXTENSION_VERSION,
420
+ locale: "en"
421
+ }),
422
+ prompt: normalizeSystemPrompts(context.systemPrompt).join("\n\n"),
423
+ chatMessagePrompts: buildChatMessagePrompts(messages, cascadeId, model),
424
+ chatModelUid: options?.chatModelUid ?? model.requestModelId ?? model.id,
425
+ requestType: 5,
426
+ plannerMode: 1,
427
+ toolChoice: create$1(ChatToolChoiceSchema, { choice: {
428
+ case: "optionName",
429
+ value: "auto"
430
+ } }),
431
+ systemPromptCacheOptions: create$1(PromptCacheOptionsSchema, { type: 1 }),
432
+ disableParallelToolCalls: true,
433
+ cascadeId,
434
+ executionId: crypto.randomUUID(),
435
+ configuration: create$1(CompletionConfigurationSchema, {
436
+ numCompletions: 1n,
437
+ maxTokens: BigInt(options?.maxTokens ?? model.maxTokens ?? 64e3),
438
+ maxNewlines: 200n,
439
+ temperature: options?.temperature ?? .4,
440
+ firstTemperature: options?.temperature ?? .4,
441
+ topK: 50n,
442
+ topP: options?.topP ?? 1,
443
+ stopPatterns,
444
+ fimEotProbThreshold: 1
445
+ }),
446
+ tools: (context.tools ?? []).map((tool) => create$1(ChatToolDefinitionSchema, {
447
+ name: tool.name,
448
+ description: tool.description,
449
+ jsonSchemaString: JSON.stringify(toolWireSchema(tool)),
450
+ strict: tool.strict ?? false
451
+ }))
452
+ });
453
+ }
454
+ /** Map omp `Message` history onto Cascade `ChatMessagePrompt`s (USER / SYSTEM / TOOL channels). */
455
+ function buildChatMessagePrompts(messages, cascadeId, model) {
456
+ const prompts = [];
457
+ for (const [index, msg] of messages.entries()) if (msg.role === "user" || msg.role === "developer") {
458
+ let promptText = "";
459
+ const images = [];
460
+ if (typeof msg.content === "string") promptText = msg.content;
461
+ else for (const part of msg.content) if (part.type === "text") promptText += part.text;
462
+ else if (part.type === "image") images.push(create$1(ImageDataSchema, {
463
+ base64Data: part.data,
464
+ mimeType: part.mimeType
465
+ }));
466
+ prompts.push(create$1(ChatMessagePromptSchema, {
467
+ messageId: deterministicUuid(`${cascadeId}\0${index}\0${msg.role}`),
468
+ source: 1,
469
+ prompt: promptText,
470
+ images
471
+ }));
472
+ } else if (msg.role === "assistant") {
473
+ const isNativeDevinMessage = msg.api === model.api && msg.provider === model.provider && msg.model === model.id;
474
+ let promptText = "";
475
+ let thinkingText = "";
476
+ let signature = "";
477
+ const toolCalls = [];
478
+ for (const part of msg.content) if (part.type === "text") promptText += `${part.text}${isDemotedThinking(part) ? "\n" : ""}`;
479
+ else if (part.type === "thinking") {
480
+ thinkingText += part.thinking;
481
+ if (isNativeDevinMessage && !signature && part.thinkingSignature) signature = part.thinkingSignature;
482
+ } else if (part.type === "toolCall") toolCalls.push(create$1(ChatToolCallSchema, {
483
+ id: part.id,
484
+ name: part.name,
485
+ argumentsJson: JSON.stringify(part.arguments)
486
+ }));
487
+ if (!promptText && !thinkingText && !signature && toolCalls.length === 0) continue;
488
+ prompts.push(create$1(ChatMessagePromptSchema, {
489
+ messageId: isNativeDevinMessage && msg.responseId ? msg.responseId : `bot-${deterministicUuid(`${cascadeId}\0${index}\0assistant`)}`,
490
+ source: 2,
491
+ prompt: promptText,
492
+ thinking: thinkingText,
493
+ signature,
494
+ signatureType: "",
495
+ toolCalls
496
+ }));
497
+ } else {
498
+ let resultText = "";
499
+ const images = [];
500
+ for (const part of msg.content) if (part.type === "text") resultText += part.text;
501
+ else if (part.type === "image") images.push(create$1(ImageDataSchema, {
502
+ base64Data: part.data,
503
+ mimeType: part.mimeType
504
+ }));
505
+ prompts.push(create$1(ChatMessagePromptSchema, {
506
+ messageId: deterministicUuid(`${cascadeId}\0${index}\0tool\0${msg.toolCallId}`),
507
+ source: 4,
508
+ toolCallId: msg.toolCallId,
509
+ toolResultIsError: msg.isError,
510
+ prompt: resultText,
511
+ images
512
+ }));
513
+ }
514
+ return prompts;
515
+ }
516
+ /**
517
+ * Parse a Connect end-of-stream JSON trailer and return its structured error
518
+ * when it carries `{ error: { code, message } }`, else `null`. The trailer is
519
+ * untrusted server output, so the shape is checked with guards rather than asserted.
520
+ */
521
+ function readConnectTrailerError(text) {
522
+ if (text.length === 0) return null;
523
+ let parsed;
524
+ try {
525
+ parsed = JSON.parse(text);
526
+ } catch {
527
+ return null;
528
+ }
529
+ if (!parsed || typeof parsed !== "object" || !("error" in parsed)) return null;
530
+ const err = parsed.error;
531
+ if (!err || typeof err !== "object") return null;
532
+ const code = "code" in err && typeof err.code === "string" ? err.code : "";
533
+ const message = "message" in err && typeof err.message === "string" ? err.message : "";
534
+ if (!code && !message) return null;
535
+ return {
536
+ code,
537
+ message,
538
+ formatted: `Devin stream error${code ? ` ${code}` : ""}: ${message}`
539
+ };
540
+ }
541
+ //#endregion
542
+ export { streamDevin };