@botiverse/raft-sdk 0.3.1 → 0.3.2
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/cjs/index.cjs +54 -10
- package/dist/esm/index.js +54 -10
- package/dist/index.d.ts +10 -1
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -11102,6 +11102,43 @@ function sortBySeq(messages) {
|
|
|
11102
11102
|
function projectRaftMessages(envelopes) {
|
|
11103
11103
|
return envelopes.map(projectRaftMessage).filter((m) => m !== null);
|
|
11104
11104
|
}
|
|
11105
|
+
/** The conversation fields a target string names; `null` for a shape this cannot read. */
|
|
11106
|
+
function identityFromTarget(target) {
|
|
11107
|
+
const dm = /^dm:@([^:\s]+)(?::([^:\s]+))?$/.exec(target);
|
|
11108
|
+
if (dm) return dm[2] ? {
|
|
11109
|
+
channel_type: "thread",
|
|
11110
|
+
channel_name: dm[2],
|
|
11111
|
+
parent_channel_name: dm[1],
|
|
11112
|
+
parent_channel_type: "dm"
|
|
11113
|
+
} : {
|
|
11114
|
+
channel_type: "dm",
|
|
11115
|
+
channel_name: dm[1]
|
|
11116
|
+
};
|
|
11117
|
+
const channel = /^#([^:\s]+)(?::([^:\s]+))?$/.exec(target);
|
|
11118
|
+
if (channel) return channel[2] ? {
|
|
11119
|
+
channel_type: "thread",
|
|
11120
|
+
channel_name: channel[2],
|
|
11121
|
+
parent_channel_name: channel[1],
|
|
11122
|
+
parent_channel_type: "channel"
|
|
11123
|
+
} : {
|
|
11124
|
+
channel_type: "channel",
|
|
11125
|
+
channel_name: channel[1]
|
|
11126
|
+
};
|
|
11127
|
+
return null;
|
|
11128
|
+
}
|
|
11129
|
+
/**
|
|
11130
|
+
* Project envelopes that all belong to one known conversation. Some Server
|
|
11131
|
+
* responses (held previews) send envelopes without conversation fields
|
|
11132
|
+
* because the request already named the target; fill them from `target`
|
|
11133
|
+
* instead of dropping the message.
|
|
11134
|
+
*/
|
|
11135
|
+
function projectRaftMessagesInTarget(envelopes, target) {
|
|
11136
|
+
const identity = identityFromTarget(target);
|
|
11137
|
+
return envelopes.map((envelope) => projectRaftMessage(identity && !hasAgentMessageIdentity(envelope) ? {
|
|
11138
|
+
...envelope,
|
|
11139
|
+
...identity
|
|
11140
|
+
} : envelope)).filter((m) => m !== null);
|
|
11141
|
+
}
|
|
11105
11142
|
//#endregion
|
|
11106
11143
|
//#region ../shared/src/agentOps/frontier.ts
|
|
11107
11144
|
const MAX_EXACT_SEQS = 2500;
|
|
@@ -11157,10 +11194,11 @@ var SeenFrontier = class SeenFrontier {
|
|
|
11157
11194
|
* Attest that the model saw the context a held send/claim returned. Call it
|
|
11158
11195
|
* only after the held messages actually reached the model (the SDK cannot
|
|
11159
11196
|
* know that, so it never records this implicitly). Returns false and records
|
|
11160
|
-
* nothing when the context was withheld
|
|
11197
|
+
* nothing when the context was withheld, not fully shown
|
|
11198
|
+
* (`contextComplete: false`), or the Server sent no boundary.
|
|
11161
11199
|
*/
|
|
11162
11200
|
recordHeld(held) {
|
|
11163
|
-
if (held.withheld || held.seenUpToSeq === null) return false;
|
|
11201
|
+
if (held.withheld || held.contextComplete === false || held.seenUpToSeq === null) return false;
|
|
11164
11202
|
this.recordUpTo(held.target, held.seenUpToSeq);
|
|
11165
11203
|
return true;
|
|
11166
11204
|
}
|
|
@@ -11557,6 +11595,7 @@ function heldText(held, action) {
|
|
|
11557
11595
|
if (held.formalMentionCount > 0) lines.push(`Note: ${held.formalMentionCount} of these messages formally @mention you.`);
|
|
11558
11596
|
if (held.omittedMessageCount > 0) lines.push(`${held.omittedMessageCount} earlier ${held.omittedMessageCount === 1 ? "message" : "messages"} not shown.`);
|
|
11559
11597
|
if (held.heldMessages.length > 0) lines.push(formatAgentMessages(held.heldMessages.map((m) => toAgentMessageLike(m.raw))));
|
|
11598
|
+
if (!held.contextComplete) lines.push("Not all of them are shown here; read the conversation before sending again.");
|
|
11560
11599
|
lines.push(`Full text: raft message read --target "${held.target}"`);
|
|
11561
11600
|
return lines.join("\n");
|
|
11562
11601
|
}
|
|
@@ -11568,26 +11607,30 @@ function heldNext(held) {
|
|
|
11568
11607
|
target: held.target,
|
|
11569
11608
|
...held.continuation
|
|
11570
11609
|
},
|
|
11571
|
-
why: held.withheld ? "Newer messages exist in this conversation but were withheld; read them, then send again with the same idempotencyKey." : "Newer messages arrived in this conversation. Show the held messages to the model, call frontier.recordHeld(held) to attest that, then send again with these args (same idempotencyKey, seen.upToSeq)."
|
|
11610
|
+
why: held.withheld ? "Newer messages exist in this conversation but were withheld; read them, then send again with the same idempotencyKey." : !held.contextComplete ? "Newer messages arrived in this conversation and not all of them are shown here; read the conversation, then send again with the same idempotencyKey." : "Newer messages arrived in this conversation. Show the held messages to the model, call frontier.recordHeld(held) to attest that, then send again with these args (same idempotencyKey, seen.upToSeq)."
|
|
11572
11611
|
};
|
|
11573
11612
|
}
|
|
11574
11613
|
function projectHeld(target, data, idempotencyKey) {
|
|
11575
11614
|
const withheld = data.freshnessContextMode === "withheld";
|
|
11576
|
-
const heldMessages =
|
|
11615
|
+
const heldMessages = projectRaftMessagesInTarget(data.heldMessages ?? [], target);
|
|
11577
11616
|
const seenUpToSeq = typeof data.seenUpToSeq === "number" ? data.seenUpToSeq : null;
|
|
11617
|
+
const newMessageCount = withheld ? data.withheldMessageCount ?? 0 : data.newMessageCount ?? heldMessages.length;
|
|
11618
|
+
const omittedMessageCount = data.omittedMessageCount ?? 0;
|
|
11619
|
+
const contextComplete = !withheld && heldMessages.length + omittedMessageCount >= newMessageCount;
|
|
11578
11620
|
return {
|
|
11579
11621
|
target,
|
|
11580
11622
|
idempotencyKey,
|
|
11581
11623
|
continuation: {
|
|
11582
11624
|
idempotencyKey,
|
|
11583
|
-
|
|
11625
|
+
...contextComplete && seenUpToSeq !== null ? { seen: { upToSeq: seenUpToSeq } } : {}
|
|
11584
11626
|
},
|
|
11585
|
-
newMessageCount
|
|
11627
|
+
newMessageCount,
|
|
11586
11628
|
heldMessages,
|
|
11587
|
-
omittedMessageCount
|
|
11629
|
+
omittedMessageCount,
|
|
11588
11630
|
formalMentionCount: data.mentionAnnotation?.formalMentionCount ?? 0,
|
|
11589
11631
|
seenUpToSeq,
|
|
11590
|
-
withheld
|
|
11632
|
+
withheld,
|
|
11633
|
+
contextComplete
|
|
11591
11634
|
};
|
|
11592
11635
|
}
|
|
11593
11636
|
function isHeldResponse(data) {
|
|
@@ -11644,9 +11687,10 @@ async function sendMessage(client, request, frontier, internal = {}) {
|
|
|
11644
11687
|
...request,
|
|
11645
11688
|
idempotencyKey
|
|
11646
11689
|
};
|
|
11690
|
+
const base = projectHeld(request.target, data, idempotencyKey);
|
|
11647
11691
|
const held = {
|
|
11648
|
-
...
|
|
11649
|
-
resend: (options) => sendMessage(client, options.seen === "held" && typeof data.seenUpToSeq === "number" ? {
|
|
11692
|
+
...base,
|
|
11693
|
+
resend: (options) => sendMessage(client, options.seen === "held" && base.contextComplete && typeof data.seenUpToSeq === "number" ? {
|
|
11650
11694
|
...keyed,
|
|
11651
11695
|
seen: {
|
|
11652
11696
|
upToSeq: data.seenUpToSeq,
|
package/dist/esm/index.js
CHANGED
|
@@ -11101,6 +11101,43 @@ function sortBySeq(messages) {
|
|
|
11101
11101
|
function projectRaftMessages(envelopes) {
|
|
11102
11102
|
return envelopes.map(projectRaftMessage).filter((m) => m !== null);
|
|
11103
11103
|
}
|
|
11104
|
+
/** The conversation fields a target string names; `null` for a shape this cannot read. */
|
|
11105
|
+
function identityFromTarget(target) {
|
|
11106
|
+
const dm = /^dm:@([^:\s]+)(?::([^:\s]+))?$/.exec(target);
|
|
11107
|
+
if (dm) return dm[2] ? {
|
|
11108
|
+
channel_type: "thread",
|
|
11109
|
+
channel_name: dm[2],
|
|
11110
|
+
parent_channel_name: dm[1],
|
|
11111
|
+
parent_channel_type: "dm"
|
|
11112
|
+
} : {
|
|
11113
|
+
channel_type: "dm",
|
|
11114
|
+
channel_name: dm[1]
|
|
11115
|
+
};
|
|
11116
|
+
const channel = /^#([^:\s]+)(?::([^:\s]+))?$/.exec(target);
|
|
11117
|
+
if (channel) return channel[2] ? {
|
|
11118
|
+
channel_type: "thread",
|
|
11119
|
+
channel_name: channel[2],
|
|
11120
|
+
parent_channel_name: channel[1],
|
|
11121
|
+
parent_channel_type: "channel"
|
|
11122
|
+
} : {
|
|
11123
|
+
channel_type: "channel",
|
|
11124
|
+
channel_name: channel[1]
|
|
11125
|
+
};
|
|
11126
|
+
return null;
|
|
11127
|
+
}
|
|
11128
|
+
/**
|
|
11129
|
+
* Project envelopes that all belong to one known conversation. Some Server
|
|
11130
|
+
* responses (held previews) send envelopes without conversation fields
|
|
11131
|
+
* because the request already named the target; fill them from `target`
|
|
11132
|
+
* instead of dropping the message.
|
|
11133
|
+
*/
|
|
11134
|
+
function projectRaftMessagesInTarget(envelopes, target) {
|
|
11135
|
+
const identity = identityFromTarget(target);
|
|
11136
|
+
return envelopes.map((envelope) => projectRaftMessage(identity && !hasAgentMessageIdentity(envelope) ? {
|
|
11137
|
+
...envelope,
|
|
11138
|
+
...identity
|
|
11139
|
+
} : envelope)).filter((m) => m !== null);
|
|
11140
|
+
}
|
|
11104
11141
|
//#endregion
|
|
11105
11142
|
//#region ../shared/src/agentOps/frontier.ts
|
|
11106
11143
|
const MAX_EXACT_SEQS = 2500;
|
|
@@ -11156,10 +11193,11 @@ var SeenFrontier = class SeenFrontier {
|
|
|
11156
11193
|
* Attest that the model saw the context a held send/claim returned. Call it
|
|
11157
11194
|
* only after the held messages actually reached the model (the SDK cannot
|
|
11158
11195
|
* know that, so it never records this implicitly). Returns false and records
|
|
11159
|
-
* nothing when the context was withheld
|
|
11196
|
+
* nothing when the context was withheld, not fully shown
|
|
11197
|
+
* (`contextComplete: false`), or the Server sent no boundary.
|
|
11160
11198
|
*/
|
|
11161
11199
|
recordHeld(held) {
|
|
11162
|
-
if (held.withheld || held.seenUpToSeq === null) return false;
|
|
11200
|
+
if (held.withheld || held.contextComplete === false || held.seenUpToSeq === null) return false;
|
|
11163
11201
|
this.recordUpTo(held.target, held.seenUpToSeq);
|
|
11164
11202
|
return true;
|
|
11165
11203
|
}
|
|
@@ -11556,6 +11594,7 @@ function heldText(held, action) {
|
|
|
11556
11594
|
if (held.formalMentionCount > 0) lines.push(`Note: ${held.formalMentionCount} of these messages formally @mention you.`);
|
|
11557
11595
|
if (held.omittedMessageCount > 0) lines.push(`${held.omittedMessageCount} earlier ${held.omittedMessageCount === 1 ? "message" : "messages"} not shown.`);
|
|
11558
11596
|
if (held.heldMessages.length > 0) lines.push(formatAgentMessages(held.heldMessages.map((m) => toAgentMessageLike(m.raw))));
|
|
11597
|
+
if (!held.contextComplete) lines.push("Not all of them are shown here; read the conversation before sending again.");
|
|
11559
11598
|
lines.push(`Full text: raft message read --target "${held.target}"`);
|
|
11560
11599
|
return lines.join("\n");
|
|
11561
11600
|
}
|
|
@@ -11567,26 +11606,30 @@ function heldNext(held) {
|
|
|
11567
11606
|
target: held.target,
|
|
11568
11607
|
...held.continuation
|
|
11569
11608
|
},
|
|
11570
|
-
why: held.withheld ? "Newer messages exist in this conversation but were withheld; read them, then send again with the same idempotencyKey." : "Newer messages arrived in this conversation. Show the held messages to the model, call frontier.recordHeld(held) to attest that, then send again with these args (same idempotencyKey, seen.upToSeq)."
|
|
11609
|
+
why: held.withheld ? "Newer messages exist in this conversation but were withheld; read them, then send again with the same idempotencyKey." : !held.contextComplete ? "Newer messages arrived in this conversation and not all of them are shown here; read the conversation, then send again with the same idempotencyKey." : "Newer messages arrived in this conversation. Show the held messages to the model, call frontier.recordHeld(held) to attest that, then send again with these args (same idempotencyKey, seen.upToSeq)."
|
|
11571
11610
|
};
|
|
11572
11611
|
}
|
|
11573
11612
|
function projectHeld(target, data, idempotencyKey) {
|
|
11574
11613
|
const withheld = data.freshnessContextMode === "withheld";
|
|
11575
|
-
const heldMessages =
|
|
11614
|
+
const heldMessages = projectRaftMessagesInTarget(data.heldMessages ?? [], target);
|
|
11576
11615
|
const seenUpToSeq = typeof data.seenUpToSeq === "number" ? data.seenUpToSeq : null;
|
|
11616
|
+
const newMessageCount = withheld ? data.withheldMessageCount ?? 0 : data.newMessageCount ?? heldMessages.length;
|
|
11617
|
+
const omittedMessageCount = data.omittedMessageCount ?? 0;
|
|
11618
|
+
const contextComplete = !withheld && heldMessages.length + omittedMessageCount >= newMessageCount;
|
|
11577
11619
|
return {
|
|
11578
11620
|
target,
|
|
11579
11621
|
idempotencyKey,
|
|
11580
11622
|
continuation: {
|
|
11581
11623
|
idempotencyKey,
|
|
11582
|
-
|
|
11624
|
+
...contextComplete && seenUpToSeq !== null ? { seen: { upToSeq: seenUpToSeq } } : {}
|
|
11583
11625
|
},
|
|
11584
|
-
newMessageCount
|
|
11626
|
+
newMessageCount,
|
|
11585
11627
|
heldMessages,
|
|
11586
|
-
omittedMessageCount
|
|
11628
|
+
omittedMessageCount,
|
|
11587
11629
|
formalMentionCount: data.mentionAnnotation?.formalMentionCount ?? 0,
|
|
11588
11630
|
seenUpToSeq,
|
|
11589
|
-
withheld
|
|
11631
|
+
withheld,
|
|
11632
|
+
contextComplete
|
|
11590
11633
|
};
|
|
11591
11634
|
}
|
|
11592
11635
|
function isHeldResponse(data) {
|
|
@@ -11643,9 +11686,10 @@ async function sendMessage(client, request, frontier, internal = {}) {
|
|
|
11643
11686
|
...request,
|
|
11644
11687
|
idempotencyKey
|
|
11645
11688
|
};
|
|
11689
|
+
const base = projectHeld(request.target, data, idempotencyKey);
|
|
11646
11690
|
const held = {
|
|
11647
|
-
...
|
|
11648
|
-
resend: (options) => sendMessage(client, options.seen === "held" && typeof data.seenUpToSeq === "number" ? {
|
|
11691
|
+
...base,
|
|
11692
|
+
resend: (options) => sendMessage(client, options.seen === "held" && base.contextComplete && typeof data.seenUpToSeq === "number" ? {
|
|
11649
11693
|
...keyed,
|
|
11650
11694
|
seen: {
|
|
11651
11695
|
upToSeq: data.seenUpToSeq,
|
package/dist/index.d.ts
CHANGED
|
@@ -457,12 +457,14 @@ export declare class SeenFrontier {
|
|
|
457
457
|
* Attest that the model saw the context a held send/claim returned. Call it
|
|
458
458
|
* only after the held messages actually reached the model (the SDK cannot
|
|
459
459
|
* know that, so it never records this implicitly). Returns false and records
|
|
460
|
-
* nothing when the context was withheld
|
|
460
|
+
* nothing when the context was withheld, not fully shown
|
|
461
|
+
* (`contextComplete: false`), or the Server sent no boundary.
|
|
461
462
|
*/
|
|
462
463
|
recordHeld(held: {
|
|
463
464
|
target: string;
|
|
464
465
|
seenUpToSeq: number | null;
|
|
465
466
|
withheld: boolean;
|
|
467
|
+
contextComplete?: boolean;
|
|
466
468
|
}): boolean;
|
|
467
469
|
/** What to attest on a send or claim to `target`; omits `seenUpToSeq` when nothing contiguous is known. */
|
|
468
470
|
attestation(target: string): SeenAttestation;
|
|
@@ -625,6 +627,13 @@ interface RaftHeldBase {
|
|
|
625
627
|
seenUpToSeq: number | null;
|
|
626
628
|
/** Reviewer isolation: bodies withheld, only a count. */
|
|
627
629
|
withheld: boolean;
|
|
630
|
+
/**
|
|
631
|
+
* Whether `heldMessages` plus `omittedMessageCount` account for every one of
|
|
632
|
+
* `newMessageCount`. When false the model cannot have seen all of them, so
|
|
633
|
+
* no `seen` is offered and `frontier.recordHeld` records nothing; read the
|
|
634
|
+
* conversation instead.
|
|
635
|
+
*/
|
|
636
|
+
contextComplete: boolean;
|
|
628
637
|
}
|
|
629
638
|
interface RaftHeld extends RaftHeldBase {
|
|
630
639
|
/**
|