@askalf/dario 5.5.58 → 5.5.59
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/cc-template.js +40 -9
- package/package.json +1 -1
package/dist/cc-template.js
CHANGED
|
@@ -1605,17 +1605,21 @@ export function buildCCRequest(clientBody, billingTag, cacheControl, identity, o
|
|
|
1605
1605
|
continue;
|
|
1606
1606
|
msg.content = msg.content.filter((b) => !(b.type === 'text' && (typeof b.text !== 'string' || b.text.trim() === '')));
|
|
1607
1607
|
}
|
|
1608
|
-
// A
|
|
1609
|
-
//
|
|
1610
|
-
//
|
|
1611
|
-
//
|
|
1612
|
-
//
|
|
1613
|
-
//
|
|
1614
|
-
//
|
|
1615
|
-
//
|
|
1608
|
+
// A turn left with no blocks is dropped — but only MID-conversation, where
|
|
1609
|
+
// the API combines the now-adjacent same-role turns and where the #1066
|
|
1610
|
+
// session-killer lives (the empty turn sits in history, so every later
|
|
1611
|
+
// request carries it). BOTH roles: a user turn whose only block was empty,
|
|
1612
|
+
// and an assistant turn the filter emptied (a null/non-string text block the
|
|
1613
|
+
// proxy-level string scrub leaves behind, dario#1092) — either one mid-stream
|
|
1614
|
+
// is "messages.N: … content must contain at least one block" upstream. The
|
|
1615
|
+
// FINAL turn is deliberately left in place per the dario#1033 decision below:
|
|
1616
|
+
// popping it would expose the assistant turn behind it and convert an honest
|
|
1617
|
+
// "content must contain at least one block" into a misleading prefill
|
|
1618
|
+
// rejection. Hoisted with the filter (dario#1077): removing a block can empty
|
|
1619
|
+
// a turn on any path.
|
|
1616
1620
|
for (let i = messages.length - 2; i >= 0; i--) {
|
|
1617
1621
|
const m = messages[i];
|
|
1618
|
-
if (
|
|
1622
|
+
if (Array.isArray(m.content) && m.content.length === 0) {
|
|
1619
1623
|
messages.splice(i, 1);
|
|
1620
1624
|
}
|
|
1621
1625
|
}
|
|
@@ -1661,6 +1665,33 @@ export function buildCCRequest(clientBody, billingTag, cacheControl, identity, o
|
|
|
1661
1665
|
// configure how NON-CC clients are dressed up as CC, which a genuine CC
|
|
1662
1666
|
// client doesn't need.
|
|
1663
1667
|
if (isGenuineCCClient(clientBody)) {
|
|
1668
|
+
// ── dario#1092: recover an empty FINAL user turn (genuine CC only) ──
|
|
1669
|
+
// CC's stream-interruption retry path can append a user turn with
|
|
1670
|
+
// content:[] as the final message. #1033 leaves an empty final user turn in
|
|
1671
|
+
// place on the GENERAL path so a malformed third-party client gets an honest
|
|
1672
|
+
// upstream error rather than a mangled conversation. But on a genuine CC
|
|
1673
|
+
// session that empty turn is CC's OWN retry artifact, and "let upstream name
|
|
1674
|
+
// it" is the #1066 session-killer: it sticks in history and every later
|
|
1675
|
+
// request dies with "messages.N: user messages must have non-empty content".
|
|
1676
|
+
// The retry's intent is to regenerate the response whose stream was cut, so
|
|
1677
|
+
// rewind to it — drop the empty user turn and the assistant turn it
|
|
1678
|
+
// interrupted, landing the request back on the last real user turn for a
|
|
1679
|
+
// clean regeneration.
|
|
1680
|
+
//
|
|
1681
|
+
// Bounded and distinct from the #37 runaway loop: that popped a NON-empty
|
|
1682
|
+
// trailing assistant with no empty user after it; this fires ONLY on a
|
|
1683
|
+
// trailing EMPTY user turn and pops at most the one pair. Mid-conversation
|
|
1684
|
+
// empties are already gone above, so a trailing empty user is the only shape
|
|
1685
|
+
// that can reach here, and the assistant behind it is real.
|
|
1686
|
+
{
|
|
1687
|
+
const last = messages.length > 0 ? messages[messages.length - 1] : undefined;
|
|
1688
|
+
if (last && last.role === 'user' && Array.isArray(last.content) && last.content.length === 0) {
|
|
1689
|
+
messages.pop();
|
|
1690
|
+
const prev = messages[messages.length - 1];
|
|
1691
|
+
if (prev && prev.role === 'assistant')
|
|
1692
|
+
messages.pop();
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1664
1695
|
const clientSystem = clientBody.system;
|
|
1665
1696
|
const system = clientSystem.map((b, i) => {
|
|
1666
1697
|
const copy = { ...b };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askalf/dario",
|
|
3
|
-
"version": "5.5.
|
|
3
|
+
"version": "5.5.59",
|
|
4
4
|
"description": "Use your Claude Pro/Max subscription in any tool — Cursor, Cline, Aider, the Agent SDK, your scripts — at subscription pricing, not per-token API bills. One local Anthropic + OpenAI-compatible endpoint.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|