mohdel 0.99.0 → 0.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -301,7 +301,9 @@ function buildRequest (envelope, spec, config) {
301
301
  const args = {
302
302
  model: spec?.model ?? bareOf(envelope.model),
303
303
  temperature: 0,
304
- messages: toChatMessages(envelope.prompt)
304
+ messages: toChatMessages(envelope.prompt, {
305
+ reasoningPad: typeof spec?.reasoningContentPlaceholder === 'string' ? spec.reasoningContentPlaceholder : null
306
+ })
305
307
  }
306
308
 
307
309
  if (envelope.outputBudget !== undefined) {
@@ -351,9 +353,20 @@ function buildRequest (envelope, spec, config) {
351
353
 
352
354
  /**
353
355
  * @param {string | import('#core/envelope.js').Message[]} prompt
356
+ * @param {{ reasoningPad?: string | null }} [opts]
357
+ * `reasoningPad`: when a string (including `''`), assistant messages without
358
+ * extractable reasoning get `reasoning_content: <pad>` so providers that
359
+ * require the field on every assistant turn (e.g. deepseek-v4-pro) accept
360
+ * the resumed transcript. `null` / unset disables padding (default — most
361
+ * chat-completions providers don't require it).
362
+ *
363
+ * Scope: this is a chat-completions wire-format quirk. Gemini's
364
+ * `thoughtSignature` and Anthropic's `thinking` blocks live in their
365
+ * own adapters and have their own roundtrip rules.
354
366
  * @returns {Array<any>}
355
367
  */
356
- function toChatMessages (prompt) {
368
+ function toChatMessages (prompt, opts = {}) {
369
+ const pad = typeof opts.reasoningPad === 'string' ? opts.reasoningPad : null
357
370
  if (typeof prompt === 'string') return [{ role: 'user', content: prompt }]
358
371
  return prompt.map(m => {
359
372
  if (m.role === 'tool') {
@@ -364,6 +377,7 @@ function toChatMessages (prompt) {
364
377
  }
365
378
  }
366
379
  const reasoning = m.role === 'assistant' ? extractReasoning(m.content) : null
380
+ const reasoningField = reasoning ?? (pad !== null && m.role === 'assistant' ? pad : null)
367
381
  if (m.role === 'assistant' && m.toolCalls?.length) {
368
382
  // Chat Completions assistant turn: optional `content` + the
369
383
  // `tool_calls` array. `arguments` must be a JSON string on
@@ -380,11 +394,11 @@ function toChatMessages (prompt) {
380
394
  }
381
395
  }))
382
396
  }
383
- if (reasoning) msg.reasoning_content = reasoning
397
+ if (reasoningField !== null) msg.reasoning_content = reasoningField
384
398
  return msg
385
399
  }
386
400
  const msg = { role: m.role, content: flattenText(m.content) }
387
- if (reasoning) msg.reasoning_content = reasoning
401
+ if (reasoningField !== null) msg.reasoning_content = reasoningField
388
402
  return msg
389
403
  })
390
404
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mohdel",
3
- "version": "0.99.0",
3
+ "version": "0.100.0",
4
4
  "license": "MIT",
5
5
  "author": {
6
6
  "name": "Christophe Le Bars",
@@ -87,7 +87,7 @@
87
87
  "@opentelemetry/exporter-trace-otlp-grpc": "^0.216.0",
88
88
  "@opentelemetry/sdk-node": "^0.216.0",
89
89
  "chalk": "^5.4.0",
90
- "mohdel-thin-gate-linux-x64-gnu": "0.99.0"
90
+ "mohdel-thin-gate-linux-x64-gnu": "0.100.0"
91
91
  },
92
92
  "dependencies": {
93
93
  "@anthropic-ai/sdk": "^0.91.1",