@m6d/cortex-angular 0.8.0 → 0.9.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m6d/cortex-angular",
3
- "version": "0.8.0",
3
+ "version": "0.9.1",
4
4
  "description": "Reusable AI agent chat UI library for Angular",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,
@@ -84,7 +84,9 @@ export type MediaRenderContext = {
84
84
  * Draws a closed media fence's `source` into `host`, resolves once drawn, and
85
85
  * returns the teardown. A consumer's `mediaRenderers` config entry has this
86
86
  * shape too: one per fence language, replacing the built-in of the same name
87
- * or adding a language of its own.
87
+ * or adding a language of its own. The same source can be drawn twice at once,
88
+ * inline and in its expanded view, so a renderer keeps no state that two
89
+ * drawings would share.
88
90
  */
89
91
  export type MediaRenderer = (host: HTMLElement, source: string, context: MediaRenderContext) => Promise<() => void>;
90
92
  export type MediaRenderers = Partial<Record<string, MediaRenderer>>;
@@ -92,31 +94,6 @@ export type MediaRenderers = Partial<Record<string, MediaRenderer>>;
92
94
  export type Localized<T> = T | Partial<Record<Locale, T>>;
93
95
  export type CortexViewMode = "helper" | "full";
94
96
  export type CortexTheme = "light" | "dark" | "system";
95
- /**
96
- * What a host's own header receives in place of the widget's: where the
97
- * widget is, what to show, and the actions the default header offers. One
98
- * header serves both screens; `screen` says which is showing.
99
- */
100
- export type CortexHeaderContext = {
101
- screen: "chat" | "threads";
102
- viewMode: CortexViewMode;
103
- /** The open thread's title; null on a new chat. */
104
- title: string | null;
105
- /** `agentName` in the widget's locale. */
106
- agentName: string | undefined;
107
- isWorking: boolean;
108
- /** Whether the host enabled the debug switch, and whether it is on. */
109
- debug: {
110
- shown: boolean;
111
- on: boolean;
112
- };
113
- newChat: () => void;
114
- /** Shows the history: the history screen, or in full mode the sidebar where it is hidden. */
115
- openHistory: () => void;
116
- /** Returns to the open chat from wherever `openHistory` went. */
117
- closeHistory: () => void;
118
- toggleDebug: () => void;
119
- };
120
97
  export type CortexToolCallContext = {
121
98
  threadId: string;
122
99
  };
@@ -140,7 +117,7 @@ export type CortexToolComponentInputs = {
140
117
  };
141
118
  /**
142
119
  * The framework-neutral part of the widget's configuration. Each SDK extends it
143
- * with its own `toolComponents` slot, which is the one field whose type is
120
+ * with its own `toolComponents` field, which is the one field whose type is
144
121
  * inherently framework-bound.
145
122
  */
146
123
  export type CortexConfig = {
@@ -181,6 +158,71 @@ export type CortexConfig = {
181
158
  trustSameOriginEmbeds?: boolean;
182
159
  hooks?: CortexHooks;
183
160
  };
161
+ /**
162
+ * What the header receives, the host's own or the widget's: where the widget
163
+ * is, what to show, and the actions the default header offers. One header
164
+ * serves both screens; `screen` says which is showing.
165
+ */
166
+ export type CortexHeaderContext = {
167
+ screen: "chat" | "threads";
168
+ viewMode: CortexViewMode;
169
+ /** The open thread's title; null on a new chat. */
170
+ title: string | null;
171
+ /** `agentName` in the widget's locale. */
172
+ agentName: string | undefined;
173
+ /** How many conversations the history lists; 0 while it loads. */
174
+ threadCount: number;
175
+ isWorking: boolean;
176
+ /** Whether the host enabled the debug switch, and whether it is on. */
177
+ debug: {
178
+ shown: boolean;
179
+ on: boolean;
180
+ };
181
+ newChat: () => void;
182
+ /** Shows the history: the history screen, or in full mode the sidebar where it is hidden. */
183
+ openHistory: () => void;
184
+ /** Returns to the open chat from wherever `openHistory` went. */
185
+ closeHistory: () => void;
186
+ toggleDebug: () => void;
187
+ };
188
+ /**
189
+ * What the blank-chat landing receives, the host's own or the widget's. The
190
+ * composer arrives ready to place as the SDK's own view type (`View`), so a
191
+ * custom landing keeps the widget's attachments and send rules. Each SDK
192
+ * exports it as `CortexLandingContext` with its view type filled in.
193
+ */
194
+ export type LandingContext<View> = {
195
+ /** The agent's greeting in the widget's locale, or the built-in one. */
196
+ greeting: string;
197
+ /** Empty until the handshake answers, and for an agent that takes no messages. */
198
+ suggestions: Suggestion[];
199
+ /** Newest first; undefined while the first load is out. */
200
+ threads: ThreadSummary[] | undefined;
201
+ /** The composer, or the notice an agent that takes no messages shows instead; empty until the handshake answers. */
202
+ composer: View;
203
+ /**
204
+ * Sends a first message, which opens a thread and swaps the landing for it.
205
+ * Does nothing until the handshake answers, or for an agent that takes no messages.
206
+ */
207
+ send: (prompt: string) => void;
208
+ openThread: (thread: ThreadSummary) => void;
209
+ };
210
+ /** What the history's list receives, the host's own or the widget's. Its header is the header slot. */
211
+ export type CortexThreadListContext = {
212
+ /** Newest first; undefined while the first load is out. */
213
+ threads: ThreadSummary[] | undefined;
214
+ /** The open thread's id; undefined on a new chat. */
215
+ selectedThreadId: string | undefined;
216
+ openThread: (thread: ThreadSummary) => void;
217
+ deleteThread: (threadId: string) => void;
218
+ newChat: () => void;
219
+ };
220
+ /** Each part of the widget a host can draw itself, with the context it receives. */
221
+ export type CortexSlotContexts<View> = {
222
+ header: CortexHeaderContext;
223
+ landing: LandingContext<View>;
224
+ threadList: CortexThreadListContext;
225
+ };
184
226
  export type QueuedAttachment = {
185
227
  localId: string;
186
228
  filename: string;
@@ -214,6 +256,10 @@ export type CortexAngularConfig = CortexConfig & {
214
256
  toolComponents?: Record<string, Type<CortexToolComponentInputs>>;
215
257
  injector?: Injector;
216
258
  };
259
+ /** The landing's context, its composer a template to place with `ngTemplateOutlet`. */
260
+ export type CortexLandingContext = LandingContext<TemplateRef<unknown>>;
261
+ /** Each part of the widget a host can draw itself, with the context it receives. */
262
+ export type CortexAngularSlotContexts = CortexSlotContexts<TemplateRef<unknown>>;
217
263
  declare class AttachmentQueueService {
218
264
  readonly items: import("@angular/core").WritableSignal<QueuedAttachment[]>;
219
265
  private readonly flags;
@@ -340,26 +386,6 @@ declare class CortexChatService {
340
386
  static ɵfac: i0.ɵɵFactoryDeclaration<CortexChatService, never>;
341
387
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
342
388
  }
343
- export type HeaderTemplateContext = {
344
- $implicit: CortexHeaderContext;
345
- };
346
- /**
347
- * Marks the host's own header for `<cortex-chat-widget>`. When present it
348
- * replaces the default header on both the chat and the history screen, and
349
- * receives the widget's state and actions as its context:
350
- *
351
- * <cortex-chat-widget [config]="config">
352
- * <ng-template cortexHeader let-chat>
353
- * <div class="cortex-widget__chat-header">{{ chat.title ?? chat.agentName }}</div>
354
- * </ng-template>
355
- * </cortex-chat-widget>
356
- */
357
- export declare class CortexHeaderDirective {
358
- readonly template: TemplateRef<HeaderTemplateContext>;
359
- static ngTemplateContextGuard(_directive: CortexHeaderDirective, _context: unknown): _context is HeaderTemplateContext;
360
- static ɵfac: i0.ɵɵFactoryDeclaration<CortexHeaderDirective, never>;
361
- static ɵdir: i0.ɵɵDirectiveDeclaration<CortexHeaderDirective, "ng-template[cortexHeader]", never, {}, {}, never, never, true, never>;
362
- }
363
389
  /** The chat widget: the thread list, the open conversation and its composer, for the agent `config` points at. */
364
390
  export declare class CortexChatWidgetComponent implements OnInit {
365
391
  readonly config: import("@angular/core").InputSignal<CortexAngularConfig>;
@@ -368,13 +394,18 @@ export declare class CortexChatWidgetComponent implements OnInit {
368
394
  protected readonly sidebarOpen: import("@angular/core").WritableSignal<boolean>;
369
395
  protected readonly viewMode: import("@angular/core").Signal<CortexViewMode>;
370
396
  private readonly composer;
371
- /** The host's own header, if it gave one; it replaces the default on both screens. */
372
- protected readonly customHeader: import("@angular/core").Signal<CortexHeaderDirective | undefined>;
397
+ private readonly landingComposer;
398
+ /** The host's own parts by slot; each replaces the widget's default and gets the same context. */
399
+ private readonly slotDirectives;
400
+ protected readonly slots: import("@angular/core").Signal<Map<keyof CortexAngularSlotContexts, TemplateRef<{
401
+ $implicit: CortexHeaderContext | CortexThreadListContext | LandingContext<TemplateRef<unknown>>;
402
+ }>>>;
373
403
  protected readonly chatHeader: import("@angular/core").Signal<{
374
404
  screen: "chat" | "threads";
375
405
  viewMode: CortexViewMode;
376
406
  title: string | null;
377
407
  agentName: string | undefined;
408
+ threadCount: number;
378
409
  isWorking: boolean;
379
410
  debug: {
380
411
  shown: boolean;
@@ -390,6 +421,7 @@ export declare class CortexChatWidgetComponent implements OnInit {
390
421
  viewMode: CortexViewMode;
391
422
  title: string | null;
392
423
  agentName: string | undefined;
424
+ threadCount: number;
393
425
  isWorking: boolean;
394
426
  debug: {
395
427
  shown: boolean;
@@ -400,21 +432,36 @@ export declare class CortexChatWidgetComponent implements OnInit {
400
432
  closeHistory: () => void;
401
433
  toggleDebug: () => void;
402
434
  }>;
435
+ protected readonly landing: import("@angular/core").Signal<{
436
+ threads: ThreadSummary[] | undefined;
437
+ composer: TemplateRef<unknown>;
438
+ openThread: (thread: ThreadSummary) => void;
439
+ greeting: string;
440
+ suggestions: Suggestion[];
441
+ send: (prompt: string) => void;
442
+ }>;
443
+ protected readonly threadList: import("@angular/core").Signal<{
444
+ threads: ThreadSummary[] | undefined;
445
+ selectedThreadId: string | undefined;
446
+ openThread: (thread: ThreadSummary) => void;
447
+ deleteThread: (threadId: string) => import("rxjs").Subscription;
448
+ newChat: () => void;
449
+ }>;
403
450
  protected chatService: CortexChatService;
404
451
  protected queue: AttachmentQueueService;
452
+ private threadService;
405
453
  private readonly injector;
406
454
  private readonly destroyRef;
407
455
  ngOnInit(): void;
408
456
  private headerContext;
409
- protected toggleSidebar(): void;
410
457
  protected closeSidebar(): void;
411
- protected toggleDebugMode(): void;
412
- protected selectThread(thread: ThreadSummary): void;
413
- protected openHistory(): void;
414
- protected closeHistory(): void;
458
+ private toggleDebugMode;
459
+ private selectThread;
460
+ private openHistory;
461
+ private closeHistory;
415
462
  protected onWidgetDragOver(event: DragEvent): void;
416
463
  protected onWidgetDrop(event: DragEvent): void;
417
- protected newChat(): void;
464
+ private newChat;
418
465
  static ɵfac: i0.ɵɵFactoryDeclaration<CortexChatWidgetComponent, never>;
419
466
  static ɵcmp: i0.ɵɵComponentDeclaration<CortexChatWidgetComponent, "cortex-chat-widget", never, {
420
467
  "config": {
@@ -423,8 +470,42 @@ export declare class CortexChatWidgetComponent implements OnInit {
423
470
  "isSignal": true;
424
471
  };
425
472
  }, {}, [
426
- "customHeader"
473
+ "slotDirectives"
427
474
  ], never, true, never>;
428
475
  }
476
+ export type SlotName = keyof CortexAngularSlotContexts;
477
+ export type SlotTemplateContext<Slot extends SlotName> = {
478
+ $implicit: CortexAngularSlotContexts[Slot];
479
+ };
480
+ /**
481
+ * Marks the host's own part of `<cortex-chat-widget>`, named by `cortexSlot`:
482
+ * `header`, `landing` or `threadList`. It replaces the widget's default and
483
+ * receives the context the default is drawn from; `header` serves both the
484
+ * chat and the history screen.
485
+ *
486
+ * <cortex-chat-widget [config]="config">
487
+ * <ng-template cortexSlot="header" let-chat>
488
+ * <div class="cortex-widget__chat-header">{{ chat.title ?? chat.agentName }}</div>
489
+ * </ng-template>
490
+ * </cortex-chat-widget>
491
+ */
492
+ export declare class CortexSlotDirective<Slot extends SlotName> {
493
+ readonly slot: import("@angular/core").InputSignal<Slot>;
494
+ private readonly template;
495
+ /** The slot this template fills, paired with the template, for the widget's lookup by slot name. */
496
+ entry(): readonly [
497
+ Slot,
498
+ TemplateRef<SlotTemplateContext<Slot>>
499
+ ];
500
+ static ngTemplateContextGuard<Slot extends SlotName>(_directive: CortexSlotDirective<Slot>, _context: unknown): _context is SlotTemplateContext<Slot>;
501
+ static ɵfac: i0.ɵɵFactoryDeclaration<CortexSlotDirective<any>, never>;
502
+ static ɵdir: i0.ɵɵDirectiveDeclaration<CortexSlotDirective<any>, "ng-template[cortexSlot]", never, {
503
+ "slot": {
504
+ "alias": "cortexSlot";
505
+ "required": true;
506
+ "isSignal": true;
507
+ };
508
+ }, {}, never, never, true, never>;
509
+ }
429
510
 
430
511
  export {};