dsh-provider-qoder 0.2.0 → 0.2.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.
package/lib/index.d.ts CHANGED
@@ -44,6 +44,7 @@ interface Config {
44
44
  /** @deprecated Migrated to modelsByRegion for the selected region. */
45
45
  models?: QoderCatalogModel[];
46
46
  streamIdleTimeoutMs?: number;
47
+ preserveThinking?: boolean;
47
48
  }
48
49
  declare const Config: z<Config>;
49
50
  //#endregion
package/lib/index.js CHANGED
@@ -823,10 +823,7 @@ function validateMessageShapes(messages) {
823
823
  if (message.role !== "assistant") throw unsupported("Qoder tool calls are valid only in assistant messages.");
824
824
  continue;
825
825
  }
826
- if (block.type === "reasoning") {
827
- if (message.role !== "assistant") throw unsupported("Qoder historical reasoning is valid only in assistant messages.");
828
- continue;
829
- }
826
+ if (block.type === "reasoning") continue;
830
827
  throw unsupported(`Qoder transport encountered unsupported block type: ${String(block.type)}`);
831
828
  }
832
829
  }
@@ -881,6 +878,7 @@ async function validateAndTranslateMessages(messages, systemPrompt, attachments,
881
878
  uploader: pipeline?.uploader,
882
879
  credentials: pipeline?.credentials
883
880
  };
881
+ const preserveThinking = pipeline?.preserveThinking ?? true;
884
882
  const output = [];
885
883
  if (typeof systemPrompt === "string" && systemPrompt.trim().length > 0) output.push({
886
884
  role: "system",
@@ -911,6 +909,7 @@ async function validateAndTranslateMessages(messages, systemPrompt, attachments,
911
909
  continue;
912
910
  }
913
911
  let text = "";
912
+ let reasoningText = "";
914
913
  const userContent = [];
915
914
  const pendingImages = [];
916
915
  let hasImage = false;
@@ -944,14 +943,19 @@ async function validateAndTranslateMessages(messages, systemPrompt, attachments,
944
943
  });
945
944
  continue;
946
945
  }
947
- if (block.type === "reasoning") continue;
946
+ if (block.type === "reasoning") {
947
+ if (message.role === "assistant") reasoningText += block.text;
948
+ continue;
949
+ }
948
950
  }
949
951
  if (message.role === "assistant") {
950
- if (!text && toolCalls.length === 0) continue;
952
+ const hasReasoning = preserveThinking && reasoningText.length > 0;
953
+ if (!text && toolCalls.length === 0 && !hasReasoning) continue;
951
954
  output.push({
952
955
  role: "assistant",
953
956
  content: text || " ",
954
- ...toolCalls.length === 0 ? {} : { tool_calls: toolCalls }
957
+ ...toolCalls.length === 0 ? {} : { tool_calls: toolCalls },
958
+ ...hasReasoning ? { reasoning_content: reasoningText } : {}
955
959
  });
956
960
  continue;
957
961
  }
@@ -2002,16 +2006,22 @@ async function* parseQoderSse(stream, options = {}) {
2002
2006
  };
2003
2007
  toolCalls.set(upstreamIndex, state);
2004
2008
  }
2005
- if (rawCall.id !== void 0) {
2006
- if (typeof rawCall.id !== "string" || !rawCall.id) throw malformed("Qoder tool call has an invalid id.");
2009
+ if (rawCall.id !== void 0) if (rawCall.id === "" || rawCall.id === null) {} else if (typeof rawCall.id !== "string") throw malformed("Qoder tool call has an invalid id.");
2010
+ else {
2007
2011
  if (state.id && state.id !== rawCall.id) throw malformed("Qoder changed a streamed tool-call id.");
2008
2012
  state.id = rawCall.id;
2009
2013
  }
2014
+ let hasNewName = false;
2010
2015
  if (rawCall.function?.name !== void 0) {
2011
2016
  const name = rawCall.function.name;
2012
- if (typeof name !== "string" || !name) throw malformed("Qoder tool call has an invalid name.");
2013
- if (state.name && state.name !== name) throw malformed("Qoder changed a streamed tool-call name.");
2014
- state.name = name;
2017
+ if (name === "" || name === null) {} else if (typeof name !== "string") throw malformed("Qoder tool call has an invalid name.");
2018
+ else {
2019
+ if (state.name && state.name !== name) throw malformed("Qoder changed a streamed tool-call name.");
2020
+ if (state.name !== name) {
2021
+ state.name = name;
2022
+ hasNewName = true;
2023
+ }
2024
+ }
2015
2025
  }
2016
2026
  if (rawCall.function?.arguments !== void 0) {
2017
2027
  if (typeof rawCall.function.arguments !== "string") throw malformed("Qoder tool-call arguments delta is not a string.");
@@ -2029,7 +2039,7 @@ async function* parseQoderSse(stream, options = {}) {
2029
2039
  ...state.name ? { name: state.name } : {},
2030
2040
  argumentsDelta
2031
2041
  };
2032
- } else if (wasOpen && state.blockIndex !== void 0 && rawCall.function?.name !== void 0) yield {
2042
+ } else if (wasOpen && state.blockIndex !== void 0 && hasNewName) yield {
2033
2043
  type: "tool-call-delta",
2034
2044
  index: state.blockIndex,
2035
2045
  id: ToolCallId(state.id),
@@ -2199,6 +2209,7 @@ var DefaultQoderTransport = class {
2199
2209
  modelFlights = new SingleFlight();
2200
2210
  attachments;
2201
2211
  imageUploader;
2212
+ preserveThinking;
2202
2213
  constructor(options) {
2203
2214
  this.region = options.region;
2204
2215
  this.resolvePat = options.resolvePat;
@@ -2208,6 +2219,7 @@ var DefaultQoderTransport = class {
2208
2219
  this.responseHeaderTimeoutMs = options.responseHeaderTimeoutMs ?? 3e4;
2209
2220
  this.metadataTimeoutMs = options.metadataTimeoutMs;
2210
2221
  this.attachments = options.attachments;
2222
+ this.preserveThinking = options.preserveThinking;
2211
2223
  this.auth = new QoderAuthService({
2212
2224
  fetch: this.fetchImpl,
2213
2225
  logger: this.logger,
@@ -2272,7 +2284,8 @@ var DefaultQoderTransport = class {
2272
2284
  const credentials = await this.auth.getCredentials(pat, options.signal);
2273
2285
  const messages = await translateQoderMessages(options, this.attachments, {
2274
2286
  uploader: this.imageUploader,
2275
- credentials
2287
+ credentials,
2288
+ preserveThinking: this.preserveThinking
2276
2289
  });
2277
2290
  yield* streamQoderChat(options, model, await this.auth.getCredentials(pat, options.signal), messages, {
2278
2291
  fetch: this.fetchImpl,
@@ -2319,7 +2332,8 @@ const Config = z.object({
2319
2332
  region: z.union(["global", "china"]).default("global"),
2320
2333
  modelsByRegion: modelsByRegionSchema.default({}),
2321
2334
  models: z.array(catalogModel),
2322
- streamIdleTimeoutMs: z.number().step(1).min(1).default(defaultStreamIdleTimeoutMs)
2335
+ streamIdleTimeoutMs: z.number().step(1).min(1).default(defaultStreamIdleTimeoutMs),
2336
+ preserveThinking: z.boolean().default(true)
2323
2337
  });
2324
2338
  function resolveModels(models) {
2325
2339
  const resolved = models ?? defaultModels;
@@ -2461,7 +2475,8 @@ function apply(ctx, config = {}) {
2461
2475
  region: initialRegion,
2462
2476
  modelsByRegion: { ...config.modelsByRegion },
2463
2477
  ...hasConfiguredModels ? { models: resolveModels(config.models) } : {},
2464
- streamIdleTimeoutMs: config.streamIdleTimeoutMs ?? 3e5
2478
+ streamIdleTimeoutMs: config.streamIdleTimeoutMs ?? 3e5,
2479
+ preserveThinking: config.preserveThinking ?? true
2465
2480
  };
2466
2481
  let current = () => baseConfig;
2467
2482
  let legacyModelsRegion = initialRegion;
@@ -2470,12 +2485,13 @@ function apply(ctx, config = {}) {
2470
2485
  global: [],
2471
2486
  china: []
2472
2487
  };
2473
- const createTransport = (region, streamIdleTimeoutMs, resolvePat = () => resolveManagedQoderPat(ctx.credentials)) => createQoderTransport({
2488
+ const createTransport = (region, streamIdleTimeoutMs, preserveThinking, resolvePat = () => resolveManagedQoderPat(ctx.credentials)) => createQoderTransport({
2474
2489
  region,
2475
2490
  resolvePat,
2476
2491
  logger,
2477
2492
  streamIdleTimeoutMs,
2478
- attachments: ctx.attachments
2493
+ attachments: ctx.attachments,
2494
+ preserveThinking
2479
2495
  });
2480
2496
  const resolveConfig = () => {
2481
2497
  const value = current();
@@ -2483,14 +2499,16 @@ function apply(ctx, config = {}) {
2483
2499
  return {
2484
2500
  region,
2485
2501
  models: mergeQoderDiscoveryMetadata(modelsFor(value, region, legacyModelsRegion), discoveredCatalogs[region]),
2486
- streamIdleTimeoutMs: value.streamIdleTimeoutMs ?? 3e5
2502
+ streamIdleTimeoutMs: value.streamIdleTimeoutMs ?? 3e5,
2503
+ preserveThinking: value.preserveThinking ?? true
2487
2504
  };
2488
2505
  };
2489
2506
  const initial = resolveConfig();
2490
- let activeTransport = createTransport(initial.region, initial.streamIdleTimeoutMs);
2507
+ let activeTransport = createTransport(initial.region, initial.streamIdleTimeoutMs, initial.preserveThinking);
2491
2508
  let activeTransportConfig = {
2492
2509
  region: initial.region,
2493
- streamIdleTimeoutMs: initial.streamIdleTimeoutMs
2510
+ streamIdleTimeoutMs: initial.streamIdleTimeoutMs,
2511
+ preserveThinking: initial.preserveThinking
2494
2512
  };
2495
2513
  const adapter = new QoderAdapter({
2496
2514
  resolveTransport: () => activeTransport,
@@ -2501,11 +2519,12 @@ function apply(ctx, config = {}) {
2501
2519
  const registration = ctx.llm.registerAdapter([providerQoder], adapter);
2502
2520
  const refreshAdapter = () => {
2503
2521
  const next = resolveConfig();
2504
- if (next.region !== activeTransportConfig.region || next.streamIdleTimeoutMs !== activeTransportConfig.streamIdleTimeoutMs) {
2505
- activeTransport = createTransport(next.region, next.streamIdleTimeoutMs);
2522
+ if (next.region !== activeTransportConfig.region || next.streamIdleTimeoutMs !== activeTransportConfig.streamIdleTimeoutMs || next.preserveThinking !== activeTransportConfig.preserveThinking) {
2523
+ activeTransport = createTransport(next.region, next.streamIdleTimeoutMs, next.preserveThinking);
2506
2524
  activeTransportConfig = {
2507
2525
  region: next.region,
2508
- streamIdleTimeoutMs: next.streamIdleTimeoutMs
2526
+ streamIdleTimeoutMs: next.streamIdleTimeoutMs,
2527
+ preserveThinking: next.preserveThinking
2509
2528
  };
2510
2529
  }
2511
2530
  adapter.replaceModels(next.models);
@@ -2559,7 +2578,7 @@ function apply(ctx, config = {}) {
2559
2578
  const discoverModels = async (signal, suppliedPat) => {
2560
2579
  const snapshot = resolveConfig();
2561
2580
  const normalizedPat = suppliedPat?.trim();
2562
- const models = await (normalizedPat ? createTransport(snapshot.region, snapshot.streamIdleTimeoutMs, () => Promise.resolve(normalizedPat)) : activeTransport).discoverModels(signal);
2581
+ const models = await (normalizedPat ? createTransport(snapshot.region, snapshot.streamIdleTimeoutMs, snapshot.preserveThinking, () => Promise.resolve(normalizedPat)) : activeTransport).discoverModels(signal);
2563
2582
  discoveredCatalogs[snapshot.region] = models;
2564
2583
  refreshAdapter();
2565
2584
  await persistDiscoveredModels(snapshot.region);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-provider-qoder",
3
3
  "description": "Global Qoder subscription adapter for the DeepSeek Harness LLM seam",
4
- "version": "0.2.0",
4
+ "version": "0.2.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },