@myagentroam/node 0.9.106 → 0.9.107

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.
@@ -18,6 +18,30 @@ export function convergeConversationWatchPage(previous, previousObserved, next,
18
18
  page: composeConversationRuntimePage(previous, next),
19
19
  authority: authority ?? next.source
20
20
  };
21
+ // A Runner history read can lag a Run that the Watch has already delivered. Keep the
22
+ // unconfirmed Runtime tail until the history includes that Turn; source priority alone
23
+ // does not establish that the returned window contains the latest conversation.
24
+ if (previous?.source === 'runtime' &&
25
+ previous.turns.length > 0 &&
26
+ next.source !== 'runtime' &&
27
+ (authority === undefined || sourceRank(next.source) >= sourceRank(authority))) {
28
+ const boundary = previous.turns.findLastIndex((turn) => next.turns.some((candidate) => sameConversationTurn(candidate, turn)));
29
+ if (boundary < 0)
30
+ return { page: previous, authority: next.source };
31
+ const tail = previous.turns
32
+ .slice(boundary + 1)
33
+ .filter((turn) => !next.turns.some((candidate) => sameConversationTurn(candidate, turn)));
34
+ if (tail.length > 0)
35
+ return {
36
+ page: {
37
+ ...next,
38
+ source: 'runtime',
39
+ snapshotSequence: previous.snapshotSequence,
40
+ turns: [...next.turns, ...tail]
41
+ },
42
+ authority: next.source
43
+ };
44
+ }
21
45
  if (previous === undefined ||
22
46
  authority === undefined ||
23
47
  sourceRank(next.source) >= sourceRank(authority))
@@ -249,8 +249,20 @@ export class NativeSessionWatchService {
249
249
  const page = await (readHistoricalPage
250
250
  ? this.options.readHistoryPage(session, limit)
251
251
  : this.options.readPage(session, limit));
252
- if (mode === 'observation' && revisionBeforeRead !== watch.eventRevision)
253
- return watch.page;
252
+ if (revisionBeforeRead !== watch.eventRevision) {
253
+ // Initial still needs a full page for its new lease, whose pending events will
254
+ // replay above that page's sequence. Never publish this invalidated read to
255
+ // existing leases or replace their shared observation state.
256
+ if (mode !== 'initial')
257
+ return watch.page;
258
+ const initial = this.options.convergePage(watch.page, watch.observedPage, page, watch.authority).page;
259
+ if (watch.page === undefined && watch.signature === undefined)
260
+ watch.signature = JSON.stringify({
261
+ source: initial.source,
262
+ turns: initial.turns.slice(-(EMITTED_TURN_LIMIT + 1))
263
+ });
264
+ return initial;
265
+ }
254
266
  stage = 'present_session';
255
267
  const presented = this.options.present(session);
256
268
  const sessionSignature = JSON.stringify(presented);
@@ -265,7 +277,7 @@ export class NativeSessionWatchService {
265
277
  : page.turns.slice(-EMITTED_TURN_LIMIT);
266
278
  const observed = { ...page, turns };
267
279
  stage = 'converge_page';
268
- const convergence = this.options.convergePage(watch.page, watch.observedPage, observed, watch.authority);
280
+ const convergence = this.options.convergePage(watch.page, watch.observedPage, page, watch.authority);
269
281
  const converged = convergence.page;
270
282
  const accepted = converged.turns.length <= EMITTED_TURN_LIMIT + 1
271
283
  ? converged
@@ -285,8 +297,9 @@ export class NativeSessionWatchService {
285
297
  const changed = signature !== watch.signature;
286
298
  if (changed) {
287
299
  watch.signature = signature;
288
- watch.page = accepted;
289
300
  }
301
+ if (changed || watch.page === undefined)
302
+ watch.page = accepted;
290
303
  stage = 'emit_page';
291
304
  if (completingConvergence && accepted.source === 'runtime')
292
305
  this.releasePendingEvents(session.id);
@@ -294,7 +307,8 @@ export class NativeSessionWatchService {
294
307
  this.emitSnapshotToLeases(session, accepted, true);
295
308
  else if (changed)
296
309
  this.emitObservedPage(session, accepted);
297
- return mode === 'initial' ? page : accepted;
310
+ // Initial uses the full result of the same authority decision as observation.
311
+ return mode === 'initial' ? converged : accepted;
298
312
  }
299
313
  catch (error) {
300
314
  watch.failures += 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myagentroam/node",
3
- "version": "0.9.106",
3
+ "version": "0.9.107",
4
4
  "description": "MyAgentRoam Node runtime CLI.",
5
5
  "license": "Apache-2.0 AND GPL-2.0-or-later",
6
6
  "type": "module",
@@ -30,9 +30,9 @@
30
30
  "npm": "11.12.1",
31
31
  "ws": "^8.21.3",
32
32
  "zod": "4.4.3",
33
- "@myagentroam/agent": "0.9.106",
34
- "@myagentroam/code-navigation": "0.9.106",
35
- "@myagentroam/protocol": "0.9.106"
33
+ "@myagentroam/agent": "0.9.107",
34
+ "@myagentroam/code-navigation": "0.9.107",
35
+ "@myagentroam/protocol": "0.9.107"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/ws": "^8.18.1"