@tutti-os/agent-gui 0.0.113 → 0.0.115

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.
@@ -82,7 +82,7 @@ import {
82
82
  AgentFileMentionPalette,
83
83
  agentMentionItemKey,
84
84
  isAgentMentionItemDisabled
85
- } from "./chunk-DIFAX3KB.js";
85
+ } from "./chunk-MWN3AIQJ.js";
86
86
  import {
87
87
  normalizeAgentGUIAgents,
88
88
  projectAgentGUIAgentsToInternalTargets
@@ -93,7 +93,7 @@ import {
93
93
  DEFAULT_AGENT_MENTION_FILTER,
94
94
  agentGuiScheduler,
95
95
  buildWorkspaceAgentActivityListViewModel
96
- } from "./chunk-WA5LSG5S.js";
96
+ } from "./chunk-FRCZZ7ON.js";
97
97
  import {
98
98
  AGENT_RICH_TEXT_CARET_ANCHOR,
99
99
  createAgentSessionMarkdownLink,
@@ -7730,14 +7730,12 @@ function useAgentGUIConversationBatchDeletion(input) {
7730
7730
  sessionViewRef,
7731
7731
  setDraftByScopeKey,
7732
7732
  submittedDraftSnapshotsRef,
7733
- sessionEngine,
7734
7733
  activeConversationIdRef,
7735
7734
  markSelectedConversationDetailPending,
7736
7735
  setIntent,
7737
7736
  setIsLoadingMessages,
7738
7737
  setActiveConversationId,
7739
7738
  persistActiveConversation,
7740
- removeConversations,
7741
7739
  workspaceId,
7742
7740
  setIsDeletingProjectConversations,
7743
7741
  agentActivityRuntime,
@@ -7762,18 +7760,9 @@ function useAgentGUIConversationBatchDeletion(input) {
7762
7760
  scopeKeys: deletedScopeKeys,
7763
7761
  targetAgentSessionIds: targetIds
7764
7762
  });
7765
- for (const id of targetIds) {
7766
- sessionEngine.dispatch({
7767
- agentSessionId: id,
7768
- type: "queue/sessionCleaned"
7769
- });
7770
- }
7771
- removeConversations([...targetIds]);
7772
7763
  },
7773
7764
  [
7774
7765
  deleteAgentSessionView,
7775
- removeConversations,
7776
- sessionEngine,
7777
7766
  sessionViewRef,
7778
7767
  setDraftByScopeKey,
7779
7768
  submittedDraftSnapshotsRef
@@ -7927,14 +7916,10 @@ function useAgentGUIConversationDeletion(input) {
7927
7916
  agentActivityRuntime,
7928
7917
  setDraftByScopeKey,
7929
7918
  submittedDraftSnapshotsRef,
7930
- sessionEngine,
7931
7919
  deleteAgentSessionView,
7932
- conversationsRef,
7933
- markSelectedConversationDetailPending,
7934
7920
  setIntent,
7935
7921
  setActiveConversationId,
7936
7922
  persistActiveConversation,
7937
- removeConversations,
7938
7923
  agentHostApi,
7939
7924
  workspaceId
7940
7925
  } = input;
@@ -7969,28 +7954,13 @@ function useAgentGUIConversationDeletion(input) {
7969
7954
  setIsDeletingConversation(true);
7970
7955
  setDetailError(null);
7971
7956
  if (activeConversationIdRef.current === target.id) {
7972
- const currentConversations = conversationsRef.current;
7973
- const targetIndex = currentConversations.findIndex(
7974
- (conversation) => conversation.id === target.id
7975
- );
7976
- const nextConversations = currentConversations.filter(
7977
- (conversation) => conversation.id !== target.id
7978
- );
7979
- const nextActive = nextConversations[Math.max(0, targetIndex)]?.id ?? nextConversations[Math.max(0, targetIndex - 1)]?.id ?? null;
7980
- if (nextActive) {
7981
- markSelectedConversationDetailPending(nextActive);
7982
- }
7983
- activeConversationIdRef.current = nextActive;
7957
+ activeConversationIdRef.current = null;
7984
7958
  flushSync2(() => {
7985
- if (nextActive) {
7986
- setIntent({ tag: "active", id: nextActive });
7987
- } else {
7988
- setIsLoadingMessages(false);
7989
- setIntent({ tag: "home" });
7990
- }
7991
- setActiveConversationId(nextActive);
7959
+ setIsLoadingMessages(false);
7960
+ setIntent({ tag: "home" });
7961
+ setActiveConversationId(null);
7992
7962
  });
7993
- persistActiveConversation(nextActive);
7963
+ persistActiveConversation(null);
7994
7964
  }
7995
7965
  void activation.unactivate(target.id).then(
7996
7966
  () => agentActivityRuntime.deleteSession({
@@ -8011,12 +7981,7 @@ function useAgentGUIConversationDeletion(input) {
8011
7981
  scopeKeys: /* @__PURE__ */ new Set([deletedScopeKey]),
8012
7982
  targetAgentSessionIds: /* @__PURE__ */ new Set([target.id])
8013
7983
  });
8014
- sessionEngine.dispatch({
8015
- agentSessionId: target.id,
8016
- type: "queue/sessionCleaned"
8017
- });
8018
7984
  deleteAgentSessionView(sessionViewRef(target.id));
8019
- removeConversations([target.id]);
8020
7985
  setPendingDeleteConversation(null);
8021
7986
  }).catch((error) => {
8022
7987
  const message = getAgentGUIErrorMessage(error);
@@ -8037,14 +8002,10 @@ function useAgentGUIConversationDeletion(input) {
8037
8002
  activeConversationIdRef,
8038
8003
  agentActivityRuntime,
8039
8004
  agentHostApi.toast,
8040
- conversationsRef,
8041
8005
  deleteAgentSessionView,
8042
8006
  isDeletingConversation,
8043
- markSelectedConversationDetailPending,
8044
8007
  pendingDeleteConversation,
8045
8008
  persistActiveConversation,
8046
- removeConversations,
8047
- sessionEngine,
8048
8009
  sessionViewRef,
8049
8010
  setActiveConversationId,
8050
8011
  setDetailError,
@@ -10794,7 +10755,7 @@ function useAgentGUIConversationDetail(input) {
10794
10755
  effectiveDetailError: input.detailError ?? input.activeSessionReconcileError ?? (input.activeConversationId !== null ? input.activeEngineError : null),
10795
10756
  hasProviderSessionNotFoundError,
10796
10757
  isCancelPending: input.activeCancelStatus === "awaitingTurn",
10797
- isInterrupting: input.activeCancelStatus === "requested",
10758
+ isInterrupting: input.activeCancelStatus === "requested" || input.activeCancelStatus === "accepted",
10798
10759
  pendingApproval: hasProviderSessionNotFoundError ? null : rawPendingApproval,
10799
10760
  queueStatus: input.activeQueueStatus,
10800
10761
  queuedPrompts,
@@ -12622,17 +12583,6 @@ function useAgentGUINodeController({
12622
12583
  getErrorCode: getAgentGUIErrorCode
12623
12584
  });
12624
12585
  const activeConversationLiveState = activation.stateFor(activeConversationId);
12625
- const removeConversations = useCallback25(
12626
- (conversationIds) => {
12627
- for (const agentSessionId of conversationIds) {
12628
- sessionEngine.dispatch({
12629
- type: "session/removed",
12630
- agentSessionId
12631
- });
12632
- }
12633
- },
12634
- [sessionEngine]
12635
- );
12636
12586
  const setUserProjectsSnapshot = useCallback25(
12637
12587
  (projects) => {
12638
12588
  setUserProjects(
@@ -12833,7 +12783,6 @@ function useAgentGUINodeController({
12833
12783
  planImplementationTurnIdRef,
12834
12784
  prefillPromptRequest,
12835
12785
  previewMode,
12836
- removeConversations,
12837
12786
  reportActiveConversationCleared: reportAgentGUIActiveConversationCleared,
12838
12787
  sessionEngine,
12839
12788
  setUserProjectsSnapshot,
@@ -28949,9 +28898,6 @@ var AgentGUIConversationRailPane = memo7(
28949
28898
  );
28950
28899
 
28951
28900
  // agent-gui/agentGuiNode/controller/useAgentGUIConversationRailQuery.ts
28952
- import {
28953
- selectWorkspaceAgentConsumerSessions as selectWorkspaceAgentConsumerSessions4
28954
- } from "@tutti-os/agent-activity-core";
28955
28901
  import { useEffect as useEffect31, useMemo as useMemo33, useRef as useRef36 } from "react";
28956
28902
 
28957
28903
  // agent-gui/agentGuiNode/controller/agentGuiConversationRailDiagnostics.ts
@@ -29212,6 +29158,25 @@ function updateConversationRailSectionPageState(current, sectionId, value) {
29212
29158
  next.set(sectionId, value);
29213
29159
  return next;
29214
29160
  }
29161
+ function appendConversationRailSectionPage(input) {
29162
+ return {
29163
+ ...input.queryState,
29164
+ sectionPageStates: updateConversationRailSectionPageState(
29165
+ input.queryState.sectionPageStates,
29166
+ input.sectionId,
29167
+ conversationRailPageState(input.page)
29168
+ ),
29169
+ sections: input.queryState.sections?.map(
29170
+ (section) => section.id === input.sectionId ? {
29171
+ ...section,
29172
+ sessionIds: mergeConversationRailSessionIds(
29173
+ section.sessionIds,
29174
+ input.page.sessions.map((session) => session.agentSessionId)
29175
+ )
29176
+ } : section
29177
+ ) ?? null
29178
+ };
29179
+ }
29215
29180
  function conversationRailPageState(page) {
29216
29181
  return {
29217
29182
  hasMore: page.hasMore,
@@ -29222,6 +29187,9 @@ function conversationRailPageState(page) {
29222
29187
  }
29223
29188
 
29224
29189
  // agent-gui/agentGuiNode/controller/agentGuiConversationRailQuerySnapshot.ts
29190
+ import {
29191
+ selectWorkspaceAgentConsumerSessions as selectWorkspaceAgentConsumerSessions4
29192
+ } from "@tutti-os/agent-activity-core";
29225
29193
  var EMPTY_CONVERSATION_RAIL_QUERY_STATE = {
29226
29194
  pending: false,
29227
29195
  reconcilingSessionIds: [],
@@ -29239,6 +29207,19 @@ var EMPTY_CONVERSATION_SEARCH_QUERY_STATE = {
29239
29207
  resolvedQuery: "",
29240
29208
  sessionIds: []
29241
29209
  };
29210
+ function appendConversationSearchPage(state, page) {
29211
+ return {
29212
+ ...state,
29213
+ failed: false,
29214
+ hasMore: page.hasMore,
29215
+ loadingMore: false,
29216
+ nextCursor: page.nextCursor ?? null,
29217
+ sessionIds: mergeConversationRailSessionIds(
29218
+ state.sessionIds,
29219
+ page.sessions.map((session) => session.agentSessionId)
29220
+ )
29221
+ };
29222
+ }
29242
29223
  function buildConversationRailQuerySnapshot(input) {
29243
29224
  const searchResolved = input.searchState.requestKey === input.searchRequestKey && input.searchState.resolvedQuery === input.searchQuery;
29244
29225
  return {
@@ -29253,11 +29234,49 @@ function buildConversationRailQuerySnapshot(input) {
29253
29234
  },
29254
29235
  runtimeSectionsEnabled: input.runtimeSectionsEnabled,
29255
29236
  runtimeRailMemberships: input.queryState.sections,
29237
+ runtimeRailConversations: input.runtimeRailConversations,
29256
29238
  runtimeRailReconcilingSessionIds: input.queryState.reconcilingSessionIds,
29257
29239
  runtimeRailSectionsPending: input.queryState.pending,
29258
29240
  sectionPageStates: input.queryState.sectionPageStates
29259
29241
  };
29260
29242
  }
29243
+ function createConversationRailQuerySnapshotSelector() {
29244
+ const selectRailTitlePrompts = createAgentGUIConversationRailTitlePromptSelector();
29245
+ return (input, previous, force = false) => {
29246
+ const runtimeRailConversations = projectCanonicalAgentGUIConversationSummaries(
29247
+ selectWorkspaceAgentConsumerSessions4(input.engineState),
29248
+ selectRailTitlePrompts(input.engineState)
29249
+ );
29250
+ if (!force && previous?.runtimeRailConversations.length === runtimeRailConversations.length && previous.runtimeRailConversations.every(
29251
+ (conversation, index) => conversationSummariesRenderEqual2(
29252
+ conversation,
29253
+ runtimeRailConversations[index]
29254
+ )
29255
+ )) {
29256
+ return previous;
29257
+ }
29258
+ return buildConversationRailQuerySnapshot({
29259
+ ...input,
29260
+ runtimeRailConversations
29261
+ });
29262
+ };
29263
+ }
29264
+
29265
+ // agent-gui/agentGuiNode/controller/agentGuiConversationRailQueryTypes.ts
29266
+ function resolveConversationRailQueryScope(workspaceId, scope) {
29267
+ const agentTargetId = scope.conversationFilter.kind === "agentTarget" ? scope.conversationFilter.agentTargetId.trim() : scope.sectionAgentTargetFallbackId?.trim() ?? "";
29268
+ const projectPaths = scope.userProjects.map((project) => project.path.trim()).filter(Boolean);
29269
+ return {
29270
+ agentTargetId,
29271
+ scopeKey: JSON.stringify([
29272
+ workspaceId,
29273
+ scope.conversationFilter.kind === "agentTarget" ? `agentTarget:${scope.conversationFilter.agentTargetId.trim()}` : "all",
29274
+ scope.previewMode,
29275
+ agentTargetId,
29276
+ JSON.stringify(projectPaths)
29277
+ ])
29278
+ };
29279
+ }
29261
29280
 
29262
29281
  // agent-gui/agentGuiNode/controller/AgentGUIConversationRailTargetedPageRefresher.ts
29263
29282
  var SECTION_PAGE_SIZE = 5;
@@ -29341,10 +29360,9 @@ var AgentGUIConversationRailTargetedPageRefresher = class {
29341
29360
  // agent-gui/agentGuiNode/controller/AgentGUIConversationRailQueryController.ts
29342
29361
  var SECTION_PAGE_SIZE2 = 5;
29343
29362
  var CONVERSATION_SEARCH_DEBOUNCE_MS = 300;
29344
- var CONVERSATION_RAIL_QUERY_CACHE_FRESH_MS = 3e4;
29345
29363
  var AgentGUIConversationRailQueryController = class {
29346
29364
  getSnapshot = () => this.snapshot;
29347
- isInteractionLocked = () => this.queryState.pending && this.queryState.resolvedScopeKey !== this.railSectionQueryKey && !(this.searchQuery && this.snapshot.railSearch.enabled);
29365
+ isInteractionLocked = () => this.publicationBlocked() || this.queryState.pending && this.queryState.resolvedScopeKey !== this.railSectionQueryKey && !(this.searchQuery && this.snapshot.railSearch.enabled);
29348
29366
  subscribe = (listener) => {
29349
29367
  this.listeners.add(listener);
29350
29368
  return () => this.listeners.delete(listener);
@@ -29378,10 +29396,13 @@ var AgentGUIConversationRailQueryController = class {
29378
29396
  searchRequestSequence = 0;
29379
29397
  attached = false;
29380
29398
  ingestingSessions = false;
29399
+ sectionPublicationState = "idle";
29400
+ searchPublicationState = "idle";
29401
+ selectSnapshot = createConversationRailQuerySnapshotSelector();
29381
29402
  previousMembershipRecords;
29382
29403
  unsubscribeEngine = null;
29383
29404
  constructor(input) {
29384
- this.cacheFreshMs = input.cacheFreshMs ?? CONVERSATION_RAIL_QUERY_CACHE_FRESH_MS;
29405
+ this.cacheFreshMs = input.cacheFreshMs ?? 3e4;
29385
29406
  this.cacheNow = input.cacheNow ?? Date.now;
29386
29407
  this.diagnosticLogger = input.diagnosticLogger ?? createConversationRailDiagnosticLogger(input.runtime);
29387
29408
  this.diagnosticNow = input.diagnosticNow ?? Date.now;
@@ -29397,6 +29418,7 @@ var AgentGUIConversationRailQueryController = class {
29397
29418
  this.sessionSectionsQueryCache = input.sessionSectionsQueryCache ?? input.runtime.getSessionSectionsQueryCache?.(input.workspaceId) ?? createWorkspaceQueryCache();
29398
29419
  this.scheduler = input.scheduler ?? agentGuiScheduler;
29399
29420
  this.workspaceId = input.workspaceId;
29421
+ const initialEngineState = this.engine.getSnapshot();
29400
29422
  this.targetedPageRefresher = new AgentGUIConversationRailTargetedPageRefresher({
29401
29423
  onResolved: (pages) => {
29402
29424
  this.upsertSessions(pages.flatMap(({ page }) => page.sessions));
@@ -29405,15 +29427,20 @@ var AgentGUIConversationRailQueryController = class {
29405
29427
  queryState: this.queryState
29406
29428
  });
29407
29429
  this.writeCurrentQueryCache();
29408
- this.emit();
29430
+ this.sectionPublicationState = "idle";
29431
+ this.publishIfReady(void 0, true);
29432
+ },
29433
+ onFailed: () => {
29434
+ this.sectionPublicationState = "failed";
29435
+ if (this.railSectionQueryKey) {
29436
+ this.sessionSectionsQueryCache.invalidate(this.railSectionQueryKey);
29437
+ }
29409
29438
  },
29410
29439
  runtime: this.runtime,
29411
29440
  workspaceId: this.workspaceId
29412
29441
  });
29413
- this.previousMembershipRecords = projectConversationRailMembershipRecords(
29414
- this.engine.getSnapshot()
29415
- );
29416
- this.emit();
29442
+ this.previousMembershipRecords = projectConversationRailMembershipRecords(initialEngineState);
29443
+ this.publish(initialEngineState, true);
29417
29444
  }
29418
29445
  attach() {
29419
29446
  if (this.attached) return () => {
@@ -29422,24 +29449,20 @@ var AgentGUIConversationRailQueryController = class {
29422
29449
  this.unsubscribeEngine = this.engine.subscribe((state) => {
29423
29450
  this.handleEngineState(state);
29424
29451
  });
29425
- if (this.scope) this.refreshFirstPages("attach");
29426
- if (this.searchQuery) this.requestSearch();
29452
+ const engineState = this.engine.getSnapshot();
29453
+ this.handleEngineState(engineState);
29454
+ if (this.scope && this.sectionPublicationState !== "pending") {
29455
+ this.refreshFirstPages("attach");
29456
+ }
29457
+ if (this.searchQuery && this.searchPublicationState !== "pending") {
29458
+ this.requestSearch();
29459
+ }
29427
29460
  return () => this.detach();
29428
29461
  }
29429
29462
  configure(scope) {
29430
29463
  const previousScopeKey = this.railSectionQueryKey;
29431
29464
  const previousAgentTargetId = this.sectionAgentTargetId;
29432
- const sectionAgentTargetId = scope.conversationFilter.kind === "agentTarget" ? scope.conversationFilter.agentTargetId.trim() : scope.sectionAgentTargetFallbackId?.trim() ?? "";
29433
- const userProjectPathKey = JSON.stringify(
29434
- scope.userProjects.map((project) => project.path.trim()).filter((path) => path.length > 0)
29435
- );
29436
- const nextScopeKey = JSON.stringify([
29437
- this.workspaceId,
29438
- scope.conversationFilter.kind === "agentTarget" ? `agentTarget:${scope.conversationFilter.agentTargetId.trim()}` : "all",
29439
- scope.previewMode,
29440
- sectionAgentTargetId,
29441
- userProjectPathKey
29442
- ]);
29465
+ const { agentTargetId: sectionAgentTargetId, scopeKey: nextScopeKey } = resolveConversationRailQueryScope(this.workspaceId, scope);
29443
29466
  const scopeChanged = nextScopeKey !== this.railSectionQueryKey;
29444
29467
  this.providerSwitchDiagnostics.configure({
29445
29468
  attached: this.attached,
@@ -29454,12 +29477,13 @@ var AgentGUIConversationRailQueryController = class {
29454
29477
  if (!scopeChanged) return;
29455
29478
  this.cancelPagingRequests();
29456
29479
  this.targetedPageRefresher.cancel();
29480
+ this.resetPublication();
29457
29481
  this.queryState = {
29458
29482
  ...this.queryState,
29459
29483
  pending: this.runtimeSectionsEnabled(),
29460
29484
  reconcilingSessionIds: []
29461
29485
  };
29462
- this.emit();
29486
+ this.publish(void 0, true);
29463
29487
  if (this.attached) this.refreshFirstPages("scope_change");
29464
29488
  if (this.searchQuery) this.requestSearch();
29465
29489
  }
@@ -29471,7 +29495,7 @@ var AgentGUIConversationRailQueryController = class {
29471
29495
  }
29472
29496
  loadMoreSectionConversations = (section) => {
29473
29497
  const scopeKey = this.railSectionQueryKey;
29474
- if (this.scope?.previewMode || !scopeKey || this.queryState.pending || this.queryState.resolvedScopeKey !== scopeKey) {
29498
+ if (this.scope?.previewMode || !scopeKey || this.publicationBlocked() || this.queryState.pending || this.queryState.resolvedScopeKey !== scopeKey) {
29475
29499
  return;
29476
29500
  }
29477
29501
  const currentPageState = this.queryState.sectionPageStates.get(section.id);
@@ -29495,7 +29519,7 @@ var AgentGUIConversationRailQueryController = class {
29495
29519
  { ...currentPageState, isLoading: true }
29496
29520
  )
29497
29521
  };
29498
- this.emit();
29522
+ this.publishIfReady(void 0, true);
29499
29523
  const request = membership.kind === "pinned" ? this.runtime.listPinnedSessionsPage({
29500
29524
  agentTargetId: this.sectionAgentTargetId || void 0,
29501
29525
  cursor: currentPageState.nextCursor || void 0,
@@ -29515,30 +29539,13 @@ var AgentGUIConversationRailQueryController = class {
29515
29539
  return;
29516
29540
  }
29517
29541
  this.upsertSessions(page.sessions);
29518
- this.queryState = {
29519
- ...this.queryState,
29520
- sectionPageStates: updateConversationRailSectionPageState(
29521
- this.queryState.sectionPageStates,
29522
- section.id,
29523
- {
29524
- hasMore: page.hasMore,
29525
- isLoading: false,
29526
- nextCursor: page.nextCursor ?? null,
29527
- totalCount: page.totalCount
29528
- }
29529
- ),
29530
- sections: this.queryState.sections?.map(
29531
- (candidate) => candidate.id === section.id ? {
29532
- ...candidate,
29533
- sessionIds: mergeConversationRailSessionIds(
29534
- candidate.sessionIds,
29535
- page.sessions.map((session) => session.agentSessionId)
29536
- )
29537
- } : candidate
29538
- ) ?? null
29539
- };
29542
+ this.queryState = appendConversationRailSectionPage({
29543
+ page,
29544
+ queryState: this.queryState,
29545
+ sectionId: section.id
29546
+ });
29540
29547
  this.writeCurrentQueryCache();
29541
- this.emit();
29548
+ this.publishIfReady(void 0, true);
29542
29549
  }).catch(() => {
29543
29550
  if (abortController.signal.aborted || requestSequence !== this.pagingRequestSequence) {
29544
29551
  return;
@@ -29552,7 +29559,7 @@ var AgentGUIConversationRailQueryController = class {
29552
29559
  )
29553
29560
  };
29554
29561
  this.writeCurrentQueryCache();
29555
- this.emit();
29562
+ this.publishIfReady(void 0, true);
29556
29563
  }).finally(() => {
29557
29564
  if (this.pagingAbortControllers.get(section.id) === abortController) {
29558
29565
  this.pagingAbortControllers.delete(section.id);
@@ -29561,7 +29568,7 @@ var AgentGUIConversationRailQueryController = class {
29561
29568
  };
29562
29569
  loadMoreSearchResults = () => {
29563
29570
  const listSessionsPage = this.runtime.listSessionsPage;
29564
- if (!this.searchEnabled() || !listSessionsPage || this.searchState.pending || this.searchState.loadingMore || !this.searchState.hasMore || !this.searchState.nextCursor || this.searchState.requestKey !== this.searchRequestKey || this.searchState.resolvedQuery !== this.searchQuery) {
29571
+ if (!this.searchEnabled() || !listSessionsPage || this.publicationBlocked() || this.searchState.pending || this.searchState.loadingMore || !this.searchState.hasMore || !this.searchState.nextCursor || this.searchState.requestKey !== this.searchRequestKey || this.searchState.resolvedQuery !== this.searchQuery) {
29565
29572
  return;
29566
29573
  }
29567
29574
  const requestSequence = this.searchRequestSequence;
@@ -29569,7 +29576,7 @@ var AgentGUIConversationRailQueryController = class {
29569
29576
  this.searchAbortController?.abort();
29570
29577
  this.searchAbortController = abortController;
29571
29578
  this.searchState = { ...this.searchState, loadingMore: true };
29572
- this.emit();
29579
+ this.publishIfReady(void 0, true);
29573
29580
  void listSessionsPage({
29574
29581
  agentTargetId: this.sectionAgentTargetId || void 0,
29575
29582
  cursor: this.searchState.nextCursor ?? void 0,
@@ -29582,18 +29589,8 @@ var AgentGUIConversationRailQueryController = class {
29582
29589
  return;
29583
29590
  }
29584
29591
  this.upsertSessions(page.sessions);
29585
- this.searchState = {
29586
- ...this.searchState,
29587
- failed: false,
29588
- hasMore: page.hasMore,
29589
- loadingMore: false,
29590
- nextCursor: page.nextCursor ?? null,
29591
- sessionIds: mergeConversationRailSessionIds(
29592
- this.searchState.sessionIds,
29593
- page.sessions.map((session) => session.agentSessionId)
29594
- )
29595
- };
29596
- this.emit();
29592
+ this.searchState = appendConversationSearchPage(this.searchState, page);
29593
+ this.publishIfReady(void 0, true);
29597
29594
  }).catch(() => {
29598
29595
  if (abortController.signal.aborted || requestSequence !== this.searchRequestSequence) {
29599
29596
  return;
@@ -29603,7 +29600,7 @@ var AgentGUIConversationRailQueryController = class {
29603
29600
  failed: true,
29604
29601
  loadingMore: false
29605
29602
  };
29606
- this.emit();
29603
+ this.publishIfReady(void 0, true);
29607
29604
  });
29608
29605
  };
29609
29606
  retrySearchResults = () => {
@@ -29612,10 +29609,15 @@ var AgentGUIConversationRailQueryController = class {
29612
29609
  };
29613
29610
  handleEngineState(state) {
29614
29611
  const next = projectConversationRailMembershipRecords(state);
29615
- if (this.ingestingSessions || !this.runtimeSectionsEnabled() || state.engineRuntime.workspaceReconcile.status === "loading") {
29612
+ if (this.ingestingSessions) {
29616
29613
  this.previousMembershipRecords = next;
29617
29614
  return;
29618
29615
  }
29616
+ if (!this.runtimeSectionsEnabled() || state.engineRuntime.workspaceReconcile.status === "loading") {
29617
+ this.previousMembershipRecords = next;
29618
+ this.publishIfReady(state);
29619
+ return;
29620
+ }
29619
29621
  const plan = planRuntimeRailMembershipRefresh({
29620
29622
  activeConversationId: this.getActiveConversationId(),
29621
29623
  agentTargetId: this.sectionAgentTargetId || null,
@@ -29625,7 +29627,10 @@ var AgentGUIConversationRailQueryController = class {
29625
29627
  searchActive: Boolean(this.searchQuery && this.searchEnabled())
29626
29628
  });
29627
29629
  this.previousMembershipRecords = next;
29628
- if (plan.kind !== "refresh_pages") return;
29630
+ if (plan.kind !== "refresh_pages") {
29631
+ this.publishIfReady(state);
29632
+ return;
29633
+ }
29629
29634
  if (plan.pageIds.length > 0 && this.railSectionQueryKey) {
29630
29635
  this.sessionSectionsQueryCache.invalidate(this.railSectionQueryKey);
29631
29636
  }
@@ -29636,27 +29641,34 @@ var AgentGUIConversationRailQueryController = class {
29636
29641
  plan.reconcilingSessionIds
29637
29642
  )
29638
29643
  };
29639
- this.emit();
29640
- if (plan.refreshSearch) this.requestSearch();
29641
- this.cancelPagingRequests();
29642
- this.targetedPageRefresher.refresh({
29643
- agentTargetId: this.sectionAgentTargetId,
29644
- pageIds: plan.pageIds
29645
- });
29644
+ if (plan.refreshSearch) this.requestSearch(true);
29645
+ if (plan.pageIds.length > 0) {
29646
+ this.cancelPagingRequests();
29647
+ this.sectionPublicationState = "pending";
29648
+ this.targetedPageRefresher.refresh({
29649
+ agentTargetId: this.sectionAgentTargetId,
29650
+ pageIds: plan.pageIds
29651
+ });
29652
+ }
29653
+ this.publishIfReady(state);
29646
29654
  }
29647
29655
  refreshFirstPages(refreshReason) {
29648
29656
  const listSections = this.runtime.listSessionSections;
29649
29657
  const scopeKey = this.railSectionQueryKey;
29650
29658
  if (!this.runtimeSectionsEnabled() || !listSections || !scopeKey) {
29651
29659
  this.queryState = EMPTY_CONVERSATION_RAIL_QUERY_STATE;
29652
- this.emit();
29660
+ this.sectionPublicationState = "idle";
29661
+ this.publishIfReady(void 0, true);
29653
29662
  return;
29654
29663
  }
29664
+ if (this.publicationBlocked()) {
29665
+ this.sectionPublicationState = "pending";
29666
+ }
29655
29667
  const cached = this.sessionSectionsQueryCache.read(scopeKey);
29656
29668
  const cacheApplyStartedAt = cached && this.providerSwitchDiagnostics.hasPending(scopeKey) ? this.diagnosticNow() : null;
29657
29669
  if (cached && this.queryState.resolvedScopeKey !== scopeKey) {
29658
29670
  this.applyCachedFirstPages(cached);
29659
- this.emit();
29671
+ this.publishIfReady(void 0, true);
29660
29672
  }
29661
29673
  if (cached && !cached.stale && this.cacheNow() - cached.resolvedAtUnixMs <= this.cacheFreshMs) {
29662
29674
  this.providerSwitchDiagnostics.complete(scopeKey, {
@@ -29667,6 +29679,8 @@ var AgentGUIConversationRailQueryController = class {
29667
29679
  sectionCount: cached.value.sectionCount,
29668
29680
  status: "ready"
29669
29681
  });
29682
+ this.sectionPublicationState = "idle";
29683
+ this.publishIfReady(void 0, true);
29670
29684
  return;
29671
29685
  }
29672
29686
  const cacheStatus = cached ? "stale" : "miss";
@@ -29680,7 +29694,7 @@ var AgentGUIConversationRailQueryController = class {
29680
29694
  ...this.queryState,
29681
29695
  pending: true
29682
29696
  };
29683
- this.emit();
29697
+ this.publishIfReady(void 0, true);
29684
29698
  void this.sessionSectionsQueryCache.request(scopeKey, async () => {
29685
29699
  const page = await listSections({
29686
29700
  agentTargetId: this.sectionAgentTargetId || void 0,
@@ -29698,7 +29712,8 @@ var AgentGUIConversationRailQueryController = class {
29698
29712
  }
29699
29713
  const requestResolvedAt = this.diagnosticNow();
29700
29714
  this.applyCachedFirstPages(entry);
29701
- this.emit();
29715
+ this.sectionPublicationState = "idle";
29716
+ this.publishIfReady(void 0, true);
29702
29717
  const completedAt = this.diagnosticNow();
29703
29718
  this.providerSwitchDiagnostics.complete(scopeKey, {
29704
29719
  cacheStatus,
@@ -29762,7 +29777,11 @@ var AgentGUIConversationRailQueryController = class {
29762
29777
  sectionPageStates: /* @__PURE__ */ new Map(),
29763
29778
  sections: []
29764
29779
  };
29765
- this.emit();
29780
+ if (this.publicationBlocked()) {
29781
+ this.sectionPublicationState = "failed";
29782
+ } else {
29783
+ this.publish(void 0, true);
29784
+ }
29766
29785
  });
29767
29786
  }
29768
29787
  applyCachedFirstPages(entry) {
@@ -29775,7 +29794,7 @@ var AgentGUIConversationRailQueryController = class {
29775
29794
  scopeKey: this.railSectionQueryKey
29776
29795
  });
29777
29796
  }
29778
- requestSearch() {
29797
+ requestSearch(membershipRefresh = false) {
29779
29798
  this.clearSearchDebounceTimer();
29780
29799
  this.searchRequestKey = this.searchEnabled() && this.searchQuery ? JSON.stringify([
29781
29800
  this.workspaceId,
@@ -29788,20 +29807,23 @@ var AgentGUIConversationRailQueryController = class {
29788
29807
  this.searchAbortController = null;
29789
29808
  const listSessionsPage = this.runtime.listSessionsPage;
29790
29809
  if (!this.searchRequestKey || !listSessionsPage) {
29810
+ this.searchPublicationState = "idle";
29791
29811
  this.searchState = EMPTY_CONVERSATION_SEARCH_QUERY_STATE;
29792
- this.emit();
29812
+ this.publishIfReady(void 0, true);
29793
29813
  return;
29794
29814
  }
29795
29815
  const requestKey = this.searchRequestKey;
29796
29816
  const query = this.searchQuery;
29817
+ const tracksPublication = membershipRefresh || this.publicationBlocked();
29797
29818
  const abortController = new AbortController();
29798
29819
  this.searchAbortController = abortController;
29820
+ if (tracksPublication) this.searchPublicationState = "pending";
29799
29821
  this.searchState = {
29800
29822
  ...EMPTY_CONVERSATION_SEARCH_QUERY_STATE,
29801
29823
  pending: true,
29802
29824
  requestKey
29803
29825
  };
29804
- this.emit();
29826
+ this.publishIfReady(void 0, true);
29805
29827
  void listSessionsPage({
29806
29828
  agentTargetId: this.sectionAgentTargetId || void 0,
29807
29829
  limit: 100,
@@ -29823,7 +29845,12 @@ var AgentGUIConversationRailQueryController = class {
29823
29845
  resolvedQuery: query,
29824
29846
  sessionIds: page.sessions.map((session) => session.agentSessionId)
29825
29847
  };
29826
- this.emit();
29848
+ if (tracksPublication) {
29849
+ this.searchPublicationState = "idle";
29850
+ this.publishIfReady(void 0, true);
29851
+ } else {
29852
+ this.publishIfReady(void 0, true);
29853
+ }
29827
29854
  }).catch(() => {
29828
29855
  if (abortController.signal.aborted || requestSequence !== this.searchRequestSequence || requestKey !== this.searchRequestKey) {
29829
29856
  return;
@@ -29834,7 +29861,11 @@ var AgentGUIConversationRailQueryController = class {
29834
29861
  requestKey,
29835
29862
  resolvedQuery: query
29836
29863
  };
29837
- this.emit();
29864
+ if (tracksPublication) {
29865
+ this.searchPublicationState = "failed";
29866
+ } else {
29867
+ this.publishIfReady(void 0, true);
29868
+ }
29838
29869
  });
29839
29870
  }
29840
29871
  scheduleSearch() {
@@ -29847,7 +29878,7 @@ var AgentGUIConversationRailQueryController = class {
29847
29878
  return;
29848
29879
  }
29849
29880
  this.searchRequestKey = null;
29850
- this.emit();
29881
+ this.publishIfReady(void 0, true);
29851
29882
  this.searchDebounceTask = this.scheduler.schedule(
29852
29883
  CONVERSATION_SEARCH_DEBOUNCE_MS,
29853
29884
  () => {
@@ -29880,17 +29911,35 @@ var AgentGUIConversationRailQueryController = class {
29880
29911
  searchEnabled() {
29881
29912
  return Boolean(!this.scope?.previewMode && this.runtime.listSessionsPage);
29882
29913
  }
29883
- emit() {
29884
- this.snapshot = buildConversationRailQuerySnapshot({
29885
- queryState: this.queryState,
29886
- runtimeSectionsEnabled: this.runtimeSectionsEnabled(),
29887
- searchEnabled: this.searchEnabled(),
29888
- searchQuery: this.searchQuery,
29889
- searchRequestKey: this.searchRequestKey,
29890
- searchState: this.searchState
29891
- });
29914
+ publishIfReady(state = this.engine.getSnapshot(), force = false) {
29915
+ if (this.publicationBlocked()) return;
29916
+ this.publish(state, force);
29917
+ }
29918
+ publish(state = this.engine.getSnapshot(), force = false) {
29919
+ const snapshot = this.selectSnapshot(
29920
+ {
29921
+ engineState: state,
29922
+ queryState: this.queryState,
29923
+ runtimeSectionsEnabled: this.runtimeSectionsEnabled(),
29924
+ searchEnabled: this.searchEnabled(),
29925
+ searchQuery: this.searchQuery,
29926
+ searchRequestKey: this.searchRequestKey,
29927
+ searchState: this.searchState
29928
+ },
29929
+ this.snapshot,
29930
+ force
29931
+ );
29932
+ if (snapshot === this.snapshot) return;
29933
+ this.snapshot = snapshot;
29892
29934
  for (const listener of this.listeners) listener(this.snapshot);
29893
29935
  }
29936
+ resetPublication() {
29937
+ this.sectionPublicationState = "idle";
29938
+ this.searchPublicationState = "idle";
29939
+ }
29940
+ publicationBlocked() {
29941
+ return this.sectionPublicationState !== "idle" || this.searchPublicationState !== "idle";
29942
+ }
29894
29943
  cancelPagingRequests(incrementSequence = true) {
29895
29944
  if (incrementSequence) this.pagingRequestSequence += 1;
29896
29945
  for (const controller of this.pagingAbortControllers.values()) {
@@ -29905,6 +29954,17 @@ var AgentGUIConversationRailQueryController = class {
29905
29954
  this.unsubscribeEngine = null;
29906
29955
  this.cancelPagingRequests();
29907
29956
  this.targetedPageRefresher.cancel();
29957
+ if (this.publicationBlocked() && this.railSectionQueryKey) {
29958
+ this.sessionSectionsQueryCache.invalidate(this.railSectionQueryKey);
29959
+ }
29960
+ if (this.publicationBlocked()) {
29961
+ if (this.sectionPublicationState === "pending") {
29962
+ this.sectionPublicationState = "failed";
29963
+ }
29964
+ if (this.searchPublicationState === "pending") {
29965
+ this.searchPublicationState = "failed";
29966
+ }
29967
+ }
29908
29968
  this.clearSearchDebounceTimer();
29909
29969
  this.searchRequestSequence += 1;
29910
29970
  this.searchAbortController?.abort();
@@ -29960,17 +30020,6 @@ function useAgentGUIConversationRailQuery({
29960
30020
  identitySnapshot,
29961
30021
  Object.is
29962
30022
  );
29963
- const selectRuntimeRailConversations = useMemo33(
29964
- () => createRuntimeRailConversationsSelector(
29965
- createAgentGUIConversationRailTitlePromptSelector()
29966
- ),
29967
- []
29968
- );
29969
- const runtimeRailConversations = useEngineSelector(
29970
- engine,
29971
- selectRuntimeRailConversations,
29972
- conversationSummaryListsRenderEqual
29973
- );
29974
30023
  return useMemo33(
29975
30024
  () => ({
29976
30025
  ...querySnapshot,
@@ -29981,23 +30030,11 @@ function useAgentGUIConversationRailQuery({
29981
30030
  loadMore: controller.loadMoreSearchResults,
29982
30031
  retry: controller.retrySearchResults
29983
30032
  },
29984
- runtimeRailConversations
30033
+ runtimeRailConversations: querySnapshot.runtimeRailConversations
29985
30034
  }),
29986
- [controller, querySnapshot, runtimeRailConversations]
29987
- );
29988
- }
29989
- function createRuntimeRailConversationsSelector(selectTitlePrompts) {
29990
- return (state) => projectCanonicalAgentGUIConversationSummaries(
29991
- selectWorkspaceAgentConsumerSessions4(state),
29992
- selectTitlePrompts(state)
30035
+ [controller, querySnapshot]
29993
30036
  );
29994
30037
  }
29995
- function conversationSummaryListsRenderEqual(left, right) {
29996
- return left.length === right.length && left.every((conversation, index) => {
29997
- const other = right[index];
29998
- return other !== void 0 && conversationSummariesRenderEqual2(conversation, other);
29999
- });
30000
- }
30001
30038
  function identitySnapshot(snapshot) {
30002
30039
  return snapshot;
30003
30040
  }
@@ -35353,4 +35390,4 @@ export {
35353
35390
  resolveAgentGUIAgentTarget,
35354
35391
  AgentGUI
35355
35392
  };
35356
- //# sourceMappingURL=chunk-PEOMUPWF.js.map
35393
+ //# sourceMappingURL=chunk-ATDAII35.js.map