@newheap/platform-ai-chat 0.5.0 → 0.7.0

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/index.d.ts CHANGED
@@ -13,7 +13,21 @@ interface AssistantStatus {
13
13
  };
14
14
  /** True when the caller also passes the admin policy and may use the `admin/*` endpoints. */
15
15
  canAdminister: boolean;
16
+ /** Sharing, live update and notification features; missing on servers without them. */
17
+ collaboration?: AssistantCollaboration | null;
16
18
  }
19
+ interface AssistantCollaboration {
20
+ /** Owners can invite colleagues directly through the application's directory. */
21
+ directory: boolean;
22
+ /** Path of the SignalR hub for live updates, for example `/hub/assistant`; `null` when off. */
23
+ hubPath: string | null;
24
+ /** Web Push notifications are configured on the server. */
25
+ push: boolean;
26
+ /** Maximum participants per conversation, not counting the owner. */
27
+ maxParticipants: number;
28
+ }
29
+ /** The caller's relation to a conversation. */
30
+ type ConversationRole = 'owner' | 'participant';
17
31
  interface AgentSummary {
18
32
  id: string;
19
33
  version: number;
@@ -28,18 +42,46 @@ interface ConversationSummary {
28
42
  status: ConversationStatus;
29
43
  createdAt: string;
30
44
  updatedAt: string;
45
+ /** Default `owner` for servers without sharing. */
46
+ role?: ConversationRole;
47
+ /** People the owner shared the conversation with. */
48
+ participantCount?: number;
49
+ /** Sequence of the latest message. */
50
+ lastMessageSequence?: number;
51
+ /** The caller's read position; the conversation is unread while it is lower than `lastMessageSequence`. */
52
+ lastReadSequence?: number;
53
+ /** The owner or participant whose turn runs or waits for approval. */
54
+ activeActorId?: string | null;
31
55
  }
32
56
  interface Conversation extends ConversationSummary {
33
57
  agentVersion: number;
34
58
  messages: Message[];
35
59
  pendingApproval: ApprovalPart | null;
60
+ /** The owner followed by the participants; empty while the conversation is not shared. */
61
+ members?: ConversationMember[];
62
+ /** The current invitation-link token; only for the owner. */
63
+ shareToken?: string | null;
64
+ /** The caller's actor id, to recognize the caller's own messages. */
65
+ currentActorId?: string | null;
36
66
  }
37
67
  type ConversationStatus = 'idle' | 'running' | 'waiting-for-approval' | 'failed' | 'archived';
68
+ /** The owner or a participant of a shared conversation. */
69
+ interface ConversationMember {
70
+ actorId: string;
71
+ /** `null` when the application provides no name. */
72
+ displayName: string | null;
73
+ role: ConversationRole;
74
+ joinedAt: string;
75
+ }
38
76
  interface Message {
39
77
  id: string;
40
78
  role: 'user' | 'assistant' | 'tool';
41
79
  createdAt: string;
42
80
  parts: MessagePart[];
81
+ /** Position in the conversation; missing on optimistic messages and old servers. */
82
+ sequence?: number;
83
+ /** The writer of a user message. */
84
+ authorActorId?: string | null;
43
85
  }
44
86
  type MessagePart = TextPart | ToolCallPart | ApprovalPart;
45
87
  interface TextPart {
@@ -130,6 +172,34 @@ interface DecideApprovalRequest {
130
172
  expectedProposalHash: string;
131
173
  reason?: string;
132
174
  }
175
+ /** Response of `POST conversations/{id}/share-link`. */
176
+ interface ShareLink {
177
+ token: string;
178
+ }
179
+ /** A person the owner may invite, from the application's directory. */
180
+ interface DirectoryEntry {
181
+ actorId: string;
182
+ displayName: string;
183
+ detail: string | null;
184
+ }
185
+ /** Response of `GET` and `PUT notifications`. */
186
+ interface NotificationSettings {
187
+ /** The caller's choice; on by default. */
188
+ pushEnabled: boolean;
189
+ /** The server has Web Push configured. */
190
+ pushAvailable: boolean;
191
+ /** The VAPID key browsers subscribe with. */
192
+ publicKey: string | null;
193
+ }
194
+ /** Body of `PUT notifications/push-subscription`: `PushSubscription.toJSON()` plus the text language. */
195
+ interface PushSubscriptionRequest {
196
+ endpoint: string;
197
+ keys: {
198
+ p256dh: string;
199
+ auth: string;
200
+ };
201
+ language?: string;
202
+ }
133
203
 
134
204
  interface TurnStartedEvent {
135
205
  turnId: string;
@@ -204,9 +274,42 @@ declare const NhAssistantClientErrorCodes: {
204
274
  readonly invalidResponse: "assistant-invalid-response";
205
275
  readonly streamInterrupted: "assistant-stream-interrupted";
206
276
  readonly server: "assistant-server";
277
+ /** The open conversation was deleted by its owner, or the user left or was removed. */
278
+ readonly conversationRemoved: "assistant-conversation-removed";
207
279
  };
208
280
  type NhAssistantClientErrorCode = typeof NhAssistantClientErrorCodes[keyof typeof NhAssistantClientErrorCodes];
209
281
 
282
+ /** `ConversationChanged`: status, title, active actor, latest message or participants changed. */
283
+ interface LiveConversationChanged {
284
+ conversationId: string;
285
+ status: ConversationStatus;
286
+ title: string | null;
287
+ updatedAt: string;
288
+ activeActorId: string | null;
289
+ lastMessageSequence: number;
290
+ participantCount: number;
291
+ }
292
+ /** `ConversationRead`: the current user read the conversation, for example in another tab. */
293
+ interface LiveConversationRead {
294
+ conversationId: string;
295
+ lastReadSequence: number;
296
+ }
297
+ /** `ConversationRemoved`: the conversation is no longer available to the current user. */
298
+ interface LiveConversationRemoved {
299
+ conversationId: string;
300
+ }
301
+ /**
302
+ * `ConversationEvent`: one turn event with the same `type` and `data` as the server-sent events
303
+ * of the starting request, or `message.created` with a `Message` when a participant's message
304
+ * was stored.
305
+ */
306
+ interface LiveConversationEvent {
307
+ conversationId: string;
308
+ actorId: string;
309
+ type: string;
310
+ data: unknown;
311
+ }
312
+
210
313
  type AssistantStyle = 'default' | 'direct' | 'personal' | 'detailed';
211
314
  type AssistantAddressForm = 'informal' | 'formal';
212
315
  type AssistantResponseLength = 'short' | 'normal' | 'long';
@@ -357,6 +460,41 @@ interface NhAssistantConfig {
357
460
  markdown?: {
358
461
  enabled: boolean;
359
462
  };
463
+ /**
464
+ * Live updates of shared and parallel conversations through the server's SignalR hub, which
465
+ * `GET status` reports. Uses `@microsoft/signalr`, loaded on first use. Default `true`; when off
466
+ * or unavailable the assistant reloads snapshots instead.
467
+ */
468
+ liveUpdates?: boolean;
469
+ /**
470
+ * Base the server's hub path is appended to, for example `'/api'` when a proxy serves the API
471
+ * below a prefix, as for the NewHeap background operation hub. Default: the origin of `apiBaseUrl`.
472
+ */
473
+ hubBaseUrl?: string;
474
+ /**
475
+ * Web Push notifications for people who are away. Copy the bundled worker from
476
+ * `node_modules/@newheap/platform-ai-chat/push` into the application's assets and point
477
+ * `serviceWorkerUrl` to it. Without this setting the assistant never subscribes the browser.
478
+ */
479
+ push?: NhAssistantPushConfig;
480
+ /**
481
+ * Builds the invitation link an owner copies. Default: the current page with
482
+ * `#nh-assistant-join=<conversationId>.<token>`; the panel joins when the page opens with it.
483
+ */
484
+ buildShareLink?: (conversationId: string, token: string) => string;
485
+ }
486
+ interface NhAssistantPushConfig {
487
+ /** URL of the bundled worker, for example `/nh-assistant/nh-assistant-push-worker.js`. */
488
+ serviceWorkerUrl: string;
489
+ /**
490
+ * Scope of the worker. Default: the worker's folder. Keep it apart from an application service
491
+ * worker; the assistant worker only shows notifications and never controls pages.
492
+ */
493
+ scope?: string;
494
+ /** Page a notification opens when no window of the application is open. Default `/`. */
495
+ openUrl?: string;
496
+ /** Icon URL of the notifications. */
497
+ icon?: string;
360
498
  }
361
499
  declare const NH_ASSISTANT_CONFIG: InjectionToken<NhAssistantConfig>;
362
500
  declare const NH_ASSISTANT_ACCESS_POLICY: InjectionToken<NhAssistantAccessPolicy>;
@@ -455,6 +593,28 @@ declare class NhAssistantApiService {
455
593
  sendMessage(conversationId: string, request: SendMessageRequest): Observable<NhAssistantSseEvent>;
456
594
  decideApproval(conversationId: string, approvalId: string, request: DecideApprovalRequest): Observable<NhAssistantSseEvent>;
457
595
  cancel(conversationId: string): Observable<void>;
596
+ /** Raises the caller's read position to `sequence`, or to the latest message when omitted. */
597
+ markRead(conversationId: string, sequence?: number): Observable<void>;
598
+ /** Owner only: creates a new invitation link; an earlier link stops working. */
599
+ createShareLink(conversationId: string): Observable<ShareLink>;
600
+ /** Owner only: the invitation link stops working; people who joined stay. */
601
+ revokeShareLink(conversationId: string): Observable<void>;
602
+ /** Joins a shared conversation with the token of its invitation link. */
603
+ joinConversation(conversationId: string, token: string): Observable<Conversation>;
604
+ /** Owner only: searches the application's directory for people to invite. */
605
+ searchParticipantCandidates(conversationId: string, query: string): Observable<DirectoryEntry[]>;
606
+ /** Owner only: invites a person the directory returned. */
607
+ inviteParticipant(conversationId: string, actorId: string): Observable<void>;
608
+ /** The owner removes a participant, or a participant passes their own id to leave. */
609
+ removeParticipant(conversationId: string, actorId: string): Observable<void>;
610
+ /** The caller's notification choice and the server's Web Push key. */
611
+ getNotificationSettings(): Observable<NotificationSettings>;
612
+ /** Turns push notifications on or off for every browser of the caller. */
613
+ updateNotificationSettings(pushEnabled: boolean): Observable<NotificationSettings>;
614
+ /** Registers this browser's push subscription for the caller. */
615
+ subscribePush(subscription: PushSubscriptionRequest): Observable<void>;
616
+ /** Removes this browser's push subscription. */
617
+ unsubscribePush(endpoint: string): Observable<void>;
458
618
  /** The caller's own assistant preferences. */
459
619
  getPreferences(): Observable<AssistantPreferences>;
460
620
  /** Replaces the caller's own assistant preferences and returns the stored values. */
@@ -513,6 +673,13 @@ declare class NhAssistantAdminApiService {
513
673
  declare function applyNhAssistantEvent(conversation: Conversation, event: NhAssistantSseEvent, clientMessageId?: string): Conversation;
514
674
  /** Records the user's approval decision locally until the server state is reloaded. */
515
675
  declare function applyNhAssistantApprovalDecision(conversation: Conversation, approvalId: string, decision: 'approve' | 'reject'): Conversation;
676
+ /**
677
+ * Applies a live update of another session: `message.created` adds a participant's message,
678
+ * the turn events behave exactly like the starting request's stream. Unknown types are ignored.
679
+ */
680
+ declare function applyNhAssistantLiveEvent(conversation: Conversation, event: LiveConversationEvent): Conversation;
681
+ /** Applies the shared state of a conversation that a live update announced. */
682
+ declare function applyNhAssistantConversationChange(conversation: Conversation, change: LiveConversationChanged): Conversation;
516
683
  /**
517
684
  * True when an assistant message after the latest user message contains non-blank text,
518
685
  * so the latest turn produced a visible answer. Tool calls and approvals alone do not count.
@@ -538,6 +705,52 @@ declare function normalizeNhAssistantClientContext(value: unknown): ClientContex
538
705
  /** Short text for the page-context chip: the first entity's label, the title or the route. */
539
706
  declare function describeNhAssistantClientContext(context: ClientContext): string;
540
707
 
708
+ type NhAssistantLiveState = 'off' | 'connecting' | 'connected' | 'reconnecting' | 'disconnected';
709
+ /**
710
+ * Live updates of the assistant hub: conversation changes, read positions, removals and the
711
+ * turn events of other sessions. Connects only while the store asks for it, reconnects on its
712
+ * own and emits `resync` after every (re)connect, because updates sent while disconnected are lost.
713
+ */
714
+ declare class NhAssistantLiveService {
715
+ private readonly config;
716
+ private readonly injector;
717
+ private readonly browser;
718
+ private readonly changedSubject;
719
+ private readonly readSubject;
720
+ private readonly removedSubject;
721
+ private readonly eventSubject;
722
+ private readonly resyncSubject;
723
+ private readonly stateSignal;
724
+ private connection?;
725
+ private hubPath;
726
+ private hubUrl;
727
+ private revision;
728
+ private restartTimer?;
729
+ readonly changed$: Observable<LiveConversationChanged>;
730
+ readonly read$: Observable<LiveConversationRead>;
731
+ readonly removed$: Observable<LiveConversationRemoved>;
732
+ readonly events$: Observable<LiveConversationEvent>;
733
+ /** Reload snapshots: emitted after every (re)connect. */
734
+ readonly resync$: Observable<void>;
735
+ readonly state: _angular_core.Signal<NhAssistantLiveState>;
736
+ constructor();
737
+ /**
738
+ * Connects to the hub at `hubPath`, or disconnects when it is `null`. Calling it again with the
739
+ * same path keeps the connection; another path or `restart` reconnects, for example after the
740
+ * signed-in user changed.
741
+ */
742
+ connect(hubPath: string | null, restart?: boolean): Promise<void>;
743
+ stop(): Promise<void>;
744
+ private build;
745
+ /** Starts over after the automatic reconnect gave up or the first start failed. */
746
+ private scheduleRestart;
747
+ private token;
748
+ /** `hubBaseUrl` + `hubPath`, or the hub path on the origin of `apiBaseUrl`. */
749
+ private resolveUrl;
750
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantLiveService, never>;
751
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<NhAssistantLiveService>;
752
+ }
753
+
541
754
  /** A user-facing assistant failure: a stable code and a translation key, never raw server text. */
542
755
  interface NhAssistantError {
543
756
  code: string;
@@ -551,8 +764,26 @@ type NhAssistantNotice = NhAssistantError;
551
764
  /** Notice code for a completed turn that produced no answer text and no server code. */
552
765
  declare const NH_ASSISTANT_NO_ANSWER_NOTICE_CODE = "assistant-no-answer";
553
766
  /**
554
- * Signal-based state of one assistant scope: availability, agents, the conversation list
555
- * and the active conversation with its streamed turn.
767
+ * A conversation that needs attention outside the open thread: a turn runs, an approval waits or
768
+ * there is something unread.
769
+ */
770
+ interface NhAssistantActivity {
771
+ id: string;
772
+ title: string | null;
773
+ status: ConversationStatus;
774
+ unread: boolean;
775
+ shared: boolean;
776
+ /** True for the conversation shown in the panel. */
777
+ active: boolean;
778
+ updatedAt: string;
779
+ }
780
+ /** True when a conversation has messages the caller has not read. A running turn is not unread yet. */
781
+ declare function nhAssistantIsUnread(summary: Pick<ConversationSummary, 'status' | 'lastMessageSequence' | 'lastReadSequence'>): boolean;
782
+ /**
783
+ * Signal-based state of one assistant scope: availability, agents, the conversation list and
784
+ * every conversation this tab has opened. Several conversations can run turns at the same time;
785
+ * the public signals describe the conversation that is open in the panel. With live updates the
786
+ * store follows turns of other people and of the user's other tabs.
556
787
  */
557
788
  declare class NhAssistantStore {
558
789
  private readonly api;
@@ -560,6 +791,10 @@ declare class NhAssistantStore {
560
791
  private readonly injector;
561
792
  private readonly accessPolicy;
562
793
  private readonly uiState;
794
+ private readonly live;
795
+ private readonly push;
796
+ private readonly document;
797
+ private readonly browser;
563
798
  private readonly accessGrantedState;
564
799
  private readonly statusState;
565
800
  private readonly statusLoadingState;
@@ -567,24 +802,30 @@ declare class NhAssistantStore {
567
802
  private readonly conversationsState;
568
803
  private readonly conversationsTotalState;
569
804
  private readonly conversationsLoadingState;
570
- private readonly activeConversationState;
805
+ private readonly sessionsState;
806
+ private readonly activeIdState;
571
807
  private readonly conversationLoadingState;
572
- private readonly streamingState;
573
- private readonly decidingState;
574
- private readonly errorState;
575
- private readonly noticeState;
576
- private readonly lastUsageState;
808
+ /** The conversation a message is being prepared for; `''` while a new conversation is created. */
809
+ private readonly sendingState;
810
+ private readonly draftErrorState;
577
811
  private readonly restoredDraftState;
578
812
  private readonly pageContextState;
579
813
  private readonly pageContextExcludedState;
580
814
  private readonly restorePanelOpenState;
815
+ private readonly viewingState;
816
+ private readonly pageVisibleState;
817
+ private readonly streams;
818
+ private readonly cancelTimers;
819
+ private readonly pendingSendResolves;
820
+ private readonly markingRead;
821
+ private readonly liveSubscription;
581
822
  private accessSubscription?;
582
- private streamSubscription?;
583
- private cancelTimer?;
823
+ private refreshTimer?;
584
824
  private initialization?;
585
825
  private statusRevision;
586
826
  private accountRevision;
587
- private pendingSendResolve?;
827
+ private collaborationKey;
828
+ private readonly activeSession;
588
829
  /** True when the access policy allows the user and the server reports the assistant as enabled. */
589
830
  readonly enabled: _angular_core.Signal<boolean>;
590
831
  readonly accessGranted: _angular_core.Signal<boolean | null>;
@@ -596,13 +837,17 @@ declare class NhAssistantStore {
596
837
  maxToolCallsPerTurn: number;
597
838
  } | null>;
598
839
  readonly agents: _angular_core.Signal<AgentSummary[]>;
840
+ /** Sharing, live update and notification features the server offers. */
841
+ readonly collaboration: _angular_core.Signal<AssistantCollaboration | null>;
599
842
  readonly selectedAgentId: _angular_core.Signal<string | null>;
600
843
  readonly selectedAgent: _angular_core.Signal<AgentSummary | null>;
601
844
  readonly conversations: _angular_core.Signal<ConversationSummary[]>;
602
845
  readonly conversationsTotal: _angular_core.Signal<number>;
603
846
  readonly conversationsLoading: _angular_core.Signal<boolean>;
847
+ /** The conversation open in the panel, or `null` for a new one. */
604
848
  readonly activeConversation: _angular_core.Signal<Conversation | null>;
605
849
  readonly conversationLoading: _angular_core.Signal<boolean>;
850
+ /** True while this tab sends a message or streams a turn of the open conversation. */
606
851
  readonly streaming: _angular_core.Signal<boolean>;
607
852
  readonly pendingApproval: _angular_core.Signal<ApprovalPart | null>;
608
853
  readonly deciding: _angular_core.Signal<boolean>;
@@ -620,29 +865,64 @@ declare class NhAssistantStore {
620
865
  readonly restorePanelOpen: _angular_core.Signal<boolean>;
621
866
  /** True while the user can send: enabled, an agent is chosen and no turn runs or waits. */
622
867
  readonly canSend: _angular_core.Signal<boolean>;
868
+ /** The owner and participants of the open conversation; empty while it is not shared. */
869
+ readonly members: _angular_core.Signal<ConversationMember[]>;
870
+ /** True when the current user owns the open conversation (or it is new). */
871
+ readonly isOwner: _angular_core.Signal<boolean>;
872
+ /** True when the current user may decide the pending approval: it belongs to their own turn. */
873
+ readonly canDecide: _angular_core.Signal<boolean>;
874
+ /** The member whose turn runs or waits in the open conversation, when it is someone else. */
875
+ readonly activeMember: _angular_core.Signal<ConversationMember | null>;
876
+ /** Conversations that need attention: running, waiting for approval or unread. Most recent first. */
877
+ readonly activity: _angular_core.Signal<NhAssistantActivity[]>;
878
+ readonly runningCount: _angular_core.Signal<number>;
879
+ readonly waitingCount: _angular_core.Signal<number>;
880
+ readonly unreadCount: _angular_core.Signal<number>;
881
+ /** Live update connection state. */
882
+ readonly liveState: _angular_core.Signal<NhAssistantLiveState>;
623
883
  constructor();
624
884
  /** Evaluates the access policy and loads the server status once. Safe to call repeatedly. */
625
885
  initialize(): Promise<void>;
626
886
  /** Reloads the server status, for example after the host changed the signed-in user. */
627
887
  reloadStatus(): Promise<void>;
628
888
  refreshConversations(): Promise<void>;
629
- /** Chooses the agent for the next new conversation. Switching away from the active conversation's agent starts a new one. */
889
+ /** Chooses the agent for the next new conversation. Switching away from the open conversation's agent starts a new one. */
630
890
  selectAgent(agentId: string): void;
631
- /** Leaves the active conversation; the next message creates a new one. */
891
+ /**
892
+ * Leaves the open conversation; the next message creates a new one. Turns of other
893
+ * conversations keep running in the background.
894
+ */
632
895
  startNewConversation(): void;
896
+ /** Opens a conversation; one that this tab already follows opens immediately. */
633
897
  openConversation(conversationId: string): Promise<void>;
634
- private loadConversation;
898
+ /** Tells the store whether the user can see the open thread, so it can mark it as read. */
899
+ setViewing(viewing: boolean): void;
635
900
  deleteConversation(conversationId: string): Promise<void>;
636
901
  /**
637
- * Sends a user message. Creates a conversation with the selected agent when none is
638
- * active, shows the message optimistically and applies the streamed events.
639
- * Resolves `false` when the message was not accepted.
902
+ * Sends a user message. Creates a conversation with the selected agent when none is open,
903
+ * shows the message optimistically and applies the streamed events. Other conversations keep
904
+ * their own turns. Resolves `false` when the message was not accepted.
640
905
  */
641
906
  send(text: string): Promise<boolean>;
642
907
  /** Approves or rejects the pending approval. Ignores repeated calls while a decision is in flight. */
643
908
  decide(decision: ApprovalDecision, reason?: string): void;
644
- /** Asks the server to stop the running turn or to abandon a waiting approval. */
909
+ /** Asks the server to stop the running turn or to abandon a waiting approval of the open conversation. */
645
910
  cancel(): Promise<void>;
911
+ /** Joins a shared conversation with an invitation link and opens it. Resolves `false` on failure. */
912
+ joinConversation(conversationId: string, token: string): Promise<boolean>;
913
+ /** Owner only: creates a new invitation link for the open conversation and returns its token. */
914
+ createShareLink(): Promise<string | null>;
915
+ /** Owner only: the invitation link of the open conversation stops working. */
916
+ revokeShareLink(): Promise<boolean>;
917
+ /** Owner only: searches the application's directory for people to invite to the open conversation. */
918
+ searchParticipantCandidates(query: string): Promise<DirectoryEntry[]>;
919
+ /** Owner only: invites a person from the directory to the open conversation. */
920
+ inviteParticipant(actorId: string): Promise<boolean>;
921
+ /**
922
+ * The owner removes a participant of the open conversation; with the current user's own id a
923
+ * participant leaves it.
924
+ */
925
+ removeParticipant(actorId: string): Promise<boolean>;
646
926
  clearError(): void;
647
927
  clearNotice(): void;
648
928
  /** Persists only drawer visibility, never the page context or a message draft. */
@@ -653,6 +933,8 @@ declare class NhAssistantStore {
653
933
  setPageContextExcluded(excluded: boolean): void;
654
934
  /** Returns and clears the draft of a message that was not accepted. */
655
935
  consumeRestoredDraft(): string | null;
936
+ private loadConversation;
937
+ private setActive;
656
938
  /**
657
939
  * Page context for one message: `undefined` omits the field (no getter, getter failed or
658
940
  * invalid shape), `null` sends an explicit "none" (no context or left out by the user).
@@ -660,22 +942,101 @@ declare class NhAssistantStore {
660
942
  private contextForMessage;
661
943
  private readPageContext;
662
944
  private startInitialization;
945
+ /** Connects live updates and notifications once per account and server configuration. */
946
+ private startCollaboration;
947
+ /** Forgets everything about the previous account: turns, conversations, live updates and push. */
948
+ private resetAccount;
663
949
  private createConversation;
664
950
  private runStream;
665
- private stopLocalTurn;
951
+ private stopAllTurns;
666
952
  private applyEvent;
667
- /** A completed turn with a server code, or without any answer text, explains itself with a notice. */
668
- private completionNotice;
669
953
  private afterTurn;
670
- private reloadActiveConversation;
671
- private updateActive;
954
+ private reloadSession;
955
+ private markActiveReadWhenSeen;
956
+ private onLiveChanged;
957
+ private onLiveRead;
958
+ private onLiveRemoved;
959
+ private onLiveEvent;
960
+ /** After a reconnect: updates sent while disconnected are lost, so reload what is shown. */
961
+ private resync;
962
+ private scheduleRefresh;
963
+ /** Stores a snapshot, keeping at most `maxSessions` idle conversations in memory. */
964
+ private upsertSession;
965
+ private patchSession;
966
+ private patchSummary;
967
+ /**
968
+ * Keeps local knowledge when the list is reloaded: the status of turns this tab streams, and a
969
+ * read position the server already confirmed, which a list response sent earlier may not show.
970
+ */
971
+ private withLocalState;
972
+ /** Removes a deleted, left or inaccessible conversation everywhere. */
973
+ private forget;
672
974
  private removeMessage;
673
975
  private selectInitialAgent;
976
+ /** Shows an error on a conversation, or on the new-conversation view for `null`. */
674
977
  private setError;
675
978
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantStore, never>;
676
979
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<NhAssistantStore>;
677
980
  }
678
981
 
982
+ /**
983
+ * Push state of this browser for the signed-in user:
984
+ * - `unavailable`: the server, the browser or the host configuration does not support Web Push;
985
+ * - `off`: the user turned notifications off;
986
+ * - `prompt`: on, but the browser has not asked for permission yet (it asks on the next message sent);
987
+ * - `blocked`: on, but the browser denied permission;
988
+ * - `on`: this browser receives notifications.
989
+ */
990
+ type NhAssistantPushState = 'unavailable' | 'off' | 'prompt' | 'blocked' | 'on';
991
+ /**
992
+ * Keeps this browser's Web Push subscription in line with the user's choice. Notifications are on
993
+ * by default; because browsers only ask for permission after a user action, the assistant asks
994
+ * when the user sends a message or turns notifications on. The bundled service worker shows a
995
+ * notification only when no window of the application is focused.
996
+ */
997
+ declare class NhAssistantPushService {
998
+ private readonly api;
999
+ private readonly config;
1000
+ private readonly translate;
1001
+ private readonly browser;
1002
+ private readonly settingsState;
1003
+ private readonly permissionState;
1004
+ private readonly subscribedState;
1005
+ private readonly busyState;
1006
+ private readonly openSubject;
1007
+ private registration?;
1008
+ private revision;
1009
+ private readonly onWorkerMessage;
1010
+ /** The caller's server-side choice, or `null` before it was loaded. */
1011
+ readonly settings: _angular_core.Signal<NotificationSettings | null>;
1012
+ readonly busy: _angular_core.Signal<boolean>;
1013
+ /** Conversations a clicked notification asks to open. */
1014
+ readonly openConversation$: Observable<string>;
1015
+ readonly state: _angular_core.Signal<NhAssistantPushState>;
1016
+ constructor();
1017
+ /**
1018
+ * Loads the user's choice and, when permission was granted before, renews this browser's
1019
+ * subscription, which also moves it to the current user and to a rotated server key.
1020
+ */
1021
+ activate(serverSupportsPush: boolean): Promise<void>;
1022
+ /**
1023
+ * Forgets the user. The browser subscription is cancelled, so a previous user on a shared device
1024
+ * stops receiving notifications even when the server cannot be told.
1025
+ */
1026
+ deactivate(): Promise<void>;
1027
+ /** Asks for permission once, after a user action such as sending a message. */
1028
+ onUserGesture(): Promise<void>;
1029
+ /** Turns notifications on or off for every browser of the user. Call it from a user action. */
1030
+ setEnabled(enabled: boolean): Promise<void>;
1031
+ private subscribe;
1032
+ private unsubscribe;
1033
+ private register;
1034
+ private scope;
1035
+ private isSupported;
1036
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantPushService, never>;
1037
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<NhAssistantPushService>;
1038
+ }
1039
+
679
1040
  /** Drawer width on wider screens; below the mobile breakpoint the panel fills the screen. */
680
1041
  declare const NH_ASSISTANT_PANEL_WIDTH = "420px";
681
1042
  declare const NH_ASSISTANT_PANEL_MOBILE_QUERY = "(max-width: 599.98px)";
@@ -713,7 +1074,14 @@ declare class NhAssistantPanelService {
713
1074
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<NhAssistantPanelService>;
714
1075
  }
715
1076
 
716
- type NhAssistantIconName = 'assistant' | 'close' | 'send' | 'stop' | 'plus' | 'list' | 'trash' | 'tool' | 'check' | 'x' | 'warning' | 'chevron-down' | 'clock' | 'settings' | 'admin' | 'edit' | 'refresh' | 'link' | 'page';
1077
+ /** Fragment the panel reads to join a shared conversation: `#nh-assistant-join=<id>.<token>`. */
1078
+ declare const NH_ASSISTANT_JOIN_FRAGMENT = "nh-assistant-join";
1079
+ /** Fragment a clicked notification opens: `#nh-assistant-conversation=<id>`. */
1080
+ declare const NH_ASSISTANT_CONVERSATION_FRAGMENT = "nh-assistant-conversation";
1081
+ /** Builds the default invitation link: the current page with the join fragment. */
1082
+ declare function nhAssistantShareLink(conversationId: string, token: string): string;
1083
+
1084
+ type NhAssistantIconName = 'assistant' | 'close' | 'send' | 'stop' | 'plus' | 'list' | 'trash' | 'tool' | 'check' | 'x' | 'warning' | 'chevron-down' | 'clock' | 'settings' | 'admin' | 'edit' | 'refresh' | 'link' | 'page' | 'users' | 'copy' | 'bell' | 'leave';
717
1085
  /**
718
1086
  * Optional icon classes of the host's icon library, for example `{ close: 'ph ph-x' }`.
719
1087
  * Icons without a class use the library's small built-in outline glyphs.
@@ -731,13 +1099,16 @@ declare class NhAssistantIconComponent {
731
1099
 
732
1100
  /**
733
1101
  * Header button that opens the assistant panel. It renders nothing while the assistant is
734
- * disabled on the server or the access policy denies the user. A badge marks a conversation
735
- * that waits for approval. Projected content replaces the default icon.
1102
+ * disabled on the server or the access policy denies the user. One small badge shows what needs
1103
+ * attention, in this order: an approval that waits, the number of unread conversations, or a
1104
+ * turn that runs. Projected content replaces the default icon.
736
1105
  */
737
1106
  declare class NhAssistantLauncherComponent {
738
1107
  readonly store: NhAssistantStore;
739
1108
  readonly panel: NhAssistantPanelService;
740
1109
  readonly waitingForApproval: _angular_core.Signal<boolean>;
1110
+ readonly badge: _angular_core.Signal<"running" | "unread" | "waiting" | null>;
1111
+ readonly unreadLabel: _angular_core.Signal<string>;
741
1112
  readonly label: _angular_core.Signal<"nh-assistant.launcher.close" | "nh-assistant.launcher.open">;
742
1113
  constructor();
743
1114
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantLauncherComponent, never>;
@@ -746,11 +1117,13 @@ declare class NhAssistantLauncherComponent {
746
1117
 
747
1118
  /**
748
1119
  * The assistant drawer. Place it once in the application layout; it renders nothing in
749
- * place and appears as an overlay when `NhAssistantPanelService.open()` is called.
1120
+ * place and appears as an overlay when `NhAssistantPanelService.open()` is called. It opens
1121
+ * by itself for an invitation link (`#nh-assistant-join=...`) and for a clicked notification.
750
1122
  */
751
1123
  declare class NhAssistantPanelComponent implements AfterViewInit, OnDestroy {
752
1124
  readonly store: NhAssistantStore;
753
1125
  readonly panel: NhAssistantPanelService;
1126
+ readonly push: NhAssistantPushService;
754
1127
  private readonly config;
755
1128
  private readonly viewContainerRef;
756
1129
  private readonly router;
@@ -760,6 +1133,10 @@ declare class NhAssistantPanelComponent implements AfterViewInit, OnDestroy {
760
1133
  readonly markdown: boolean;
761
1134
  readonly showConversations: _angular_core.WritableSignal<boolean>;
762
1135
  readonly showPreferences: _angular_core.WritableSignal<boolean>;
1136
+ readonly showShare: _angular_core.WritableSignal<boolean>;
1137
+ readonly shareSection: _angular_core.WritableSignal<"members" | "link" | "all">;
1138
+ readonly notificationError: _angular_core.WritableSignal<NhAssistantError | null>;
1139
+ readonly notificationsLabel: _angular_core.Signal<"nh-assistant.panel.notifications-off" | "nh-assistant.panel.notifications-on">;
763
1140
  readonly adminRoute: string | any[] | null;
764
1141
  readonly conversation: _angular_core.Signal<Conversation | null>;
765
1142
  private readonly conversationId;
@@ -768,6 +1145,12 @@ declare class NhAssistantPanelComponent implements AfterViewInit, OnDestroy {
768
1145
  readonly busy: _angular_core.Signal<boolean>;
769
1146
  readonly composerDisabled: _angular_core.Signal<boolean>;
770
1147
  readonly composerStatus: _angular_core.Signal<"running" | "waiting-for-approval" | null>;
1148
+ /** Name of another participant whose turn runs or waits, or `null`. */
1149
+ readonly activeMemberName: _angular_core.Signal<string | null>;
1150
+ /** The owner and the person who started the turn may stop it. */
1151
+ readonly canStop: _angular_core.Signal<boolean>;
1152
+ readonly shared: _angular_core.Signal<boolean>;
1153
+ readonly canShare: _angular_core.Signal<boolean>;
771
1154
  readonly errorKeys: _angular_core.Signal<string[]>;
772
1155
  readonly noticeKeys: _angular_core.Signal<string[]>;
773
1156
  constructor();
@@ -777,17 +1160,29 @@ declare class NhAssistantPanelComponent implements AfterViewInit, OnDestroy {
777
1160
  describeContext(context: ClientContext): string;
778
1161
  toggleConversations(): void;
779
1162
  togglePreferences(): void;
1163
+ toggleShare(section?: 'all' | 'link' | 'members'): void;
1164
+ /** Applies the notification choice immediately, including browser permission handling. */
1165
+ toggleNotifications(): Promise<void>;
780
1166
  newConversation(): void;
781
1167
  openConversation(conversationId: string): void;
782
1168
  deleteConversation(conversationId: string): void;
783
1169
  send(text: string): void;
1170
+ /**
1171
+ * Opens the panel for an invitation link or a clicked notification in the URL fragment and
1172
+ * removes the fragment, so a reload or a shared screenshot does not reuse the token.
1173
+ */
1174
+ private openFromLocation;
784
1175
  decide(decision: ApprovalDecision): void;
785
1176
  cancel(): void;
786
1177
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantPanelComponent, never>;
787
1178
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantPanelComponent, "nh-assistant-panel", never, {}, {}, never, never, true, never>;
788
1179
  }
789
1180
 
790
- /** The user's conversations with loading and empty states; selecting one opens it. */
1181
+ /**
1182
+ * The user's own and shared conversations with loading and empty states; selecting one opens it.
1183
+ * Each row marks a running turn, a waiting approval and unread messages. A participant leaves a
1184
+ * shared conversation instead of deleting it.
1185
+ */
791
1186
  declare class NhAssistantConversationListComponent {
792
1187
  readonly conversations: _angular_core.InputSignal<readonly ConversationSummary[]>;
793
1188
  readonly total: _angular_core.InputSignal<number>;
@@ -795,8 +1190,11 @@ declare class NhAssistantConversationListComponent {
795
1190
  readonly loading: _angular_core.InputSignal<boolean>;
796
1191
  readonly disabled: _angular_core.InputSignal<boolean>;
797
1192
  readonly conversationSelect: _angular_core.OutputEmitterRef<string>;
1193
+ /** The owner deletes the conversation; a participant leaves it. */
798
1194
  readonly conversationDelete: _angular_core.OutputEmitterRef<string>;
799
1195
  readonly conversationCreate: _angular_core.OutputEmitterRef<void>;
1196
+ unread(conversation: ConversationSummary): boolean;
1197
+ indicator(conversation: ConversationSummary): 'running' | 'waiting' | 'unread' | null;
800
1198
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantConversationListComponent, never>;
801
1199
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantConversationListComponent, "nh-assistant-conversation-list", never, { "conversations": { "alias": "conversations"; "required": true; "isSignal": true; }; "total": { "alias": "total"; "required": false; "isSignal": true; }; "activeConversationId": { "alias": "activeConversationId"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "conversationSelect": "conversationSelect"; "conversationDelete": "conversationDelete"; "conversationCreate": "conversationCreate"; }, never, never, true, never>;
802
1200
  }
@@ -815,7 +1213,16 @@ declare class NhAssistantThreadComponent {
815
1213
  readonly streaming: _angular_core.InputSignal<boolean>;
816
1214
  readonly deciding: _angular_core.InputSignal<boolean>;
817
1215
  readonly markdown: _angular_core.InputSignal<boolean>;
1216
+ /** The owner and participants of a shared conversation; empty while it is not shared. */
1217
+ readonly members: _angular_core.InputSignal<readonly ConversationMember[]>;
1218
+ /** The current user, to tell their own messages from those of others. */
1219
+ readonly currentActorId: _angular_core.InputSignal<string | null>;
1220
+ /** False when the pending approval belongs to another participant's turn. */
1221
+ readonly canDecide: _angular_core.InputSignal<boolean>;
1222
+ /** Name of the participant who decides the pending approval, when it is someone else. */
1223
+ readonly decisionOwner: _angular_core.InputSignal<string | null>;
818
1224
  readonly approvalDecision: _angular_core.OutputEmitterRef<ApprovalDecision>;
1225
+ private readonly names;
819
1226
  readonly virtualThreshold = 200;
820
1227
  readonly virtual: _angular_core.Signal<boolean>;
821
1228
  /**
@@ -832,10 +1239,14 @@ declare class NhAssistantThreadComponent {
832
1239
  private readonly viewport;
833
1240
  constructor();
834
1241
  trackMessage(_index: number, message: Message): string;
1242
+ /** True for a user message written by another person in a shared conversation. */
1243
+ isOthers(message: Message): boolean;
1244
+ /** Display name of another person's message, or `null` when the application provides none. */
1245
+ authorName(message: Message): string | null;
835
1246
  private scrollElement;
836
1247
  private scrollToEnd;
837
1248
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantThreadComponent, never>;
838
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantThreadComponent, "nh-assistant-thread", never, { "messages": { "alias": "messages"; "required": true; "isSignal": true; }; "streaming": { "alias": "streaming"; "required": false; "isSignal": true; }; "deciding": { "alias": "deciding"; "required": false; "isSignal": true; }; "markdown": { "alias": "markdown"; "required": false; "isSignal": true; }; }, { "approvalDecision": "approvalDecision"; }, never, never, true, never>;
1249
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantThreadComponent, "nh-assistant-thread", never, { "messages": { "alias": "messages"; "required": true; "isSignal": true; }; "streaming": { "alias": "streaming"; "required": false; "isSignal": true; }; "deciding": { "alias": "deciding"; "required": false; "isSignal": true; }; "markdown": { "alias": "markdown"; "required": false; "isSignal": true; }; "members": { "alias": "members"; "required": false; "isSignal": true; }; "currentActorId": { "alias": "currentActorId"; "required": false; "isSignal": true; }; "canDecide": { "alias": "canDecide"; "required": false; "isSignal": true; }; "decisionOwner": { "alias": "decisionOwner"; "required": false; "isSignal": true; }; }, { "approvalDecision": "approvalDecision"; }, never, never, true, never>;
839
1250
  }
840
1251
 
841
1252
  /**
@@ -851,6 +1262,10 @@ declare class NhAssistantComposerComponent {
851
1262
  readonly busy: _angular_core.InputSignal<boolean>;
852
1263
  /** Announces why sending is temporarily unavailable. */
853
1264
  readonly status: _angular_core.InputSignal<"running" | "waiting-for-approval" | null>;
1265
+ /** Name of the participant whose turn runs or waits, when it is someone else. */
1266
+ readonly statusActor: _angular_core.InputSignal<string | null>;
1267
+ /** False when the user may not stop the running turn, such as another participant's turn. */
1268
+ readonly canStop: _angular_core.InputSignal<boolean>;
854
1269
  readonly maxLength: _angular_core.InputSignal<number | null>;
855
1270
  /** Text to put back into the input, for example a message the server did not accept. */
856
1271
  readonly restore: _angular_core.InputSignal<string | null>;
@@ -877,7 +1292,7 @@ declare class NhAssistantComposerComponent {
877
1292
  submit(): void;
878
1293
  private restoreOwnedFocus;
879
1294
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantComposerComponent, never>;
880
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantComposerComponent, "nh-assistant-composer", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "sendDisabled": { "alias": "sendDisabled"; "required": false; "isSignal": true; }; "busy": { "alias": "busy"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "maxLength": { "alias": "maxLength"; "required": false; "isSignal": true; }; "restore": { "alias": "restore"; "required": false; "isSignal": true; }; }, { "send": "send"; "cancel": "cancel"; "restored": "restored"; }, never, never, true, never>;
1295
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantComposerComponent, "nh-assistant-composer", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "sendDisabled": { "alias": "sendDisabled"; "required": false; "isSignal": true; }; "busy": { "alias": "busy"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "statusActor": { "alias": "statusActor"; "required": false; "isSignal": true; }; "canStop": { "alias": "canStop"; "required": false; "isSignal": true; }; "maxLength": { "alias": "maxLength"; "required": false; "isSignal": true; }; "restore": { "alias": "restore"; "required": false; "isSignal": true; }; }, { "send": "send"; "cancel": "cancel"; "restored": "restored"; }, never, ["[nhAssistantComposerControls]"], true, never>;
881
1296
  }
882
1297
 
883
1298
  /** Shows one tool invocation with its status and expandable input and result previews. */
@@ -926,6 +1341,13 @@ declare class NhAssistantApprovalCardComponent {
926
1341
  readonly approval: _angular_core.InputSignal<ApprovalPart>;
927
1342
  /** True while the host submits a decision; disables both buttons. */
928
1343
  readonly deciding: _angular_core.InputSignal<boolean>;
1344
+ /**
1345
+ * False when the approval belongs to another participant's turn: only the person whose
1346
+ * permissions the action would use may decide it.
1347
+ */
1348
+ readonly canDecide: _angular_core.InputSignal<boolean>;
1349
+ /** Name of the participant who decides, shown when the current user cannot. */
1350
+ readonly decisionOwner: _angular_core.InputSignal<string | null>;
929
1351
  readonly decide: _angular_core.OutputEmitterRef<ApprovalDecision>;
930
1352
  private readonly now;
931
1353
  private readonly submitted;
@@ -939,7 +1361,7 @@ declare class NhAssistantApprovalCardComponent {
939
1361
  constructor();
940
1362
  choose(decision: ApprovalDecision): void;
941
1363
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantApprovalCardComponent, never>;
942
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantApprovalCardComponent, "nh-assistant-approval-card", never, { "approval": { "alias": "approval"; "required": true; "isSignal": true; }; "deciding": { "alias": "deciding"; "required": false; "isSignal": true; }; }, { "decide": "decide"; }, never, never, true, never>;
1364
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantApprovalCardComponent, "nh-assistant-approval-card", never, { "approval": { "alias": "approval"; "required": true; "isSignal": true; }; "deciding": { "alias": "deciding"; "required": false; "isSignal": true; }; "canDecide": { "alias": "canDecide"; "required": false; "isSignal": true; }; "decisionOwner": { "alias": "decisionOwner"; "required": false; "isSignal": true; }; }, { "decide": "decide"; }, never, never, true, never>;
943
1365
  }
944
1366
 
945
1367
  /**
@@ -950,23 +1372,27 @@ declare class NhAssistantAgentPickerComponent {
950
1372
  readonly agents: _angular_core.InputSignal<readonly AgentSummary[]>;
951
1373
  readonly selectedAgentId: _angular_core.InputSignal<string | null>;
952
1374
  readonly disabled: _angular_core.InputSignal<boolean>;
1375
+ /** Compact prompt-bar control; capability information remains in the tooltip and accessible description. */
1376
+ readonly compact: _angular_core.InputSignal<boolean>;
953
1377
  readonly agentChange: _angular_core.OutputEmitterRef<string>;
954
1378
  readonly selectId: string;
955
1379
  readonly selected: _angular_core.Signal<AgentSummary | null>;
956
1380
  onChange(event: Event): void;
957
1381
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantAgentPickerComponent, never>;
958
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantAgentPickerComponent, "nh-assistant-agent-picker", never, { "agents": { "alias": "agents"; "required": true; "isSignal": true; }; "selectedAgentId": { "alias": "selectedAgentId"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "agentChange": "agentChange"; }, never, never, true, never>;
1382
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantAgentPickerComponent, "nh-assistant-agent-picker", never, { "agents": { "alias": "agents"; "required": true; "isSignal": true; }; "selectedAgentId": { "alias": "selectedAgentId"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "compact": { "alias": "compact"; "required": false; "isSignal": true; }; }, { "agentChange": "agentChange"; }, never, never, true, never>;
959
1383
  }
960
1384
 
961
1385
  /** Maximum length of the user's own instructions. */
962
1386
  declare const NH_ASSISTANT_MAX_CUSTOM_INSTRUCTIONS = 1000;
963
1387
  /**
964
- * The user's own assistant preferences: style, form of address, answer length and
965
- * optional instructions. Preferences steer style only; the server keeps them below the
966
- * application context and agent instructions.
1388
+ * The user's own assistant preferences: desktop notifications, style, form of address,
1389
+ * answer length and optional instructions. Notifications apply immediately; the other
1390
+ * preferences steer style only and are saved together, below the application context and
1391
+ * agent instructions.
967
1392
  */
968
1393
  declare class NhAssistantPreferencesComponent {
969
1394
  private readonly api;
1395
+ readonly push: NhAssistantPushService;
970
1396
  private subscription?;
971
1397
  /** Emitted when the user leaves the preferences. */
972
1398
  readonly closed: _angular_core.OutputEmitterRef<void>;
@@ -994,6 +1420,8 @@ declare class NhAssistantPreferencesComponent {
994
1420
  readonly errorKeys: _angular_core.Signal<string[]>;
995
1421
  constructor();
996
1422
  load(): void;
1423
+ /** Turns desktop notifications on or off; turning them on asks the browser for permission. */
1424
+ toggleNotifications(event: Event): Promise<void>;
997
1425
  onInstructionsInput(event: Event): void;
998
1426
  choose<T>(target: {
999
1427
  set(value: T): void;
@@ -1004,6 +1432,63 @@ declare class NhAssistantPreferencesComponent {
1004
1432
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantPreferencesComponent, "nh-assistant-preferences", never, {}, { "closed": "closed"; "saved": "saved"; }, never, never, true, never>;
1005
1433
  }
1006
1434
 
1435
+ /**
1436
+ * Sharing of the open conversation. The owner creates, copies, renews or stops an invitation
1437
+ * link, invites colleagues through the application's directory when it offers one, and removes
1438
+ * participants. A participant sees who takes part and can leave.
1439
+ */
1440
+ declare class NhAssistantShareComponent {
1441
+ readonly store: NhAssistantStore;
1442
+ private readonly config;
1443
+ private searchTimer?;
1444
+ private searchRevision;
1445
+ /** Emitted when the user leaves the view. */
1446
+ readonly closed: _angular_core.OutputEmitterRef<void>;
1447
+ /** Show the invitation link, participants, or both (the default for custom hosts). */
1448
+ readonly section: _angular_core.InputSignal<"members" | "link" | "all">;
1449
+ readonly id: string;
1450
+ readonly conversation: _angular_core.Signal<Conversation | null>;
1451
+ readonly isOwner: _angular_core.Signal<boolean>;
1452
+ readonly busy: _angular_core.WritableSignal<boolean>;
1453
+ readonly copied: _angular_core.WritableSignal<boolean>;
1454
+ readonly query: _angular_core.WritableSignal<string>;
1455
+ readonly searching: _angular_core.WritableSignal<boolean>;
1456
+ readonly candidates: _angular_core.WritableSignal<DirectoryEntry[]>;
1457
+ readonly invited: _angular_core.WritableSignal<string | null>;
1458
+ readonly directory: _angular_core.Signal<boolean>;
1459
+ readonly maxParticipants: _angular_core.Signal<number | null>;
1460
+ readonly participants: _angular_core.Signal<ConversationMember[]>;
1461
+ readonly link: _angular_core.Signal<string | null>;
1462
+ readonly full: _angular_core.Signal<boolean>;
1463
+ constructor();
1464
+ createLink(): Promise<void>;
1465
+ revokeLink(): Promise<void>;
1466
+ copy(input: HTMLInputElement): Promise<void>;
1467
+ onSearch(event: Event): void;
1468
+ invite(entry: DirectoryEntry): Promise<void>;
1469
+ remove(member: ConversationMember): Promise<void>;
1470
+ leave(): Promise<void>;
1471
+ isCurrentUser(member: ConversationMember): boolean;
1472
+ private run;
1473
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantShareComponent, never>;
1474
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantShareComponent, "nh-assistant-share", never, { "section": { "alias": "section"; "required": false; "isSignal": true; }; }, { "closed": "closed"; }, never, never, true, never>;
1475
+ }
1476
+
1477
+ /**
1478
+ * One slim row of the other conversations that need attention: a running turn, an approval that
1479
+ * waits, or an unread answer. It renders nothing when there are none, so it costs no space in the
1480
+ * usual case. Selecting a chip opens that conversation; its turn keeps running meanwhile.
1481
+ */
1482
+ declare class NhAssistantActivityComponent {
1483
+ readonly items: _angular_core.InputSignal<readonly NhAssistantActivity[]>;
1484
+ readonly conversationSelect: _angular_core.OutputEmitterRef<string>;
1485
+ /** The open conversation already shows its own state. */
1486
+ readonly others: _angular_core.Signal<NhAssistantActivity[]>;
1487
+ state(item: NhAssistantActivity): 'running' | 'waiting' | 'unread';
1488
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantActivityComponent, never>;
1489
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantActivityComponent, "nh-assistant-activity", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; }, { "conversationSelect": "conversationSelect"; }, never, never, true, never>;
1490
+ }
1491
+
1007
1492
  /**
1008
1493
  * Translates the first key that has a translation and otherwise returns the fallback text.
1009
1494
  * Used for server-provided keys (agent names, error message keys, result codes) that the
@@ -1029,5 +1514,5 @@ declare function nhAssistantErrorKeys(error: NhAssistantError | null): string[];
1029
1514
  /** Dash-case identifiers as the contract requires for agent and MCP server ids. */
1030
1515
  declare const NH_ASSISTANT_DASH_CASE: RegExp;
1031
1516
 
1032
- export { NH_ASSISTANT_ACCESS_POLICY, NH_ASSISTANT_CONFIG, NH_ASSISTANT_FETCH, NH_ASSISTANT_ICONS, NH_ASSISTANT_MAX_CUSTOM_INSTRUCTIONS, NH_ASSISTANT_NO_ANSWER_NOTICE_CODE, NH_ASSISTANT_PAGE_CONTEXT_LIMITS, NH_ASSISTANT_PANEL_MOBILE_QUERY, NH_ASSISTANT_PANEL_WIDTH, NH_ASSISTANT_SSE_EVENT_TYPES, NH_ASSISTANT_TRANSLATIONS, NH_ASSISTANT_VIRTUAL_SCROLL_THRESHOLD, NhAssistantAdminApiService, NhAssistantAgentPickerComponent, NhAssistantAllowAllAccessPolicy, NhAssistantApiError, NhAssistantApiService, NhAssistantApprovalCardComponent, NhAssistantClientErrorCodes, NhAssistantComposerComponent, NhAssistantConversationListComponent, NhAssistantLauncherComponent, NhAssistantPanelComponent, NhAssistantPanelService, NhAssistantPreferencesComponent, NhAssistantSseParser, NhAssistantStore, NhAssistantThreadComponent, NhAssistantToolCallCardComponent, NhAssistantToolCallGroupComponent, NhAssistantTranslationMerger, applyNhAssistantApprovalDecision, applyNhAssistantEvent, describeNhAssistantClientContext, formatNhAssistantCountdown, nhAssistantCodeForStatus, nhAssistantErrorMessageKey, nhAssistantLatestTurnHasText, normalizeNhAssistantClientContext, provideNhAssistant, NH_ASSISTANT_DASH_CASE as ɵNH_ASSISTANT_DASH_CASE, NhAssistantIconComponent as ɵNhAssistantIconComponent, NhAssistantTranslatePipe as ɵNhAssistantTranslatePipe, nhAssistantErrorKeys as ɵnhAssistantErrorKeys, toNhAssistantError as ɵtoNhAssistantError };
1033
- export type { AdminAgent, AdminAgentInput, AgentSummary, ApplicationContext, ApplicationContextVersion, ApprovalDecision, ApprovalPart, ApprovalPresentation, ApprovalPresentationField, ApprovalRequiredEvent, ApprovalStatus, AssistantAddressForm, AssistantAutonomy, AssistantErrorEvent, AssistantPreferences, AssistantResponseLength, AssistantStatus, AssistantStyle, ClientContext, ClientContextEntity, Conversation, ConversationPage, ConversationStatus, ConversationSummary, CreateConversationRequest, DecideApprovalRequest, McpAuthMode, McpServer, McpServerInput, McpServerTestResult, McpTool, McpToolEffect, McpToolStatus, Message, MessageDeltaEvent, MessagePart, NhAssistantAccessPolicy, NhAssistantClientContext, NhAssistantClientErrorCode, NhAssistantConfig, NhAssistantError, NhAssistantFetch, NhAssistantIconName, NhAssistantNotice, NhAssistantRawSseMessage, NhAssistantSseEvent, NhAssistantSseEventMap, NhAssistantSseEventType, NhAssistantStatusCodes, NhAssistantToolCallGroupState, SendMessageRequest, TextPart, ToolCallPart, ToolCallStatus, ToolCatalogEffect, ToolCatalogEntry, ToolCompletedEvent, ToolStartedEvent, TurnCompletedEvent, TurnCompletionStatus, TurnStartedEvent, TurnUsage, UpdateAdminAgentRequest, UpdateApplicationContextRequest, UpdateMcpToolRequest };
1517
+ export { NH_ASSISTANT_ACCESS_POLICY, NH_ASSISTANT_CONFIG, NH_ASSISTANT_CONVERSATION_FRAGMENT, NH_ASSISTANT_FETCH, NH_ASSISTANT_ICONS, NH_ASSISTANT_JOIN_FRAGMENT, NH_ASSISTANT_MAX_CUSTOM_INSTRUCTIONS, NH_ASSISTANT_NO_ANSWER_NOTICE_CODE, NH_ASSISTANT_PAGE_CONTEXT_LIMITS, NH_ASSISTANT_PANEL_MOBILE_QUERY, NH_ASSISTANT_PANEL_WIDTH, NH_ASSISTANT_SSE_EVENT_TYPES, NH_ASSISTANT_TRANSLATIONS, NH_ASSISTANT_VIRTUAL_SCROLL_THRESHOLD, NhAssistantActivityComponent, NhAssistantAdminApiService, NhAssistantAgentPickerComponent, NhAssistantAllowAllAccessPolicy, NhAssistantApiError, NhAssistantApiService, NhAssistantApprovalCardComponent, NhAssistantClientErrorCodes, NhAssistantComposerComponent, NhAssistantConversationListComponent, NhAssistantLauncherComponent, NhAssistantLiveService, NhAssistantPanelComponent, NhAssistantPanelService, NhAssistantPreferencesComponent, NhAssistantPushService, NhAssistantShareComponent, NhAssistantSseParser, NhAssistantStore, NhAssistantThreadComponent, NhAssistantToolCallCardComponent, NhAssistantToolCallGroupComponent, NhAssistantTranslationMerger, applyNhAssistantApprovalDecision, applyNhAssistantConversationChange, applyNhAssistantEvent, applyNhAssistantLiveEvent, describeNhAssistantClientContext, formatNhAssistantCountdown, nhAssistantCodeForStatus, nhAssistantErrorMessageKey, nhAssistantIsUnread, nhAssistantLatestTurnHasText, nhAssistantShareLink, normalizeNhAssistantClientContext, provideNhAssistant, NH_ASSISTANT_DASH_CASE as ɵNH_ASSISTANT_DASH_CASE, NhAssistantIconComponent as ɵNhAssistantIconComponent, NhAssistantTranslatePipe as ɵNhAssistantTranslatePipe, nhAssistantErrorKeys as ɵnhAssistantErrorKeys, toNhAssistantError as ɵtoNhAssistantError };
1518
+ export type { AdminAgent, AdminAgentInput, AgentSummary, ApplicationContext, ApplicationContextVersion, ApprovalDecision, ApprovalPart, ApprovalPresentation, ApprovalPresentationField, ApprovalRequiredEvent, ApprovalStatus, AssistantAddressForm, AssistantAutonomy, AssistantCollaboration, AssistantErrorEvent, AssistantPreferences, AssistantResponseLength, AssistantStatus, AssistantStyle, ClientContext, ClientContextEntity, Conversation, ConversationMember, ConversationPage, ConversationRole, ConversationStatus, ConversationSummary, CreateConversationRequest, DecideApprovalRequest, DirectoryEntry, LiveConversationChanged, LiveConversationEvent, LiveConversationRead, LiveConversationRemoved, McpAuthMode, McpServer, McpServerInput, McpServerTestResult, McpTool, McpToolEffect, McpToolStatus, Message, MessageDeltaEvent, MessagePart, NhAssistantAccessPolicy, NhAssistantActivity, NhAssistantClientContext, NhAssistantClientErrorCode, NhAssistantConfig, NhAssistantError, NhAssistantFetch, NhAssistantIconName, NhAssistantLiveState, NhAssistantNotice, NhAssistantPushConfig, NhAssistantPushState, NhAssistantRawSseMessage, NhAssistantSseEvent, NhAssistantSseEventMap, NhAssistantSseEventType, NhAssistantStatusCodes, NhAssistantToolCallGroupState, NotificationSettings, PushSubscriptionRequest, SendMessageRequest, ShareLink, TextPart, ToolCallPart, ToolCallStatus, ToolCatalogEffect, ToolCatalogEntry, ToolCompletedEvent, ToolStartedEvent, TurnCompletedEvent, TurnCompletionStatus, TurnStartedEvent, TurnUsage, UpdateAdminAgentRequest, UpdateApplicationContextRequest, UpdateMcpToolRequest };