@agentunion/fastaun 0.5.11 → 0.5.13

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/_packed_docs/CHANGELOG.md +46 -0
  3. package/_packed_docs/INDEX.md +3 -3
  4. package/_packed_docs/KITE_DOCS_GUIDE.md +1 -1
  5. package/_packed_docs/agent.md/SCHEMA.md +84 -84
  6. package/_packed_docs/aun/345/210/206/345/270/203/345/274/217/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +8 -6
  7. package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +29 -15
  8. package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +21 -3
  9. package/_packed_docs/sdk/09-group-rpc-manual.md +29 -2
  10. package/dist/agent-md-schema.js +8 -4
  11. package/dist/agent-md-schema.js.map +1 -1
  12. package/dist/client/delivery.d.ts +2 -3
  13. package/dist/client/delivery.js +69 -222
  14. package/dist/client/delivery.js.map +1 -1
  15. package/dist/client/group-state.js +1 -0
  16. package/dist/client/group-state.js.map +1 -1
  17. package/dist/client/rpc-pipeline.js +18 -8
  18. package/dist/client/rpc-pipeline.js.map +1 -1
  19. package/dist/client/v2-e2ee.d.ts +0 -1
  20. package/dist/client/v2-e2ee.js +43 -62
  21. package/dist/client/v2-e2ee.js.map +1 -1
  22. package/dist/client.d.ts +17 -0
  23. package/dist/client.js +269 -16
  24. package/dist/client.js.map +1 -1
  25. package/dist/facades.d.ts +6 -0
  26. package/dist/facades.js +66 -0
  27. package/dist/facades.js.map +1 -1
  28. package/dist/seq-tracker.d.ts +2 -2
  29. package/dist/seq-tracker.js +11 -17
  30. package/dist/seq-tracker.js.map +1 -1
  31. package/dist/tools/cross-sdk-agent.js +50 -20
  32. package/dist/tools/cross-sdk-agent.js.map +1 -1
  33. package/dist/version.d.ts +1 -1
  34. package/dist/version.js +1 -1
  35. package/package.json +1 -1
@@ -60,11 +60,16 @@ function deduplicateForwardPageMessages(value, afterSeq) {
60
60
  }
61
61
  return [...bySeq.entries()].sort(([a], [b]) => a - b).map(([, row]) => row);
62
62
  }
63
- function shouldContinueForwardPage({ rawCount, nextAfterSeq, nextAfter, limit, hasMoreField, hasMore, serverHead, pendingAckSeq, }) {
63
+ function contiguousPullSeq(afterSeq, seqs, proof) {
64
+ const pulledMax = seqs.length > 0 ? Math.max(...seqs) : 0;
65
+ const serverProof = safeNonNegativeSeq(proof);
66
+ return Math.max(afterSeq, pulledMax, serverProof ?? 0);
67
+ }
68
+ function shouldContinueForwardPage({ rawCount, nextAfterSeq, nextAfter, limit, hasMoreField, hasMore, serverHead, observedUpper, pendingAckSeq, }) {
64
69
  // 无新 seq 或游标未前进时必须停止,避免错误元数据造成循环。
65
70
  if (rawCount <= 0 || nextAfter <= nextAfterSeq)
66
71
  return false;
67
- if (hasMore || serverHead > nextAfter || pendingAckSeq > 0)
72
+ if (hasMore || serverHead > nextAfter || observedUpper > nextAfter || pendingAckSeq > 0)
68
73
  return true;
69
74
  // 仅旧服务缺失 has_more 时,以满页保留兼容续拉。
70
75
  return !hasMoreField && limit > 0 && rawCount >= limit;
@@ -767,6 +772,8 @@ export class V2E2EECoordinator {
767
772
  pending.delete(key);
768
773
  const seq = Number(entry.msg.seq ?? 0);
769
774
  if (entry.groupId) {
775
+ if (client._delivery.isSelfSentGroupMessage?.(entry.msg))
776
+ continue;
770
777
  plaintext = normalizeGroupMentionMode(plaintext, entry.msg, entry.msg.envelope_json);
771
778
  plaintext.group_id = entry.groupId;
772
779
  await client._publishPulledMessage('group.message_created', `group:${entry.groupId}`, seq, plaintext, false, 'pending_retry');
@@ -1051,12 +1058,7 @@ export class V2E2EECoordinator {
1051
1058
  }
1052
1059
  if (publish) {
1053
1060
  const event = client._delivery.p2pAppEventForMessage(plaintext);
1054
- if (orderedPublish) {
1055
- await client._delivery.publishOrderedMessage(event.event, client._aid ? `p2p:${client._aid}` : '', seq, event.payload, source);
1056
- }
1057
- else {
1058
- await client._publishAppEvent(event.event, event.payload, source);
1059
- }
1061
+ await client._publishAppEvent(event.event, event.payload, source);
1060
1062
  }
1061
1063
  return plaintext;
1062
1064
  }
@@ -1077,12 +1079,7 @@ export class V2E2EECoordinator {
1077
1079
  seq,
1078
1080
  };
1079
1081
  if (publish) {
1080
- if (orderedPublish) {
1081
- await client._delivery.publishOrderedMessage('group.message_recalled', `group:${groupId}`, seq, recallPayload, source);
1082
- }
1083
- else {
1084
- await client._publishAppEvent('group.message_recalled', recallPayload, source);
1085
- }
1082
+ await client._publishAppEvent('group.message_recalled', recallPayload, source);
1086
1083
  }
1087
1084
  return recallPayload;
1088
1085
  }
@@ -1129,24 +1126,14 @@ export class V2E2EECoordinator {
1129
1126
  client._clientLog.warn(`Group Tail 单条消息解密失败,连续性证明仍保留: group=${groupId}, seq=${seq}`);
1130
1127
  return null;
1131
1128
  }
1129
+ if (publish && !history && client._delivery.isSelfSentGroupMessage?.(msg)) {
1130
+ return plaintext;
1131
+ }
1132
1132
  if (publish) {
1133
- if (orderedPublish) {
1134
- await client._delivery.publishOrderedMessage('group.message_created', `group:${groupId}`, seq, plaintext, source);
1135
- }
1136
- else {
1137
- await client._publishAppEvent('group.message_created', plaintext, source);
1138
- }
1133
+ await client._publishAppEvent('group.message_created', plaintext, source);
1139
1134
  }
1140
1135
  return plaintext;
1141
1136
  }
1142
- async applyTailFloor(ns, floor) {
1143
- const client = this.client;
1144
- if (!ns || floor <= 0 || client._seqTracker.getContiguousSeq(ns) >= floor)
1145
- return;
1146
- client._seqTracker.forceContiguousSeq(ns, floor);
1147
- client._persistSeq(ns);
1148
- await client._saveSeqTrackerState?.();
1149
- }
1150
1137
  async pullV2TailInternal(params, deferPublish = false) {
1151
1138
  const client = this.client;
1152
1139
  if (params.window_mode !== 'tail')
@@ -1159,9 +1146,6 @@ export class V2E2EECoordinator {
1159
1146
  if (ns)
1160
1147
  client._delivery.syncStarted(ns);
1161
1148
  const result = await client._callRawV2Rpc('message.v2.pull', { window_mode: 'tail', after_seq: afterSeq, limit, _rpc_foreground: true });
1162
- const floor = Number(result.retention_floor_seq ?? 0);
1163
- const previous = ns ? client._seqTracker.getSyncState(ns) : null;
1164
- await this.applyTailFloor(ns, Number.isSafeInteger(floor) ? floor : 0);
1165
1149
  const page = validateTailPage(result, afterSeq, limit);
1166
1150
  if (ns) {
1167
1151
  client._seqTracker.commitTailWindow(ns, {
@@ -1180,8 +1164,6 @@ export class V2E2EECoordinator {
1180
1164
  decoded.push(plaintext);
1181
1165
  }
1182
1166
  const ack = ns ? client._seqTracker.getContiguousSeq(ns) : 0;
1183
- if (previous && ack > previous.ack)
1184
- await this.ackV2(ack);
1185
1167
  if (ns)
1186
1168
  client._delivery.syncProgress(ns, {
1187
1169
  rawCount: page.messages.length,
@@ -1291,6 +1273,7 @@ export class V2E2EECoordinator {
1291
1273
  if (seqs.length > 0) {
1292
1274
  pageMaxSeq = Math.max(...seqs);
1293
1275
  }
1276
+ const pageContiguousSeq = contiguousPullSeq(pageContigBefore, seqs, result.contiguous_seq);
1294
1277
  const deferredKeyFetches = new Map();
1295
1278
  let blockedSeq = 0;
1296
1279
  const pageDecryptedBefore = decrypted.length;
@@ -1391,7 +1374,7 @@ export class V2E2EECoordinator {
1391
1374
  const serverAckSeq = parsedServerAckSeq ?? 0;
1392
1375
  const retentionFloor = Math.max(0, Number(result.retention_floor_seq ?? 0));
1393
1376
  if (ns) {
1394
- const commitTarget = Math.max(pageContigBefore, Number.isFinite(retentionFloor) ? retentionFloor : 0, pageCount === 1 ? deferredServerCursor : 0, blockedSeq > 0 ? blockedSeq - 1 : (seqs.length > 0 ? pageMaxSeq : pageContigBefore));
1377
+ const commitTarget = Math.max(pageContigBefore, Number.isFinite(retentionFloor) ? retentionFloor : 0, pageCount === 1 ? deferredServerCursor : 0, serverAckSeq, blockedSeq > 0 ? blockedSeq - 1 : pageContiguousSeq);
1395
1378
  let ackSeq = pageContigBefore;
1396
1379
  let contigAdvanced = false;
1397
1380
  try {
@@ -1441,7 +1424,7 @@ export class V2E2EECoordinator {
1441
1424
  || (contigAdvanced && ackSeq > knownServerAckSeq));
1442
1425
  if (ackNeeded) {
1443
1426
  this.recordForwardAck(ns, ackSeq);
1444
- const nextAfter = Math.max(pageMaxSeq, nextAfterSeq);
1427
+ const nextAfter = Math.max(pageContiguousSeq, nextAfterSeq);
1445
1428
  const canContinuePage = blockedSeq <= 0 && messages.length > 0 && nextAfter > nextAfterSeq;
1446
1429
  if (canContinuePage) {
1447
1430
  pendingAckSeq = Math.max(pendingAckSeq, ackSeq);
@@ -1469,7 +1452,7 @@ export class V2E2EECoordinator {
1469
1452
  currentSeq: client._seqTracker.getContiguousSeq(ns),
1470
1453
  targetSeq: serverHead,
1471
1454
  });
1472
- const nextAfter = Math.max(pageMaxSeq, nextAfterSeq);
1455
+ const nextAfter = Math.max(pageContiguousSeq, nextAfterSeq);
1473
1456
  const rawCount = messages.length;
1474
1457
  if (blockedSeq > 0)
1475
1458
  break;
@@ -1481,6 +1464,7 @@ export class V2E2EECoordinator {
1481
1464
  hasMoreField,
1482
1465
  hasMore,
1483
1466
  serverHead,
1467
+ observedUpper: Math.max(client._seqTracker.getMaxSeenSeq(ns), Number(client._pendingP2pPullUpper?.get?.(ns) ?? 0)),
1484
1468
  pendingAckSeq,
1485
1469
  });
1486
1470
  if (!shouldContinue)
@@ -1621,22 +1605,8 @@ export class V2E2EECoordinator {
1621
1605
  client._clientLog.debug(`group.v2.send ok: group=${gid}, use_cache=${useCache}, seq=${String((isJsonObject(result) ? result.seq : '') ?? '')}`);
1622
1606
  return result;
1623
1607
  };
1624
- const markSentSeq = async (result) => {
1625
- if (!isJsonObject(result))
1626
- return;
1627
- const obj = result;
1628
- const seq = Number(obj.seq ?? 0);
1629
- if (!Number.isFinite(seq) || seq <= 0)
1630
- return;
1631
- const ns = `group:${gid}`;
1632
- client._seqTracker.onMessageSeq(ns, seq);
1633
- client._markPublishedSeq(ns, seq);
1634
- await client._saveSeqTrackerState();
1635
- client._clientLog.debug(`group.v2.send marked own seq: group=${gid}, ns=${ns}, seq=${seq}`);
1636
- };
1637
1608
  try {
1638
1609
  const result = await attempt(true);
1639
- await markSentSeq(result);
1640
1610
  return client._delivery.attachSendResultEnvelope('group.send', withExplicitGroupAid({
1641
1611
  group_id: gid,
1642
1612
  payload,
@@ -1652,7 +1622,6 @@ export class V2E2EECoordinator {
1652
1622
  client._clientLog.debug(`V2 group speculative send rejected (code=${String(excCode)}), refreshing bootstrap`);
1653
1623
  this.deleteBootstrapCacheEntry(`group:${gid}`);
1654
1624
  const result = await attempt(false);
1655
- await markSentSeq(result);
1656
1625
  return client._delivery.attachSendResultEnvelope('group.send', withExplicitGroupAid({
1657
1626
  group_id: gid,
1658
1627
  payload,
@@ -1842,9 +1811,6 @@ export class V2E2EECoordinator {
1842
1811
  const resultAid = String(result.group_aid ?? result.groupAid ?? '').trim();
1843
1812
  if (resultAid)
1844
1813
  groupAid = resultAid;
1845
- const floor = Number(result.retention_floor_message_seq ?? result.retention_floor_seq ?? 0);
1846
- const previous = client._seqTracker.getSyncState(ns);
1847
- await this.applyTailFloor(ns, Number.isSafeInteger(floor) ? floor : 0);
1848
1814
  const page = validateTailPage(result, afterSeq, limit);
1849
1815
  client._seqTracker.commitTailWindow(ns, {
1850
1816
  windowStartSeq: page.windowStart,
@@ -1862,8 +1828,6 @@ export class V2E2EECoordinator {
1862
1828
  decoded.push(plaintext);
1863
1829
  }
1864
1830
  const ack = client._seqTracker.getContiguousSeq(ns);
1865
- if (ack > previous.ack)
1866
- await this.ackGroupV2(groupId, ack, groupAid);
1867
1831
  if (ownsCursor)
1868
1832
  client._delivery.syncProgress(ns, {
1869
1833
  rawCount: page.messages.length,
@@ -2019,6 +1983,7 @@ export class V2E2EECoordinator {
2019
1983
  if (seqs.length > 0) {
2020
1984
  pageMaxSeq = Math.max(...seqs);
2021
1985
  }
1986
+ const pageContiguousSeq = contiguousPullSeq(pageContigBefore, seqs, result.contiguous_seq);
2022
1987
  const deferredKeyFetches = new Map();
2023
1988
  let blockedSeq = 0;
2024
1989
  const pageDecryptedBefore = decrypted.length;
@@ -2059,7 +2024,12 @@ export class V2E2EECoordinator {
2059
2024
  };
2060
2025
  v1Msg = normalizeGroupMentionMode(v1Msg, msg, msg.envelope_json);
2061
2026
  attachGatewayProximity(v1Msg, msg);
2062
- await client._publishPulledMessage('group.message_created', ns, seq, v1Msg, false);
2027
+ if (!client._delivery.isSelfSentGroupMessage?.(msg)) {
2028
+ await client._publishPulledMessage('group.message_created', ns, seq, v1Msg, false);
2029
+ }
2030
+ else {
2031
+ client._markPublishedSeq(ns, seq);
2032
+ }
2063
2033
  decrypted.push(v1Msg);
2064
2034
  client._clientLog.debug(`group.v2.pull plaintext V1 delivered: group=${gid}, seq=${seq}`);
2065
2035
  continue;
@@ -2097,7 +2067,12 @@ export class V2E2EECoordinator {
2097
2067
  if (plaintext) {
2098
2068
  plaintext.group_id = gid;
2099
2069
  plaintext.group_aid = eventGroupAid;
2100
- await client._publishPulledMessage('group.message_created', ns, seq, plaintext, false);
2070
+ if (!client._delivery.isSelfSentGroupMessage?.(msg)) {
2071
+ await client._publishPulledMessage('group.message_created', ns, seq, plaintext, false);
2072
+ }
2073
+ else {
2074
+ client._markPublishedSeq(ns, seq);
2075
+ }
2101
2076
  decrypted.push(plaintext);
2102
2077
  }
2103
2078
  }
@@ -2130,7 +2105,12 @@ export class V2E2EECoordinator {
2130
2105
  plaintext = normalizeGroupMentionMode(plaintext, msg, msg.envelope_json);
2131
2106
  plaintext.group_id = gid;
2132
2107
  plaintext.group_aid = eventGroupAid;
2133
- await client._publishPulledMessage('group.message_created', ns, seq, plaintext, false);
2108
+ if (!client._delivery.isSelfSentGroupMessage?.(msg)) {
2109
+ await client._publishPulledMessage('group.message_created', ns, seq, plaintext, false);
2110
+ }
2111
+ else {
2112
+ client._markPublishedSeq(ns, seq);
2113
+ }
2134
2114
  decrypted.push(plaintext);
2135
2115
  client._logMessageDebug('decrypt-ok', 'group.v2.pull', 'group.message_created', plaintext);
2136
2116
  }
@@ -2140,7 +2120,7 @@ export class V2E2EECoordinator {
2140
2120
  const retentionFloor = Math.max(client._pullRetentionFloor(result, 'retention_floor_message_seq', 'retention_floor_message_seq'));
2141
2121
  const visibilityFloor = Math.max(0, Math.max(0, Number(result.earliest_available_message_seq ?? 1) - 1), Number(cursor?.join_seq ?? 0));
2142
2122
  const effectiveFloor = Math.max(retentionFloor, visibilityFloor);
2143
- const commitTarget = Math.max(pageContigBefore, effectiveFloor, ownsCursor && pageCount === 1 ? deferredServerCursor : 0, blockedSeq > 0 ? blockedSeq - 1 : (seqs.length > 0 ? pageMaxSeq : pageContigBefore));
2123
+ const commitTarget = Math.max(pageContigBefore, effectiveFloor, ownsCursor && pageCount === 1 ? deferredServerCursor : 0, ownsCursor ? cursorCurrentSeq : 0, blockedSeq > 0 ? blockedSeq - 1 : pageContiguousSeq);
2144
2124
  let ackSeq = pageContigBefore;
2145
2125
  let contigAdvanced = false;
2146
2126
  if (ownsCursor) {
@@ -2193,7 +2173,7 @@ export class V2E2EECoordinator {
2193
2173
  || (contigAdvanced && ackSeq > knownServerCursorSeq));
2194
2174
  if (ackNeeded) {
2195
2175
  this.recordForwardAck(ns, ackSeq);
2196
- const nextAfter = Math.max(pageMaxSeq, nextAfterSeq);
2176
+ const nextAfter = Math.max(pageContiguousSeq, nextAfterSeq);
2197
2177
  const canContinuePage = blockedSeq <= 0 && messages.length > 0 && nextAfter > nextAfterSeq && ownsCursor;
2198
2178
  if (canContinuePage) {
2199
2179
  pendingAckSeq = Math.max(pendingAckSeq, ackSeq);
@@ -2214,7 +2194,7 @@ export class V2E2EECoordinator {
2214
2194
  currentSeq: client._seqTracker.getContiguousSeq(ns),
2215
2195
  targetSeq: serverHead,
2216
2196
  });
2217
- const nextAfter = Math.max(pageMaxSeq, nextAfterSeq);
2197
+ const nextAfter = Math.max(pageContiguousSeq, nextAfterSeq);
2218
2198
  if (!ownsCursor)
2219
2199
  break;
2220
2200
  const rawCount = messages.length;
@@ -2228,6 +2208,7 @@ export class V2E2EECoordinator {
2228
2208
  hasMoreField,
2229
2209
  hasMore,
2230
2210
  serverHead,
2211
+ observedUpper: Math.max(client._seqTracker.getMaxSeenSeq(ns), Number(client._delivery.pendingPullUpper?.(ns) ?? 0)),
2231
2212
  pendingAckSeq,
2232
2213
  });
2233
2214
  if (!shouldContinue)