@newheap/platform-ai-chat 0.4.0 → 0.6.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
+ private readonly push;
754
1127
  private readonly config;
755
1128
  private readonly viewContainerRef;
756
1129
  private readonly router;
@@ -760,6 +1133,7 @@ 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>;
763
1137
  readonly adminRoute: string | any[] | null;
764
1138
  readonly conversation: _angular_core.Signal<Conversation | null>;
765
1139
  private readonly conversationId;
@@ -768,6 +1142,12 @@ declare class NhAssistantPanelComponent implements AfterViewInit, OnDestroy {
768
1142
  readonly busy: _angular_core.Signal<boolean>;
769
1143
  readonly composerDisabled: _angular_core.Signal<boolean>;
770
1144
  readonly composerStatus: _angular_core.Signal<"running" | "waiting-for-approval" | null>;
1145
+ /** Name of another participant whose turn runs or waits, or `null`. */
1146
+ readonly activeMemberName: _angular_core.Signal<string | null>;
1147
+ /** The owner and the person who started the turn may stop it. */
1148
+ readonly canStop: _angular_core.Signal<boolean>;
1149
+ readonly shared: _angular_core.Signal<boolean>;
1150
+ readonly canShare: _angular_core.Signal<boolean>;
771
1151
  readonly errorKeys: _angular_core.Signal<string[]>;
772
1152
  readonly noticeKeys: _angular_core.Signal<string[]>;
773
1153
  constructor();
@@ -777,17 +1157,27 @@ declare class NhAssistantPanelComponent implements AfterViewInit, OnDestroy {
777
1157
  describeContext(context: ClientContext): string;
778
1158
  toggleConversations(): void;
779
1159
  togglePreferences(): void;
1160
+ toggleShare(): void;
780
1161
  newConversation(): void;
781
1162
  openConversation(conversationId: string): void;
782
1163
  deleteConversation(conversationId: string): void;
783
1164
  send(text: string): void;
1165
+ /**
1166
+ * Opens the panel for an invitation link or a clicked notification in the URL fragment and
1167
+ * removes the fragment, so a reload or a shared screenshot does not reuse the token.
1168
+ */
1169
+ private openFromLocation;
784
1170
  decide(decision: ApprovalDecision): void;
785
1171
  cancel(): void;
786
1172
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantPanelComponent, never>;
787
1173
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantPanelComponent, "nh-assistant-panel", never, {}, {}, never, never, true, never>;
788
1174
  }
789
1175
 
790
- /** The user's conversations with loading and empty states; selecting one opens it. */
1176
+ /**
1177
+ * The user's own and shared conversations with loading and empty states; selecting one opens it.
1178
+ * Each row marks a running turn, a waiting approval and unread messages. A participant leaves a
1179
+ * shared conversation instead of deleting it.
1180
+ */
791
1181
  declare class NhAssistantConversationListComponent {
792
1182
  readonly conversations: _angular_core.InputSignal<readonly ConversationSummary[]>;
793
1183
  readonly total: _angular_core.InputSignal<number>;
@@ -795,8 +1185,11 @@ declare class NhAssistantConversationListComponent {
795
1185
  readonly loading: _angular_core.InputSignal<boolean>;
796
1186
  readonly disabled: _angular_core.InputSignal<boolean>;
797
1187
  readonly conversationSelect: _angular_core.OutputEmitterRef<string>;
1188
+ /** The owner deletes the conversation; a participant leaves it. */
798
1189
  readonly conversationDelete: _angular_core.OutputEmitterRef<string>;
799
1190
  readonly conversationCreate: _angular_core.OutputEmitterRef<void>;
1191
+ unread(conversation: ConversationSummary): boolean;
1192
+ indicator(conversation: ConversationSummary): 'running' | 'waiting' | 'unread' | null;
800
1193
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantConversationListComponent, never>;
801
1194
  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
1195
  }
@@ -805,8 +1198,9 @@ declare class NhAssistantConversationListComponent {
805
1198
  declare const NH_ASSISTANT_VIRTUAL_SCROLL_THRESHOLD = 200;
806
1199
  /**
807
1200
  * The messages of a conversation as a live log. Assistant text renders as sanitized
808
- * Markdown, tool calls and approvals as cards. The thread follows new content while the
809
- * user is at the bottom.
1201
+ * Markdown, consecutive tool calls as one collapsible group that counts along, and
1202
+ * approvals as cards. While a turn runs without visible progress, a working indicator
1203
+ * shows the elapsed time. The thread follows new content while the user is at the bottom.
810
1204
  */
811
1205
  declare class NhAssistantThreadComponent {
812
1206
  private readonly injector;
@@ -814,18 +1208,40 @@ declare class NhAssistantThreadComponent {
814
1208
  readonly streaming: _angular_core.InputSignal<boolean>;
815
1209
  readonly deciding: _angular_core.InputSignal<boolean>;
816
1210
  readonly markdown: _angular_core.InputSignal<boolean>;
1211
+ /** The owner and participants of a shared conversation; empty while it is not shared. */
1212
+ readonly members: _angular_core.InputSignal<readonly ConversationMember[]>;
1213
+ /** The current user, to tell their own messages from those of others. */
1214
+ readonly currentActorId: _angular_core.InputSignal<string | null>;
1215
+ /** False when the pending approval belongs to another participant's turn. */
1216
+ readonly canDecide: _angular_core.InputSignal<boolean>;
1217
+ /** Name of the participant who decides the pending approval, when it is someone else. */
1218
+ readonly decisionOwner: _angular_core.InputSignal<string | null>;
817
1219
  readonly approvalDecision: _angular_core.OutputEmitterRef<ApprovalDecision>;
1220
+ private readonly names;
818
1221
  readonly virtualThreshold = 200;
819
1222
  readonly virtual: _angular_core.Signal<boolean>;
1223
+ /**
1224
+ * True while the turn runs and nothing else shows progress: before the first part and
1225
+ * between tool calls while the model decides what to do next. Streaming text and a
1226
+ * running tool group show their own progress; an approval waits for the user.
1227
+ */
820
1228
  readonly working: _angular_core.Signal<boolean>;
1229
+ /** Whole seconds since the running turn started. */
1230
+ readonly elapsedSeconds: _angular_core.Signal<number>;
1231
+ private readonly turnStartedAt;
1232
+ private readonly now;
821
1233
  private readonly scroller;
822
1234
  private readonly viewport;
823
1235
  constructor();
824
1236
  trackMessage(_index: number, message: Message): string;
1237
+ /** True for a user message written by another person in a shared conversation. */
1238
+ isOthers(message: Message): boolean;
1239
+ /** Display name of another person's message, or `null` when the application provides none. */
1240
+ authorName(message: Message): string | null;
825
1241
  private scrollElement;
826
1242
  private scrollToEnd;
827
1243
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantThreadComponent, never>;
828
- 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>;
1244
+ 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>;
829
1245
  }
830
1246
 
831
1247
  /**
@@ -841,6 +1257,10 @@ declare class NhAssistantComposerComponent {
841
1257
  readonly busy: _angular_core.InputSignal<boolean>;
842
1258
  /** Announces why sending is temporarily unavailable. */
843
1259
  readonly status: _angular_core.InputSignal<"running" | "waiting-for-approval" | null>;
1260
+ /** Name of the participant whose turn runs or waits, when it is someone else. */
1261
+ readonly statusActor: _angular_core.InputSignal<string | null>;
1262
+ /** False when the user may not stop the running turn, such as another participant's turn. */
1263
+ readonly canStop: _angular_core.InputSignal<boolean>;
844
1264
  readonly maxLength: _angular_core.InputSignal<number | null>;
845
1265
  /** Text to put back into the input, for example a message the server did not accept. */
846
1266
  readonly restore: _angular_core.InputSignal<string | null>;
@@ -867,7 +1287,7 @@ declare class NhAssistantComposerComponent {
867
1287
  submit(): void;
868
1288
  private restoreOwnedFocus;
869
1289
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantComposerComponent, never>;
870
- 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>;
1290
+ 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, never, true, never>;
871
1291
  }
872
1292
 
873
1293
  /** Shows one tool invocation with its status and expandable input and result previews. */
@@ -882,6 +1302,29 @@ declare class NhAssistantToolCallCardComponent {
882
1302
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantToolCallCardComponent, "nh-assistant-tool-call-card", never, { "part": { "alias": "part"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
883
1303
  }
884
1304
 
1305
+ /** Overall state of a run of tool calls, from most to least urgent. */
1306
+ type NhAssistantToolCallGroupState = 'awaiting-approval' | 'running' | 'failed' | 'succeeded';
1307
+ /**
1308
+ * Summarizes consecutive tool calls in one collapsed line that counts along live: the
1309
+ * tool that runs now while the assistant works, and how many tools were used and failed
1310
+ * afterwards. Expanding it shows every call as a card.
1311
+ */
1312
+ declare class NhAssistantToolCallGroupComponent {
1313
+ readonly calls: _angular_core.InputSignal<readonly ToolCallPart[]>;
1314
+ readonly callsId: string;
1315
+ readonly expanded: _angular_core.WritableSignal<boolean>;
1316
+ /** The call that currently needs attention or runs; the latest one when several do. */
1317
+ readonly current: _angular_core.Signal<ToolCallPart | null>;
1318
+ readonly total: _angular_core.Signal<number>;
1319
+ readonly finished: _angular_core.Signal<number>;
1320
+ readonly failed: _angular_core.Signal<number>;
1321
+ readonly state: _angular_core.Signal<NhAssistantToolCallGroupState>;
1322
+ readonly stateIcon: _angular_core.Signal<NhAssistantIconName>;
1323
+ toggle(): void;
1324
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantToolCallGroupComponent, never>;
1325
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantToolCallGroupComponent, "nh-assistant-tool-call-group", never, { "calls": { "alias": "calls"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
1326
+ }
1327
+
885
1328
  /** Formats remaining milliseconds as `m:ss`, or `h:mm:ss` above one hour. */
886
1329
  declare function formatNhAssistantCountdown(milliseconds: number): string;
887
1330
  /**
@@ -893,6 +1336,13 @@ declare class NhAssistantApprovalCardComponent {
893
1336
  readonly approval: _angular_core.InputSignal<ApprovalPart>;
894
1337
  /** True while the host submits a decision; disables both buttons. */
895
1338
  readonly deciding: _angular_core.InputSignal<boolean>;
1339
+ /**
1340
+ * False when the approval belongs to another participant's turn: only the person whose
1341
+ * permissions the action would use may decide it.
1342
+ */
1343
+ readonly canDecide: _angular_core.InputSignal<boolean>;
1344
+ /** Name of the participant who decides, shown when the current user cannot. */
1345
+ readonly decisionOwner: _angular_core.InputSignal<string | null>;
896
1346
  readonly decide: _angular_core.OutputEmitterRef<ApprovalDecision>;
897
1347
  private readonly now;
898
1348
  private readonly submitted;
@@ -906,7 +1356,7 @@ declare class NhAssistantApprovalCardComponent {
906
1356
  constructor();
907
1357
  choose(decision: ApprovalDecision): void;
908
1358
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantApprovalCardComponent, never>;
909
- 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>;
1359
+ 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>;
910
1360
  }
911
1361
 
912
1362
  /**
@@ -928,12 +1378,14 @@ declare class NhAssistantAgentPickerComponent {
928
1378
  /** Maximum length of the user's own instructions. */
929
1379
  declare const NH_ASSISTANT_MAX_CUSTOM_INSTRUCTIONS = 1000;
930
1380
  /**
931
- * The user's own assistant preferences: style, form of address, answer length and
932
- * optional instructions. Preferences steer style only; the server keeps them below the
933
- * application context and agent instructions.
1381
+ * The user's own assistant preferences: desktop notifications, style, form of address,
1382
+ * answer length and optional instructions. Notifications apply immediately; the other
1383
+ * preferences steer style only and are saved together, below the application context and
1384
+ * agent instructions.
934
1385
  */
935
1386
  declare class NhAssistantPreferencesComponent {
936
1387
  private readonly api;
1388
+ readonly push: NhAssistantPushService;
937
1389
  private subscription?;
938
1390
  /** Emitted when the user leaves the preferences. */
939
1391
  readonly closed: _angular_core.OutputEmitterRef<void>;
@@ -961,6 +1413,8 @@ declare class NhAssistantPreferencesComponent {
961
1413
  readonly errorKeys: _angular_core.Signal<string[]>;
962
1414
  constructor();
963
1415
  load(): void;
1416
+ /** Turns desktop notifications on or off; turning them on asks the browser for permission. */
1417
+ toggleNotifications(event: Event): Promise<void>;
964
1418
  onInstructionsInput(event: Event): void;
965
1419
  choose<T>(target: {
966
1420
  set(value: T): void;
@@ -971,6 +1425,61 @@ declare class NhAssistantPreferencesComponent {
971
1425
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantPreferencesComponent, "nh-assistant-preferences", never, {}, { "closed": "closed"; "saved": "saved"; }, never, never, true, never>;
972
1426
  }
973
1427
 
1428
+ /**
1429
+ * Sharing of the open conversation. The owner creates, copies, renews or stops an invitation
1430
+ * link, invites colleagues through the application's directory when it offers one, and removes
1431
+ * participants. A participant sees who takes part and can leave.
1432
+ */
1433
+ declare class NhAssistantShareComponent {
1434
+ readonly store: NhAssistantStore;
1435
+ private readonly config;
1436
+ private searchTimer?;
1437
+ private searchRevision;
1438
+ /** Emitted when the user leaves the view. */
1439
+ readonly closed: _angular_core.OutputEmitterRef<void>;
1440
+ readonly id: string;
1441
+ readonly conversation: _angular_core.Signal<Conversation | null>;
1442
+ readonly isOwner: _angular_core.Signal<boolean>;
1443
+ readonly busy: _angular_core.WritableSignal<boolean>;
1444
+ readonly copied: _angular_core.WritableSignal<boolean>;
1445
+ readonly query: _angular_core.WritableSignal<string>;
1446
+ readonly searching: _angular_core.WritableSignal<boolean>;
1447
+ readonly candidates: _angular_core.WritableSignal<DirectoryEntry[]>;
1448
+ readonly invited: _angular_core.WritableSignal<string | null>;
1449
+ readonly directory: _angular_core.Signal<boolean>;
1450
+ readonly maxParticipants: _angular_core.Signal<number | null>;
1451
+ readonly participants: _angular_core.Signal<ConversationMember[]>;
1452
+ readonly link: _angular_core.Signal<string | null>;
1453
+ readonly full: _angular_core.Signal<boolean>;
1454
+ constructor();
1455
+ createLink(): Promise<void>;
1456
+ revokeLink(): Promise<void>;
1457
+ copy(input: HTMLInputElement): Promise<void>;
1458
+ onSearch(event: Event): void;
1459
+ invite(entry: DirectoryEntry): Promise<void>;
1460
+ remove(member: ConversationMember): Promise<void>;
1461
+ leave(): Promise<void>;
1462
+ isCurrentUser(member: ConversationMember): boolean;
1463
+ private run;
1464
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantShareComponent, never>;
1465
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantShareComponent, "nh-assistant-share", never, {}, { "closed": "closed"; }, never, never, true, never>;
1466
+ }
1467
+
1468
+ /**
1469
+ * One slim row of the other conversations that need attention: a running turn, an approval that
1470
+ * waits, or an unread answer. It renders nothing when there are none, so it costs no space in the
1471
+ * usual case. Selecting a chip opens that conversation; its turn keeps running meanwhile.
1472
+ */
1473
+ declare class NhAssistantActivityComponent {
1474
+ readonly items: _angular_core.InputSignal<readonly NhAssistantActivity[]>;
1475
+ readonly conversationSelect: _angular_core.OutputEmitterRef<string>;
1476
+ /** The open conversation already shows its own state. */
1477
+ readonly others: _angular_core.Signal<NhAssistantActivity[]>;
1478
+ state(item: NhAssistantActivity): 'running' | 'waiting' | 'unread';
1479
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantActivityComponent, never>;
1480
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantActivityComponent, "nh-assistant-activity", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; }, { "conversationSelect": "conversationSelect"; }, never, never, true, never>;
1481
+ }
1482
+
974
1483
  /**
975
1484
  * Translates the first key that has a translation and otherwise returns the fallback text.
976
1485
  * Used for server-provided keys (agent names, error message keys, result codes) that the
@@ -996,5 +1505,5 @@ declare function nhAssistantErrorKeys(error: NhAssistantError | null): string[];
996
1505
  /** Dash-case identifiers as the contract requires for agent and MCP server ids. */
997
1506
  declare const NH_ASSISTANT_DASH_CASE: RegExp;
998
1507
 
999
- 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, 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 };
1000
- 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, SendMessageRequest, TextPart, ToolCallPart, ToolCallStatus, ToolCatalogEffect, ToolCatalogEntry, ToolCompletedEvent, ToolStartedEvent, TurnCompletedEvent, TurnCompletionStatus, TurnStartedEvent, TurnUsage, UpdateAdminAgentRequest, UpdateApplicationContextRequest, UpdateMcpToolRequest };
1508
+ 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 };
1509
+ 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 };