@memberjunction/ng-composer 6.1.0-edge.1 → 6.1.0-edge.2

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.
@@ -1,61 +1,77 @@
1
1
  import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
2
+ import { BeforeSkillsOpenedEventArgs } from '../../events/composer-events';
2
3
  import * as i0 from "@angular/core";
3
4
  import * as i1 from "@angular/forms";
4
5
  import * as i2 from "../mention/mention-editor.component";
5
6
  const _c0 = ["mentionEditor"];
6
7
  function MessageInputBoxComponent_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
7
8
  const _r2 = i0.ɵɵgetCurrentView();
8
- i0.ɵɵelementStart(0, "button", 9);
9
- i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_1_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.planModeToggle.emit(); return i0.ɵɵresetView($event.stopPropagation()); });
10
- i0.ɵɵelement(1, "i", 10);
9
+ i0.ɵɵelementStart(0, "button", 10);
10
+ i0.ɵɵlistener("mousedown", function MessageInputBoxComponent_Conditional_4_Conditional_1_Template_button_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r2); $event.preventDefault(); return i0.ɵɵresetView($event.stopPropagation()); })("click", function MessageInputBoxComponent_Conditional_4_Conditional_1_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.OnSkillsClick($event); return i0.ɵɵresetView($event.stopPropagation()); });
11
+ i0.ɵɵelement(1, "i", 11);
11
12
  i0.ɵɵelementEnd();
12
13
  } if (rf & 2) {
13
14
  const ctx_r2 = i0.ɵɵnextContext(2);
14
- i0.ɵɵclassProp("plan-mode-button-icon--active", ctx_r2.planModeActive);
15
- i0.ɵɵproperty("disabled", ctx_r2.disabled)("title", ctx_r2.planModeActive ? "Plan Mode ON \u2014 the agent presents a plan for your approval before it acts" : "Plan Mode: have the agent present a plan for your approval before it acts");
16
- i0.ɵɵattribute("aria-pressed", ctx_r2.planModeActive);
15
+ i0.ɵɵclassProp("skills-button-icon--active", ctx_r2.SkillsActive);
16
+ i0.ɵɵproperty("disabled", ctx_r2.Disabled);
17
+ i0.ɵɵattribute("aria-expanded", ctx_r2.SkillsActive);
17
18
  } }
18
19
  function MessageInputBoxComponent_Conditional_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
19
20
  const _r4 = i0.ɵɵgetCurrentView();
20
- i0.ɵɵelementStart(0, "button", 11);
21
- i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_2_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.openFilePicker(); return i0.ɵɵresetView($event.stopPropagation()); });
22
- i0.ɵɵelement(1, "i", 12);
21
+ i0.ɵɵelementStart(0, "button", 12);
22
+ i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_2_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.PlanModeToggle.emit(); return i0.ɵɵresetView($event.stopPropagation()); });
23
+ i0.ɵɵelement(1, "i", 13);
23
24
  i0.ɵɵelementEnd();
24
25
  } if (rf & 2) {
25
26
  const ctx_r2 = i0.ɵɵnextContext(2);
26
- i0.ɵɵproperty("disabled", ctx_r2.disabled);
27
+ i0.ɵɵclassProp("plan-mode-button-icon--active", ctx_r2.PlanModeActive);
28
+ i0.ɵɵproperty("disabled", ctx_r2.Disabled)("title", ctx_r2.PlanModeActive ? "Plan Mode ON \u2014 the agent presents a plan for your approval before it acts" : "Plan Mode: have the agent present a plan for your approval before it acts");
29
+ i0.ɵɵattribute("aria-pressed", ctx_r2.PlanModeActive);
27
30
  } }
28
31
  function MessageInputBoxComponent_Conditional_4_Conditional_3_Template(rf, ctx) { if (rf & 1) {
29
32
  const _r5 = i0.ɵɵgetCurrentView();
30
- i0.ɵɵelementStart(0, "button", 13);
31
- i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_3_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.onRealtimeClick(); return i0.ɵɵresetView($event.stopPropagation()); });
32
- i0.ɵɵelement(1, "i", 14);
33
+ i0.ɵɵelementStart(0, "button", 14);
34
+ i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_3_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.OpenFilePicker(); return i0.ɵɵresetView($event.stopPropagation()); });
35
+ i0.ɵɵelement(1, "i", 15);
33
36
  i0.ɵɵelementEnd();
34
- i0.ɵɵelementStart(2, "button", 15);
35
- i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_3_Template_button_click_2_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.onRealtimeOptionsClick(); return i0.ɵɵresetView($event.stopPropagation()); });
36
- i0.ɵɵelement(3, "i", 16);
37
+ } if (rf & 2) {
38
+ const ctx_r2 = i0.ɵɵnextContext(2);
39
+ i0.ɵɵproperty("disabled", ctx_r2.Disabled);
40
+ } }
41
+ function MessageInputBoxComponent_Conditional_4_Conditional_4_Template(rf, ctx) { if (rf & 1) {
42
+ const _r6 = i0.ɵɵgetCurrentView();
43
+ i0.ɵɵelementStart(0, "button", 16);
44
+ i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_4_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.OnRealtimeClick(); return i0.ɵɵresetView($event.stopPropagation()); });
45
+ i0.ɵɵelement(1, "i", 17);
46
+ i0.ɵɵelementEnd();
47
+ i0.ɵɵelementStart(2, "button", 18);
48
+ i0.ɵɵlistener("click", function MessageInputBoxComponent_Conditional_4_Conditional_4_Template_button_click_2_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.OnRealtimeOptionsClick(); return i0.ɵɵresetView($event.stopPropagation()); });
49
+ i0.ɵɵelement(3, "i", 19);
37
50
  i0.ɵɵelementEnd();
38
51
  } if (rf & 2) {
39
52
  const ctx_r2 = i0.ɵɵnextContext(2);
40
- i0.ɵɵclassProp("voice-button-icon--active", ctx_r2.voiceActive);
41
- i0.ɵɵproperty("disabled", !ctx_r2.canStartRealtime)("title", ctx_r2.voiceActive ? "Voice call active" : "Start a voice call");
53
+ i0.ɵɵclassProp("voice-button-icon--active", ctx_r2.VoiceActive);
54
+ i0.ɵɵproperty("disabled", !ctx_r2.CanStartRealtime)("title", ctx_r2.VoiceActive ? "Voice call active" : "Start a voice call");
42
55
  i0.ɵɵadvance(2);
43
- i0.ɵɵproperty("disabled", !ctx_r2.canStartRealtime);
56
+ i0.ɵɵproperty("disabled", !ctx_r2.CanStartRealtime);
44
57
  } }
45
58
  function MessageInputBoxComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
46
59
  i0.ɵɵelementStart(0, "div", 4);
47
- i0.ɵɵconditionalCreate(1, MessageInputBoxComponent_Conditional_4_Conditional_1_Template, 2, 5, "button", 7);
48
- i0.ɵɵconditionalCreate(2, MessageInputBoxComponent_Conditional_4_Conditional_2_Template, 2, 1, "button", 8);
49
- i0.ɵɵconditionalCreate(3, MessageInputBoxComponent_Conditional_4_Conditional_3_Template, 4, 5);
60
+ i0.ɵɵconditionalCreate(1, MessageInputBoxComponent_Conditional_4_Conditional_1_Template, 2, 4, "button", 7);
61
+ i0.ɵɵconditionalCreate(2, MessageInputBoxComponent_Conditional_4_Conditional_2_Template, 2, 5, "button", 8);
62
+ i0.ɵɵconditionalCreate(3, MessageInputBoxComponent_Conditional_4_Conditional_3_Template, 2, 1, "button", 9);
63
+ i0.ɵɵconditionalCreate(4, MessageInputBoxComponent_Conditional_4_Conditional_4_Template, 4, 5);
50
64
  i0.ɵɵelementEnd();
51
65
  } if (rf & 2) {
52
66
  const ctx_r2 = i0.ɵɵnextContext();
53
67
  i0.ɵɵadvance();
54
- i0.ɵɵconditional(ctx_r2.enablePlanMode ? 1 : -1);
68
+ i0.ɵɵconditional(ctx_r2.EnableSkills ? 1 : -1);
55
69
  i0.ɵɵadvance();
56
- i0.ɵɵconditional(ctx_r2.enableAttachments ? 2 : -1);
70
+ i0.ɵɵconditional(ctx_r2.EnablePlanMode ? 2 : -1);
57
71
  i0.ɵɵadvance();
58
- i0.ɵɵconditional(ctx_r2.enableRealtime ? 3 : -1);
72
+ i0.ɵɵconditional(ctx_r2.EnableAttachments ? 3 : -1);
73
+ i0.ɵɵadvance();
74
+ i0.ɵɵconditional(ctx_r2.EnableRealtime ? 4 : -1);
59
75
  } }
60
76
  /**
61
77
  * Reusable message input box component (presentational)
@@ -74,99 +90,179 @@ function MessageInputBoxComponent_Conditional_4_Template(rf, ctx) { if (rf & 1)
74
90
  */
75
91
  export class MessageInputBoxComponent {
76
92
  mentionEditor;
77
- placeholder = 'Type your message to start a new conversation...';
78
- disabled = false;
79
- value = '';
80
- showCharacterCount = false;
93
+ Placeholder = 'Type your message to start a new conversation...';
94
+ Disabled = false;
95
+ Value = '';
96
+ ShowCharacterCount = false;
81
97
  /** Master switch for all mention/command triggers (pass-through to the mention editor). */
82
- enableMentions = true;
98
+ EnableMentions = true;
83
99
  /** Explicit trigger-provider list (pass-through to the mention editor; explicit list wins over discovery). */
84
100
  TriggerProviders = null;
85
101
  /** Discovery-mode filter: provider Keys to skip (pass-through to the mention editor). */
86
102
  ExcludedTriggerKeys = [];
87
103
  /** Optional metadata provider scoping this composer (pass-through to the mention editor). */
88
104
  Provider = null;
89
- currentUser;
90
- rows = 3;
105
+ CurrentUser;
106
+ Rows = 3;
91
107
  // Attachment settings
92
- enableAttachments = true;
93
- maxAttachments = 10;
94
- maxAttachmentSizeBytes = 20 * 1024 * 1024; // 20MB
95
- acceptedFileTypes = 'image/*';
108
+ EnableAttachments = true;
109
+ MaxAttachments = 10;
110
+ MaxAttachmentSizeBytes = 20 * 1024 * 1024; // 20MB
111
+ AcceptedFileTypes = 'image/*';
96
112
  /** Shows the in-composer mic button when true. */
97
- enableRealtime = false;
113
+ EnableRealtime = false;
98
114
  /** Whether a realtime voice session is currently active (mic renders in its active state). */
99
- voiceActive = false;
100
- /** Whether a voice session can be started right now (mic disabled when false). */
101
- canStartRealtime = true;
115
+ VoiceActive = false;
116
+ /** Whether a voice session can be started right now (mic Disabled when false). */
117
+ CanStartRealtime = true;
102
118
  /** Shows the in-composer Plan Mode toggle button when true. */
103
- enablePlanMode = false;
119
+ EnablePlanMode = false;
104
120
  /** Current Plan Mode toggle state (renders the button in its active state). */
105
- planModeActive = false;
121
+ PlanModeActive = false;
122
+ /**
123
+ * Shows the in-composer Skills button when true.
124
+ *
125
+ * Gated separately from `EnableMentions` because a host can have the `/` trigger active and
126
+ * still not want the button — but the common case is that a composer offering skill commands
127
+ * should advertise them, since `/` is otherwise invisible.
128
+ */
129
+ EnableSkills = false;
130
+ /**
131
+ * True while the skill dropdown is open, driving the button's expanded state.
132
+ *
133
+ * Note the ARIA differs from Plan Mode next to it, deliberately: Plan Mode is a toggle BUTTON
134
+ * (a mode that stays on), so `aria-pressed` is right there. This one opens a popup, so it is
135
+ * `aria-expanded` + `aria-haspopup`. Using `aria-pressed` here would have a screen reader
136
+ * announce "pressed" for something that actually just revealed a list.
137
+ *
138
+ * DERIVED, not an @Input, and this is the difference from Plan Mode. Plan Mode's active state is
139
+ * a persisted user preference the host owns and threads down. "Is the skill dropdown open" is
140
+ * intrinsic to this composer, so an @Input would be an API the host cannot meaningfully answer
141
+ * and would leave the button permanently unpressed if nobody bound it.
142
+ */
143
+ get SkillsActive() {
144
+ return this.mentionEditor?.IsTriggerOpen('/') ?? false;
145
+ }
106
146
  /** Composer lost focus — hosts persist drafts on this. */
107
- blurred = new EventEmitter();
108
- textSubmitted = new EventEmitter();
109
- valueChange = new EventEmitter();
110
- attachmentsChanged = new EventEmitter();
111
- attachmentError = new EventEmitter();
112
- attachmentClicked = new EventEmitter();
147
+ Blurred = new EventEmitter();
148
+ TextSubmitted = new EventEmitter();
149
+ ValueChange = new EventEmitter();
150
+ AttachmentsChanged = new EventEmitter();
151
+ AttachmentError = new EventEmitter();
152
+ AttachmentClicked = new EventEmitter();
113
153
  /** Emitted when the user clicks the mic button to start/stop a voice session. */
114
- voiceRequested = new EventEmitter();
154
+ VoiceRequested = new EventEmitter();
115
155
  /**
116
156
  * Emitted when the user clicks the small caret next to the phone button — the host opens the
117
157
  * voice agent/model picker so call options (which agent, which voice model) stay reachable
118
158
  * without adding friction to the plain phone click's instant-start path.
119
159
  */
120
- voiceOptionsRequested = new EventEmitter();
160
+ VoiceOptionsRequested = new EventEmitter();
121
161
  /** Emitted when the user clicks the in-composer Plan Mode toggle button. */
122
- planModeToggle = new EventEmitter();
123
- onRealtimeClick() {
124
- this.voiceRequested.emit();
162
+ PlanModeToggle = new EventEmitter();
163
+ /**
164
+ * Fired BEFORE the Skills button opens the dropdown. Flip `Cancel` to veto — a host gating
165
+ * skills by entitlement, or surfacing them elsewhere, blocks it here.
166
+ *
167
+ * A pair rather than a lone emitter because this is an ACTION a host might reasonably refuse
168
+ * (UI_LAYERING_GUIDE section 6, rule 1). Handlers must be synchronous; `Cancel` travels back
169
+ * through EventEmitter's synchronous dispatch.
170
+ */
171
+ BeforeSkillsOpened = new EventEmitter();
172
+ /**
173
+ * Fired AFTER the dropdown actually opened. Not emitted on the canceled path, and not emitted
174
+ * when no active provider owns the trigger — so a host counting this counts dropdowns the user
175
+ * saw, rather than clicks.
176
+ */
177
+ AfterSkillsOpened = new EventEmitter();
178
+ /**
179
+ * Open the skill-command dropdown, the same one `/` opens.
180
+ *
181
+ * Routed through the editor's OpenTrigger rather than a parallel menu so permission filtering,
182
+ * per-skill icons and chip insertion all stay in one implementation.
183
+ */
184
+ /**
185
+ * NOTE: the template pairs this with
186
+ * `(mousedown)="$event.preventDefault(); $event.stopPropagation()"`, and BOTH halves are
187
+ * load-bearing.
188
+ *
189
+ * `preventDefault` — a <button> takes focus on mousedown, which blurs the editor, and the editor
190
+ * closes its dropdown 200ms after losing focus. Without it the menu opened and then shut itself.
191
+ *
192
+ * `stopPropagation` — the editor's click-away listener is on `document:mousedown` and exempts only
193
+ * presses inside the EDITOR's host. This button is a sibling of `<mj-mention-editor>`, so a press
194
+ * on it read as an outside press: mousedown closed the dropdown, then click saw `SkillsActive`
195
+ * already false and reopened it. The menu blinked, could not be dismissed by the button that
196
+ * opened it, and the Before/After pair fired on every click — the exact over-counting the toggle
197
+ * branch below exists to prevent. Stopping propagation states that this press belongs to the
198
+ * dropdown machinery.
199
+ */
200
+ OnSkillsClick(event) {
201
+ // Toggle closed first. A disclosure button has to be able to close what it opened, and without
202
+ // this a second click re-ran the open path: it re-emitted the Before/After pair (so a host
203
+ // counting opens over-counted) and re-captured the trigger's baseline at the new caret, which
204
+ // corrupts the query offset once anything has been typed.
205
+ if (this.SkillsActive) {
206
+ this.mentionEditor?.closeMentionDropdown();
207
+ return;
208
+ }
209
+ const args = new BeforeSkillsOpenedEventArgs();
210
+ this.BeforeSkillsOpened.emit(args);
211
+ if (args.Cancel) {
212
+ return;
213
+ }
214
+ const anchor = event?.currentTarget ?? null;
215
+ if (this.mentionEditor?.OpenTrigger('/', anchor)) {
216
+ this.AfterSkillsOpened.emit();
217
+ }
218
+ }
219
+ OnRealtimeClick() {
220
+ this.VoiceRequested.emit();
125
221
  }
126
- onRealtimeOptionsClick() {
127
- this.voiceOptionsRequested.emit();
222
+ OnRealtimeOptionsClick() {
223
+ this.VoiceOptionsRequested.emit();
128
224
  }
129
- get canSend() {
130
- const hasText = this.value.trim().length > 0;
225
+ get CanSend() {
226
+ const hasText = this.Value.trim().length > 0;
131
227
  const hasAttachments = this.mentionEditor?.hasAttachments() || false;
132
- return !this.disabled && (hasText || hasAttachments);
228
+ return !this.Disabled && (hasText || hasAttachments);
133
229
  }
134
230
  /**
135
- * Handle value changes from MentionEditorComponent
231
+ * Handle Value changes from MentionEditorComponent
136
232
  */
137
- onValueChange(newValue) {
138
- this.value = newValue;
139
- this.valueChange.emit(this.value);
233
+ OnValueChange(newValue) {
234
+ this.Value = newValue;
235
+ this.ValueChange.emit(this.Value);
140
236
  }
141
237
  /**
142
238
  * Handle attachment changes from MentionEditorComponent
143
239
  */
144
- onAttachmentsChanged(attachments) {
145
- this.attachmentsChanged.emit(attachments);
240
+ OnAttachmentsChanged(attachments) {
241
+ this.AttachmentsChanged.emit(attachments);
146
242
  }
147
243
  /**
148
244
  * Handle attachment errors from MentionEditorComponent
149
245
  */
150
- onAttachmentError(error) {
151
- this.attachmentError.emit(error);
246
+ OnAttachmentError(error) {
247
+ this.AttachmentError.emit(error);
152
248
  }
153
249
  /**
154
250
  * Handle attachment click from MentionEditorComponent
155
251
  */
156
- onAttachmentClicked(attachment) {
157
- this.attachmentClicked.emit(attachment);
252
+ OnAttachmentClicked(attachment) {
253
+ this.AttachmentClicked.emit(attachment);
158
254
  }
159
255
  /**
160
256
  * Handle Enter key from MentionEditorComponent
161
257
  * Extracts plain text with JSON-encoded mentions for message submission
162
258
  */
163
- onEnterPressed(_text) {
164
- this.onSendClick();
259
+ OnEnterPressed(_text) {
260
+ this.OnSendClick();
165
261
  }
166
262
  /**
167
263
  * Handle mention selection from MentionEditorComponent
168
264
  */
169
- onMentionSelected(suggestion) {
265
+ OnMentionSelected(suggestion) {
170
266
  // MentionEditorComponent already inserts the mention chip
171
267
  // This is just for additional tracking/analytics if needed
172
268
  }
@@ -174,24 +270,24 @@ export class MessageInputBoxComponent {
174
270
  * Send the message
175
271
  * Extracts plain text with JSON-encoded mentions for proper persistence
176
272
  */
177
- onSendClick() {
178
- if (this.canSend) {
273
+ OnSendClick() {
274
+ if (this.CanSend) {
179
275
  // Get plain text with JSON-encoded mentions (preserves configuration info)
180
- const textToSend = this.mentionEditor?.getPlainTextWithJsonMentions() || this.value.trim();
181
- this.textSubmitted.emit(textToSend);
182
- this.value = ''; // Clear input after sending
276
+ const textToSend = this.mentionEditor?.getPlainTextWithJsonMentions() || this.Value.trim();
277
+ this.TextSubmitted.emit(textToSend);
278
+ this.Value = ''; // Clear input after sending
183
279
  // Clear the editor content
184
280
  if (this.mentionEditor) {
185
281
  this.mentionEditor.clear();
186
282
  }
187
- this.valueChange.emit(this.value);
283
+ this.ValueChange.emit(this.Value);
188
284
  }
189
285
  }
190
286
  /**
191
287
  * Handle clicks on the container - focus the mention editor
192
288
  * Only moves cursor to end if clicking outside the contentEditable area
193
289
  */
194
- onContainerClick(event) {
290
+ OnContainerClick(event) {
195
291
  const target = event.target;
196
292
  // Don't handle clicks on the send button
197
293
  if (target.closest('.send-button-icon')) {
@@ -235,19 +331,19 @@ export class MessageInputBoxComponent {
235
331
  /**
236
332
  * Get mention chip data including configuration presets
237
333
  */
238
- getMentionChipsData() {
334
+ GetMentionChipsData() {
239
335
  return this.mentionEditor?.getMentionChipsData() || [];
240
336
  }
241
337
  /**
242
338
  * Get pending attachments from the editor
243
339
  */
244
- getPendingAttachments() {
340
+ GetPendingAttachments() {
245
341
  return this.mentionEditor?.getPendingAttachments() || [];
246
342
  }
247
343
  /**
248
344
  * Open file picker programmatically
249
345
  */
250
- openFilePicker() {
346
+ OpenFilePicker() {
251
347
  this.mentionEditor?.openFilePicker();
252
348
  }
253
349
  /**
@@ -262,44 +358,44 @@ export class MessageInputBoxComponent {
262
358
  } if (rf & 2) {
263
359
  let _t;
264
360
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.mentionEditor = _t.first);
265
- } }, inputs: { placeholder: "placeholder", disabled: "disabled", value: "value", showCharacterCount: "showCharacterCount", enableMentions: "enableMentions", TriggerProviders: "TriggerProviders", ExcludedTriggerKeys: "ExcludedTriggerKeys", Provider: "Provider", currentUser: "currentUser", rows: "rows", enableAttachments: "enableAttachments", maxAttachments: "maxAttachments", maxAttachmentSizeBytes: "maxAttachmentSizeBytes", acceptedFileTypes: "acceptedFileTypes", enableRealtime: "enableRealtime", voiceActive: "voiceActive", canStartRealtime: "canStartRealtime", enablePlanMode: "enablePlanMode", planModeActive: "planModeActive" }, outputs: { blurred: "blurred", textSubmitted: "textSubmitted", valueChange: "valueChange", attachmentsChanged: "attachmentsChanged", attachmentError: "attachmentError", attachmentClicked: "attachmentClicked", voiceRequested: "voiceRequested", voiceOptionsRequested: "voiceOptionsRequested", planModeToggle: "planModeToggle" }, standalone: false, decls: 7, vars: 14, consts: [["mentionEditor", ""], [1, "message-input-box-container", 3, "click"], [1, "input-wrapper"], [3, "ngModelChange", "valueChange", "enterPressed", "mentionSelected", "attachmentsChanged", "attachmentError", "attachmentClicked", "editorBlurred", "placeholder", "disabled", "currentUser", "enableMentions", "TriggerProviders", "ExcludedTriggerKeys", "Provider", "enableAttachments", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "ngModel"], [1, "attach-buttons"], ["title", "Send message (Enter)", 1, "send-button-icon", 3, "click", "disabled"], [1, "fa-solid", "fa-paper-plane"], ["aria-label", "Toggle Plan Mode", 1, "attach-button-icon", "plan-mode-button-icon", 3, "plan-mode-button-icon--active", "disabled", "title"], ["title", "Attach file", 1, "attach-button-icon", 3, "disabled"], ["aria-label", "Toggle Plan Mode", 1, "attach-button-icon", "plan-mode-button-icon", 3, "click", "disabled", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-route"], ["title", "Attach file", 1, "attach-button-icon", 3, "click", "disabled"], [1, "fa-solid", "fa-paperclip"], ["aria-label", "Start a voice call", 1, "attach-button-icon", "voice-button-icon", 3, "click", "disabled", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-phone"], ["title", "Voice call options (choose agent and voice model)", "aria-label", "Voice call options", 1, "attach-button-icon", "voice-options-button-icon", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"]], template: function MessageInputBoxComponent_Template(rf, ctx) { if (rf & 1) {
361
+ } }, inputs: { Placeholder: "Placeholder", Disabled: "Disabled", Value: "Value", ShowCharacterCount: "ShowCharacterCount", EnableMentions: "EnableMentions", TriggerProviders: "TriggerProviders", ExcludedTriggerKeys: "ExcludedTriggerKeys", Provider: "Provider", CurrentUser: "CurrentUser", Rows: "Rows", EnableAttachments: "EnableAttachments", MaxAttachments: "MaxAttachments", MaxAttachmentSizeBytes: "MaxAttachmentSizeBytes", AcceptedFileTypes: "AcceptedFileTypes", EnableRealtime: "EnableRealtime", VoiceActive: "VoiceActive", CanStartRealtime: "CanStartRealtime", EnablePlanMode: "EnablePlanMode", PlanModeActive: "PlanModeActive", EnableSkills: "EnableSkills" }, outputs: { Blurred: "Blurred", TextSubmitted: "TextSubmitted", ValueChange: "ValueChange", AttachmentsChanged: "AttachmentsChanged", AttachmentError: "AttachmentError", AttachmentClicked: "AttachmentClicked", VoiceRequested: "VoiceRequested", VoiceOptionsRequested: "VoiceOptionsRequested", PlanModeToggle: "PlanModeToggle", BeforeSkillsOpened: "BeforeSkillsOpened", AfterSkillsOpened: "AfterSkillsOpened" }, standalone: false, decls: 7, vars: 14, consts: [["mentionEditor", ""], [1, "message-input-box-container", 3, "click"], [1, "input-wrapper"], [3, "ngModelChange", "valueChange", "enterPressed", "mentionSelected", "attachmentsChanged", "attachmentError", "attachmentClicked", "editorBlurred", "placeholder", "disabled", "currentUser", "enableMentions", "TriggerProviders", "ExcludedTriggerKeys", "Provider", "enableAttachments", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "ngModel"], [1, "attach-buttons"], ["title", "Send message (Enter)", 1, "send-button-icon", 3, "click", "disabled"], [1, "fa-solid", "fa-paper-plane"], ["aria-haspopup", "true", "title", "Skills, or type / in the message box", "aria-label", "Show skills", 1, "attach-button-icon", "skills-button-icon", 3, "skills-button-icon--active", "disabled"], ["aria-label", "Toggle Plan Mode", 1, "attach-button-icon", "plan-mode-button-icon", 3, "plan-mode-button-icon--active", "disabled", "title"], ["title", "Attach file", 1, "attach-button-icon", 3, "disabled"], ["aria-haspopup", "true", "title", "Skills, or type / in the message box", "aria-label", "Show skills", 1, "attach-button-icon", "skills-button-icon", 3, "mousedown", "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-wand-magic-sparkles"], ["aria-label", "Toggle Plan Mode", 1, "attach-button-icon", "plan-mode-button-icon", 3, "click", "disabled", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-route"], ["title", "Attach file", 1, "attach-button-icon", 3, "click", "disabled"], [1, "fa-solid", "fa-paperclip"], ["aria-label", "Start a voice call", 1, "attach-button-icon", "voice-button-icon", 3, "click", "disabled", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-phone"], ["title", "Voice call options (choose agent and voice model)", "aria-label", "Voice call options", 1, "attach-button-icon", "voice-options-button-icon", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"]], template: function MessageInputBoxComponent_Template(rf, ctx) { if (rf & 1) {
266
362
  const _r1 = i0.ɵɵgetCurrentView();
267
363
  i0.ɵɵelementStart(0, "div", 1);
268
- i0.ɵɵlistener("click", function MessageInputBoxComponent_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onContainerClick($event)); });
364
+ i0.ɵɵlistener("click", function MessageInputBoxComponent_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnContainerClick($event)); });
269
365
  i0.ɵɵelementStart(1, "div", 2)(2, "mj-mention-editor", 3, 0);
270
- i0.ɵɵtwoWayListener("ngModelChange", function MessageInputBoxComponent_Template_mj_mention_editor_ngModelChange_2_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.value, $event) || (ctx.value = $event); return i0.ɵɵresetView($event); });
271
- i0.ɵɵlistener("valueChange", function MessageInputBoxComponent_Template_mj_mention_editor_valueChange_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onValueChange($event)); })("enterPressed", function MessageInputBoxComponent_Template_mj_mention_editor_enterPressed_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onEnterPressed($event)); })("mentionSelected", function MessageInputBoxComponent_Template_mj_mention_editor_mentionSelected_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onMentionSelected($event)); })("attachmentsChanged", function MessageInputBoxComponent_Template_mj_mention_editor_attachmentsChanged_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAttachmentsChanged($event)); })("attachmentError", function MessageInputBoxComponent_Template_mj_mention_editor_attachmentError_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAttachmentError($event)); })("attachmentClicked", function MessageInputBoxComponent_Template_mj_mention_editor_attachmentClicked_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAttachmentClicked($event)); })("editorBlurred", function MessageInputBoxComponent_Template_mj_mention_editor_editorBlurred_2_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.blurred.emit()); });
366
+ i0.ɵɵtwoWayListener("ngModelChange", function MessageInputBoxComponent_Template_mj_mention_editor_ngModelChange_2_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.Value, $event) || (ctx.Value = $event); return i0.ɵɵresetView($event); });
367
+ i0.ɵɵlistener("valueChange", function MessageInputBoxComponent_Template_mj_mention_editor_valueChange_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnValueChange($event)); })("enterPressed", function MessageInputBoxComponent_Template_mj_mention_editor_enterPressed_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnEnterPressed($event)); })("mentionSelected", function MessageInputBoxComponent_Template_mj_mention_editor_mentionSelected_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnMentionSelected($event)); })("attachmentsChanged", function MessageInputBoxComponent_Template_mj_mention_editor_attachmentsChanged_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnAttachmentsChanged($event)); })("attachmentError", function MessageInputBoxComponent_Template_mj_mention_editor_attachmentError_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnAttachmentError($event)); })("attachmentClicked", function MessageInputBoxComponent_Template_mj_mention_editor_attachmentClicked_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnAttachmentClicked($event)); })("editorBlurred", function MessageInputBoxComponent_Template_mj_mention_editor_editorBlurred_2_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.Blurred.emit()); });
272
368
  i0.ɵɵelementEnd();
273
- i0.ɵɵconditionalCreate(4, MessageInputBoxComponent_Conditional_4_Template, 4, 3, "div", 4);
369
+ i0.ɵɵconditionalCreate(4, MessageInputBoxComponent_Conditional_4_Template, 5, 4, "div", 4);
274
370
  i0.ɵɵelementStart(5, "button", 5);
275
- i0.ɵɵlistener("click", function MessageInputBoxComponent_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSendClick()); });
371
+ i0.ɵɵlistener("click", function MessageInputBoxComponent_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnSendClick()); });
276
372
  i0.ɵɵelement(6, "i", 6);
277
373
  i0.ɵɵelementEnd()()();
278
374
  } if (rf & 2) {
279
375
  i0.ɵɵadvance(2);
280
- i0.ɵɵproperty("placeholder", ctx.placeholder)("disabled", ctx.disabled)("currentUser", ctx.currentUser)("enableMentions", ctx.enableMentions)("TriggerProviders", ctx.TriggerProviders)("ExcludedTriggerKeys", ctx.ExcludedTriggerKeys)("Provider", ctx.Provider)("enableAttachments", ctx.enableAttachments)("maxAttachments", ctx.maxAttachments)("maxAttachmentSizeBytes", ctx.maxAttachmentSizeBytes)("acceptedFileTypes", ctx.acceptedFileTypes);
281
- i0.ɵɵtwoWayProperty("ngModel", ctx.value);
376
+ i0.ɵɵproperty("placeholder", ctx.Placeholder)("disabled", ctx.Disabled)("currentUser", ctx.CurrentUser)("enableMentions", ctx.EnableMentions)("TriggerProviders", ctx.TriggerProviders)("ExcludedTriggerKeys", ctx.ExcludedTriggerKeys)("Provider", ctx.Provider)("enableAttachments", ctx.EnableAttachments)("maxAttachments", ctx.MaxAttachments)("maxAttachmentSizeBytes", ctx.MaxAttachmentSizeBytes)("acceptedFileTypes", ctx.AcceptedFileTypes);
377
+ i0.ɵɵtwoWayProperty("ngModel", ctx.Value);
282
378
  i0.ɵɵadvance(2);
283
- i0.ɵɵconditional(ctx.enableAttachments || ctx.enableRealtime || ctx.enablePlanMode ? 4 : -1);
379
+ i0.ɵɵconditional(ctx.EnableAttachments || ctx.EnableRealtime || ctx.EnablePlanMode || ctx.EnableSkills ? 4 : -1);
284
380
  i0.ɵɵadvance();
285
- i0.ɵɵproperty("disabled", !ctx.canSend);
286
- } }, dependencies: [i1.NgControlStatus, i1.NgModel, i2.MentionEditorComponent], styles: [".message-input-box-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-sm);\n transition: all 0.2s ease;\n overflow: visible;\n position: relative;\n cursor: text;\n}\n.message-input-box-container[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 16px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.input-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: flex-end;\n padding: 5px;\n}\n.input-wrapper[_ngcontent-%COMP%] mj-mention-editor[_ngcontent-%COMP%] {\n flex: 1;\n display: block;\n}\n\n.message-input-box-textarea[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 100px;\n padding: 1rem;\n padding-right: 3.5rem;\n border: 0 !important;\n outline: 0 !important;\n box-shadow: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n appearance: none !important;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n resize: vertical;\n background: transparent;\n color: var(--mj-text-primary);\n border: 0 !important;\n}\n.message-input-box-textarea[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n}\n.message-input-box-textarea[_ngcontent-%COMP%]:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n background: var(--mj-bg-surface-sunken);\n}\n.message-input-box-textarea[_ngcontent-%COMP%]:focus, .message-input-box-textarea[_ngcontent-%COMP%]:active, .message-input-box-textarea[_ngcontent-%COMP%]:focus-visible {\n outline: 0 !important;\n box-shadow: none !important;\n}\n\n.send-button-icon[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 0.75rem;\n right: 0.75rem;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.send-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n.send-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n}\n.send-button-icon[_ngcontent-%COMP%]:active:not(:disabled) {\n transform: scale(0.95);\n}\n.send-button-icon[_ngcontent-%COMP%]:disabled {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n\n\n.attach-buttons[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 0.75rem;\n right: 3rem;\n display: flex;\n gap: 2px;\n}\n.attach-button-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.attach-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n.attach-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n color: var(--mj-brand-primary);\n transform: scale(1.05);\n}\n.attach-button-icon[_ngcontent-%COMP%]:active:not(:disabled) {\n transform: scale(0.95);\n}\n.attach-button-icon[_ngcontent-%COMP%]:disabled {\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n\n\n\n.plan-mode-button-icon--active[_ngcontent-%COMP%]:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.plan-mode-button-icon--active[_ngcontent-%COMP%]:not(:disabled):hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n color: var(--mj-text-inverse);\n}\n\n\n\n@media (max-width: 768px) {\n .message-input-box-container[_ngcontent-%COMP%] {\n border-radius: 10px;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 6%, transparent);\n }\n .message-input-box-textarea[_ngcontent-%COMP%] {\n min-height: 80px;\n padding: 0.75rem;\n padding-right: 3rem;\n font-size: 16px;\n line-height: 1.4;\n }\n .send-button-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n bottom: 0.625rem;\n right: 0.625rem;\n border-radius: 6px;\n }\n .send-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n .attach-buttons[_ngcontent-%COMP%] {\n bottom: 0.625rem;\n right: 2.75rem;\n }\n .attach-button-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n}\n\n\n@media (max-width: 480px) {\n .message-input-box-container[_ngcontent-%COMP%] {\n border-radius: 8px;\n border-width: 1.5px;\n }\n .message-input-box-textarea[_ngcontent-%COMP%] {\n min-height: 60px;\n padding: 0.625rem;\n padding-right: 2.75rem;\n font-size: 16px;\n line-height: 1.3;\n }\n .send-button-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n bottom: 0.5rem;\n right: 0.5rem;\n border-radius: 6px;\n }\n .send-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n .attach-buttons[_ngcontent-%COMP%] {\n bottom: 0.5rem;\n right: 2.75rem;\n }\n .attach-button-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n}\n\n\n\n\n\n\n.voice-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.voice-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) i[_ngcontent-%COMP%] {\n filter: drop-shadow(0 0 4px color-mix(in srgb, var(--mj-brand-primary) 55%, transparent));\n}\n.voice-button-icon[_ngcontent-%COMP%]:disabled i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n}\n.voice-button-icon--active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n}\n.voice-button-icon--active[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n\n\n\n\n.voice-options-button-icon[_ngcontent-%COMP%] {\n width: 20px;\n margin-left: -4px;\n}\n.voice-options-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n}\n.voice-options-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.voice-options-button-icon[_ngcontent-%COMP%]:disabled i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n}"] });
381
+ i0.ɵɵproperty("disabled", !ctx.CanSend);
382
+ } }, dependencies: [i1.NgControlStatus, i1.NgModel, i2.MentionEditorComponent], styles: [".message-input-box-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-sm);\n transition: all 0.2s ease;\n overflow: visible;\n position: relative;\n cursor: text;\n}\n.message-input-box-container[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 16px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.input-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: flex-end;\n padding: 5px;\n}\n.input-wrapper[_ngcontent-%COMP%] mj-mention-editor[_ngcontent-%COMP%] {\n flex: 1;\n display: block;\n}\n\n.message-input-box-textarea[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 100px;\n padding: 1rem;\n padding-right: 3.5rem;\n border: 0 !important;\n outline: 0 !important;\n box-shadow: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n appearance: none !important;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n resize: vertical;\n background: transparent;\n color: var(--mj-text-primary);\n border: 0 !important;\n}\n.message-input-box-textarea[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n}\n.message-input-box-textarea[_ngcontent-%COMP%]:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n background: var(--mj-bg-surface-sunken);\n}\n.message-input-box-textarea[_ngcontent-%COMP%]:focus, .message-input-box-textarea[_ngcontent-%COMP%]:active, .message-input-box-textarea[_ngcontent-%COMP%]:focus-visible {\n outline: 0 !important;\n box-shadow: none !important;\n}\n\n.send-button-icon[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 0.75rem;\n right: 0.75rem;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.send-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n.send-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n}\n.send-button-icon[_ngcontent-%COMP%]:active:not(:disabled) {\n transform: scale(0.95);\n}\n.send-button-icon[_ngcontent-%COMP%]:disabled {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n\n\n.attach-buttons[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 0.75rem;\n right: 3rem;\n display: flex;\n gap: 2px;\n}\n.attach-button-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.attach-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n.attach-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n color: var(--mj-brand-primary);\n transform: scale(1.05);\n}\n.attach-button-icon[_ngcontent-%COMP%]:active:not(:disabled) {\n transform: scale(0.95);\n}\n.attach-button-icon[_ngcontent-%COMP%]:disabled {\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n\n\n\n.plan-mode-button-icon--active[_ngcontent-%COMP%]:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.plan-mode-button-icon--active[_ngcontent-%COMP%]:not(:disabled):hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n color: var(--mj-text-inverse);\n}\n\n\n\n\n.skills-button-icon--active[_ngcontent-%COMP%]:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.skills-button-icon--active[_ngcontent-%COMP%]:not(:disabled):hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n color: var(--mj-text-inverse);\n}\n\n\n\n@media (max-width: 768px) {\n .message-input-box-container[_ngcontent-%COMP%] {\n border-radius: 10px;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 6%, transparent);\n }\n .message-input-box-textarea[_ngcontent-%COMP%] {\n min-height: 80px;\n padding: 0.75rem;\n padding-right: 3rem;\n font-size: 16px;\n line-height: 1.4;\n }\n .send-button-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n bottom: 0.625rem;\n right: 0.625rem;\n border-radius: 6px;\n }\n .send-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n .attach-buttons[_ngcontent-%COMP%] {\n bottom: 0.625rem;\n right: 2.75rem;\n }\n .attach-button-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n}\n\n\n@media (max-width: 480px) {\n .message-input-box-container[_ngcontent-%COMP%] {\n border-radius: 8px;\n border-width: 1.5px;\n }\n .message-input-box-textarea[_ngcontent-%COMP%] {\n min-height: 60px;\n padding: 0.625rem;\n padding-right: 2.75rem;\n font-size: 16px;\n line-height: 1.3;\n }\n .send-button-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n bottom: 0.5rem;\n right: 0.5rem;\n border-radius: 6px;\n }\n .send-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n .attach-buttons[_ngcontent-%COMP%] {\n bottom: 0.5rem;\n right: 2.75rem;\n }\n .attach-button-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n}\n\n\n\n\n\n\n.voice-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.voice-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) i[_ngcontent-%COMP%] {\n filter: drop-shadow(0 0 4px color-mix(in srgb, var(--mj-brand-primary) 55%, transparent));\n}\n.voice-button-icon[_ngcontent-%COMP%]:disabled i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n}\n.voice-button-icon--active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n}\n.voice-button-icon--active[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n\n\n\n\n.voice-options-button-icon[_ngcontent-%COMP%] {\n width: 20px;\n margin-left: -4px;\n}\n.voice-options-button-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n}\n.voice-options-button-icon[_ngcontent-%COMP%]:hover:not(:disabled) i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.voice-options-button-icon[_ngcontent-%COMP%]:disabled i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n}"] });
287
383
  }
288
384
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MessageInputBoxComponent, [{
289
385
  type: Component,
290
- args: [{ standalone: false, selector: 'mj-message-input-box', template: "<div class=\"message-input-box-container\" (click)=\"onContainerClick($event)\">\n <div class=\"input-wrapper\">\n <mj-mention-editor\n #mentionEditor\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [currentUser]=\"currentUser\"\n [enableMentions]=\"enableMentions\"\n [TriggerProviders]=\"TriggerProviders\"\n [ExcludedTriggerKeys]=\"ExcludedTriggerKeys\"\n [Provider]=\"Provider\"\n [enableAttachments]=\"enableAttachments\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n [(ngModel)]=\"value\"\n (valueChange)=\"onValueChange($event)\"\n (enterPressed)=\"onEnterPressed($event)\"\n (mentionSelected)=\"onMentionSelected($event)\"\n (attachmentsChanged)=\"onAttachmentsChanged($event)\"\n (attachmentError)=\"onAttachmentError($event)\"\n (attachmentClicked)=\"onAttachmentClicked($event)\"\n (editorBlurred)=\"blurred.emit()\">\n </mj-mention-editor>\n\n <!-- Attach + voice + plan-mode buttons - Positioned over editor -->\n @if (enableAttachments || enableRealtime || enablePlanMode) {\n <div class=\"attach-buttons\">\n @if (enablePlanMode) {\n <button\n class=\"attach-button-icon plan-mode-button-icon\"\n [class.plan-mode-button-icon--active]=\"planModeActive\"\n [disabled]=\"disabled\"\n [attr.aria-pressed]=\"planModeActive\"\n (click)=\"planModeToggle.emit(); $event.stopPropagation()\"\n [title]=\"planModeActive ? 'Plan Mode ON \u2014 the agent presents a plan for your approval before it acts' : 'Plan Mode: have the agent present a plan for your approval before it acts'\"\n aria-label=\"Toggle Plan Mode\"\n >\n <i class=\"fa-solid fa-route\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (enableAttachments) {\n <button\n class=\"attach-button-icon\"\n [disabled]=\"disabled\"\n (click)=\"openFilePicker(); $event.stopPropagation()\"\n title=\"Attach file\"\n >\n <i class=\"fa-solid fa-paperclip\"></i>\n </button>\n }\n @if (enableRealtime) {\n <button\n class=\"attach-button-icon voice-button-icon\"\n [class.voice-button-icon--active]=\"voiceActive\"\n [disabled]=\"!canStartRealtime\"\n (click)=\"onRealtimeClick(); $event.stopPropagation()\"\n [title]=\"voiceActive ? 'Voice call active' : 'Start a voice call'\"\n aria-label=\"Start a voice call\"\n >\n <i class=\"fa-solid fa-phone\" aria-hidden=\"true\"></i>\n </button>\n <!-- Caret beside the phone: opens the agent/model picker so call OPTIONS stay one\n click away while the plain phone click keeps its instant-start behavior. -->\n <button\n class=\"attach-button-icon voice-options-button-icon\"\n [disabled]=\"!canStartRealtime\"\n (click)=\"onRealtimeOptionsClick(); $event.stopPropagation()\"\n title=\"Voice call options (choose agent and voice model)\"\n aria-label=\"Voice call options\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n\n <!-- Send Button (Icon Only) - Positioned over editor -->\n <button\n class=\"send-button-icon\"\n [disabled]=\"!canSend\"\n (click)=\"onSendClick()\"\n title=\"Send message (Enter)\"\n >\n <i class=\"fa-solid fa-paper-plane\"></i>\n </button>\n </div>\n</div>\n", styles: [".message-input-box-container {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-sm);\n transition: all 0.2s ease;\n overflow: visible;\n position: relative;\n cursor: text;\n}\n.message-input-box-container:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 16px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.input-wrapper {\n position: relative;\n display: flex;\n align-items: flex-end;\n padding: 5px;\n}\n.input-wrapper mj-mention-editor {\n flex: 1;\n display: block;\n}\n\n.message-input-box-textarea {\n flex: 1;\n min-height: 100px;\n padding: 1rem;\n padding-right: 3.5rem;\n border: 0 !important;\n outline: 0 !important;\n box-shadow: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n appearance: none !important;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n resize: vertical;\n background: transparent;\n color: var(--mj-text-primary);\n border: 0 !important;\n}\n.message-input-box-textarea::placeholder {\n color: var(--mj-text-muted);\n}\n.message-input-box-textarea:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n background: var(--mj-bg-surface-sunken);\n}\n.message-input-box-textarea:focus, .message-input-box-textarea:active, .message-input-box-textarea:focus-visible {\n outline: 0 !important;\n box-shadow: none !important;\n}\n\n.send-button-icon {\n position: absolute;\n bottom: 0.75rem;\n right: 0.75rem;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.send-button-icon i {\n font-size: 1rem;\n}\n.send-button-icon:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n}\n.send-button-icon:active:not(:disabled) {\n transform: scale(0.95);\n}\n.send-button-icon:disabled {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Attach buttons container */\n.attach-buttons {\n position: absolute;\n bottom: 0.75rem;\n right: 3rem;\n display: flex;\n gap: 2px;\n}\n.attach-button-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.attach-button-icon i {\n font-size: 1rem;\n}\n.attach-button-icon:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n color: var(--mj-brand-primary);\n transform: scale(1.05);\n}\n.attach-button-icon:active:not(:disabled) {\n transform: scale(0.95);\n}\n.attach-button-icon:disabled {\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Plan Mode toggle \u2014 inherits .attach-button-icon; when active it fills with the brand color\n so the on/off state reads clearly at a glance (parallels the voice button's active state). */\n.plan-mode-button-icon--active:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.plan-mode-button-icon--active:not(:disabled):hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n color: var(--mj-text-inverse);\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n .message-input-box-container {\n border-radius: 10px;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 6%, transparent);\n }\n .message-input-box-textarea {\n min-height: 80px;\n padding: 0.75rem;\n padding-right: 3rem;\n font-size: 16px;\n line-height: 1.4;\n }\n .send-button-icon {\n width: 32px;\n height: 32px;\n bottom: 0.625rem;\n right: 0.625rem;\n border-radius: 6px;\n }\n .send-button-icon i {\n font-size: 0.875rem;\n }\n .attach-buttons {\n bottom: 0.625rem;\n right: 2.75rem;\n }\n .attach-button-icon {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon i {\n font-size: 0.875rem;\n }\n}\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .message-input-box-container {\n border-radius: 8px;\n border-width: 1.5px;\n }\n .message-input-box-textarea {\n min-height: 60px;\n padding: 0.625rem;\n padding-right: 2.75rem;\n font-size: 16px;\n line-height: 1.3;\n }\n .send-button-icon {\n width: 36px;\n height: 36px;\n bottom: 0.5rem;\n right: 0.5rem;\n border-radius: 6px;\n }\n .send-button-icon i {\n font-size: 0.875rem;\n }\n .attach-buttons {\n bottom: 0.5rem;\n right: 2.75rem;\n }\n .attach-button-icon {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon i {\n font-size: 0.875rem;\n }\n}\n\n/* Voice call button \u2014 a phone icon in the attach-buttons cluster, left of send.\n Inherits .attach-button-icon base. Subtle brand glow on hover; active state (call\n live) renders a brand-color tint. The orb visual now lives ONLY inside the call\n overlay's banner. */\n.voice-button-icon i {\n color: var(--mj-brand-primary);\n}\n.voice-button-icon:hover:not(:disabled) i {\n filter: drop-shadow(0 0 4px color-mix(in srgb, var(--mj-brand-primary) 55%, transparent));\n}\n.voice-button-icon:disabled i {\n color: var(--mj-text-disabled);\n}\n.voice-button-icon--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n}\n.voice-button-icon--active:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n/* Voice OPTIONS caret \u2014 a slim chevron hugging the phone button. Opens the agent/model\n picker; intentionally quieter (smaller icon, narrower hit area) than the phone so the\n common instant-start click stays the visual primary. */\n.voice-options-button-icon {\n width: 20px;\n margin-left: -4px;\n}\n.voice-options-button-icon i {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n}\n.voice-options-button-icon:hover:not(:disabled) i {\n color: var(--mj-brand-primary);\n}\n.voice-options-button-icon:disabled i {\n color: var(--mj-text-disabled);\n}\n"] }]
386
+ args: [{ standalone: false, selector: 'mj-message-input-box', template: "<div class=\"message-input-box-container\" (click)=\"OnContainerClick($event)\">\n <div class=\"input-wrapper\">\n <mj-mention-editor\n #mentionEditor\n [placeholder]=\"Placeholder\"\n [disabled]=\"Disabled\"\n [currentUser]=\"CurrentUser\"\n [enableMentions]=\"EnableMentions\"\n [TriggerProviders]=\"TriggerProviders\"\n [ExcludedTriggerKeys]=\"ExcludedTriggerKeys\"\n [Provider]=\"Provider\"\n [enableAttachments]=\"EnableAttachments\"\n [maxAttachments]=\"MaxAttachments\"\n [maxAttachmentSizeBytes]=\"MaxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"AcceptedFileTypes\"\n [(ngModel)]=\"Value\"\n (valueChange)=\"OnValueChange($event)\"\n (enterPressed)=\"OnEnterPressed($event)\"\n (mentionSelected)=\"OnMentionSelected($event)\"\n (attachmentsChanged)=\"OnAttachmentsChanged($event)\"\n (attachmentError)=\"OnAttachmentError($event)\"\n (attachmentClicked)=\"OnAttachmentClicked($event)\"\n (editorBlurred)=\"Blurred.emit()\">\n </mj-mention-editor>\n\n <!-- Attach + voice + plan-mode buttons - Positioned over editor -->\n @if (EnableAttachments || EnableRealtime || EnablePlanMode || EnableSkills) {\n <div class=\"attach-buttons\">\n @if (EnableSkills) {\n <button\n class=\"attach-button-icon skills-button-icon\"\n [class.skills-button-icon--active]=\"SkillsActive\"\n [disabled]=\"Disabled\"\n [attr.aria-expanded]=\"SkillsActive\"\n aria-haspopup=\"true\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (click)=\"OnSkillsClick($event); $event.stopPropagation()\"\n title=\"Skills, or type / in the message box\"\n aria-label=\"Show skills\"\n >\n <i class=\"fa-solid fa-wand-magic-sparkles\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (EnablePlanMode) {\n <button\n class=\"attach-button-icon plan-mode-button-icon\"\n [class.plan-mode-button-icon--active]=\"PlanModeActive\"\n [disabled]=\"Disabled\"\n [attr.aria-pressed]=\"PlanModeActive\"\n (click)=\"PlanModeToggle.emit(); $event.stopPropagation()\"\n [title]=\"PlanModeActive ? 'Plan Mode ON \u2014 the agent presents a plan for your approval before it acts' : 'Plan Mode: have the agent present a plan for your approval before it acts'\"\n aria-label=\"Toggle Plan Mode\"\n >\n <i class=\"fa-solid fa-route\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (EnableAttachments) {\n <button\n class=\"attach-button-icon\"\n [disabled]=\"Disabled\"\n (click)=\"OpenFilePicker(); $event.stopPropagation()\"\n title=\"Attach file\"\n >\n <i class=\"fa-solid fa-paperclip\"></i>\n </button>\n }\n @if (EnableRealtime) {\n <button\n class=\"attach-button-icon voice-button-icon\"\n [class.voice-button-icon--active]=\"VoiceActive\"\n [disabled]=\"!CanStartRealtime\"\n (click)=\"OnRealtimeClick(); $event.stopPropagation()\"\n [title]=\"VoiceActive ? 'Voice call active' : 'Start a voice call'\"\n aria-label=\"Start a voice call\"\n >\n <i class=\"fa-solid fa-phone\" aria-hidden=\"true\"></i>\n </button>\n <!-- Caret beside the phone: opens the agent/model picker so call OPTIONS stay one\n click away while the plain phone click keeps its instant-start behavior. -->\n <button\n class=\"attach-button-icon voice-options-button-icon\"\n [disabled]=\"!CanStartRealtime\"\n (click)=\"OnRealtimeOptionsClick(); $event.stopPropagation()\"\n title=\"Voice call options (choose agent and voice model)\"\n aria-label=\"Voice call options\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n\n <!-- Send Button (Icon Only) - Positioned over editor -->\n <button\n class=\"send-button-icon\"\n [disabled]=\"!CanSend\"\n (click)=\"OnSendClick()\"\n title=\"Send message (Enter)\"\n >\n <i class=\"fa-solid fa-paper-plane\"></i>\n </button>\n </div>\n</div>\n", styles: [".message-input-box-container {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-sm);\n transition: all 0.2s ease;\n overflow: visible;\n position: relative;\n cursor: text;\n}\n.message-input-box-container:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 16px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.input-wrapper {\n position: relative;\n display: flex;\n align-items: flex-end;\n padding: 5px;\n}\n.input-wrapper mj-mention-editor {\n flex: 1;\n display: block;\n}\n\n.message-input-box-textarea {\n flex: 1;\n min-height: 100px;\n padding: 1rem;\n padding-right: 3.5rem;\n border: 0 !important;\n outline: 0 !important;\n box-shadow: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n appearance: none !important;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n resize: vertical;\n background: transparent;\n color: var(--mj-text-primary);\n border: 0 !important;\n}\n.message-input-box-textarea::placeholder {\n color: var(--mj-text-muted);\n}\n.message-input-box-textarea:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n background: var(--mj-bg-surface-sunken);\n}\n.message-input-box-textarea:focus, .message-input-box-textarea:active, .message-input-box-textarea:focus-visible {\n outline: 0 !important;\n box-shadow: none !important;\n}\n\n.send-button-icon {\n position: absolute;\n bottom: 0.75rem;\n right: 0.75rem;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.send-button-icon i {\n font-size: 1rem;\n}\n.send-button-icon:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n}\n.send-button-icon:active:not(:disabled) {\n transform: scale(0.95);\n}\n.send-button-icon:disabled {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Attach buttons container */\n.attach-buttons {\n position: absolute;\n bottom: 0.75rem;\n right: 3rem;\n display: flex;\n gap: 2px;\n}\n.attach-button-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.attach-button-icon i {\n font-size: 1rem;\n}\n.attach-button-icon:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n color: var(--mj-brand-primary);\n transform: scale(1.05);\n}\n.attach-button-icon:active:not(:disabled) {\n transform: scale(0.95);\n}\n.attach-button-icon:disabled {\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Plan Mode toggle \u2014 inherits .attach-button-icon; when active it fills with the brand color\n so the on/off state reads clearly at a glance (parallels the voice button's active state). */\n.plan-mode-button-icon--active:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.plan-mode-button-icon--active:not(:disabled):hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n color: var(--mj-text-inverse);\n}\n\n/* Same active treatment as Plan Mode \u2014 the two are peers in the strip, so a different one would\n read as a different KIND of control. Everything else comes from .attach-button-icon. */\n.skills-button-icon--active:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.skills-button-icon--active:not(:disabled):hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n color: var(--mj-text-inverse);\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n .message-input-box-container {\n border-radius: 10px;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 6%, transparent);\n }\n .message-input-box-textarea {\n min-height: 80px;\n padding: 0.75rem;\n padding-right: 3rem;\n font-size: 16px;\n line-height: 1.4;\n }\n .send-button-icon {\n width: 32px;\n height: 32px;\n bottom: 0.625rem;\n right: 0.625rem;\n border-radius: 6px;\n }\n .send-button-icon i {\n font-size: 0.875rem;\n }\n .attach-buttons {\n bottom: 0.625rem;\n right: 2.75rem;\n }\n .attach-button-icon {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon i {\n font-size: 0.875rem;\n }\n}\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .message-input-box-container {\n border-radius: 8px;\n border-width: 1.5px;\n }\n .message-input-box-textarea {\n min-height: 60px;\n padding: 0.625rem;\n padding-right: 2.75rem;\n font-size: 16px;\n line-height: 1.3;\n }\n .send-button-icon {\n width: 36px;\n height: 36px;\n bottom: 0.5rem;\n right: 0.5rem;\n border-radius: 6px;\n }\n .send-button-icon i {\n font-size: 0.875rem;\n }\n .attach-buttons {\n bottom: 0.5rem;\n right: 2.75rem;\n }\n .attach-button-icon {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon i {\n font-size: 0.875rem;\n }\n}\n\n/* Voice call button \u2014 a phone icon in the attach-buttons cluster, left of send.\n Inherits .attach-button-icon base. Subtle brand glow on hover; active state (call\n live) renders a brand-color tint. The orb visual now lives ONLY inside the call\n overlay's banner. */\n.voice-button-icon i {\n color: var(--mj-brand-primary);\n}\n.voice-button-icon:hover:not(:disabled) i {\n filter: drop-shadow(0 0 4px color-mix(in srgb, var(--mj-brand-primary) 55%, transparent));\n}\n.voice-button-icon:disabled i {\n color: var(--mj-text-disabled);\n}\n.voice-button-icon--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n}\n.voice-button-icon--active:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n/* Voice OPTIONS caret \u2014 a slim chevron hugging the phone button. Opens the agent/model\n picker; intentionally quieter (smaller icon, narrower hit area) than the phone so the\n common instant-start click stays the visual primary. */\n.voice-options-button-icon {\n width: 20px;\n margin-left: -4px;\n}\n.voice-options-button-icon i {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n}\n.voice-options-button-icon:hover:not(:disabled) i {\n color: var(--mj-brand-primary);\n}\n.voice-options-button-icon:disabled i {\n color: var(--mj-text-disabled);\n}\n"] }]
291
387
  }], null, { mentionEditor: [{
292
388
  type: ViewChild,
293
389
  args: ['mentionEditor']
294
- }], placeholder: [{
390
+ }], Placeholder: [{
295
391
  type: Input
296
- }], disabled: [{
392
+ }], Disabled: [{
297
393
  type: Input
298
- }], value: [{
394
+ }], Value: [{
299
395
  type: Input
300
- }], showCharacterCount: [{
396
+ }], ShowCharacterCount: [{
301
397
  type: Input
302
- }], enableMentions: [{
398
+ }], EnableMentions: [{
303
399
  type: Input
304
400
  }], TriggerProviders: [{
305
401
  type: Input
@@ -307,46 +403,52 @@ export class MessageInputBoxComponent {
307
403
  type: Input
308
404
  }], Provider: [{
309
405
  type: Input
310
- }], currentUser: [{
406
+ }], CurrentUser: [{
311
407
  type: Input
312
- }], rows: [{
408
+ }], Rows: [{
313
409
  type: Input
314
- }], enableAttachments: [{
410
+ }], EnableAttachments: [{
315
411
  type: Input
316
- }], maxAttachments: [{
412
+ }], MaxAttachments: [{
317
413
  type: Input
318
- }], maxAttachmentSizeBytes: [{
414
+ }], MaxAttachmentSizeBytes: [{
319
415
  type: Input
320
- }], acceptedFileTypes: [{
416
+ }], AcceptedFileTypes: [{
321
417
  type: Input
322
- }], enableRealtime: [{
418
+ }], EnableRealtime: [{
323
419
  type: Input
324
- }], voiceActive: [{
420
+ }], VoiceActive: [{
325
421
  type: Input
326
- }], canStartRealtime: [{
422
+ }], CanStartRealtime: [{
327
423
  type: Input
328
- }], enablePlanMode: [{
424
+ }], EnablePlanMode: [{
329
425
  type: Input
330
- }], planModeActive: [{
426
+ }], PlanModeActive: [{
331
427
  type: Input
332
- }], blurred: [{
428
+ }], EnableSkills: [{
429
+ type: Input
430
+ }], Blurred: [{
431
+ type: Output
432
+ }], TextSubmitted: [{
433
+ type: Output
434
+ }], ValueChange: [{
333
435
  type: Output
334
- }], textSubmitted: [{
436
+ }], AttachmentsChanged: [{
335
437
  type: Output
336
- }], valueChange: [{
438
+ }], AttachmentError: [{
337
439
  type: Output
338
- }], attachmentsChanged: [{
440
+ }], AttachmentClicked: [{
339
441
  type: Output
340
- }], attachmentError: [{
442
+ }], VoiceRequested: [{
341
443
  type: Output
342
- }], attachmentClicked: [{
444
+ }], VoiceOptionsRequested: [{
343
445
  type: Output
344
- }], voiceRequested: [{
446
+ }], PlanModeToggle: [{
345
447
  type: Output
346
- }], voiceOptionsRequested: [{
448
+ }], BeforeSkillsOpened: [{
347
449
  type: Output
348
- }], planModeToggle: [{
450
+ }], AfterSkillsOpened: [{
349
451
  type: Output
350
452
  }] }); })();
351
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MessageInputBoxComponent, { className: "MessageInputBoxComponent", filePath: "src/lib/components/message/message-input-box.component.ts", lineNumber: 27 }); })();
453
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MessageInputBoxComponent, { className: "MessageInputBoxComponent", filePath: "src/lib/components/message/message-input-box.component.ts", lineNumber: 28 }); })();
352
454
  //# sourceMappingURL=message-input-box.component.js.map