mohdel 3.8.1 → 3.9.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.
package/js/core/envelope.js
CHANGED
|
@@ -122,6 +122,13 @@
|
|
|
122
122
|
* @property {('text'|'reasoning'|'image')} type
|
|
123
123
|
* @property {string} [text]
|
|
124
124
|
* Required on `text` and `reasoning` parts.
|
|
125
|
+
* @property {string} [encrypted]
|
|
126
|
+
* On a `reasoning` part: the provider's opaque reasoning, replayed only
|
|
127
|
+
* to `model` and dropped for any other.
|
|
128
|
+
* @property {string} [id]
|
|
129
|
+
* On a `reasoning` part carrying `encrypted`: the provider's item id.
|
|
130
|
+
* @property {string} [model]
|
|
131
|
+
* On a `reasoning` part carrying `encrypted`: the model that produced it.
|
|
125
132
|
* @property {string} [fileUri]
|
|
126
133
|
* Required on `image` parts. Same schemes and local-read rules as
|
|
127
134
|
* an envelope `images` ref. Accepted on `user` and `tool` messages.
|
package/js/core/events.js
CHANGED
|
@@ -101,6 +101,10 @@
|
|
|
101
101
|
* `'insufficientOutputBudget' | 'aborted' | ...` additive union.
|
|
102
102
|
* @property {ToolCall[]} [toolCalls]
|
|
103
103
|
* Present when `status === 'tool_use'`.
|
|
104
|
+
* @property {import('./envelope.js').MessagePart[]} [reasoningParts]
|
|
105
|
+
* Reasoning parts carrying `encrypted`, from a provider that returns its
|
|
106
|
+
* reasoning to be replayed. A multi-turn caller puts them at the head
|
|
107
|
+
* of the assistant message it records for this result.
|
|
104
108
|
* @property {number} [maxInterFrameMs]
|
|
105
109
|
* Longest gap (ms) between adapter events during the call —
|
|
106
110
|
* from `startedAt` to the first frame, between consecutive
|
|
@@ -562,7 +562,7 @@ function flattenText (content) {
|
|
|
562
562
|
/** @param {string | import('#core/envelope.js').MessagePart[]} content */
|
|
563
563
|
function extractReasoning (content) {
|
|
564
564
|
if (typeof content === 'string' || !Array.isArray(content)) return null
|
|
565
|
-
const parts = content.filter(p => p.type === 'reasoning' && p.text).map(p => p.text)
|
|
565
|
+
const parts = content.filter(p => p.type === 'reasoning' && p.text && !p.encrypted).map(p => p.text)
|
|
566
566
|
return parts.length ? parts.join('\n') : null
|
|
567
567
|
}
|
|
568
568
|
|
|
@@ -70,7 +70,8 @@ export async function * openai (envelope, deps = {}) {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
const { instructions, input } = splitPrompt(envelope.prompt, imageParts, {
|
|
73
|
-
toolResultImages: ['openai', 'chatgpt'].includes(providerOf(envelope.model))
|
|
73
|
+
toolResultImages: ['openai', 'chatgpt'].includes(providerOf(envelope.model)),
|
|
74
|
+
model: envelope.model
|
|
74
75
|
})
|
|
75
76
|
if (imageInputs.length) injectImageParts(input, imageInputs)
|
|
76
77
|
|
|
@@ -94,6 +95,8 @@ export async function * openai (envelope, deps = {}) {
|
|
|
94
95
|
// Tool-call accumulation: itemId → {call_id, name, arguments}
|
|
95
96
|
/** @type {Map<string, {call_id: string, name: string, arguments: string}>} */
|
|
96
97
|
const toolItems = new Map()
|
|
98
|
+
/** @type {import('#core/envelope.js').MessagePart[]} */
|
|
99
|
+
const reasoningParts = []
|
|
97
100
|
|
|
98
101
|
try {
|
|
99
102
|
const stream = await client.responses.stream(request, { signal })
|
|
@@ -122,6 +125,18 @@ export async function * openai (envelope, deps = {}) {
|
|
|
122
125
|
}
|
|
123
126
|
break
|
|
124
127
|
|
|
128
|
+
case 'response.output_item.done':
|
|
129
|
+
if (event.item?.type === 'reasoning' && event.item.encrypted_content) {
|
|
130
|
+
reasoningParts.push({
|
|
131
|
+
type: 'reasoning',
|
|
132
|
+
text: (event.item.summary ?? []).map(s => s.text).join('\n'),
|
|
133
|
+
id: event.item.id,
|
|
134
|
+
encrypted: event.item.encrypted_content,
|
|
135
|
+
model: envelope.model
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
break
|
|
139
|
+
|
|
125
140
|
case 'response.function_call_arguments.delta':
|
|
126
141
|
if (event.item_id && event.delta) {
|
|
127
142
|
const t = toolItems.get(event.item_id)
|
|
@@ -240,6 +255,7 @@ export async function * openai (envelope, deps = {}) {
|
|
|
240
255
|
}
|
|
241
256
|
}
|
|
242
257
|
if (warning) done.result.warning = warning
|
|
258
|
+
if (reasoningParts.length) done.result.reasoningParts = reasoningParts
|
|
243
259
|
if (toolItems.size > 0) {
|
|
244
260
|
done.result.toolCalls = fromOpenAIToolCalls(Array.from(toolItems.values()))
|
|
245
261
|
}
|
|
@@ -346,6 +362,7 @@ function buildRequest (envelope, input, instructions) {
|
|
|
346
362
|
request.max_output_tokens += headroom
|
|
347
363
|
}
|
|
348
364
|
request.reasoning = { effort }
|
|
365
|
+
if (effort !== 'none') request.include = ['reasoning.encrypted_content']
|
|
349
366
|
}
|
|
350
367
|
}
|
|
351
368
|
|
|
@@ -392,7 +409,7 @@ function buildRequest (envelope, input, instructions) {
|
|
|
392
409
|
*
|
|
393
410
|
* @param {string | import('#core/envelope.js').Message[]} prompt
|
|
394
411
|
* @param {Map<object, import('./_images.js').LoadedImage>} imageParts
|
|
395
|
-
* @param {{toolResultImages: boolean}} opts
|
|
412
|
+
* @param {{toolResultImages: boolean, model: string}} opts
|
|
396
413
|
*/
|
|
397
414
|
function splitPrompt (prompt, imageParts, opts) {
|
|
398
415
|
if (typeof prompt === 'string') {
|
|
@@ -410,6 +427,18 @@ function splitPrompt (prompt, imageParts, opts) {
|
|
|
410
427
|
}
|
|
411
428
|
for (const m of prompt) {
|
|
412
429
|
if (m.role !== 'tool') flushHoisted()
|
|
430
|
+
if (m.role === 'assistant' && Array.isArray(m.content)) {
|
|
431
|
+
for (const p of m.content) {
|
|
432
|
+
if (p.type === 'reasoning' && p.encrypted && p.model === opts.model) {
|
|
433
|
+
input.push({
|
|
434
|
+
type: 'reasoning',
|
|
435
|
+
id: p.id,
|
|
436
|
+
summary: p.text ? [{ type: 'summary_text', text: p.text }] : [],
|
|
437
|
+
encrypted_content: p.encrypted
|
|
438
|
+
})
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
413
442
|
if (m.role === 'system') {
|
|
414
443
|
systemParts.push(flattenText(m.content))
|
|
415
444
|
} else if (m.role === 'tool') {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mohdel",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Christophe Le Bars",
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
"@opentelemetry/exporter-trace-otlp-grpc": "^0.222.0",
|
|
145
145
|
"@opentelemetry/sdk-node": "^0.222.0",
|
|
146
146
|
"chalk": "^6.0.1",
|
|
147
|
-
"mohdel-thin-gate-linux-x64-gnu": "3.
|
|
147
|
+
"mohdel-thin-gate-linux-x64-gnu": "3.9.0"
|
|
148
148
|
},
|
|
149
149
|
"dependencies": {
|
|
150
150
|
"@anthropic-ai/sdk": "^0.129.0",
|