@chatcode/chatcode-cli 3.0.4-rc.7 → 3.0.5-rc.1

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 (143) hide show
  1. package/README.i18n.yaml +6 -6
  2. package/README.md +10 -4
  3. package/README.zh.md +10 -4
  4. package/lib/bin.js +23 -9
  5. package/lib/{command-errors-Ca64Lgba.js → command-errors-CsRCh0gk.js} +12 -12
  6. package/lib/{command-trees-CVc4Xu_z.js → command-trees-CD_43rxX.js} +2 -2
  7. package/lib/{component-identity-6aEut5Yt.js → component-identity-DGA2-TeB.js} +3 -3
  8. package/lib/{dump-config-ZzrfvtnX.js → dump-config-D8kXfdTs.js} +1 -1
  9. package/lib/dump-config-DuCc-QB7.js +2 -0
  10. package/lib/{dump-config-schema-BlO-eZ-J.js → dump-config-schema-CtZbroi6.js} +2 -2
  11. package/lib/{extension-events-C7MUpqVE.js → extension-events-D0BjYRqT.js} +21 -21
  12. package/lib/{host-access-CLbyAGT5.js → host-access-DLJjuR07.js} +1 -1
  13. package/lib/{keymap-82JwLLHe.js → keymap-C4cs2IBN.js} +2 -2
  14. package/lib/{plugin-BlQlWIR5.js → plugin-CGtTByud.js} +801 -456
  15. package/lib/{plugin-BZdazFXS.js → plugin-CYw-MBRn.js} +1 -1
  16. package/lib/{profile-boot-B0aEEQIR.js → profile-boot-CffsubnV.js} +7 -7
  17. package/lib/profile-boot.js +1 -1
  18. package/lib/{scenes-BNS0ZFyQ.js → scenes-CbAGK5Uy.js} +3 -3
  19. package/lib/{settings-sections-CXH24cu5.js → settings-sections-DYKDa04e.js} +3 -3
  20. package/lib/{statusBarSettings-BAMzn8fX.js → statusBarSettings-T1m8xad4.js} +3 -3
  21. package/lib/{themes-DXUIvP7m.js → themes-BY2ui1Dv.js} +12 -12
  22. package/lib/tui-compat-command-trees.js +1 -1
  23. package/lib/tui-compat-extensions.js +3 -3
  24. package/lib/tui-compat-plugin-host.js +5 -5
  25. package/lib/tui-compat-scenes.js +1 -1
  26. package/lib/tui-compat-settings-sections.js +1 -1
  27. package/lib/tui-compat-working-activity.js +1 -1
  28. package/lib/tui-compat-workspaces.js +1 -1
  29. package/lib/tui-compat.js +7 -7
  30. package/lib/types/bin.d.ts +9 -0
  31. package/lib/types/tui-compat.d.ts +1 -1
  32. package/lib/types/web-instance-process.d.ts +20 -0
  33. package/lib/{web-instance-DbP7IHPv.js → web-instance-D_Ppi2Zo.js} +176 -14
  34. package/lib/{web-instance-B0jec7cq.js → web-instance-amvCJWnq.js} +1 -1
  35. package/lib/{workspaces-CUJXNU5W.js → workspaces-D5VKbESy.js} +2 -2
  36. package/package.json +28 -29
  37. package/runtime/manifest.json +2 -2
  38. package/runtime/node_modules/@deepseek-ai/dsh-agent-default-model/lib/index.js +7 -3
  39. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/client.js +11 -3
  40. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/contract/snapshot.d.ts +1 -0
  41. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/assistant-stream.d.ts +2 -0
  42. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/assistant-stream.js +4 -0
  43. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/session.js +10 -3
  44. package/runtime/node_modules/@deepseek-ai/dsh-app-boot/lib/index.js +32 -11
  45. package/runtime/node_modules/@deepseek-ai/dsh-atomic-write/lib/index.js +62 -11
  46. package/runtime/node_modules/@deepseek-ai/dsh-atomic-write/lib/types/darwin-lock.d.ts +7 -0
  47. package/runtime/node_modules/@deepseek-ai/dsh-atomic-write/lib/types/index.d.ts +7 -2
  48. package/runtime/node_modules/@deepseek-ai/dsh-atomic-write/lib/types/linux-lock.d.ts +1 -1
  49. package/runtime/node_modules/@deepseek-ai/dsh-client-locale/lib/client.js +7 -7
  50. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-agent-preset/lib/client.js +62 -62
  51. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-approval/lib/client.js +10 -10
  52. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-attachment/lib/client.js +49 -49
  53. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-chat/lib/client.js +204 -204
  54. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-commands/lib/client.js +16 -16
  55. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js +159 -157
  56. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/types/client/service.d.ts +4 -2
  57. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-cordis/lib/client.js +74 -74
  58. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-deliverables/lib/client.js +129 -123
  59. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-deliverables/lib/index.js +19 -14
  60. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-deliverables/lib/types/changes.d.ts +2 -2
  61. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-deliverables/lib/types/client/Deliverables.d.ts +1 -2
  62. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-deliverables/lib/types/client/locales.d.ts +2 -1
  63. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-deliverables/lib/types/client/present-open.d.ts +1 -1
  64. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-deliverables/package.json +2 -4
  65. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-directory-picker-browse/lib/client.js +39 -39
  66. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-goal/lib/client.js +16 -16
  67. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-input-trigger/lib/client.js +23 -23
  68. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-jobs/lib/client.js +37 -37
  69. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-layout/lib/client.js +9 -9
  70. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-message-feedback/lib/client.js +12 -12
  71. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/client.js +119 -32
  72. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/types/client/catalog.d.ts +13 -0
  73. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/types/client/directory.d.ts +2 -0
  74. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/types/client/effort-preferences.d.ts +20 -0
  75. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/types/client/slots.d.ts +2 -1
  76. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-open-in-app/lib/client.js +8 -8
  77. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-permission-presets/lib/client.js +18 -18
  78. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-plan/lib/client.js +22 -22
  79. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-plugin-manager/lib/client.js +128 -128
  80. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-schedule/lib/client.js +182 -182
  81. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-account/lib/client.js +130 -130
  82. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/client.js +50 -50
  83. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-models/lib/client.js +88 -88
  84. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-plugin-inventory/lib/client.js +36 -36
  85. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-plugins/lib/client.js +13 -13
  86. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-subagent/lib/client.js +27 -27
  87. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-shortcuts/lib/client.js +42 -42
  88. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-sidebar/lib/client.js +44 -46
  89. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-sidebar-browser/lib/client.js +25 -25
  90. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-sidebar-documentpreview/lib/client.excel.js +9 -9
  91. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-sidebar-documentpreview/lib/client.js +70 -70
  92. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-sidebar-documentpreview/lib/client.pdf.js +9 -9
  93. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-sidebar-files/lib/client.js +18 -18
  94. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-sidebar-right/lib/client.js +26 -26
  95. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-sidebar-terminal/lib/client.js +16 -16
  96. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-sidebar-terminal/lib/client.terminal.js +11 -11
  97. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-skill/lib/client.js +20 -20
  98. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-subagent/lib/client.js +37 -37
  99. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-theme/lib/client.js +27 -27
  100. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-tool/lib/client.js +95 -95
  101. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-trajectory/lib/client.js +197 -197
  102. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-user-questions/lib/client.js +49 -49
  103. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workflow-run/lib/client.js +24 -24
  104. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/client.js +656 -152
  105. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/ArchivedSessions.d.ts +9 -2
  106. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/locales.d.ts +46 -0
  107. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/session-actions/DeleteSession.d.ts +9 -10
  108. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/session-actions/deletion.d.ts +57 -0
  109. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/package.json +2 -0
  110. package/runtime/node_modules/@deepseek-ai/dsh-experimental-client-ui-agent-team/lib/client.js +32 -32
  111. package/runtime/node_modules/@deepseek-ai/dsh-experimental-client-ui-voice-input/lib/client.js +24 -24
  112. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/index.js +899 -453
  113. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/adapter.d.ts +4 -20
  114. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/chat-completions/adapter.d.ts +8 -0
  115. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/chat-completions/serialize.d.ts +10 -0
  116. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/chat-completions/sse.d.ts +24 -0
  117. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/chat-completions/translate.d.ts +37 -0
  118. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/chat-completions/types.d.ts +159 -0
  119. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/file-store.d.ts +3 -0
  120. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/files-api.d.ts +4 -0
  121. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/index.d.ts +1 -0
  122. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/protocol-adapter.d.ts +41 -0
  123. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/protocol.d.ts +35 -0
  124. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/transport.d.ts +2 -1
  125. package/runtime/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/types/types.d.ts +2 -2
  126. package/runtime/node_modules/@deepseek-ai/dsh-mcp-client/lib/index.js +5 -4
  127. package/runtime/node_modules/@deepseek-ai/dsh-session-log-export/lib/client.js +4 -4
  128. package/runtime/node_modules/@deepseek-ai/dsh-session-log-export/lib/index.js +1 -1
  129. package/runtime/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/index.js +2 -2
  130. package/runtime/node_modules/@deepseek-ai/dsh-tool-cordis/lib/types/api-catalog.js +12 -10
  131. package/runtime/node_modules/@deepseek-ai/dsh-workspace-changes/lib/index.js +208 -39
  132. package/runtime/node_modules/@deepseek-ai/dsh-workspace-changes/lib/types/archive.d.ts +47 -0
  133. package/runtime/node_modules/@deepseek-ai/dsh-workspace-changes/lib/types/archive.js +129 -0
  134. package/runtime/node_modules/@deepseek-ai/dsh-workspace-changes/lib/types/index.d.ts +2 -0
  135. package/runtime/node_modules/@deepseek-ai/dsh-workspace-changes/lib/types/index.js +31 -8
  136. package/runtime/node_modules/@deepseek-ai/dsh-workspace-changes/lib/types/recorder.d.ts +7 -2
  137. package/runtime/node_modules/@deepseek-ai/dsh-workspace-changes/lib/types/recorder.js +35 -19
  138. package/runtime/node_modules/@deepseek-ai/dsh-workspace-changes/lib/types/types.d.ts +11 -10
  139. package/runtime/node_modules/@deepseek-ai/dsh-workspace-changes/package.json +1 -0
  140. package/scripts/link-embedded-runtime.mjs +1 -1
  141. package/lib/dump-config-CDixiJNt.js +0 -2
  142. package/lib/{home-migration-BjDmRwBB.js → home-migration-lRjtl2fP.js} +1 -1
  143. package/lib/{startup-diagnostics-C_hRCp-q.js → startup-diagnostics-4mLHYTFc.js} +1 -1
@@ -1,6 +1,6 @@
1
1
  import z from "@deepseek-ai/schemastery";
2
2
  import { isVolatile } from "@deepseek-ai/cosmokit";
3
- import { IMAGE_OFFLOAD_REQUIRED_CODE, LlmAdapter, LlmError, ProviderRequestId, ReasoningEffortId, RetryPolicySchema, ToolCallId, attributionHeaders, contentHasImage, isContextWindowExceededError, isQuotaExceededError, offloadedImageText, projectOffloadedImages, requestImageHandleText, requiredImageOffload, resolveImageAttachmentAccess, resolveRetryPolicy, textOnlyImageText } from "@deepseek-ai/dsh-llm";
3
+ import { EMPTY_RESPONSE_CODE, IMAGE_OFFLOAD_REQUIRED_CODE, LlmAdapter, LlmError, ProviderRequestId, ReasoningEffortId, RetryPolicySchema, ToolCallId, attributionHeaders, contentHasImage, isContextWindowExceededError, isQuotaExceededError, offloadedImageText, projectOffloadedImages, requestImageHandleText, requiredImageOffload, resolveImageAttachmentAccess, resolveRetryPolicy, textOnlyImageText } from "@deepseek-ai/dsh-llm";
4
4
  import { MAX_TIMER_DELAY_MS, deadline, idleWatchdog, timeoutOf } from "@deepseek-ai/dsh-timeout";
5
5
  import { ImageVariantId, longEdgeDimensions, requestImageDimensions } from "@deepseek-ai/dsh-attachment";
6
6
  import { createHash } from "node:crypto";
@@ -9,8 +9,9 @@ import { dirname, join } from "node:path";
9
9
  import { withFileLock, writeFileAtomic } from "@deepseek-ai/dsh-atomic-write";
10
10
  import { resolveDshHome } from "@deepseek-ai/dsh-home-paths";
11
11
  import { EventSourceParserStream } from "eventsource-parser/stream";
12
+ import { assertNever, deepEqualJson } from "@deepseek-ai/dsh-util-values";
13
+ import { brandString } from "@deepseek-ai/dsh-brand";
12
14
  import { getOrCreateAnonymousUserId } from "@deepseek-ai/dsh-anonymous-user-id";
13
- import { deepEqualJson } from "@deepseek-ai/dsh-util-values";
14
15
  //#region lib/types/defaults.js
15
16
  /** Shared provider limits and Chat Files API defaults. */
16
17
  /** Default maximum idle interval while an adapter stream read is outstanding. */
@@ -638,6 +639,7 @@ function providerErrorDetail$1(value) {
638
639
  }
639
640
  /** Direct Files client retaining the configured URL root and refusing redirects before credentials can leave its origin. */
640
641
  var DeepSeekFilesClient = class {
642
+ protocol;
641
643
  baseURL;
642
644
  authHeaders;
643
645
  fetchImpl;
@@ -645,17 +647,33 @@ var DeepSeekFilesClient = class {
645
647
  * @param options - endpoint, authentication headers, and optional test transport.
646
648
  */
647
649
  constructor(options) {
650
+ this.protocol = options.protocol ?? "messages";
648
651
  this.authHeaders = options.headers;
649
652
  this.fetchImpl = options.fetch ?? globalThis.fetch;
650
- this.baseURL = messagesApiRoot(options.baseURL);
653
+ this.baseURL = this.protocol === "messages" ? messagesApiRoot(options.baseURL) : options.baseURL.replace(/\/+$/u, "");
654
+ }
655
+ parseFile(value, operation) {
656
+ if (this.protocol === "messages") return parseFileObject(value, operation);
657
+ if (value === null || typeof value !== "object" || Array.isArray(value)) throw invalidResponse(operation);
658
+ const wire = value;
659
+ if (typeof wire.id !== "string" || wire.id.length === 0 || wire.object !== "file" || typeof wire.bytes !== "number" || !Number.isSafeInteger(wire.bytes) || wire.bytes < 0 || typeof wire.created_at !== "number" || !Number.isSafeInteger(wire.created_at) || wire.created_at < 0 || typeof wire.filename !== "string" || wire.filename.length === 0 || wire.purpose !== "user_data" || wire.expires_at !== void 0 && (typeof wire.expires_at !== "number" || !Number.isSafeInteger(wire.expires_at) || wire.expires_at < 0)) throw invalidResponse(operation);
660
+ return {
661
+ id: DeepSeekFileId(wire.id),
662
+ bytes: wire.bytes,
663
+ createdAt: wire.created_at,
664
+ filename: wire.filename,
665
+ ...typeof wire.expires_at === "number" ? { expiresAt: wire.expires_at } : {}
666
+ };
651
667
  }
652
668
  async request(path, init, signal) {
653
669
  let response;
654
670
  try {
655
671
  const headers = new Headers(attributionHeaders());
656
672
  for (const [name, value] of Object.entries(this.authHeaders)) headers.set(name, value);
657
- headers.set("anthropic-version", "2023-06-01");
658
- headers.set("anthropic-beta", MESSAGES_FILES_BETA);
673
+ if (this.protocol === "messages") {
674
+ headers.set("anthropic-version", "2023-06-01");
675
+ headers.set("anthropic-beta", MESSAGES_FILES_BETA);
676
+ }
659
677
  response = await this.fetchImpl(`${this.baseURL}${path}`, {
660
678
  ...init,
661
679
  redirect: "error",
@@ -684,13 +702,22 @@ var DeepSeekFilesClient = class {
684
702
  if (input.data.byteLength > 134217728) throw new LlmError("DeepSeek Files API upload exceeds 128 MiB.", "INVALID_REQUEST");
685
703
  if (!Number.isSafeInteger(input.expiresAfterSeconds) || input.expiresAfterSeconds < 3600 || input.expiresAfterSeconds > 2592e3) throw new LlmError("DeepSeek file expiry must be between 3600 and 2592000 seconds.", "INVALID_REQUEST");
686
704
  const form = new FormData();
705
+ if (this.protocol === "chat-completions") form.set("purpose", "user_data");
687
706
  form.set("expires_after[anchor]", "created_at");
688
707
  form.set("expires_after[seconds]", String(input.expiresAfterSeconds));
689
708
  form.set("file", new Blob([Uint8Array.from(input.data).buffer], { type: input.mediaType }), input.filename);
690
- const file = parseFileObject(await responseJson(await this.request("/files", {
709
+ const response = await this.request("/files", {
691
710
  method: "POST",
692
711
  body: form
693
- }, input.signal), "upload"), "upload");
712
+ }, input.signal);
713
+ const file = this.parseFile(await responseJson(response, "upload"), "upload");
714
+ if (this.protocol === "chat-completions") {
715
+ if (file.expiresAt === void 0) throw invalidResponse("upload");
716
+ return {
717
+ ...file,
718
+ expiresAt: file.expiresAt
719
+ };
720
+ }
694
721
  return {
695
722
  ...file,
696
723
  expiresAt: file.createdAt + input.expiresAfterSeconds
@@ -702,17 +729,17 @@ var DeepSeekFilesClient = class {
702
729
  * @returns the validated page with null cursors omitted.
703
730
  */
704
731
  async list(options = {}) {
705
- const query = new URLSearchParams();
706
- if (options.after !== void 0) query.set("after_id", options.after);
732
+ const query = new URLSearchParams(this.protocol === "chat-completions" ? { purpose: "user_data" } : {});
733
+ if (options.after !== void 0) query.set(this.protocol === "messages" ? "after_id" : "after", options.after);
707
734
  if (options.limit !== void 0) query.set("limit", String(options.limit));
708
735
  const value = await responseJson(await this.request(`/files?${query.toString()}`, { method: "GET" }, options.signal), "list");
709
736
  if (value === null || typeof value !== "object" || Array.isArray(value)) throw invalidResponse("list");
710
737
  const wire = value;
711
738
  const firstId = wire.first_id ?? void 0;
712
739
  const lastId = wire.last_id ?? void 0;
713
- if (!Array.isArray(wire.data) || typeof wire.has_more !== "boolean" || firstId !== void 0 && typeof firstId !== "string" || lastId !== void 0 && typeof lastId !== "string") throw invalidResponse("list");
740
+ if (this.protocol === "chat-completions" && wire.object !== "list" || !Array.isArray(wire.data) || typeof wire.has_more !== "boolean" || firstId !== void 0 && typeof firstId !== "string" || lastId !== void 0 && typeof lastId !== "string") throw invalidResponse("list");
714
741
  return {
715
- data: wire.data.map((item) => parseFileObject(item, "list")),
742
+ data: wire.data.map((item) => this.parseFile(item, "list")),
716
743
  ...typeof firstId === "string" ? { firstId: DeepSeekFileId(firstId) } : {},
717
744
  ...typeof lastId === "string" ? { lastId: DeepSeekFileId(lastId) } : {},
718
745
  hasMore: wire.has_more
@@ -725,7 +752,8 @@ var DeepSeekFilesClient = class {
725
752
  * @returns the validated file object.
726
753
  */
727
754
  async retrieve(fileId, signal) {
728
- return parseFileObject(await responseJson(await this.request(`/files/${encodeURIComponent(fileId)}`, { method: "GET" }, signal), "retrieve"), "retrieve");
755
+ const response = await this.request(`/files/${encodeURIComponent(fileId)}`, { method: "GET" }, signal);
756
+ return this.parseFile(await responseJson(response, "retrieve"), "retrieve");
729
757
  }
730
758
  /**
731
759
  * Delete one provider file.
@@ -736,7 +764,7 @@ var DeepSeekFilesClient = class {
736
764
  const value = await responseJson(await this.request(`/files/${encodeURIComponent(fileId)}`, { method: "DELETE" }, signal), "delete");
737
765
  if (value === null || typeof value !== "object" || Array.isArray(value)) throw invalidResponse("delete");
738
766
  const wire = value;
739
- if (wire.id !== fileId || wire.type !== "file_deleted") throw invalidResponse("delete");
767
+ if (wire.id !== fileId || (this.protocol === "messages" ? wire.type !== "file_deleted" : wire.object !== "file" || wire.deleted !== true)) throw invalidResponse("delete");
740
768
  }
741
769
  };
742
770
  //#endregion
@@ -910,8 +938,8 @@ var DeepSeekUploadIndex = class {
910
938
  const MAX_IMAGE_BYTES = 32 * 1024 * 1024;
911
939
  const OWNED_FILE_PREFIX = "dsh-";
912
940
  /** The Files resource's parent URL identifies the upload namespace. */
913
- function fileScope(connection) {
914
- return deepSeekFileScope(messagesApiRoot(connection.baseURL), JSON.stringify(Object.entries(connection.headers).sort(([left], [right]) => left.localeCompare(right))));
941
+ function fileScope(connection, protocol) {
942
+ return deepSeekFileScope(protocol === "messages" ? messagesApiRoot(connection.baseURL) : `chat-completions:${connection.baseURL.replace(/\/+$/u, "")}`, JSON.stringify(Object.entries(connection.headers).sort(([left], [right]) => left.localeCompare(right))));
915
943
  }
916
944
  function abortReason(signal) {
917
945
  const reason = signal.reason;
@@ -964,6 +992,7 @@ function filename(version) {
964
992
  }
965
993
  /** User-scoped durable file-id reuse for the DeepSeek route. */
966
994
  var DeepSeekFileStore = class {
995
+ protocol;
967
996
  index;
968
997
  now;
969
998
  fetchImpl;
@@ -972,12 +1001,14 @@ var DeepSeekFileStore = class {
972
1001
  * @param options - testable index, clock, and transport boundaries.
973
1002
  */
974
1003
  constructor(options = {}) {
1004
+ this.protocol = options.protocol ?? "messages";
975
1005
  this.index = options.index ?? new DeepSeekUploadIndex();
976
1006
  this.now = options.now ?? Date.now;
977
1007
  this.fetchImpl = options.fetch;
978
1008
  }
979
1009
  client(connection) {
980
1010
  return new DeepSeekFilesClient({
1011
+ protocol: this.protocol,
981
1012
  baseURL: connection.baseURL,
982
1013
  headers: connection.headers,
983
1014
  ...this.fetchImpl === void 0 ? {} : { fetch: this.fetchImpl }
@@ -993,7 +1024,7 @@ var DeepSeekFileStore = class {
993
1024
  */
994
1025
  ensureUploaded(version, connection, policy, signal) {
995
1026
  signal?.throwIfAborted();
996
- const key = `${fileScope(connection)}\0${version.variantId}`;
1027
+ const key = `${fileScope(connection, this.protocol)}\0${version.variantId}`;
997
1028
  let active = this.inflight.get(key);
998
1029
  if (active?.controller.signal.aborted) {
999
1030
  this.inflight.delete(key);
@@ -1022,7 +1053,7 @@ var DeepSeekFileStore = class {
1022
1053
  }
1023
1054
  async ensureUploadedOnce(version, connection, policy, signal) {
1024
1055
  if (version.bytes > 33554432) throw new LlmError("DeepSeek image exceeds the 32 MiB per-image limit.", "INVALID_REQUEST");
1025
- const scope = fileScope(connection);
1056
+ const scope = fileScope(connection, this.protocol);
1026
1057
  const now = this.now();
1027
1058
  const marginMs = policy.refreshMarginSeconds * 1e3;
1028
1059
  const cached = await this.index.get(scope, version.variantId, now, marginMs);
@@ -1074,7 +1105,7 @@ var DeepSeekFileStore = class {
1074
1105
  * @param connection - endpoint and API-key snapshot.
1075
1106
  */
1076
1107
  async invalidate(version, fileId, connection) {
1077
- await this.index.remove(fileScope(connection), version.variantId, fileId);
1108
+ await this.index.remove(fileScope(connection, this.protocol), version.variantId, fileId);
1078
1109
  }
1079
1110
  /**
1080
1111
  * Delete the indexed remote file for one attachment and remove its local mapping.
@@ -1085,7 +1116,7 @@ var DeepSeekFileStore = class {
1085
1116
  * @returns whether an indexed file existed and was deleted.
1086
1117
  */
1087
1118
  async release(version, connection, policy, signal) {
1088
- const scope = fileScope(connection);
1119
+ const scope = fileScope(connection, this.protocol);
1089
1120
  const record = await this.index.get(scope, version.variantId, this.now(), policy.refreshMarginSeconds * 1e3);
1090
1121
  if (record === void 0) return false;
1091
1122
  await this.client(connection).delete(record.fileId, signal);
@@ -1137,7 +1168,7 @@ var DeepSeekFileStore = class {
1137
1168
  total += deleted;
1138
1169
  if (deleted < 1e3) break;
1139
1170
  }
1140
- await this.index.clear(fileScope(connection));
1171
+ await this.index.clear(fileScope(connection, this.protocol));
1141
1172
  return total;
1142
1173
  }
1143
1174
  };
@@ -1452,177 +1483,465 @@ async function prepareFileIds(messages, versions, files) {
1452
1483
  return ids;
1453
1484
  }
1454
1485
  //#endregion
1455
- //#region lib/types/replay.js
1456
- /** Minimal native thinking metadata; durable Harness blocks own all response text. */
1457
- /** Reject malformed JSON objects at provider and durable-data reads.
1458
- * @param value - untrusted decoded JSON.
1459
- * @param code - owning failure category.
1460
- * @returns the validated object.
1461
- */
1462
- function object(value, code = "MALFORMED_RESPONSE") {
1463
- if (typeof value !== "object" || value === null || Array.isArray(value)) throw new LlmError("DeepSeek Messages expected a JSON object", code);
1464
- return value;
1465
- }
1466
- /** Construct response metadata without duplicating the assistant text.
1467
- * @param model - requested model identity.
1468
- * @param blocks - metadata in emitted block order.
1469
- * @returns the versioned envelope persisted by the existing assembler.
1486
+ //#region lib/types/transport.js
1487
+ /** Normalize HTTP and in-band Messages errors into provider-neutral failures. */
1488
+ /** Read only provider error fields used by bounded Files recovery.
1489
+ * @param raw - decoded HTTP error response.
1490
+ * @returns code, type, and message text, without unrelated response fields.
1470
1491
  */
1471
- function replayState(model, blocks) {
1472
- return {
1473
- response: {
1474
- kind: "deepseek-messages",
1475
- version: 1,
1476
- model
1477
- },
1478
- blocks
1479
- };
1492
+ function providerErrorDetail(raw) {
1493
+ const error = typeof raw === "object" && raw !== null && "error" in raw ? raw.error : void 0;
1494
+ if (typeof error !== "object" || error === null) return "";
1495
+ const fields = error;
1496
+ return [
1497
+ fields.code,
1498
+ fields.type,
1499
+ fields.message
1500
+ ].filter((value) => typeof value === "string").join(" ");
1480
1501
  }
1481
- /** Validate native replay, discarding unusable metadata before serializing durable content.
1482
- * @param message - durable assistant content and source metadata.
1483
- * @param model - target model; cross-model signatures are not portable.
1484
- * @param onDegrade - diagnostic for unusable metadata; receives no message content or signatures.
1485
- * @returns index-aligned metadata, absent for foreign, cross-model or degraded history.
1502
+ /** Classify a provider error without trusting arbitrary response fields.
1503
+ * @param raw - decoded response or in-band error event.
1504
+ * @param status - HTTP status when the error preceded streaming.
1505
+ * @param headers - response headers for retry delay and request identity.
1506
+ * @param protocol - API family used in fallback diagnostics; defaults to Messages.
1507
+ * @returns a stable error consumed by LlmRuntime and llm-retry.
1486
1508
  */
1487
- function readReplay(message, model, onDegrade) {
1488
- try {
1489
- return validateReplay(message, model);
1490
- } catch (error) {
1491
- /* v8 ignore next -- the validator only throws INVALID_REPLAY_STATE; preserve future non-replay failures. */
1492
- if (!(error instanceof LlmError) || error.code !== "INVALID_REPLAY_STATE") throw error;
1493
- onDegrade?.(error.message);
1494
- return;
1495
- }
1496
- }
1497
- function validateReplay(message, model) {
1498
- if (message.source.kind !== "model" || message.source.replayState === void 0) return void 0;
1499
- const fail = (detail) => {
1500
- throw new LlmError(`DeepSeek Messages replay: ${detail}`, "INVALID_REPLAY_STATE");
1501
- };
1502
- const envelope = object(message.source.replayState, "INVALID_REPLAY_STATE");
1503
- const response = object(envelope.response, "INVALID_REPLAY_STATE");
1504
- if (response.kind !== "deepseek-messages" || response.version !== 1) return fail("unsupported kind or version");
1505
- if (response.model !== message.source.model) return fail("model does not match assistant source model");
1506
- if (!Array.isArray(envelope.blocks) || envelope.blocks.length !== message.content.length) return fail("block count mismatch");
1507
- const blocks = envelope.blocks.map((value, index) => {
1508
- const block = object(value, "INVALID_REPLAY_STATE");
1509
- if (block.type !== message.content[index]?.type || block.type !== "text" && block.type !== "reasoning" && block.type !== "tool-call") return fail("block type mismatch");
1510
- if (block.signature !== void 0 && (block.type !== "reasoning" || typeof block.signature !== "string")) return fail("invalid signature");
1511
- return {
1512
- type: block.type,
1513
- ...typeof block.signature === "string" ? { signature: block.signature } : {}
1514
- };
1509
+ function providerError(raw, status, headers, protocol = "Messages") {
1510
+ const envelope = typeof raw === "object" && raw !== null ? raw : {};
1511
+ const error = typeof envelope.error === "object" && envelope.error !== null ? envelope.error : {};
1512
+ const message = typeof error.message === "string" ? error.message : `DeepSeek ${protocol} request failed (${status ?? "stream error"})`;
1513
+ const type = typeof error.type === "string" ? error.type : "";
1514
+ const detail = `${type} ${typeof error.code === "string" ? error.code : ""} ${message}`;
1515
+ let code;
1516
+ if (status === 401 || status === 403 || ["authentication_error", "permission_error"].includes(type)) code = "AUTH";
1517
+ else if (isQuotaExceededError(detail) || status === 402) code = "QUOTA";
1518
+ else if (status === 429 || type === "rate_limit_error") code = "RATE_LIMIT";
1519
+ else if (isContextWindowExceededError(detail)) code = "CONTEXT_WINDOW_EXCEEDED";
1520
+ else if (status === 400 || status === 413 || type === "invalid_request_error") code = "INVALID_REQUEST";
1521
+ else if (status !== void 0 && status >= 500 || ["api_error", "overloaded_error"].includes(type)) code = "SERVER";
1522
+ else code = status === void 0 ? "SERVER" : `HTTP_${status}`;
1523
+ const retry = headers?.get("retry-after");
1524
+ const delay = retry == null ? NaN : /^\d+(?:\.\d+)?$/u.test(retry) ? Number(retry) * 1e3 : Date.parse(retry) - Date.now();
1525
+ const id = headers?.get("request-id") ?? headers?.get("x-request-id") ?? headers?.get("x-deepseek-request-id");
1526
+ return new LlmError(message, code, {
1527
+ ...status === void 0 ? {} : { status },
1528
+ ...id ? { requestId: ProviderRequestId(id) } : {},
1529
+ ...Number.isFinite(delay) && delay > 0 ? { providerRetryAfterMs: delay } : {}
1515
1530
  });
1516
- return response.model === model ? blocks : void 0;
1517
1531
  }
1518
1532
  //#endregion
1519
- //#region lib/types/serialize.js
1520
- /** Map system snapshots, tool changes, and conversation turns to Messages using the configured route capability. */
1521
- function unsupported(type) {
1522
- throw new LlmError(`DeepSeek Messages cannot represent ${type}`, "UNSUPPORTED_CONTENT");
1523
- }
1524
- /** Historical arguments that Messages cannot represent use empty input; durable content stays unchanged. */
1525
- function toolInput(raw) {
1526
- let value;
1527
- try {
1528
- value = JSON.parse(raw);
1529
- } catch (_invalidToolHistoryJson) {
1530
- return {};
1531
- }
1532
- return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
1533
- }
1534
- function assistant(message, model, onReplayDegrade) {
1535
- const replay = readReplay(message, model, onReplayDegrade);
1536
- return message.content.map((block, index) => {
1537
- switch (block.type) {
1538
- case "text": return {
1539
- type: "text",
1540
- text: block.text
1541
- };
1542
- case "reasoning": return {
1543
- type: "thinking",
1544
- thinking: block.text,
1545
- ...replay?.[index]?.signature === void 0 ? {} : { signature: replay[index].signature }
1546
- };
1547
- case "tool-call": return {
1548
- type: "tool_use",
1549
- id: block.id,
1550
- name: block.name,
1551
- input: toolInput(block.arguments)
1552
- };
1553
- default: return unsupported(`assistant content ${block.type}`);
1533
+ //#region lib/types/protocol-adapter.js
1534
+ /** Shared cancellation, image recovery, authentication, and delivery lifecycle for DeepSeek protocols. */
1535
+ var __addDisposableResource = function(env, value, async) {
1536
+ if (value !== null && value !== void 0) {
1537
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
1538
+ var dispose, inner;
1539
+ if (async) {
1540
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
1541
+ dispose = value[Symbol.asyncDispose];
1554
1542
  }
1555
- });
1556
- }
1557
- /** Serialize one complete request using already prepared image bytes.
1558
- * User and tool-result content omits reasoning and tool-call blocks.
1559
- * Empty user messages are skipped; empty tool results retain their call ids.
1560
- * Developer messages, already projected for this route by `LlmRuntime`, become
1561
- * system-role updates after the preceding user turn, with tool changes as
1562
- * `tool_addition` and `tool_removal` references to the declared tool.
1563
- * @param options - provider-neutral request.
1564
- * @param connection - validated defaults and thinking policy.
1565
- * @param history - image-projected history with complete system snapshots; durable messages remain unchanged.
1566
- * @param images - request versions for retained images.
1567
- * @param access - execution-world paths for image descriptions.
1568
- * @param onReplayDegrade - diagnostic for discarded native replay metadata.
1569
- * @param fileIds - resolved Files references; omission selects inline image bytes.
1570
- * @returns the Messages API JSON body.
1571
- */
1572
- function serialize(options, connection, history, images, access, onReplayDegrade, fileIds) {
1573
- const model = connection.models.find((entry) => entry.id === options.model);
1574
- const inHistory = model?.systemPromptUpdate === "in-history";
1575
- const input = (blocks) => blocks.flatMap((block) => {
1576
- if (block.type === "text") return block.text ? [{
1577
- type: "text",
1578
- text: block.text
1579
- }] : [];
1580
- if (block.type === "reasoning" || block.type === "tool-call") return [];
1581
- if (block.type !== "image") return unsupported(`user/tool-result content ${block.type}`);
1582
- const version = images.get(block.attachment.attachmentId);
1583
- if (version === void 0) throw new LlmError("DeepSeek Messages request image is missing", "INVALID_REQUEST");
1584
- const fileId = fileIds?.get(block.attachment.attachmentId);
1585
- if (fileIds !== void 0 && fileId === void 0) throw new LlmError("DeepSeek Messages request file id is missing", "INVALID_REQUEST");
1586
- return [{
1587
- type: "text",
1588
- text: requestImageHandleText(block.attachment, version, access(block.attachment))
1589
- }, fileId === void 0 ? {
1590
- type: "image",
1591
- source: {
1592
- type: "base64",
1593
- media_type: version.mediaType,
1594
- data: Buffer.from(version.data).toString("base64")
1543
+ if (dispose === void 0) {
1544
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
1545
+ dispose = value[Symbol.dispose];
1546
+ if (async) inner = dispose;
1547
+ }
1548
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
1549
+ if (inner) dispose = function() {
1550
+ try {
1551
+ inner.call(this);
1552
+ } catch (e) {
1553
+ return Promise.reject(e);
1595
1554
  }
1596
- } : {
1597
- type: "image",
1598
- source: {
1599
- type: "file",
1600
- file_id: fileId
1555
+ };
1556
+ env.stack.push({
1557
+ value,
1558
+ dispose,
1559
+ async
1560
+ });
1561
+ } else if (async) env.stack.push({ async: true });
1562
+ return value;
1563
+ };
1564
+ var __disposeResources = (function(SuppressedError) {
1565
+ return function(env) {
1566
+ function fail(e) {
1567
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
1568
+ env.hasError = true;
1569
+ }
1570
+ var r, s = 0;
1571
+ function next() {
1572
+ while (r = env.stack.pop()) try {
1573
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
1574
+ if (r.dispose) {
1575
+ var result = r.dispose.call(r.value);
1576
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) {
1577
+ fail(e);
1578
+ return next();
1579
+ });
1580
+ } else s |= 1;
1581
+ } catch (e) {
1582
+ fail(e);
1601
1583
  }
1602
- }];
1603
- });
1604
- const messages = [];
1605
- let historySystem;
1606
- const systemUpdates = [];
1607
- const flushSystemUpdates = () => {
1608
- if (systemUpdates.length === 0) return;
1609
- if (messages.at(-1)?.role !== "user") return unsupported("system update without a preceding user or tool-result turn");
1610
- messages.push(...systemUpdates.splice(0));
1584
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
1585
+ if (env.hasError) throw env.error;
1586
+ }
1587
+ return next();
1611
1588
  };
1612
- for (const message of history) {
1613
- if (message.role === "developer") {
1614
- const content = message.content.flatMap((block) => {
1615
- switch (block.type) {
1616
- case "text": return block.text.length === 0 ? [] : [{
1617
- type: "text",
1618
- text: block.text
1619
- }];
1620
- case "tool-addition": return [{
1621
- type: "tool_addition",
1622
- tool: {
1623
- type: "tool_reference",
1624
- name: block.toolName
1625
- }
1589
+ })(typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
1590
+ var e = new Error(message);
1591
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1592
+ });
1593
+ /** Provider adapter with protocol-independent request ownership and image recovery. */
1594
+ var DeepSeekProtocolAdapter = class extends LlmAdapter {
1595
+ dependencies;
1596
+ protocol;
1597
+ files;
1598
+ imageAccess = (ref) => {
1599
+ const attachments = this.dependencies.resolveAttachments?.();
1600
+ return attachments === void 0 ? void 0 : this.dependencies.resolveImageAccess?.(attachments, ref);
1601
+ };
1602
+ /**
1603
+ * @param dependencies - request-local configuration, authentication, and Host services.
1604
+ * @param protocol - serializer, resource URLs, and stream decoder.
1605
+ */
1606
+ constructor(dependencies, protocol) {
1607
+ super();
1608
+ this.dependencies = dependencies;
1609
+ this.protocol = protocol;
1610
+ this.files = dependencies.resolveFiles?.() ?? new DeepSeekFileStore({ protocol: protocol.files });
1611
+ }
1612
+ providerInfo(provider) {
1613
+ return {
1614
+ id: provider,
1615
+ name: this.dependencies.providerName ?? "DeepSeek"
1616
+ };
1617
+ }
1618
+ providerRetryPolicy(_provider) {
1619
+ return this.dependencies.options().retryPolicy;
1620
+ }
1621
+ async listModels(provider) {
1622
+ return this.dependencies.discoverModels?.(provider) ?? [];
1623
+ }
1624
+ resolveModel(provider, model, _signal) {
1625
+ return Promise.resolve(this.describe(this.dependencies.options(), provider, model));
1626
+ }
1627
+ imageRequestPricing(_provider, model) {
1628
+ return deepSeekImageRequestPricing(this.dependencies.options(), model, this.imageAccess);
1629
+ }
1630
+ prepareCall(provider, model, _signal) {
1631
+ const connection = this.dependencies.options();
1632
+ return Promise.resolve({
1633
+ model: this.describe(connection, provider, model),
1634
+ stream: (options) => this.generate(options, connection)
1635
+ });
1636
+ }
1637
+ stream(options) {
1638
+ return this.generate(options, this.dependencies.options());
1639
+ }
1640
+ describe(connection, provider, model) {
1641
+ const info = modelInfo(connection, provider, model);
1642
+ if (this.protocol.files === "messages") return info;
1643
+ const { toolUpdate: _toolUpdate, ...supported } = info;
1644
+ return supported;
1645
+ }
1646
+ async *generate(options, connection) {
1647
+ const env_1 = {
1648
+ stack: [],
1649
+ error: void 0,
1650
+ hasError: false
1651
+ };
1652
+ try {
1653
+ const consumer = new AbortController();
1654
+ const watchdog = __addDisposableResource(env_1, idleWatchdog(options.signal === void 0 ? consumer.signal : AbortSignal.any([consumer.signal, options.signal]), connection.streamIdleTimeoutMs, "MESSAGES_IDLE"), false);
1655
+ const iterator = this.request(options, connection, watchdog.signal, () => {
1656
+ watchdog.pulse();
1657
+ });
1658
+ try {
1659
+ while (true) {
1660
+ const next = await watchdog.next(iterator);
1661
+ if (next.done) return;
1662
+ yield next.value;
1663
+ }
1664
+ } catch (error) {
1665
+ if (timeoutOf(watchdog.signal, "MESSAGES_IDLE") !== void 0) throw new LlmError(`DeepSeek ${this.protocol.name} stream idle timeout`, "TIMEOUT", { cause: error });
1666
+ if (options.signal?.aborted) throw new LlmError(`DeepSeek ${this.protocol.name} request aborted`, "ABORTED", { cause: error });
1667
+ if (error instanceof LlmError) throw error;
1668
+ throw new LlmError(`DeepSeek ${this.protocol.name} transport failed`, "TRANSPORT", { cause: error });
1669
+ } finally {
1670
+ consumer.abort();
1671
+ try {
1672
+ await iterator.return(void 0);
1673
+ } catch (_abortedRequestCleanup) {}
1674
+ }
1675
+ } catch (e_1) {
1676
+ env_1.error = e_1;
1677
+ env_1.hasError = true;
1678
+ } finally {
1679
+ __disposeResources(env_1);
1680
+ }
1681
+ }
1682
+ async *request(options, connection, signal, activity) {
1683
+ signal.throwIfAborted();
1684
+ const { messages, versions } = await prepareImages(options.messages, connection, options.model, this.dependencies.resolveAttachments?.(), this.imageAccess, signal);
1685
+ const auth = await this.dependencies.resolveAuth(connection);
1686
+ try {
1687
+ const files = new RequestFiles(this.files, {
1688
+ baseURL: connection.baseURL,
1689
+ headers: auth.headers
1690
+ }, connection.filePolicy, connection.filesApiTimeoutMs, signal, activity);
1691
+ let inline = false;
1692
+ while (true) {
1693
+ signal.throwIfAborted();
1694
+ files.beginAttempt();
1695
+ let fileIds;
1696
+ if (!inline) try {
1697
+ fileIds = await prepareFileIds(messages, versions, files);
1698
+ } catch (error) {
1699
+ if (!(error instanceof FileResolutionFailure)) throw error;
1700
+ inline = true;
1701
+ continue;
1702
+ }
1703
+ const history = inline ? inlineImages(messages, versions, connection) : messages;
1704
+ const { body, headers } = this.protocol.prepare(options, connection, history, versions, this.imageAccess, (reason) => {
1705
+ this.dependencies.onReplayDegrade?.({
1706
+ provider: options.provider,
1707
+ model: options.model,
1708
+ reason
1709
+ });
1710
+ }, fileIds);
1711
+ const extensions = await prepareRequestExtensions(body, {
1712
+ signal,
1713
+ ...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },
1714
+ ...options.purpose === void 0 ? {} : { purpose: options.purpose }
1715
+ }, this.dependencies.prepareExtensions, (fields, error) => {
1716
+ this.dependencies.onExtensionsOmitted?.({
1717
+ provider: options.provider,
1718
+ model: options.model,
1719
+ fields,
1720
+ error
1721
+ });
1722
+ });
1723
+ signal.throwIfAborted();
1724
+ const response = await fetch(this.protocol.endpoint(connection.baseURL), {
1725
+ method: "POST",
1726
+ signal,
1727
+ body: extensions.payload,
1728
+ redirect: "error",
1729
+ headers: {
1730
+ ...attributionHeaders(),
1731
+ "content-type": "application/json",
1732
+ "accept": "text/event-stream",
1733
+ ...auth.headers,
1734
+ ...headers,
1735
+ "x-deepseek-harness-user-id": this.dependencies.resolveUserId(),
1736
+ ...options.sessionId === void 0 ? {} : { "x-deepseek-harness-session-id": String(options.sessionId) },
1737
+ ...options.purpose === "compaction" ? { "x-deepseek-harness-compact": "1" } : {}
1738
+ }
1739
+ });
1740
+ if (!response.ok) {
1741
+ const text = await response.text();
1742
+ let raw;
1743
+ try {
1744
+ raw = JSON.parse(text);
1745
+ } catch (_nonJsonGatewayError) {}
1746
+ const detail = providerErrorDetail(raw);
1747
+ if (await files.retry(detail)) continue;
1748
+ const failure = providerError(raw, response.status, response.headers, this.protocol.name);
1749
+ throw new LlmError(files.errorMessage(response.status, failure.message, detail), failure.code, {
1750
+ ...failure.failure,
1751
+ cause: new Error(text)
1752
+ });
1753
+ }
1754
+ await extensions.accept();
1755
+ if (response.body === null) throw new LlmError(`DeepSeek ${this.protocol.name} returned no response body`, "EMPTY_RESPONSE");
1756
+ yield* this.protocol.translate(response.body, activity, options.model);
1757
+ return;
1758
+ }
1759
+ } catch (error) {
1760
+ if (auth.onRequestError !== void 0) {
1761
+ let mapped;
1762
+ try {
1763
+ mapped = await auth.onRequestError(error);
1764
+ } catch (_credentialUpdateFailed) {
1765
+ throw error;
1766
+ }
1767
+ throw mapped;
1768
+ }
1769
+ throw error;
1770
+ }
1771
+ }
1772
+ };
1773
+ //#endregion
1774
+ //#region lib/types/replay.js
1775
+ /** Minimal native thinking metadata; durable Harness blocks own all response text. */
1776
+ /** Reject malformed JSON objects at provider and durable-data reads.
1777
+ * @param value - untrusted decoded JSON.
1778
+ * @param code - owning failure category.
1779
+ * @returns the validated object.
1780
+ */
1781
+ function object(value, code = "MALFORMED_RESPONSE") {
1782
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new LlmError("DeepSeek Messages expected a JSON object", code);
1783
+ return value;
1784
+ }
1785
+ /** Construct response metadata without duplicating the assistant text.
1786
+ * @param model - requested model identity.
1787
+ * @param blocks - metadata in emitted block order.
1788
+ * @returns the versioned envelope persisted by the existing assembler.
1789
+ */
1790
+ function replayState(model, blocks) {
1791
+ return {
1792
+ response: {
1793
+ kind: "deepseek-messages",
1794
+ version: 1,
1795
+ model
1796
+ },
1797
+ blocks
1798
+ };
1799
+ }
1800
+ /** Validate native replay, discarding unusable metadata before serializing durable content.
1801
+ * @param message - durable assistant content and source metadata.
1802
+ * @param model - target model; cross-model signatures are not portable.
1803
+ * @param onDegrade - diagnostic for unusable metadata; receives no message content or signatures.
1804
+ * @returns index-aligned metadata, absent for foreign, cross-model or degraded history.
1805
+ */
1806
+ function readReplay(message, model, onDegrade) {
1807
+ try {
1808
+ return validateReplay(message, model);
1809
+ } catch (error) {
1810
+ /* v8 ignore next -- the validator only throws INVALID_REPLAY_STATE; preserve future non-replay failures. */
1811
+ if (!(error instanceof LlmError) || error.code !== "INVALID_REPLAY_STATE") throw error;
1812
+ onDegrade?.(error.message);
1813
+ return;
1814
+ }
1815
+ }
1816
+ function validateReplay(message, model) {
1817
+ if (message.source.kind !== "model" || message.source.replayState === void 0) return void 0;
1818
+ const fail = (detail) => {
1819
+ throw new LlmError(`DeepSeek Messages replay: ${detail}`, "INVALID_REPLAY_STATE");
1820
+ };
1821
+ const envelope = object(message.source.replayState, "INVALID_REPLAY_STATE");
1822
+ const response = object(envelope.response, "INVALID_REPLAY_STATE");
1823
+ if (response.kind !== "deepseek-messages" || response.version !== 1) return fail("unsupported kind or version");
1824
+ if (response.model !== message.source.model) return fail("model does not match assistant source model");
1825
+ if (!Array.isArray(envelope.blocks) || envelope.blocks.length !== message.content.length) return fail("block count mismatch");
1826
+ const blocks = envelope.blocks.map((value, index) => {
1827
+ const block = object(value, "INVALID_REPLAY_STATE");
1828
+ if (block.type !== message.content[index]?.type || block.type !== "text" && block.type !== "reasoning" && block.type !== "tool-call") return fail("block type mismatch");
1829
+ if (block.signature !== void 0 && (block.type !== "reasoning" || typeof block.signature !== "string")) return fail("invalid signature");
1830
+ return {
1831
+ type: block.type,
1832
+ ...typeof block.signature === "string" ? { signature: block.signature } : {}
1833
+ };
1834
+ });
1835
+ return response.model === model ? blocks : void 0;
1836
+ }
1837
+ //#endregion
1838
+ //#region lib/types/serialize.js
1839
+ /** Map system snapshots, tool changes, and conversation turns to Messages using the configured route capability. */
1840
+ function unsupported(type) {
1841
+ throw new LlmError(`DeepSeek Messages cannot represent ${type}`, "UNSUPPORTED_CONTENT");
1842
+ }
1843
+ /** Historical arguments that Messages cannot represent use empty input; durable content stays unchanged. */
1844
+ function toolInput(raw) {
1845
+ let value;
1846
+ try {
1847
+ value = JSON.parse(raw);
1848
+ } catch (_invalidToolHistoryJson) {
1849
+ return {};
1850
+ }
1851
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
1852
+ }
1853
+ function assistant(message, model, onReplayDegrade) {
1854
+ const replay = readReplay(message, model, onReplayDegrade);
1855
+ return message.content.map((block, index) => {
1856
+ switch (block.type) {
1857
+ case "text": return {
1858
+ type: "text",
1859
+ text: block.text
1860
+ };
1861
+ case "reasoning": return {
1862
+ type: "thinking",
1863
+ thinking: block.text,
1864
+ ...replay?.[index]?.signature === void 0 ? {} : { signature: replay[index].signature }
1865
+ };
1866
+ case "tool-call": return {
1867
+ type: "tool_use",
1868
+ id: block.id,
1869
+ name: block.name,
1870
+ input: toolInput(block.arguments)
1871
+ };
1872
+ default: return unsupported(`assistant content ${block.type}`);
1873
+ }
1874
+ });
1875
+ }
1876
+ /** Serialize one complete request using already prepared image bytes.
1877
+ * User and tool-result content omits reasoning and tool-call blocks.
1878
+ * Empty user messages are skipped; empty tool results retain their call ids.
1879
+ * Developer messages, already projected for this route by `LlmRuntime`, become
1880
+ * system-role updates after the preceding user turn, with tool changes as
1881
+ * `tool_addition` and `tool_removal` references to the declared tool.
1882
+ * @param options - provider-neutral request.
1883
+ * @param connection - validated defaults and thinking policy.
1884
+ * @param history - image-projected history with complete system snapshots; durable messages remain unchanged.
1885
+ * @param images - request versions for retained images.
1886
+ * @param access - execution-world paths for image descriptions.
1887
+ * @param onReplayDegrade - diagnostic for discarded native replay metadata.
1888
+ * @param fileIds - resolved Files references; omission selects inline image bytes.
1889
+ * @returns the Messages API JSON body.
1890
+ */
1891
+ function serialize$1(options, connection, history, images, access, onReplayDegrade, fileIds) {
1892
+ const model = connection.models.find((entry) => entry.id === options.model);
1893
+ const inHistory = model?.systemPromptUpdate === "in-history";
1894
+ const input = (blocks) => blocks.flatMap((block) => {
1895
+ if (block.type === "text") return block.text ? [{
1896
+ type: "text",
1897
+ text: block.text
1898
+ }] : [];
1899
+ if (block.type === "reasoning" || block.type === "tool-call") return [];
1900
+ if (block.type !== "image") return unsupported(`user/tool-result content ${block.type}`);
1901
+ const version = images.get(block.attachment.attachmentId);
1902
+ if (version === void 0) throw new LlmError("DeepSeek Messages request image is missing", "INVALID_REQUEST");
1903
+ const fileId = fileIds?.get(block.attachment.attachmentId);
1904
+ if (fileIds !== void 0 && fileId === void 0) throw new LlmError("DeepSeek Messages request file id is missing", "INVALID_REQUEST");
1905
+ return [{
1906
+ type: "text",
1907
+ text: requestImageHandleText(block.attachment, version, access(block.attachment))
1908
+ }, fileId === void 0 ? {
1909
+ type: "image",
1910
+ source: {
1911
+ type: "base64",
1912
+ media_type: version.mediaType,
1913
+ data: Buffer.from(version.data).toString("base64")
1914
+ }
1915
+ } : {
1916
+ type: "image",
1917
+ source: {
1918
+ type: "file",
1919
+ file_id: fileId
1920
+ }
1921
+ }];
1922
+ });
1923
+ const messages = [];
1924
+ let historySystem;
1925
+ const systemUpdates = [];
1926
+ const flushSystemUpdates = () => {
1927
+ if (systemUpdates.length === 0) return;
1928
+ if (messages.at(-1)?.role !== "user") return unsupported("system update without a preceding user or tool-result turn");
1929
+ messages.push(...systemUpdates.splice(0));
1930
+ };
1931
+ for (const message of history) {
1932
+ if (message.role === "developer") {
1933
+ const content = message.content.flatMap((block) => {
1934
+ switch (block.type) {
1935
+ case "text": return block.text.length === 0 ? [] : [{
1936
+ type: "text",
1937
+ text: block.text
1938
+ }];
1939
+ case "tool-addition": return [{
1940
+ type: "tool_addition",
1941
+ tool: {
1942
+ type: "tool_reference",
1943
+ name: block.toolName
1944
+ }
1626
1945
  }];
1627
1946
  case "tool-removal": return [{
1628
1947
  type: "tool_removal",
@@ -1713,52 +2032,6 @@ function serialize(options, connection, history, images, access, onReplayDegrade
1713
2032
  };
1714
2033
  }
1715
2034
  //#endregion
1716
- //#region lib/types/transport.js
1717
- /** Normalize HTTP and in-band Messages errors into provider-neutral failures. */
1718
- /** Read only provider error fields used by bounded Files recovery.
1719
- * @param raw - decoded HTTP error response.
1720
- * @returns code, type, and message text, without unrelated response fields.
1721
- */
1722
- function providerErrorDetail(raw) {
1723
- const error = typeof raw === "object" && raw !== null && "error" in raw ? raw.error : void 0;
1724
- if (typeof error !== "object" || error === null) return "";
1725
- const fields = error;
1726
- return [
1727
- fields.code,
1728
- fields.type,
1729
- fields.message
1730
- ].filter((value) => typeof value === "string").join(" ");
1731
- }
1732
- /** Classify a provider error without trusting arbitrary response fields.
1733
- * @param raw - decoded response or in-band error event.
1734
- * @param status - HTTP status when the error preceded streaming.
1735
- * @param headers - response headers for retry delay and request identity.
1736
- * @returns a stable error consumed by LlmRuntime and llm-retry.
1737
- */
1738
- function providerError(raw, status, headers) {
1739
- const envelope = typeof raw === "object" && raw !== null ? raw : {};
1740
- const error = typeof envelope.error === "object" && envelope.error !== null ? envelope.error : {};
1741
- const message = typeof error.message === "string" ? error.message : `DeepSeek Messages request failed (${status ?? "stream error"})`;
1742
- const type = typeof error.type === "string" ? error.type : "";
1743
- const detail = `${type} ${typeof error.code === "string" ? error.code : ""} ${message}`;
1744
- let code;
1745
- if (status === 401 || status === 403 || ["authentication_error", "permission_error"].includes(type)) code = "AUTH";
1746
- else if (isQuotaExceededError(detail) || status === 402) code = "QUOTA";
1747
- else if (status === 429 || type === "rate_limit_error") code = "RATE_LIMIT";
1748
- else if (isContextWindowExceededError(detail)) code = "CONTEXT_WINDOW_EXCEEDED";
1749
- else if (status === 400 || status === 413 || type === "invalid_request_error") code = "INVALID_REQUEST";
1750
- else if (status !== void 0 && status >= 500 || ["api_error", "overloaded_error"].includes(type)) code = "SERVER";
1751
- else code = status === void 0 ? "SERVER" : `HTTP_${status}`;
1752
- const retry = headers?.get("retry-after");
1753
- const delay = retry == null ? NaN : /^\d+(?:\.\d+)?$/u.test(retry) ? Number(retry) * 1e3 : Date.parse(retry) - Date.now();
1754
- const id = headers?.get("request-id") ?? headers?.get("x-request-id") ?? headers?.get("x-deepseek-request-id");
1755
- return new LlmError(message, code, {
1756
- ...status === void 0 ? {} : { status },
1757
- ...id ? { requestId: ProviderRequestId(id) } : {},
1758
- ...Number.isFinite(delay) && delay > 0 ? { providerRetryAfterMs: delay } : {}
1759
- });
1760
- }
1761
- //#endregion
1762
2035
  //#region lib/types/sse.js
1763
2036
  /** SSE framing delegated to eventsource-parser; JSON errors remain provider failures. */
1764
2037
  /** Decode complete SSE frames without treating an unterminated tail as an event.
@@ -1766,7 +2039,7 @@ function providerError(raw, status, headers) {
1766
2039
  * @param activity - pulse the idle watchdog for events and heartbeat comments.
1767
2040
  * @returns JSON events, including message_stop; the translator owns completion.
1768
2041
  */
1769
- async function* parseSse(body, activity) {
2042
+ async function* parseSse$1(body, activity) {
1770
2043
  const events = body.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream({ onComment: activity }));
1771
2044
  for await (const frame of events) {
1772
2045
  activity();
@@ -1907,7 +2180,7 @@ function stopReason(raw) {
1907
2180
  * @param model - requested model id stored in durable replay state.
1908
2181
  * @returns blocks, one final usage value, and exactly one terminal finish.
1909
2182
  */
1910
- async function* translate(events, model) {
2183
+ async function* translate$1(events, model) {
1911
2184
  const blocks = /* @__PURE__ */ new Map();
1912
2185
  const usage = {
1913
2186
  inputTokens: 0,
@@ -1986,248 +2259,421 @@ async function* translate(events, model) {
1986
2259
  object(parsed);
1987
2260
  }
1988
2261
  usage.totalTokens = usage.inputTokens + usage.outputTokens + (usage.cacheReadTokens ?? 0) + (usage.cacheWriteTokens ?? 0);
1989
- yield {
1990
- type: "usage",
1991
- usage
1992
- };
1993
- yield {
1994
- type: "finish",
1995
- reason,
1996
- replayState: replayState(model, [...blocks.values()].map((block) => block.replay))
1997
- };
1998
- return;
1999
- }
2000
- }
2001
- throw new LlmError("DeepSeek Messages stream ended before message_stop", "STREAM_CLOSED");
2002
- }
2003
- //#endregion
2004
- //#region lib/types/adapter.js
2005
- /** Direct Messages transport with one cancellable lifecycle per model request. */
2006
- var __addDisposableResource = function(env, value, async) {
2007
- if (value !== null && value !== void 0) {
2008
- if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
2009
- var dispose, inner;
2010
- if (async) {
2011
- if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
2012
- dispose = value[Symbol.asyncDispose];
2013
- }
2014
- if (dispose === void 0) {
2015
- if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
2016
- dispose = value[Symbol.dispose];
2017
- if (async) inner = dispose;
2018
- }
2019
- if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
2020
- if (inner) dispose = function() {
2021
- try {
2022
- inner.call(this);
2023
- } catch (e) {
2024
- return Promise.reject(e);
2025
- }
2026
- };
2027
- env.stack.push({
2028
- value,
2029
- dispose,
2030
- async
2031
- });
2032
- } else if (async) env.stack.push({ async: true });
2033
- return value;
2034
- };
2035
- var __disposeResources = (function(SuppressedError) {
2036
- return function(env) {
2037
- function fail(e) {
2038
- env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
2039
- env.hasError = true;
2040
- }
2041
- var r, s = 0;
2042
- function next() {
2043
- while (r = env.stack.pop()) try {
2044
- if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
2045
- if (r.dispose) {
2046
- var result = r.dispose.call(r.value);
2047
- if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) {
2048
- fail(e);
2049
- return next();
2050
- });
2051
- } else s |= 1;
2052
- } catch (e) {
2053
- fail(e);
2054
- }
2055
- if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
2056
- if (env.hasError) throw env.error;
2262
+ yield {
2263
+ type: "usage",
2264
+ usage
2265
+ };
2266
+ yield {
2267
+ type: "finish",
2268
+ reason,
2269
+ replayState: replayState(model, [...blocks.values()].map((block) => block.replay))
2270
+ };
2271
+ return;
2057
2272
  }
2058
- return next();
2059
- };
2060
- })(typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
2061
- var e = new Error(message);
2062
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
2063
- });
2064
- /** DeepSeek provider using Messages content and native thinking replay. */
2065
- var DeepSeekAdapter = class extends LlmAdapter {
2066
- dependencies;
2067
- files;
2068
- imageAccess = (ref) => {
2069
- const attachments = this.dependencies.resolveAttachments?.();
2070
- return attachments === void 0 ? void 0 : this.dependencies.resolveImageAccess?.(attachments, ref);
2071
- };
2072
- constructor(dependencies) {
2073
- super();
2074
- this.dependencies = dependencies;
2075
- this.files = dependencies.resolveFiles?.() ?? new DeepSeekFileStore();
2076
2273
  }
2077
- providerInfo(provider) {
2274
+ throw new LlmError("DeepSeek Messages stream ended before message_stop", "STREAM_CLOSED");
2275
+ }
2276
+ //#endregion
2277
+ //#region lib/types/adapter.js
2278
+ const messages = {
2279
+ name: "Messages",
2280
+ files: "messages",
2281
+ endpoint: (baseURL) => `${messagesApiRoot(baseURL)}/messages`,
2282
+ prepare: (...args) => {
2283
+ const body = serialize$1(...args);
2284
+ const betas = [...args[6] !== void 0 && args[6].size > 0 ? [MESSAGES_FILES_BETA] : [], ...body.messages.some((message) => message.content.some((block) => block.type === "tool_addition" || block.type === "tool_removal")) ? [MESSAGES_TOOL_CHANGES_BETA] : []];
2078
2285
  return {
2079
- id: provider,
2080
- name: this.dependencies.providerName ?? "DeepSeek"
2286
+ body,
2287
+ headers: {
2288
+ "anthropic-version": "2023-06-01",
2289
+ ...betas.length === 0 ? {} : { "anthropic-beta": betas.join(",") }
2290
+ }
2081
2291
  };
2292
+ },
2293
+ translate: (stream, activity, model) => translate$1(parseSse$1(stream, activity), model)
2294
+ };
2295
+ /** DeepSeek provider using Messages content and native thinking replay. */
2296
+ var DeepSeekAdapter = class extends DeepSeekProtocolAdapter {
2297
+ /** @param dependencies - request-local configuration, credentials, and Host services. */
2298
+ constructor(dependencies) {
2299
+ super(dependencies, messages);
2082
2300
  }
2083
- providerRetryPolicy(_provider) {
2084
- return this.dependencies.options().retryPolicy;
2085
- }
2086
- async listModels(provider) {
2087
- return this.dependencies.discoverModels?.(provider) ?? [];
2301
+ };
2302
+ //#endregion
2303
+ //#region lib/types/chat-completions/serialize.js
2304
+ /** DeepSeek Chat Completions serialization with verbatim reasoning and tool arguments. */
2305
+ function text(blocks) {
2306
+ return blocks.filter((block) => block.type === "text").map((block) => block.text).join("");
2307
+ }
2308
+ /**
2309
+ * Serialize prepared history without rewriting durable reasoning or tool arguments.
2310
+ * Tool-result images follow their complete consecutive tool-result group in a user message.
2311
+ * @param args - request, validated connection, prepared history/images, access resolver, replay reporter, and Files ids.
2312
+ * @returns a streaming Chat Completions request with usage enabled.
2313
+ */
2314
+ function serialize(...args) {
2315
+ const [options, connection, history, images, access, , fileIds] = args;
2316
+ const messages = [];
2317
+ let pendingImages = [];
2318
+ const flushImages = () => {
2319
+ if (pendingImages.length === 0) return;
2320
+ messages.push({
2321
+ role: "user",
2322
+ content: [{
2323
+ type: "text",
2324
+ text: "Attached image(s) from tool result:"
2325
+ }, ...pendingImages]
2326
+ });
2327
+ pendingImages = [];
2328
+ };
2329
+ const parts = (blocks) => blocks.flatMap((block) => {
2330
+ if (block.type === "text") return block.text ? [{
2331
+ type: "text",
2332
+ text: block.text
2333
+ }] : [];
2334
+ if (block.type !== "image") return [];
2335
+ const version = images.get(block.attachment.attachmentId);
2336
+ if (version === void 0) throw new LlmError("DeepSeek Chat Completions request image is missing", "INVALID_REQUEST");
2337
+ const fileId = fileIds?.get(block.attachment.attachmentId);
2338
+ if (fileIds !== void 0 && fileId === void 0) throw new LlmError("DeepSeek Chat Completions request file id is missing", "INVALID_REQUEST");
2339
+ return [{
2340
+ type: "text",
2341
+ text: requestImageHandleText(block.attachment, version, access(block.attachment))
2342
+ }, fileId === void 0 ? {
2343
+ type: "image_url",
2344
+ image_url: { url: `data:${version.mediaType};base64,${Buffer.from(version.data).toString("base64")}` }
2345
+ } : {
2346
+ type: "file",
2347
+ file_id: fileId
2348
+ }];
2349
+ });
2350
+ if (options.system !== void 0) messages.push({
2351
+ role: "system",
2352
+ content: options.system
2353
+ });
2354
+ for (const message of history) {
2355
+ if (message.role === "developer" || message.content.some((block) => block.type === "tool-addition" || block.type === "tool-removal")) throw new LlmError("DeepSeek Chat Completions does not support native tool updates", "UNSUPPORTED_CONTENT");
2356
+ if (message.role !== "tool") flushImages();
2357
+ switch (message.role) {
2358
+ case "system":
2359
+ messages.push({
2360
+ role: "system",
2361
+ content: text(message.content)
2362
+ });
2363
+ break;
2364
+ case "assistant": {
2365
+ const reasoning = message.content.filter((block) => block.type === "reasoning").map((block) => block.text).join("");
2366
+ const calls = message.content.filter((block) => block.type === "tool-call").map((block) => ({
2367
+ id: block.id,
2368
+ type: "function",
2369
+ function: {
2370
+ name: block.name,
2371
+ arguments: block.arguments
2372
+ }
2373
+ }));
2374
+ messages.push({
2375
+ role: "assistant",
2376
+ content: text(message.content),
2377
+ ...reasoning.length === 0 ? {} : { reasoning_content: reasoning },
2378
+ ...calls.length === 0 ? {} : { tool_calls: calls }
2379
+ });
2380
+ break;
2381
+ }
2382
+ case "tool": {
2383
+ const content = parts(message.content);
2384
+ messages.push({
2385
+ role: "tool",
2386
+ tool_call_id: message.toolCallId,
2387
+ content: content.filter((part) => part.type === "text").map((part) => part.text).join("") || "(no output)"
2388
+ });
2389
+ pendingImages.push(...content.filter((part) => part.type !== "text"));
2390
+ break;
2391
+ }
2392
+ case "user": {
2393
+ const content = parts(message.content);
2394
+ messages.push({
2395
+ role: "user",
2396
+ content: content.every((part) => part.type === "text") ? content.map((part) => part.text).join("") : content
2397
+ });
2398
+ break;
2399
+ }
2400
+ /* v8 ignore next 2 -- closed-union exhaustiveness guard */
2401
+ default: return assertNever(message);
2402
+ }
2088
2403
  }
2089
- resolveModel(provider, model, _signal) {
2090
- return Promise.resolve(modelInfo(this.dependencies.options(), provider, model));
2404
+ flushImages();
2405
+ const effort = resolveEffort(options.purpose === "session-title" ? "off" : options.reasoningEffort ?? connection.defaults.reasoningEffort);
2406
+ if (connection.defaults.thinking === "disabled" && effort !== void 0 && effort !== "off") throw new LlmError("DeepSeek deployment has thinking disabled", "UNSUPPORTED_REASONING_EFFORT");
2407
+ if (options.tools?.some((tool) => tool.deferLoading === true)) throw new LlmError("DeepSeek Chat Completions does not support deferred tools", "UNSUPPORTED_CONTENT");
2408
+ const thinking = effort === void 0 ? connection.defaults.thinking : effort === "off" ? "disabled" : "enabled";
2409
+ return {
2410
+ model: options.model,
2411
+ messages,
2412
+ stream: true,
2413
+ stream_options: { include_usage: true },
2414
+ ...thinking === void 0 ? {} : { thinking: { type: thinking } },
2415
+ ...effort === "low" || effort === "high" || effort === "max" ? { reasoning_effort: effort } : {},
2416
+ ...options.maxTokens === void 0 ? {} : { max_tokens: options.maxTokens },
2417
+ ...options.temperature === void 0 ? {} : { temperature: options.temperature },
2418
+ ...options.stop === void 0 ? {} : { stop: options.stop },
2419
+ ...options.tools?.length ? { tools: options.tools.map((tool) => ({
2420
+ type: "function",
2421
+ function: {
2422
+ name: tool.name,
2423
+ description: tool.description,
2424
+ parameters: tool.parameters
2425
+ }
2426
+ })) } : {}
2427
+ };
2428
+ }
2429
+ function resolveEffort(value) {
2430
+ switch (value) {
2431
+ case void 0: return;
2432
+ case "off": return "off";
2433
+ case "low": return "low";
2434
+ case "high": return "high";
2435
+ case "max": return "max";
2436
+ default: throw new LlmError(`DeepSeek Chat Completions does not support reasoning effort ${value}`, "UNSUPPORTED_REASONING_EFFORT");
2091
2437
  }
2092
- imageRequestPricing(_provider, model) {
2093
- return deepSeekImageRequestPricing(this.dependencies.options(), model, this.imageAccess);
2438
+ }
2439
+ /**
2440
+ * Parse an SSE byte stream into data payloads. Yields `[DONE]` as the final
2441
+ * value and returns; throws `LlmError('STREAM_CLOSED')` when the stream ends
2442
+ * without it (truncated response — the model call cannot be trusted).
2443
+ * @param stream - raw SSE bytes; reads may split anywhere, including mid-UTF-8 sequence.
2444
+ * @param onComment - optional transport-activity callback; comments never enter the yielded payload stream.
2445
+ * @returns each event's data payload in arrival order, the `[DONE]` sentinel last.
2446
+ */
2447
+ async function* parseSse(stream, onComment) {
2448
+ const events = stream.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream({ onComment }));
2449
+ for await (const { data } of events) {
2450
+ yield data;
2451
+ if (data === "[DONE]") return;
2094
2452
  }
2095
- prepareCall(provider, model, _signal) {
2096
- const connection = this.dependencies.options();
2097
- return Promise.resolve({
2098
- model: modelInfo(connection, provider, model),
2099
- stream: (options) => this.generate(options, connection)
2100
- });
2453
+ throw new LlmError("SSE stream ended without [DONE]", "STREAM_CLOSED");
2454
+ }
2455
+ //#endregion
2456
+ //#region lib/types/chat-completions/translate.js
2457
+ /**
2458
+ * Translate DeepSeek SSE payloads with one stateful harness block per content, reasoning, or tool
2459
+ * call index. An empty initial reasoning delta does not open a block. Finish reason and the latest
2460
+ * usage are deferred until `[DONE]`, covering both finish-attached and trailing usage-only shapes
2461
+ * while ensuring no chunk follows `finish`.
2462
+ *
2463
+ * Translate DeepSeek wire chunks into the harness `StreamChunk` protocol.
2464
+ * @module dsh-llm-deepseek/translate
2465
+ */
2466
+ /**
2467
+ * Map the wire finish_reason vocabulary to the harness FinishReason.
2468
+ * @param reason - the wire `finish_reason` string.
2469
+ * @returns the mapped reason; unrecognized values (content_filter, …) become `{kind: 'error'}` with the uppercased value as `code`.
2470
+ */
2471
+ function mapFinishReason(reason) {
2472
+ switch (reason) {
2473
+ case "stop": return { kind: "stop" };
2474
+ case "tool_calls": return { kind: "tool-calls" };
2475
+ case "length": return { kind: "max-tokens" };
2476
+ default: return {
2477
+ kind: "error",
2478
+ failure: {
2479
+ message: `model stopped: ${reason}`,
2480
+ code: reason.toUpperCase()
2481
+ }
2482
+ };
2101
2483
  }
2102
- stream(options) {
2103
- return this.generate(options, this.dependencies.options());
2484
+ }
2485
+ /**
2486
+ * Map wire usage fields. DeepSeek's `prompt_tokens` INCLUDES cache hits
2487
+ * (`prompt_tokens = prompt_cache_hit_tokens + prompt_cache_miss_tokens`,
2488
+ * api/create-chat-completion); the harness TokenUsage convention is
2489
+ * DISJOINT counts, so cache reads are subtracted out of `inputTokens`.
2490
+ * @param usage - wire usage from the finish chunk or the trailing usage-only chunk.
2491
+ * @returns disjoint harness counts; an exact total is present only when the
2492
+ * aggregate prompt/completion counters are valid and agree with any wire total.
2493
+ */
2494
+ function mapUsage(usage) {
2495
+ const cacheRead = usage.prompt_tokens_details?.cached_tokens ?? usage.prompt_cache_hit_tokens;
2496
+ const reasoning = usage.completion_tokens_details?.reasoning_tokens;
2497
+ const combined = usage.prompt_tokens + usage.completion_tokens;
2498
+ const hasExactTotal = Number.isSafeInteger(usage.prompt_tokens) && usage.prompt_tokens >= 0 && Number.isSafeInteger(usage.completion_tokens) && usage.completion_tokens >= 0 && Number.isSafeInteger(combined) && (usage.total_tokens === void 0 || usage.total_tokens === combined);
2499
+ return {
2500
+ inputTokens: usage.prompt_tokens - (cacheRead ?? 0),
2501
+ outputTokens: usage.completion_tokens,
2502
+ ...hasExactTotal ? { totalTokens: combined } : {},
2503
+ ...cacheRead !== void 0 ? { cacheReadTokens: cacheRead } : {},
2504
+ ...reasoning !== void 0 ? { reasoningTokens: reasoning } : {}
2505
+ };
2506
+ }
2507
+ /**
2508
+ * Accept one streamed identity field for a tool call. `id` and `name` are
2509
+ * identity, not accumulation: the wire sends each once, on the call's first
2510
+ * delta. A continuation delta that re-sends the field empty — or `null`, which
2511
+ * some OpenAI-compatible gateways fill in — means "no update", never "clear".
2512
+ * @param current - the identity established by an earlier delta of this call.
2513
+ * @param incoming - the field as parsed from this delta. The wire type is a
2514
+ * claim about a remote encoder, so anything but a non-empty string leaves the
2515
+ * established value alone rather than overwriting it.
2516
+ * @returns the identity in force after this delta.
2517
+ */
2518
+ function acceptIdentity(current, incoming) {
2519
+ return typeof incoming === "string" && incoming.length > 0 ? incoming : current;
2520
+ }
2521
+ /** Assemble the final ContentBlock for one open block. */
2522
+ function closeBlock(block) {
2523
+ switch (block.kind) {
2524
+ case "text": return {
2525
+ type: "text",
2526
+ text: block.text
2527
+ };
2528
+ case "reasoning": return {
2529
+ type: "reasoning",
2530
+ text: block.text
2531
+ };
2532
+ case "tool-call": return {
2533
+ type: "tool-call",
2534
+ id: brandString(block.callId ?? ""),
2535
+ name: block.name ?? "",
2536
+ arguments: block.text
2537
+ };
2104
2538
  }
2105
- async *generate(options, connection) {
2106
- const env_1 = {
2107
- stack: [],
2108
- error: void 0,
2109
- hasError: false
2539
+ }
2540
+ /**
2541
+ * Consume SSE data payloads (ending with `[DONE]`) and yield StreamChunks.
2542
+ * Malformed JSON payloads abort the stream with `MALFORMED_RESPONSE`.
2543
+ * @param payloads - SSE data payloads from {@link parseSse}, `[DONE]`-terminated.
2544
+ * @returns deltas as they arrive; `block-end`s, `usage`, and `finish` are all deferred to the `[DONE]` sentinel.
2545
+ * A `stop` (or absent) finish with no opened blocks is a degenerate provider completion and maps to an
2546
+ * `EMPTY_RESPONSE` error finish instead of a successful empty message.
2547
+ */
2548
+ async function* translate(payloads) {
2549
+ let nextIndex = 0;
2550
+ let textBlock;
2551
+ let reasoningBlock;
2552
+ const toolBlocks = /* @__PURE__ */ new Map();
2553
+ const order = [];
2554
+ let pendingFinish;
2555
+ let pendingUsage;
2556
+ function open(kind) {
2557
+ const block = {
2558
+ index: nextIndex++,
2559
+ kind,
2560
+ text: ""
2110
2561
  };
2111
- try {
2112
- const consumer = new AbortController();
2113
- const watchdog = __addDisposableResource(env_1, idleWatchdog(options.signal === void 0 ? consumer.signal : AbortSignal.any([consumer.signal, options.signal]), connection.streamIdleTimeoutMs, "MESSAGES_IDLE"), false);
2114
- const iterator = this.request(options, connection, watchdog.signal, () => {
2115
- watchdog.pulse();
2116
- });
2117
- try {
2118
- while (true) {
2119
- const next = await watchdog.next(iterator);
2120
- if (next.done) return;
2121
- yield next.value;
2122
- }
2123
- } catch (error) {
2124
- if (timeoutOf(watchdog.signal, "MESSAGES_IDLE") !== void 0) throw new LlmError("DeepSeek Messages stream idle timeout", "TIMEOUT", { cause: error });
2125
- if (options.signal?.aborted) throw new LlmError("DeepSeek Messages request aborted", "ABORTED", { cause: error });
2126
- if (error instanceof LlmError) throw error;
2127
- throw new LlmError("DeepSeek Messages transport failed", "TRANSPORT", { cause: error });
2128
- } finally {
2129
- consumer.abort();
2130
- try {
2131
- await iterator.return(void 0);
2132
- } catch (_abortedRequestCleanup) {}
2133
- }
2134
- } catch (e_1) {
2135
- env_1.error = e_1;
2136
- env_1.hasError = true;
2137
- } finally {
2138
- __disposeResources(env_1);
2139
- }
2562
+ order.push(block);
2563
+ return block;
2140
2564
  }
2141
- async *request(options, connection, signal, activity) {
2142
- signal.throwIfAborted();
2143
- const { messages, versions } = await prepareImages(options.messages, connection, options.model, this.dependencies.resolveAttachments?.(), this.imageAccess, signal);
2144
- const auth = await this.dependencies.resolveAuth(connection);
2565
+ for await (const payload of payloads) {
2566
+ if (payload === "[DONE]") {
2567
+ for (const block of order) yield {
2568
+ type: "block-end",
2569
+ index: block.index,
2570
+ block: closeBlock(block)
2571
+ };
2572
+ if (pendingUsage) yield {
2573
+ type: "usage",
2574
+ usage: pendingUsage
2575
+ };
2576
+ const reason = pendingFinish ?? { kind: "stop" };
2577
+ yield {
2578
+ type: "finish",
2579
+ reason: reason.kind === "stop" && order.length === 0 ? {
2580
+ kind: "error",
2581
+ failure: {
2582
+ message: "model returned a completed response with no content",
2583
+ code: EMPTY_RESPONSE_CODE
2584
+ }
2585
+ } : reason
2586
+ };
2587
+ return;
2588
+ }
2589
+ let chunk;
2145
2590
  try {
2146
- const files = new RequestFiles(this.files, {
2147
- baseURL: connection.baseURL,
2148
- headers: auth.headers
2149
- }, connection.filePolicy, connection.filesApiTimeoutMs, signal, activity);
2150
- let inline = false;
2151
- while (true) {
2152
- signal.throwIfAborted();
2153
- files.beginAttempt();
2154
- let fileIds;
2155
- if (!inline) try {
2156
- fileIds = await prepareFileIds(messages, versions, files);
2157
- } catch (error) {
2158
- if (!(error instanceof FileResolutionFailure)) throw error;
2159
- inline = true;
2160
- continue;
2591
+ chunk = JSON.parse(payload);
2592
+ } catch (_invalidProviderJson) {
2593
+ throw new LlmError(`malformed SSE payload: ${payload.slice(0, 120)}`, "MALFORMED_RESPONSE");
2594
+ }
2595
+ for (const choice of chunk.choices ?? []) {
2596
+ const delta = choice.delta;
2597
+ const reasoning = delta?.reasoning_content;
2598
+ if (typeof reasoning === "string" && reasoning.length > 0) {
2599
+ if (!reasoningBlock) {
2600
+ reasoningBlock = open("reasoning");
2601
+ yield {
2602
+ type: "block-start",
2603
+ index: reasoningBlock.index,
2604
+ blockType: "reasoning"
2605
+ };
2161
2606
  }
2162
- const body = serialize(options, connection, inline ? inlineImages(messages, versions, connection) : messages, versions, this.imageAccess, (reason) => {
2163
- this.dependencies.onReplayDegrade?.({
2164
- provider: options.provider,
2165
- model: options.model,
2166
- reason
2167
- });
2168
- }, fileIds);
2169
- const extensions = await prepareRequestExtensions(body, {
2170
- signal,
2171
- ...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },
2172
- ...options.purpose === void 0 ? {} : { purpose: options.purpose }
2173
- }, this.dependencies.prepareExtensions, (fields, error) => {
2174
- this.dependencies.onExtensionsOmitted?.({
2175
- provider: options.provider,
2176
- model: options.model,
2177
- fields,
2178
- error
2179
- });
2180
- });
2181
- signal.throwIfAborted();
2182
- const betas = [...fileIds !== void 0 && fileIds.size > 0 ? [MESSAGES_FILES_BETA] : [], ...body.messages.some((message) => message.content.some((block) => block.type === "tool_addition" || block.type === "tool_removal")) ? [MESSAGES_TOOL_CHANGES_BETA] : []];
2183
- const response = await fetch(`${messagesApiRoot(connection.baseURL)}/messages`, {
2184
- method: "POST",
2185
- signal,
2186
- body: extensions.payload,
2187
- redirect: "error",
2188
- headers: {
2189
- ...attributionHeaders(),
2190
- "content-type": "application/json",
2191
- "accept": "text/event-stream",
2192
- ...auth.headers,
2193
- "anthropic-version": "2023-06-01",
2194
- ...betas.length === 0 ? {} : { "anthropic-beta": betas.join(",") },
2195
- "x-deepseek-harness-user-id": this.dependencies.resolveUserId(),
2196
- ...options.sessionId === void 0 ? {} : { "x-deepseek-harness-session-id": String(options.sessionId) },
2197
- ...options.purpose === "compaction" ? { "x-deepseek-harness-compact": "1" } : {}
2198
- }
2199
- });
2200
- if (!response.ok) {
2201
- const text = await response.text();
2202
- let raw;
2203
- try {
2204
- raw = JSON.parse(text);
2205
- } catch (_nonJsonGatewayError) {}
2206
- const detail = providerErrorDetail(raw);
2207
- if (await files.retry(detail)) continue;
2208
- const failure = providerError(raw, response.status, response.headers);
2209
- throw new LlmError(files.errorMessage(response.status, failure.message, detail), failure.code, {
2210
- ...failure.failure,
2211
- cause: new Error(text)
2212
- });
2607
+ reasoningBlock.text += reasoning;
2608
+ yield {
2609
+ type: "reasoning-delta",
2610
+ index: reasoningBlock.index,
2611
+ text: reasoning
2612
+ };
2613
+ }
2614
+ const content = delta?.content;
2615
+ if (typeof content === "string" && content.length > 0) {
2616
+ if (!textBlock) {
2617
+ textBlock = open("text");
2618
+ yield {
2619
+ type: "block-start",
2620
+ index: textBlock.index,
2621
+ blockType: "text"
2622
+ };
2213
2623
  }
2214
- await extensions.accept();
2215
- if (response.body === null) throw new LlmError("DeepSeek Messages returned no response body", "EMPTY_RESPONSE");
2216
- yield* translate(parseSse(response.body, activity), options.model);
2217
- return;
2624
+ textBlock.text += content;
2625
+ yield {
2626
+ type: "text-delta",
2627
+ index: textBlock.index,
2628
+ text: content
2629
+ };
2218
2630
  }
2219
- } catch (error) {
2220
- if (auth.onRequestError !== void 0) {
2221
- let mapped;
2222
- try {
2223
- mapped = await auth.onRequestError(error);
2224
- } catch (_credentialUpdateFailed) {
2225
- throw error;
2631
+ for (const call of delta?.tool_calls ?? []) {
2632
+ let block = toolBlocks.get(call.index);
2633
+ if (!block) {
2634
+ block = open("tool-call");
2635
+ toolBlocks.set(call.index, block);
2636
+ yield {
2637
+ type: "block-start",
2638
+ index: block.index,
2639
+ blockType: "tool-call"
2640
+ };
2226
2641
  }
2227
- throw mapped;
2642
+ block.callId = acceptIdentity(block.callId, call.id);
2643
+ block.name = acceptIdentity(block.name, call.function?.name);
2644
+ const fragment = call.function?.arguments ?? "";
2645
+ block.text += fragment;
2646
+ yield {
2647
+ type: "tool-call-delta",
2648
+ index: block.index,
2649
+ id: brandString(block.callId ?? ""),
2650
+ ...block.name !== void 0 ? { name: block.name } : {},
2651
+ argumentsDelta: fragment
2652
+ };
2228
2653
  }
2229
- throw error;
2654
+ if (typeof choice.finish_reason === "string") pendingFinish = mapFinishReason(choice.finish_reason);
2230
2655
  }
2656
+ if (chunk.usage) pendingUsage = mapUsage(chunk.usage);
2657
+ }
2658
+ throw new LlmError("SSE payload stream ended without [DONE]", "STREAM_CLOSED");
2659
+ }
2660
+ //#endregion
2661
+ //#region lib/types/chat-completions/adapter.js
2662
+ const chatCompletions = {
2663
+ name: "Chat Completions",
2664
+ files: "chat-completions",
2665
+ endpoint: (baseURL) => `${baseURL.replace(/\/+$/u, "")}/chat/completions`,
2666
+ prepare: (...args) => ({
2667
+ body: serialize(...args),
2668
+ headers: {}
2669
+ }),
2670
+ translate: (stream, activity) => translate(parseSse(stream, activity))
2671
+ };
2672
+ /** DeepSeek OpenAI-compatible transport with raw reasoning replay and Files recovery. */
2673
+ var DeepSeekChatCompletionsAdapter = class extends DeepSeekProtocolAdapter {
2674
+ /** @param dependencies - explicit API root, request authentication, defaults, and Host services. */
2675
+ constructor(dependencies) {
2676
+ super(dependencies, chatCompletions);
2231
2677
  }
2232
2678
  };
2233
2679
  //#endregion
@@ -2275,4 +2721,4 @@ function registerDeepSeekProvider(ctx, provider, dependencies) {
2275
2721
  });
2276
2722
  }
2277
2723
  //#endregion
2278
- export { Config, DEFAULT_CONTEXT_WINDOW, DEFAULT_FILES_API_TIMEOUT_MS, DEFAULT_FILE_EXPIRY_SECONDS, DEFAULT_FILE_QUOTA_CLEANUP_BATCH, DEFAULT_FILE_REFRESH_MARGIN_SECONDS, DEFAULT_IMAGE_OFFLOAD_BYTE_QUANTUM, DEFAULT_IMAGE_OFFLOAD_COUNT_QUANTUM, DEFAULT_INLINE_IMAGE_OFFLOAD_BYTE_QUANTUM, DEFAULT_LOW_DETAIL_IMAGE_PIXEL_BUDGET, DEFAULT_MAX_IMAGES_PER_REQUEST, DEFAULT_MAX_INLINE_REQUEST_IMAGE_BYTES, DEFAULT_MAX_REQUEST_FILES_BYTES, DEFAULT_MAX_TOKENS, DEFAULT_REQUEST_IMAGE_MAX_BYTES, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DeepSeekAdapter, DeepSeekFileId, DeepSeekFileStore, DeepSeekFilesClient, DeepSeekUploadIndex, MAX_FILE_EXPIRY_SECONDS, MAX_FILE_UPLOAD_BYTES, MAX_IMAGE_BYTES, MAX_STORED_FILE_BYTES, MAX_STORED_FILE_COUNT, MIN_FILE_EXPIRY_SECONDS, PUBLIC_BASE_URL, REQUEST_IMAGE_MAX_DIMENSION, catalogModelInfo, deepSeekConfigFields, deepSeekFileScope, deepSeekImageRequestPricing, deepSeekImageTokens, deepSeekRequestImageDimensions, plainOptions, registerDeepSeekProvider, resolveAdapterOptions, resolveRequestImageMaxBytes, resolveRequestImageTarget };
2724
+ export { Config, DEFAULT_CONTEXT_WINDOW, DEFAULT_FILES_API_TIMEOUT_MS, DEFAULT_FILE_EXPIRY_SECONDS, DEFAULT_FILE_QUOTA_CLEANUP_BATCH, DEFAULT_FILE_REFRESH_MARGIN_SECONDS, DEFAULT_IMAGE_OFFLOAD_BYTE_QUANTUM, DEFAULT_IMAGE_OFFLOAD_COUNT_QUANTUM, DEFAULT_INLINE_IMAGE_OFFLOAD_BYTE_QUANTUM, DEFAULT_LOW_DETAIL_IMAGE_PIXEL_BUDGET, DEFAULT_MAX_IMAGES_PER_REQUEST, DEFAULT_MAX_INLINE_REQUEST_IMAGE_BYTES, DEFAULT_MAX_REQUEST_FILES_BYTES, DEFAULT_MAX_TOKENS, DEFAULT_REQUEST_IMAGE_MAX_BYTES, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DeepSeekAdapter, DeepSeekChatCompletionsAdapter, DeepSeekFileId, DeepSeekFileStore, DeepSeekFilesClient, DeepSeekUploadIndex, MAX_FILE_EXPIRY_SECONDS, MAX_FILE_UPLOAD_BYTES, MAX_IMAGE_BYTES, MAX_STORED_FILE_BYTES, MAX_STORED_FILE_COUNT, MIN_FILE_EXPIRY_SECONDS, PUBLIC_BASE_URL, REQUEST_IMAGE_MAX_DIMENSION, catalogModelInfo, deepSeekConfigFields, deepSeekFileScope, deepSeekImageRequestPricing, deepSeekImageTokens, deepSeekRequestImageDimensions, plainOptions, registerDeepSeekProvider, resolveAdapterOptions, resolveRequestImageMaxBytes, resolveRequestImageTarget };