@copilotkitnext/angular 0.0.2 → 0.0.5

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.
Files changed (173) hide show
  1. package/README.md +3 -3
  2. package/dist/README.md +3 -3
  3. package/dist/components/chat/copilot-chat-assistant-message.component.d.ts +10 -10
  4. package/dist/components/chat/copilot-chat-message-view.component.d.ts +42 -42
  5. package/dist/components/chat/copilot-chat-view.component.d.ts +14 -14
  6. package/dist/core/copilotkit.providers.d.ts +1 -1
  7. package/dist/core/copilotkit.service.d.ts +5 -5
  8. package/dist/core/copilotkit.types.d.ts +8 -10
  9. package/dist/directives/copilotkit-frontend-tool.directive.d.ts +1 -1
  10. package/dist/esm2022/components/chat/copilot-chat-assistant-message-buttons.component.mjs +384 -0
  11. package/dist/esm2022/components/chat/copilot-chat-assistant-message-renderer.component.mjs +286 -0
  12. package/dist/esm2022/components/chat/copilot-chat-assistant-message-toolbar.component.mjs +27 -0
  13. package/dist/esm2022/components/chat/copilot-chat-assistant-message.component.mjs +433 -0
  14. package/dist/esm2022/components/chat/copilot-chat-assistant-message.types.mjs +2 -0
  15. package/dist/esm2022/components/chat/copilot-chat-audio-recorder.component.mjs +202 -0
  16. package/dist/esm2022/components/chat/copilot-chat-buttons.component.mjs +321 -0
  17. package/dist/esm2022/components/chat/copilot-chat-input-defaults.mjs +38 -0
  18. package/dist/esm2022/components/chat/copilot-chat-input.component.mjs +666 -0
  19. package/dist/esm2022/components/chat/copilot-chat-input.types.mjs +10 -0
  20. package/dist/esm2022/components/chat/copilot-chat-message-view-cursor.component.mjs +45 -0
  21. package/dist/esm2022/components/chat/copilot-chat-message-view.component.mjs +296 -0
  22. package/dist/esm2022/components/chat/copilot-chat-message-view.types.mjs +2 -0
  23. package/dist/esm2022/components/chat/copilot-chat-textarea.component.mjs +188 -0
  24. package/dist/esm2022/components/chat/copilot-chat-tool-calls-view.component.mjs +216 -0
  25. package/dist/esm2022/components/chat/copilot-chat-toolbar.component.mjs +25 -0
  26. package/dist/esm2022/components/chat/copilot-chat-tools-menu.component.mjs +199 -0
  27. package/dist/esm2022/components/chat/copilot-chat-user-message-branch-navigation.component.mjs +137 -0
  28. package/dist/esm2022/components/chat/copilot-chat-user-message-buttons.component.mjs +207 -0
  29. package/dist/esm2022/components/chat/copilot-chat-user-message-renderer.component.mjs +35 -0
  30. package/dist/esm2022/components/chat/copilot-chat-user-message-toolbar.component.mjs +34 -0
  31. package/dist/esm2022/components/chat/copilot-chat-user-message.component.mjs +341 -0
  32. package/dist/esm2022/components/chat/copilot-chat-user-message.types.mjs +2 -0
  33. package/dist/esm2022/components/chat/copilot-chat-view-disclaimer.component.mjs +52 -0
  34. package/dist/esm2022/components/chat/copilot-chat-view-feather.component.mjs +55 -0
  35. package/dist/esm2022/components/chat/copilot-chat-view-handlers.service.mjs +19 -0
  36. package/dist/esm2022/components/chat/copilot-chat-view-input-container.component.mjs +110 -0
  37. package/dist/esm2022/components/chat/copilot-chat-view-scroll-to-bottom-button.component.mjs +93 -0
  38. package/dist/esm2022/components/chat/copilot-chat-view-scroll-view.component.mjs +443 -0
  39. package/dist/esm2022/components/chat/copilot-chat-view.component.mjs +479 -0
  40. package/dist/esm2022/components/chat/copilot-chat-view.types.mjs +2 -0
  41. package/dist/esm2022/components/chat/copilot-chat.component.mjs +214 -0
  42. package/dist/esm2022/components/copilotkit-tool-render.component.mjs +153 -0
  43. package/dist/esm2022/copilotkitnext-angular.mjs +5 -0
  44. package/dist/esm2022/core/chat-configuration/chat-configuration.providers.mjs +65 -0
  45. package/dist/esm2022/core/chat-configuration/chat-configuration.service.mjs +145 -0
  46. package/dist/esm2022/core/chat-configuration/chat-configuration.types.mjs +26 -0
  47. package/dist/esm2022/core/copilotkit.providers.mjs +34 -0
  48. package/dist/esm2022/core/copilotkit.service.mjs +426 -0
  49. package/dist/esm2022/core/copilotkit.types.mjs +13 -0
  50. package/dist/esm2022/directives/copilotkit-agent-context.directive.mjs +130 -0
  51. package/dist/esm2022/directives/copilotkit-agent.directive.mjs +217 -0
  52. package/dist/esm2022/directives/copilotkit-chat-config.directive.mjs +218 -0
  53. package/dist/esm2022/directives/copilotkit-config.directive.mjs +94 -0
  54. package/dist/esm2022/directives/copilotkit-frontend-tool.directive.mjs +128 -0
  55. package/dist/esm2022/directives/copilotkit-human-in-the-loop.directive.mjs +265 -0
  56. package/dist/esm2022/directives/stick-to-bottom.directive.mjs +181 -0
  57. package/dist/esm2022/index.mjs +70 -0
  58. package/dist/esm2022/lib/directives/tooltip.directive.mjs +211 -0
  59. package/dist/esm2022/lib/slots/copilot-slot.component.mjs +144 -0
  60. package/dist/esm2022/lib/slots/slot.types.mjs +6 -0
  61. package/dist/esm2022/lib/slots/slot.utils.mjs +222 -0
  62. package/dist/esm2022/lib/utils.mjs +10 -0
  63. package/dist/esm2022/services/resize-observer.service.mjs +152 -0
  64. package/dist/esm2022/services/scroll-position.service.mjs +124 -0
  65. package/dist/esm2022/types/frontend-tool.mjs +2 -0
  66. package/dist/esm2022/types/human-in-the-loop.mjs +2 -0
  67. package/dist/esm2022/utils/agent-context.utils.mjs +114 -0
  68. package/dist/esm2022/utils/agent.utils.mjs +204 -0
  69. package/dist/esm2022/utils/chat-config.utils.mjs +186 -0
  70. package/dist/esm2022/utils/copilotkit.utils.mjs +20 -0
  71. package/dist/esm2022/utils/frontend-tool.utils.mjs +224 -0
  72. package/dist/esm2022/utils/human-in-the-loop.utils.mjs +293 -0
  73. package/dist/fesm2022/copilotkitnext-angular.mjs +174 -187
  74. package/dist/fesm2022/copilotkitnext-angular.mjs.map +1 -1
  75. package/dist/utils/frontend-tool.utils.d.ts +1 -1
  76. package/package.json +23 -20
  77. package/vitest.config.mts +32 -21
  78. package/.turbo/turbo-build.log +0 -38
  79. package/.turbo/turbo-check-types.log +0 -0
  80. package/.turbo/turbo-test.log +0 -71
  81. package/ng-package.json +0 -19
  82. package/src/components/chat/__tests__/copilot-chat-assistant-message.component.spec.ts +0 -282
  83. package/src/components/chat/__tests__/copilot-chat-input.component.spec.ts +0 -419
  84. package/src/components/chat/__tests__/copilot-chat-message-view.component.spec.ts +0 -372
  85. package/src/components/chat/__tests__/copilot-chat-user-message.component.spec.ts +0 -249
  86. package/src/components/chat/copilot-chat-assistant-message-buttons.component.ts +0 -292
  87. package/src/components/chat/copilot-chat-assistant-message-renderer.component.ts +0 -472
  88. package/src/components/chat/copilot-chat-assistant-message-toolbar.component.ts +0 -29
  89. package/src/components/chat/copilot-chat-assistant-message.component.ts +0 -463
  90. package/src/components/chat/copilot-chat-assistant-message.types.ts +0 -50
  91. package/src/components/chat/copilot-chat-audio-recorder.component.ts +0 -241
  92. package/src/components/chat/copilot-chat-buttons.component.ts +0 -308
  93. package/src/components/chat/copilot-chat-buttons.component.ts.bak +0 -471
  94. package/src/components/chat/copilot-chat-input-defaults.ts +0 -47
  95. package/src/components/chat/copilot-chat-input.component.ts +0 -512
  96. package/src/components/chat/copilot-chat-input.types.ts +0 -148
  97. package/src/components/chat/copilot-chat-message-view-cursor.component.ts +0 -51
  98. package/src/components/chat/copilot-chat-message-view.component.ts +0 -233
  99. package/src/components/chat/copilot-chat-message-view.types.ts +0 -39
  100. package/src/components/chat/copilot-chat-textarea.component.ts +0 -220
  101. package/src/components/chat/copilot-chat-tool-calls-view.component.ts +0 -261
  102. package/src/components/chat/copilot-chat-toolbar.component.ts +0 -35
  103. package/src/components/chat/copilot-chat-tools-menu.component.ts +0 -185
  104. package/src/components/chat/copilot-chat-user-message-branch-navigation.component.ts +0 -121
  105. package/src/components/chat/copilot-chat-user-message-buttons.component.ts +0 -170
  106. package/src/components/chat/copilot-chat-user-message-renderer.component.ts +0 -37
  107. package/src/components/chat/copilot-chat-user-message-toolbar.component.ts +0 -37
  108. package/src/components/chat/copilot-chat-user-message.component.ts +0 -247
  109. package/src/components/chat/copilot-chat-user-message.types.ts +0 -42
  110. package/src/components/chat/copilot-chat-view-disclaimer.component.ts +0 -51
  111. package/src/components/chat/copilot-chat-view-feather.component.ts +0 -47
  112. package/src/components/chat/copilot-chat-view-handlers.service.ts +0 -14
  113. package/src/components/chat/copilot-chat-view-input-container.component.ts +0 -87
  114. package/src/components/chat/copilot-chat-view-scroll-to-bottom-button.component.ts +0 -79
  115. package/src/components/chat/copilot-chat-view-scroll-view.component.ts +0 -322
  116. package/src/components/chat/copilot-chat-view.component.ts +0 -420
  117. package/src/components/chat/copilot-chat-view.types.ts +0 -52
  118. package/src/components/chat/copilot-chat.component.ts +0 -232
  119. package/src/components/copilotkit-tool-render.component.ts +0 -169
  120. package/src/core/__tests__/copilotkit.service.spec.ts +0 -1051
  121. package/src/core/__tests__/copilotkit.service.wildcard.spec.ts +0 -316
  122. package/src/core/chat-configuration/__tests__/chat-configuration.service.spec.ts +0 -287
  123. package/src/core/chat-configuration/chat-configuration.providers.ts +0 -71
  124. package/src/core/chat-configuration/chat-configuration.service.ts +0 -162
  125. package/src/core/chat-configuration/chat-configuration.types.ts +0 -57
  126. package/src/core/copilotkit.providers.ts +0 -59
  127. package/src/core/copilotkit.service.ts +0 -542
  128. package/src/core/copilotkit.types.ts +0 -132
  129. package/src/directives/__tests__/copilotkit-agent-context.directive.spec.ts +0 -384
  130. package/src/directives/__tests__/copilotkit-agent.directive.spec.ts +0 -253
  131. package/src/directives/__tests__/copilotkit-chat-config.directive.spec.ts +0 -385
  132. package/src/directives/__tests__/copilotkit-config.directive.spec.ts +0 -69
  133. package/src/directives/__tests__/copilotkit-frontend-tool-simple.directive.spec.ts +0 -60
  134. package/src/directives/__tests__/copilotkit-frontend-tool.directive.spec.ts +0 -108
  135. package/src/directives/__tests__/copilotkit-human-in-the-loop.directive.spec.ts +0 -452
  136. package/src/directives/copilotkit-agent-context.directive.ts +0 -138
  137. package/src/directives/copilotkit-agent.directive.ts +0 -225
  138. package/src/directives/copilotkit-chat-config.directive.ts +0 -241
  139. package/src/directives/copilotkit-config.directive.ts +0 -81
  140. package/src/directives/copilotkit-frontend-tool.directive.ts +0 -145
  141. package/src/directives/copilotkit-human-in-the-loop.directive.ts +0 -281
  142. package/src/directives/stick-to-bottom.directive.ts +0 -204
  143. package/src/index.ts +0 -105
  144. package/src/lib/directives/tooltip.directive.ts +0 -292
  145. package/src/lib/slots/__tests__/slot.utils.spec.ts +0 -377
  146. package/src/lib/slots/copilot-slot.component.ts +0 -135
  147. package/src/lib/slots/index.ts +0 -3
  148. package/src/lib/slots/slot.types.ts +0 -64
  149. package/src/lib/slots/slot.utils.ts +0 -289
  150. package/src/lib/utils.ts +0 -10
  151. package/src/public-api.ts +0 -1
  152. package/src/services/resize-observer.service.ts +0 -181
  153. package/src/services/scroll-position.service.ts +0 -169
  154. package/src/styles/globals.css +0 -266
  155. package/src/styles/index.css +0 -3
  156. package/src/test-setup.ts +0 -15
  157. package/src/testing/index.ts +0 -3
  158. package/src/testing/testing.utils.ts +0 -248
  159. package/src/types/frontend-tool.ts +0 -44
  160. package/src/types/human-in-the-loop.ts +0 -52
  161. package/src/utils/__tests__/agent.utils.spec.ts +0 -234
  162. package/src/utils/__tests__/chat-config.utils.spec.ts +0 -306
  163. package/src/utils/__tests__/frontend-tool-inject.spec.ts +0 -350
  164. package/src/utils/__tests__/frontend-tool-integration.spec.ts +0 -199
  165. package/src/utils/__tests__/frontend-tool.utils.spec.ts +0 -272
  166. package/src/utils/__tests__/human-in-the-loop.utils.spec.ts +0 -365
  167. package/src/utils/agent-context.utils.ts +0 -133
  168. package/src/utils/agent.utils.ts +0 -239
  169. package/src/utils/chat-config.utils.ts +0 -221
  170. package/src/utils/copilotkit.utils.ts +0 -20
  171. package/src/utils/frontend-tool.utils.ts +0 -266
  172. package/src/utils/human-in-the-loop.utils.ts +0 -359
  173. package/tsconfig.spec.json +0 -12
@@ -1,51 +0,0 @@
1
- import {
2
- Component,
3
- Input,
4
- ChangeDetectionStrategy,
5
- ViewEncapsulation,
6
- computed,
7
- signal,
8
- OnInit,
9
- OnChanges
10
- } from '@angular/core';
11
- import { CommonModule } from '@angular/common';
12
- import { cn } from '../../lib/utils';
13
-
14
- /**
15
- * Cursor component that matches the React implementation exactly.
16
- * Shows a pulsing dot animation to indicate activity.
17
- */
18
- @Component({
19
- selector: 'copilot-chat-message-view-cursor',
20
- standalone: true,
21
- imports: [CommonModule],
22
- changeDetection: ChangeDetectionStrategy.OnPush,
23
- encapsulation: ViewEncapsulation.None,
24
- template: `
25
- <div
26
- [class]="computedClass()"
27
- ></div>
28
- `
29
- })
30
- export class CopilotChatMessageViewCursorComponent implements OnInit, OnChanges {
31
- @Input() inputClass?: string;
32
-
33
- // Signal for reactive class updates
34
- private inputClassSignal = signal<string | undefined>(undefined);
35
-
36
- // Computed class that matches React exactly: w-[11px] h-[11px] rounded-full bg-foreground animate-pulse-cursor ml-1
37
- computedClass = computed(() =>
38
- cn(
39
- 'w-[11px] h-[11px] rounded-full bg-foreground animate-pulse-cursor ml-1',
40
- this.inputClassSignal()
41
- )
42
- );
43
-
44
- ngOnInit() {
45
- this.inputClassSignal.set(this.inputClass);
46
- }
47
-
48
- ngOnChanges() {
49
- this.inputClassSignal.set(this.inputClass);
50
- }
51
- }
@@ -1,233 +0,0 @@
1
- import {
2
- Component,
3
- Input,
4
- Output,
5
- EventEmitter,
6
- ContentChild,
7
- TemplateRef,
8
- Type,
9
- ChangeDetectionStrategy,
10
- ViewEncapsulation,
11
- signal,
12
- computed,
13
- OnInit,
14
- OnChanges
15
- } from '@angular/core';
16
- import { CommonModule } from '@angular/common';
17
- import { CopilotSlotComponent } from '../../lib/slots/copilot-slot.component';
18
- import type { Message } from '@ag-ui/core';
19
- import { CopilotChatAssistantMessageComponent } from './copilot-chat-assistant-message.component';
20
- import { CopilotChatUserMessageComponent } from './copilot-chat-user-message.component';
21
- import { CopilotChatMessageViewCursorComponent } from './copilot-chat-message-view-cursor.component';
22
- import { cn } from '../../lib/utils';
23
-
24
- /**
25
- * CopilotChatMessageView component - Angular port of the React component.
26
- * Renders a list of chat messages with support for custom slots and layouts.
27
- * DOM structure and Tailwind classes match the React implementation exactly.
28
- */
29
- @Component({
30
- selector: 'copilot-chat-message-view',
31
- standalone: true,
32
- imports: [
33
- CommonModule,
34
- CopilotSlotComponent,
35
- CopilotChatAssistantMessageComponent,
36
- CopilotChatUserMessageComponent,
37
- CopilotChatMessageViewCursorComponent
38
- ],
39
- changeDetection: ChangeDetectionStrategy.OnPush,
40
- encapsulation: ViewEncapsulation.None,
41
- template: `
42
- <!-- Custom layout template support (render prop pattern) -->
43
- @if (customLayoutTemplate) {
44
- <ng-container *ngTemplateOutlet="customLayoutTemplate; context: layoutContext()"></ng-container>
45
- } @else {
46
- <!-- Default layout - exact React DOM structure: div with "flex flex-col" classes -->
47
- <div [class]="computedClass()">
48
- <!-- Message iteration - simplified without tool calls -->
49
- @for (message of messagesSignal(); track trackByMessageId($index, message)) {
50
- @if (message && message.role === 'assistant') {
51
- <!-- Assistant message with slot support -->
52
- @if (assistantMessageComponent || assistantMessageTemplate) {
53
- <copilot-slot
54
- [slot]="assistantMessageTemplate || assistantMessageComponent"
55
- [context]="mergeAssistantProps(message)"
56
- [defaultComponent]="defaultAssistantComponent">
57
- </copilot-slot>
58
- } @else {
59
- <copilot-chat-assistant-message
60
- [message]="message"
61
- [messages]="messagesSignal()"
62
- [isLoading]="isLoadingSignal()"
63
- [inputClass]="assistantMessageClass"
64
- (thumbsUp)="handleAssistantThumbsUp($event)"
65
- (thumbsDown)="handleAssistantThumbsDown($event)"
66
- (readAloud)="handleAssistantReadAloud($event)"
67
- (regenerate)="handleAssistantRegenerate($event)">
68
- </copilot-chat-assistant-message>
69
- }
70
- } @else if (message && message.role === 'user') {
71
- <!-- User message with slot support -->
72
- @if (userMessageComponent || userMessageTemplate) {
73
- <copilot-slot
74
- [slot]="userMessageTemplate || userMessageComponent"
75
- [context]="mergeUserProps(message)"
76
- [defaultComponent]="defaultUserComponent">
77
- </copilot-slot>
78
- } @else {
79
- <copilot-chat-user-message
80
- [message]="message"
81
- [inputClass]="userMessageClass">
82
- </copilot-chat-user-message>
83
- }
84
- }
85
- }
86
-
87
- <!-- Cursor - exactly like React's conditional rendering -->
88
- @if (showCursor) {
89
- @if (cursorComponent || cursorTemplate) {
90
- <copilot-slot
91
- [slot]="cursorTemplate || cursorComponent"
92
- [context]="{ inputClass: cursorClass }"
93
- [defaultComponent]="defaultCursorComponent">
94
- </copilot-slot>
95
- } @else {
96
- <copilot-chat-message-view-cursor
97
- [inputClass]="cursorClass">
98
- </copilot-chat-message-view-cursor>
99
- }
100
- }
101
- </div>
102
- }
103
- `
104
- })
105
- export class CopilotChatMessageViewComponent implements OnInit, OnChanges {
106
- // Core inputs matching React props
107
- @Input() messages: Message[] = [];
108
- @Input() showCursor = false;
109
- @Input() isLoading = false;
110
- @Input() inputClass?: string;
111
-
112
- // Handler availability handled via DI service
113
-
114
- // Assistant message slot inputs
115
- @Input() assistantMessageComponent?: Type<any>;
116
- @Input() assistantMessageTemplate?: TemplateRef<any>;
117
- @Input() assistantMessageClass?: string;
118
-
119
- // User message slot inputs
120
- @Input() userMessageComponent?: Type<any>;
121
- @Input() userMessageTemplate?: TemplateRef<any>;
122
- @Input() userMessageClass?: string;
123
-
124
-
125
- // Cursor slot inputs
126
- @Input() cursorComponent?: Type<any>;
127
- @Input() cursorTemplate?: TemplateRef<any>;
128
- @Input() cursorClass?: string;
129
-
130
- // Custom layout template (render prop pattern)
131
- @ContentChild('customLayout') customLayoutTemplate?: TemplateRef<any>;
132
-
133
- // Output events (bubbled from child components)
134
- @Output() assistantMessageThumbsUp = new EventEmitter<{ message: Message }>();
135
- @Output() assistantMessageThumbsDown = new EventEmitter<{ message: Message }>();
136
- @Output() assistantMessageReadAloud = new EventEmitter<{ message: Message }>();
137
- @Output() assistantMessageRegenerate = new EventEmitter<{ message: Message }>();
138
- @Output() userMessageCopy = new EventEmitter<{ message: Message }>();
139
- @Output() userMessageEdit = new EventEmitter<{ message: Message }>();
140
-
141
- // Default components for slots
142
- protected readonly defaultAssistantComponent = CopilotChatAssistantMessageComponent;
143
- protected readonly defaultUserComponent = CopilotChatUserMessageComponent;
144
- protected readonly defaultCursorComponent = CopilotChatMessageViewCursorComponent;
145
-
146
- // Signals for reactive updates
147
- protected messagesSignal = signal<Message[]>([]);
148
- protected showCursorSignal = signal(false);
149
- protected isLoadingSignal = signal(false);
150
- protected inputClassSignal = signal<string | undefined>(undefined);
151
-
152
- // Computed class matching React: twMerge("flex flex-col", className)
153
- computedClass = computed(() =>
154
- cn('flex flex-col', this.inputClassSignal())
155
- );
156
-
157
-
158
- // Layout context for custom templates (render prop pattern)
159
- layoutContext = computed(() => ({
160
- isLoading: this.isLoadingSignal(),
161
- messages: this.messagesSignal(),
162
- showCursor: this.showCursorSignal(),
163
- messageElements: this.messagesSignal().filter(m => m && (m.role === 'assistant' || m.role === 'user'))
164
- }));
165
-
166
- // Slot resolution computed signals
167
- assistantMessageSlot = computed(() =>
168
- this.assistantMessageComponent || this.assistantMessageClass
169
- );
170
-
171
- userMessageSlot = computed(() =>
172
- this.userMessageComponent || this.userMessageClass
173
- );
174
-
175
- cursorSlot = computed(() =>
176
- this.cursorComponent || this.cursorClass
177
- );
178
-
179
- // Props merging helpers
180
- mergeAssistantProps(message: Message) {
181
- return {
182
- message,
183
- messages: this.messagesSignal(),
184
- isLoading: this.isLoadingSignal(),
185
- inputClass: this.assistantMessageClass
186
- };
187
- }
188
-
189
- mergeUserProps(message: Message) {
190
- return {
191
- message,
192
- inputClass: this.userMessageClass
193
- };
194
- }
195
-
196
- // TrackBy function for performance optimization
197
- trackByMessageId(index: number, message: Message): string {
198
- return message?.id || `index-${index}`;
199
- }
200
-
201
- // Lifecycle hooks
202
- ngOnInit() {
203
- // Initialize signals with input values
204
- this.messagesSignal.set(this.messages);
205
- this.showCursorSignal.set(this.showCursor);
206
- this.isLoadingSignal.set(this.isLoading);
207
- this.inputClassSignal.set(this.inputClass);
208
- }
209
-
210
- ngOnChanges() {
211
- this.messagesSignal.set(this.messages);
212
- this.showCursorSignal.set(this.showCursor);
213
- this.isLoadingSignal.set(this.isLoading);
214
- this.inputClassSignal.set(this.inputClass);
215
- }
216
-
217
- // Event handlers - just pass them through
218
- handleAssistantThumbsUp(event: { message: Message }): void {
219
- this.assistantMessageThumbsUp.emit(event);
220
- }
221
-
222
- handleAssistantThumbsDown(event: { message: Message }): void {
223
- this.assistantMessageThumbsDown.emit(event);
224
- }
225
-
226
- handleAssistantReadAloud(event: { message: Message }): void {
227
- this.assistantMessageReadAloud.emit(event);
228
- }
229
-
230
- handleAssistantRegenerate(event: { message: Message }): void {
231
- this.assistantMessageRegenerate.emit(event);
232
- }
233
- }
@@ -1,39 +0,0 @@
1
- import { Message } from '@ag-ui/client';
2
- import { Type, TemplateRef } from '@angular/core';
3
-
4
- // Context interfaces for template slots
5
- export interface MessageViewContext {
6
- showCursor: boolean;
7
- messages: Message[];
8
- messageElements: any[]; // Will be populated with rendered elements
9
- }
10
-
11
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
12
- export interface CursorContext {
13
- // Empty for now, can be extended if needed
14
- }
15
-
16
- // Component input props interface
17
- export interface CopilotChatMessageViewProps {
18
- messages?: Message[];
19
- showCursor?: boolean;
20
- inputClass?: string;
21
-
22
- // Assistant message slots
23
- assistantMessageComponent?: Type<any>;
24
- assistantMessageTemplate?: TemplateRef<any>;
25
- assistantMessageClass?: string;
26
-
27
- // User message slots
28
- userMessageComponent?: Type<any>;
29
- userMessageTemplate?: TemplateRef<any>;
30
- userMessageClass?: string;
31
-
32
- // Cursor slots
33
- cursorComponent?: Type<any>;
34
- cursorTemplate?: TemplateRef<any>;
35
- cursorClass?: string;
36
- }
37
-
38
- // Re-export for convenience
39
- export type { Message };
@@ -1,220 +0,0 @@
1
- import {
2
- Component,
3
- Input,
4
- Output,
5
- EventEmitter,
6
- ElementRef,
7
- AfterViewInit,
8
- OnChanges,
9
- SimpleChanges,
10
- signal,
11
- computed,
12
- effect,
13
- inject,
14
- ChangeDetectionStrategy,
15
- ViewEncapsulation
16
- } from '@angular/core';
17
- import { CopilotChatConfigurationService } from '../../core/chat-configuration/chat-configuration.service';
18
- import { cn } from '../../lib/utils';
19
-
20
- @Component({
21
- selector: 'textarea[copilotChatTextarea]',
22
- standalone: true,
23
- imports: [],
24
- changeDetection: ChangeDetectionStrategy.OnPush,
25
- encapsulation: ViewEncapsulation.None,
26
- host: {
27
- '[value]': 'value()',
28
- '[placeholder]': 'placeholder()',
29
- '[disabled]': 'disabled()',
30
- '[class]': 'computedClass()',
31
- '[style.max-height.px]': 'maxHeight()',
32
- '[style.overflow]': "'auto'",
33
- '[style.resize]': "'none'",
34
- '(input)': 'onInput($event)',
35
- '(keydown)': 'onKeyDown($event)',
36
- '[attr.rows]': '1'
37
- },
38
- template: '',
39
- styles: []
40
- })
41
- export class CopilotChatTextareaComponent implements AfterViewInit, OnChanges {
42
- private elementRef = inject(ElementRef<HTMLTextAreaElement>);
43
- get textareaRef() { return this.elementRef; }
44
-
45
- @Input() set inputValue(val: string | undefined) {
46
- this.value.set(val || '');
47
- }
48
- @Input() set inputPlaceholder(val: string | undefined) {
49
- this.customPlaceholder.set(val);
50
- }
51
- @Input() set inputMaxRows(val: number | undefined) {
52
- this.maxRows.set(val || 5);
53
- }
54
- @Input() set inputAutoFocus(val: boolean | undefined) {
55
- this.autoFocus.set(val ?? true);
56
- }
57
- @Input() set inputDisabled(val: boolean | undefined) {
58
- this.disabled.set(val || false);
59
- }
60
- @Input() set inputClass(val: string | undefined) {
61
- this.customClass.set(val);
62
- }
63
-
64
- @Output() valueChange = new EventEmitter<string>();
65
- @Output() keyDown = new EventEmitter<KeyboardEvent>();
66
-
67
- private chatConfig = inject(CopilotChatConfigurationService);
68
-
69
- // Signals for reactive state
70
- value = signal<string>('');
71
- customPlaceholder = signal<string | undefined>(undefined);
72
- maxRows = signal<number>(5);
73
- autoFocus = signal<boolean>(true);
74
- disabled = signal<boolean>(false);
75
- customClass = signal<string | undefined>(undefined);
76
- maxHeight = signal<number>(0);
77
-
78
- // Computed values
79
- placeholder = computed(() => {
80
- return this.customPlaceholder() || this.chatConfig.labels().chatInputPlaceholder;
81
- });
82
-
83
- computedClass = computed(() => {
84
- const baseClasses = cn(
85
- // Layout and sizing
86
- 'w-full p-5 pb-0',
87
- // Behavior
88
- 'outline-none resize-none',
89
- // Background
90
- 'bg-transparent',
91
- // Typography
92
- 'antialiased font-regular leading-relaxed text-[16px]',
93
- // Placeholder styles
94
- 'placeholder:text-[#00000077] dark:placeholder:text-[#fffc]'
95
- );
96
- return cn(baseClasses, this.customClass());
97
- });
98
-
99
- constructor() {
100
- // Effect to sync value with chat configuration if available
101
- effect(() => {
102
- const configValue = this.chatConfig.inputValue();
103
- if (configValue !== undefined && !this.customPlaceholder()) {
104
- this.value.set(configValue);
105
- }
106
- });
107
- }
108
-
109
- ngAfterViewInit(): void {
110
- this.calculateMaxHeight();
111
- this.adjustHeight();
112
-
113
- if (this.autoFocus()) {
114
- setTimeout(() => {
115
- this.elementRef.nativeElement.focus();
116
- });
117
- }
118
- }
119
-
120
- ngOnChanges(changes: SimpleChanges): void {
121
- if (changes['inputMaxRows']) {
122
- this.calculateMaxHeight();
123
- }
124
- }
125
-
126
- onInput(event: Event): void {
127
- const textarea = event.target as HTMLTextAreaElement;
128
- const newValue = textarea.value;
129
-
130
- this.value.set(newValue);
131
- this.valueChange.emit(newValue);
132
-
133
- // Update chat configuration if available
134
- if (this.chatConfig) {
135
- this.chatConfig.setInputValue(newValue);
136
- }
137
-
138
- this.adjustHeight();
139
- }
140
-
141
- onKeyDown(event: KeyboardEvent): void {
142
- // Check for Enter key without Shift
143
- if (event.key === 'Enter' && !event.shiftKey) {
144
- event.preventDefault();
145
- this.keyDown.emit(event);
146
- } else {
147
- this.keyDown.emit(event);
148
- }
149
- }
150
-
151
- private calculateMaxHeight(): void {
152
- const textarea = this.elementRef.nativeElement;
153
- const maxRowsValue = this.maxRows();
154
-
155
- // Save current value
156
- const currentValue = textarea.value;
157
-
158
- // Clear content to measure single row height
159
- textarea.value = '';
160
- textarea.style.height = 'auto';
161
-
162
- // Get computed styles to account for padding
163
- const computedStyle = window.getComputedStyle(textarea);
164
- const paddingTop = parseFloat(computedStyle.paddingTop);
165
- const paddingBottom = parseFloat(computedStyle.paddingBottom);
166
-
167
- // Calculate actual content height (without padding)
168
- const contentHeight = textarea.scrollHeight - paddingTop - paddingBottom;
169
-
170
- // Calculate max height: content height for maxRows + padding
171
- const calculatedMaxHeight = contentHeight * maxRowsValue + paddingTop + paddingBottom;
172
- this.maxHeight.set(calculatedMaxHeight);
173
-
174
- // Restore original value
175
- textarea.value = currentValue;
176
-
177
- // Adjust height after calculating maxHeight
178
- if (currentValue) {
179
- this.adjustHeight();
180
- }
181
- }
182
-
183
- private adjustHeight(): void {
184
- const textarea = this.elementRef.nativeElement;
185
- const maxHeightValue = this.maxHeight();
186
-
187
- if (maxHeightValue > 0) {
188
- textarea.style.height = 'auto';
189
- textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeightValue)}px`;
190
- }
191
- }
192
-
193
- /**
194
- * Public method to focus the textarea
195
- */
196
- focus(): void {
197
- this.elementRef.nativeElement.focus();
198
- }
199
-
200
- /**
201
- * Public method to get current value
202
- */
203
- getValue(): string {
204
- return this.value();
205
- }
206
-
207
- /**
208
- * Public method to set value programmatically
209
- */
210
- setValue(value: string): void {
211
- this.value.set(value);
212
- this.valueChange.emit(value);
213
-
214
- if (this.chatConfig) {
215
- this.chatConfig.setInputValue(value);
216
- }
217
-
218
- setTimeout(() => this.adjustHeight());
219
- }
220
- }