@coder/ai-sdk-agent 0.6.1 → 0.6.3
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/README.md +866 -43
- package/dist/index.js +55 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1328,10 +1328,12 @@ var TurnTranslator = class {
|
|
|
1328
1328
|
// false only for announce-style empty snapshots, whose in-flight deltas are
|
|
1329
1329
|
// still claimable by a same-id commit.
|
|
1330
1330
|
#emittedByMessageId = /* @__PURE__ */ new Map();
|
|
1331
|
-
// Same-id revision snapshots
|
|
1332
|
-
// open (latest wins). chatd sends each revision
|
|
1333
|
-
// connection, so the suffix cannot wait for a replay — it
|
|
1334
|
-
// soon as the next step's snapshot settles ownership of
|
|
1331
|
+
// Same-id revision snapshots (their full wire content) that arrived while
|
|
1332
|
+
// the NEXT step's deltas were open (latest wins). chatd sends each revision
|
|
1333
|
+
// once on a healthy connection, so the suffix cannot wait for a replay — it
|
|
1334
|
+
// is reconciled as soon as the next step's snapshot settles ownership of
|
|
1335
|
+
// the pending deltas, or flushed by finish() when the segment ends without
|
|
1336
|
+
// one (see #78).
|
|
1335
1337
|
#deferredRevisions = /* @__PURE__ */ new Map();
|
|
1336
1338
|
#error;
|
|
1337
1339
|
#terminalStatus;
|
|
@@ -1406,22 +1408,34 @@ var TurnTranslator = class {
|
|
|
1406
1408
|
* next delta simply opens a fresh block (its pending content is tracked
|
|
1407
1409
|
* independently of blocks).
|
|
1408
1410
|
*/
|
|
1409
|
-
#reconcileRevision(out, rec,
|
|
1410
|
-
const
|
|
1411
|
-
const
|
|
1412
|
-
|
|
1411
|
+
#reconcileRevision(out, rec, content) {
|
|
1412
|
+
const fullText = joinContent(content, "text");
|
|
1413
|
+
const fullReasoning = joinContent(content, "reasoning");
|
|
1414
|
+
const textOk = fullText.length > rec.text.length && fullText.startsWith(rec.text);
|
|
1415
|
+
const reasoningOk = fullReasoning.length > rec.reasoning.length && fullReasoning.startsWith(rec.reasoning);
|
|
1416
|
+
if (!textOk && !reasoningOk) return;
|
|
1413
1417
|
this.#closeText(out);
|
|
1414
1418
|
this.#closeReasoning(out);
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1419
|
+
let seenText = 0;
|
|
1420
|
+
let seenReasoning = 0;
|
|
1421
|
+
for (const p of content) {
|
|
1422
|
+
if (p.type === "text") {
|
|
1423
|
+
const end = seenText + (p.text ?? "").length;
|
|
1424
|
+
const from = Math.max(seenText, rec.text.length);
|
|
1425
|
+
if (textOk && end > from) this.#emitTextDelta(out, fullText.slice(from, end));
|
|
1426
|
+
seenText = end;
|
|
1427
|
+
} else if (p.type === "reasoning") {
|
|
1428
|
+
const end = seenReasoning + (p.text ?? "").length;
|
|
1429
|
+
const from = Math.max(seenReasoning, rec.reasoning.length);
|
|
1430
|
+
if (reasoningOk && end > from)
|
|
1431
|
+
this.#emitReasoningDelta(out, fullReasoning.slice(from, end));
|
|
1432
|
+
seenReasoning = end;
|
|
1433
|
+
}
|
|
1424
1434
|
}
|
|
1435
|
+
if (textOk) rec.text = fullText;
|
|
1436
|
+
if (reasoningOk) rec.reasoning = fullReasoning;
|
|
1437
|
+
this.#closeText(out);
|
|
1438
|
+
this.#closeReasoning(out);
|
|
1425
1439
|
}
|
|
1426
1440
|
// --- tool helpers ---------------------------------------------------------
|
|
1427
1441
|
#isClientTool(name) {
|
|
@@ -1504,6 +1518,7 @@ var TurnTranslator = class {
|
|
|
1504
1518
|
for (const tc of ev.action_required?.tool_calls ?? []) {
|
|
1505
1519
|
if (this.#clientToolCalls.has(tc.tool_call_id)) continue;
|
|
1506
1520
|
if (this.#submittedToolCallIds.has(tc.tool_call_id)) continue;
|
|
1521
|
+
this.#flushDeferredRevisions(out);
|
|
1507
1522
|
this.#closeText(out);
|
|
1508
1523
|
this.#closeReasoning(out);
|
|
1509
1524
|
this.#clientToolCalls.add(tc.tool_call_id);
|
|
@@ -1521,6 +1536,7 @@ var TurnTranslator = class {
|
|
|
1521
1536
|
case "error":
|
|
1522
1537
|
if (ev.error) {
|
|
1523
1538
|
this.#error = ev.error;
|
|
1539
|
+
this.#flushDeferredRevisions(out);
|
|
1524
1540
|
out.push({ type: "error", error: new CoderChatError(ev.error) });
|
|
1525
1541
|
}
|
|
1526
1542
|
break;
|
|
@@ -1586,9 +1602,9 @@ var TurnTranslator = class {
|
|
|
1586
1602
|
const fullReasoning = joinContent(content, "reasoning");
|
|
1587
1603
|
const known = this.#emittedByMessageId.get(message.id);
|
|
1588
1604
|
if (known && message.id !== this.#currentAssistantId) {
|
|
1589
|
-
this.#reconcileRevision(out, known,
|
|
1605
|
+
this.#reconcileRevision(out, known, content);
|
|
1590
1606
|
} else if (known && this.#deltasSinceSnapshot && known.substantive) {
|
|
1591
|
-
this.#deferredRevisions.set(message.id,
|
|
1607
|
+
this.#deferredRevisions.set(message.id, content);
|
|
1592
1608
|
} else {
|
|
1593
1609
|
if (this.#currentAssistantId !== void 0 && this.#currentAssistantId !== message.id && !this.#deltasSinceSnapshot) {
|
|
1594
1610
|
this.#closeText(out);
|
|
@@ -1628,8 +1644,7 @@ var TurnTranslator = class {
|
|
|
1628
1644
|
for (const [id, deferred] of this.#deferredRevisions) {
|
|
1629
1645
|
if (id === message.id) continue;
|
|
1630
1646
|
const deferredRec = this.#emittedByMessageId.get(id);
|
|
1631
|
-
if (deferredRec)
|
|
1632
|
-
this.#reconcileRevision(out, deferredRec, deferred.text, deferred.reasoning);
|
|
1647
|
+
if (deferredRec) this.#reconcileRevision(out, deferredRec, deferred);
|
|
1633
1648
|
this.#deferredRevisions.delete(id);
|
|
1634
1649
|
}
|
|
1635
1650
|
}
|
|
@@ -1649,8 +1664,27 @@ var TurnTranslator = class {
|
|
|
1649
1664
|
}
|
|
1650
1665
|
}
|
|
1651
1666
|
// --- finish ---------------------------------------------------------------
|
|
1667
|
+
/**
|
|
1668
|
+
* Flushes revisions still deferred behind a delta-ownership race that never
|
|
1669
|
+
* settled — the racing step ended terminally without committing a snapshot,
|
|
1670
|
+
* so the drain in #ingestMessage never ran. chatd sent each revision once;
|
|
1671
|
+
* this is the segment's last chance to emit its suffix (#78). Attribution
|
|
1672
|
+
* care: the pending deltas' owner never committed, so they attribute to no
|
|
1673
|
+
* one — reconciliation is against the ledger alone, and only
|
|
1674
|
+
* ledger-extension suffixes may emit. Runs at finish() and, because
|
|
1675
|
+
* doGenerate() throws on a streamed error part and closes the generator
|
|
1676
|
+
* before finish() (issue #72), ahead of the error part in ingest().
|
|
1677
|
+
*/
|
|
1678
|
+
#flushDeferredRevisions(out) {
|
|
1679
|
+
for (const [id, deferred] of this.#deferredRevisions) {
|
|
1680
|
+
const rec = this.#emittedByMessageId.get(id);
|
|
1681
|
+
if (rec) this.#reconcileRevision(out, rec, deferred);
|
|
1682
|
+
}
|
|
1683
|
+
this.#deferredRevisions.clear();
|
|
1684
|
+
}
|
|
1652
1685
|
finish() {
|
|
1653
1686
|
const out = [];
|
|
1687
|
+
this.#flushDeferredRevisions(out);
|
|
1654
1688
|
this.#closeText(out);
|
|
1655
1689
|
this.#closeReasoning(out);
|
|
1656
1690
|
let unified;
|