@rulvar/bridge-ai-sdk 1.83.0 → 1.84.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/dist/index.js +51 -28
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -150,27 +150,35 @@ function bridgeAiSdk(model, options = {}) {
|
|
|
150
150
|
};
|
|
151
151
|
return;
|
|
152
152
|
}
|
|
153
|
-
if (!mapper.terminal)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
153
|
+
if (!mapper.terminal) {
|
|
154
|
+
if (signal?.aborted === true) return;
|
|
155
|
+
yield {
|
|
156
|
+
type: "error",
|
|
157
|
+
error: {
|
|
158
|
+
code: "agent",
|
|
159
|
+
message: `bridged model '${model.modelId}' ended its stream without a finish part`,
|
|
160
|
+
retryable: true,
|
|
161
|
+
data: { kind: "transport" }
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
162
165
|
}
|
|
163
166
|
};
|
|
164
167
|
}
|
|
165
168
|
async function* iterateStream(stream) {
|
|
166
169
|
const reader = stream.getReader();
|
|
170
|
+
let drained = false;
|
|
167
171
|
try {
|
|
168
172
|
while (true) {
|
|
169
173
|
const { done, value } = await reader.read();
|
|
170
|
-
if (done)
|
|
174
|
+
if (done) {
|
|
175
|
+
drained = true;
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
171
178
|
yield value;
|
|
172
179
|
}
|
|
173
180
|
} finally {
|
|
181
|
+
if (!drained) reader.cancel().catch(() => void 0);
|
|
174
182
|
reader.releaseLock();
|
|
175
183
|
}
|
|
176
184
|
}
|
|
@@ -255,7 +263,7 @@ function mapMessages(messages, context) {
|
|
|
255
263
|
type: "tool-call",
|
|
256
264
|
toolCallId: context.ids.wireFor(part.id),
|
|
257
265
|
toolName: part.name,
|
|
258
|
-
input: part.args
|
|
266
|
+
input: unwrapUnparsedArgs(part.args)
|
|
259
267
|
});
|
|
260
268
|
else if (part.type === "provider-raw" && part.provider === context.family) {
|
|
261
269
|
const reinserted = reinsertRetained(part.block);
|
|
@@ -333,7 +341,10 @@ function reinsertRetained(block) {
|
|
|
333
341
|
type: "tool-result",
|
|
334
342
|
toolCallId: record.toolCallId,
|
|
335
343
|
toolName: record.toolName,
|
|
336
|
-
output: {
|
|
344
|
+
output: record.isError === true ? {
|
|
345
|
+
type: "error-json",
|
|
346
|
+
value: record.result
|
|
347
|
+
} : {
|
|
337
348
|
type: "json",
|
|
338
349
|
value: record.result
|
|
339
350
|
},
|
|
@@ -356,6 +367,22 @@ function stringifyResult(result) {
|
|
|
356
367
|
return typeof result === "string" ? result : JSON.stringify(result) ?? "null";
|
|
357
368
|
}
|
|
358
369
|
/**
|
|
370
|
+
* Projects tool-call arguments back into the V4 prompt. The adapter
|
|
371
|
+
* parse-failure wrapper ({__unparsed: raw} and nothing else) projects as
|
|
372
|
+
* the ORIGINAL raw text the model wrote, mirroring the openai wire's
|
|
373
|
+
* guard from the v1.74 experiment review: re-encoding the internal
|
|
374
|
+
* wrapper showed the live model {"__unparsed":"..."} as its own past
|
|
375
|
+
* call and taught it to imitate that shape.
|
|
376
|
+
*/
|
|
377
|
+
function unwrapUnparsedArgs(args) {
|
|
378
|
+
if (typeof args === "object" && args !== null && !Array.isArray(args)) {
|
|
379
|
+
const keys = Object.keys(args);
|
|
380
|
+
const raw = args.__unparsed;
|
|
381
|
+
if (keys.length === 1 && keys[0] === "__unparsed" && typeof raw === "string") return raw;
|
|
382
|
+
}
|
|
383
|
+
return args;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
359
386
|
* Maps the V4 stream-part vocabulary onto ChatEvents, assembling tool
|
|
360
387
|
* arguments, normalizing usage under the Usage invariant, and collecting
|
|
361
388
|
* the turn's retention payload (reasoning parts with their signatures,
|
|
@@ -367,7 +394,6 @@ var StreamMapper = class {
|
|
|
367
394
|
adapterId;
|
|
368
395
|
ids;
|
|
369
396
|
effortDownmapped;
|
|
370
|
-
toolNames = /* @__PURE__ */ new Map();
|
|
371
397
|
startedToolWireIds = /* @__PURE__ */ new Set();
|
|
372
398
|
providerExecutedWireIds = /* @__PURE__ */ new Set();
|
|
373
399
|
reasoning = /* @__PURE__ */ new Map();
|
|
@@ -432,7 +458,6 @@ var StreamMapper = class {
|
|
|
432
458
|
this.providerExecutedWireIds.add(part.id);
|
|
433
459
|
return [];
|
|
434
460
|
}
|
|
435
|
-
this.toolNames.set(part.id, part.toolName);
|
|
436
461
|
this.startedToolWireIds.add(part.id);
|
|
437
462
|
return [{
|
|
438
463
|
type: "tool-call-start",
|
|
@@ -469,26 +494,15 @@ var StreamMapper = class {
|
|
|
469
494
|
name: part.toolName
|
|
470
495
|
});
|
|
471
496
|
const parsed = parseToolArgs(part.input);
|
|
472
|
-
|
|
497
|
+
events.push({
|
|
473
498
|
type: "tool-call-end",
|
|
474
499
|
id: canonical,
|
|
475
|
-
args: parsed.value
|
|
500
|
+
args: parsed.ok ? parsed.value : { __unparsed: part.input }
|
|
476
501
|
});
|
|
477
|
-
else {
|
|
478
|
-
this.terminal = true;
|
|
479
|
-
events.push({
|
|
480
|
-
type: "error",
|
|
481
|
-
error: {
|
|
482
|
-
code: "agent",
|
|
483
|
-
message: `bridged tool call '${part.toolName}' carried arguments that are not valid JSON`,
|
|
484
|
-
retryable: true,
|
|
485
|
-
data: { kind: "transport" }
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
502
|
return events;
|
|
490
503
|
}
|
|
491
504
|
case "tool-result":
|
|
505
|
+
if (part.preliminary === true) return [];
|
|
492
506
|
this.retained.push({
|
|
493
507
|
type: "tool-result",
|
|
494
508
|
toolCallId: part.toolCallId,
|
|
@@ -537,6 +551,9 @@ var StreamMapper = class {
|
|
|
537
551
|
}
|
|
538
552
|
mapFinish(part) {
|
|
539
553
|
if (part.finishReason.unified === "error") return [{
|
|
554
|
+
type: "usage",
|
|
555
|
+
usage: mapUsage(part.usage)
|
|
556
|
+
}, {
|
|
540
557
|
type: "error",
|
|
541
558
|
error: {
|
|
542
559
|
code: "agent",
|
|
@@ -545,6 +562,12 @@ var StreamMapper = class {
|
|
|
545
562
|
data: { kind: "transport" }
|
|
546
563
|
}
|
|
547
564
|
}];
|
|
565
|
+
for (const acc of this.reasoning.values()) this.retained.push({
|
|
566
|
+
type: "reasoning",
|
|
567
|
+
text: acc.text,
|
|
568
|
+
...acc.providerMetadata === void 0 ? {} : { providerMetadata: acc.providerMetadata }
|
|
569
|
+
});
|
|
570
|
+
this.reasoning.clear();
|
|
548
571
|
const finish = mapFinishReason(part.finishReason, this.adapterId);
|
|
549
572
|
const usage = mapUsage(part.usage);
|
|
550
573
|
const bag = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulvar/bridge-ai-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.84.0",
|
|
4
4
|
"description": "Rulvar bridge adapter wrapping any Vercel AI SDK LanguageModelV4 as a ProviderAdapter.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ai-sdk/provider": "^4.0.0",
|
|
26
|
-
"@rulvar/core": "1.
|
|
26
|
+
"@rulvar/core": "1.84.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@ai-sdk/google": "^4.0.0",
|
|
30
30
|
"@types/node": "^22.20.0",
|
|
31
31
|
"tsdown": "^0.22.3",
|
|
32
32
|
"typescript": "~6.0.3",
|
|
33
|
-
"@rulvar/testing": "1.
|
|
33
|
+
"@rulvar/testing": "1.84.0"
|
|
34
34
|
},
|
|
35
35
|
"repository": {
|
|
36
36
|
"type": "git",
|