@hef2024/llmasaservice-ui 0.16.10 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -157,6 +157,34 @@ See our storybook documentation showing how to theme, size and use the variaous
157
157
 
158
158
  https://predictabilityatscale.github.io/llmasaservice-ui/?path=/docs/chatpanel--docs
159
159
 
160
+ ## Programmatic Conversation Starting (v0.17.0+)
161
+
162
+ Create conversations programmatically with auto-sent prompts using the imperative `startNewConversation` API:
163
+
164
+ ```typescript
165
+ import { useRef } from 'react';
166
+ import AIAgentPanel, { AIAgentPanelHandle } from '@hef2024/llmasaservice-ui';
167
+
168
+ const panelRef = useRef<AIAgentPanelHandle>(null);
169
+
170
+ // Quick action button that starts a conversation
171
+ <button onClick={() =>
172
+ panelRef.current?.startNewConversation('Give me a summary')
173
+ }>
174
+ Quick Summary
175
+ </button>
176
+
177
+ <AIAgentPanel ref={panelRef} agents={['agent-id']} customerId="user-123" />
178
+ ```
179
+
180
+ Perfect for quick actions, contextual help, onboarding flows, and more!
181
+
182
+ **📖 [Read Full Documentation](./docs/CONVERSATION-STARTING.md)** - Complete guide with examples and best practices.
183
+
184
+ ## Additional Documentation
185
+
186
+ - **[Conversation History Settings](./docs/CONVERSATION-HISTORY.md)** - Configure conversation history sidebar (show/hide, position, collapse)
187
+ - **[Full API Documentation](./local-dev-docs/AIAGENTPANEL.md)** - Complete props reference and advanced features
160
188
 
161
189
  ## License
162
190
  This project is licensed under the MIT License.
package/dist/index.d.mts CHANGED
@@ -170,6 +170,12 @@ interface AgentConfig {
170
170
  localName?: string;
171
171
  avatarUrl?: string;
172
172
  }
173
+ /**
174
+ * Imperative handle for programmatic control of AIAgentPanel
175
+ */
176
+ interface AIAgentPanelHandle {
177
+ startNewConversation: (prompt: string, agent?: string) => void;
178
+ }
173
179
  /**
174
180
  * Props for AIAgentPanel
175
181
  */
@@ -218,12 +224,15 @@ interface AIAgentPanelProps {
218
224
  clickCode?: string;
219
225
  style?: string;
220
226
  }[];
227
+ initialPrompt?: string;
228
+ initialMessage?: string;
229
+ hideInitialPrompt?: boolean;
221
230
  followOnQuestions?: string[];
222
231
  followOnPrompt?: string;
223
232
  historyListLimit?: number;
224
233
  showConversationHistory?: boolean;
225
234
  }
226
- declare const AIAgentPanel: React__default.FC<AIAgentPanelProps>;
235
+ declare const AIAgentPanel: React__default.ForwardRefExoticComponent<AIAgentPanelProps & React__default.RefAttributes<AIAgentPanelHandle>>;
227
236
 
228
237
  /**
229
238
  * AIChatPanel - A modern chat interface using shadcn-style components
package/dist/index.d.ts CHANGED
@@ -170,6 +170,12 @@ interface AgentConfig {
170
170
  localName?: string;
171
171
  avatarUrl?: string;
172
172
  }
173
+ /**
174
+ * Imperative handle for programmatic control of AIAgentPanel
175
+ */
176
+ interface AIAgentPanelHandle {
177
+ startNewConversation: (prompt: string, agent?: string) => void;
178
+ }
173
179
  /**
174
180
  * Props for AIAgentPanel
175
181
  */
@@ -218,12 +224,15 @@ interface AIAgentPanelProps {
218
224
  clickCode?: string;
219
225
  style?: string;
220
226
  }[];
227
+ initialPrompt?: string;
228
+ initialMessage?: string;
229
+ hideInitialPrompt?: boolean;
221
230
  followOnQuestions?: string[];
222
231
  followOnPrompt?: string;
223
232
  historyListLimit?: number;
224
233
  showConversationHistory?: boolean;
225
234
  }
226
- declare const AIAgentPanel: React__default.FC<AIAgentPanelProps>;
235
+ declare const AIAgentPanel: React__default.ForwardRefExoticComponent<AIAgentPanelProps & React__default.RefAttributes<AIAgentPanelHandle>>;
227
236
 
228
237
  /**
229
238
  * AIChatPanel - A modern chat interface using shadcn-style components
package/dist/index.js CHANGED
@@ -3669,6 +3669,7 @@ var AIChatPanel = ({
3669
3669
  const prevIdleRef = (0, import_react11.useRef)(true);
3670
3670
  const hasNotifiedCompletionRef = (0, import_react11.useRef)(true);
3671
3671
  const latestHistoryRef = (0, import_react11.useRef)(initialHistory);
3672
+ const initialPromptSentRef = (0, import_react11.useRef)(false);
3672
3673
  (0, import_react11.useEffect)(() => {
3673
3674
  if (!initialHistory) return;
3674
3675
  setHistory((prev) => {
@@ -3913,11 +3914,22 @@ var AIChatPanel = ({
3913
3914
  const promptToSend = promptText;
3914
3915
  if (!promptToSend || !promptToSend.trim()) return;
3915
3916
  setIsLoading(true);
3917
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
3918
+ const promptKey = `${timestamp}:${promptToSend.trim()}`;
3919
+ setHistory((prevHistory) => __spreadProps(__spreadValues({}, prevHistory), {
3920
+ [promptKey]: { content: "", callId: "" }
3921
+ }));
3922
+ setLastPrompt(promptToSend.trim());
3923
+ setLastKey(promptKey);
3924
+ setTimeout(() => {
3925
+ scrollToBottom();
3926
+ }, 0);
3916
3927
  console.log("AIChatPanel.continueChat - about to call ensureConversation");
3917
3928
  ensureConversation().then((convId) => {
3918
3929
  console.log("AIChatPanel.continueChat - ensureConversation resolved with:", convId);
3919
3930
  const messagesAndHistory = [];
3920
3931
  Object.entries(history).forEach(([historyPrompt, historyEntry]) => {
3932
+ if (historyPrompt === promptKey) return;
3921
3933
  let promptForHistory = historyPrompt;
3922
3934
  const isoTimestampRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z:/;
3923
3935
  if (isoTimestampRegex.test(historyPrompt)) {
@@ -3930,13 +3942,8 @@ var AIChatPanel = ({
3930
3942
  messagesAndHistory.push({ role: "user", content: promptForHistory });
3931
3943
  messagesAndHistory.push({ role: "assistant", content: historyEntry.content });
3932
3944
  });
3933
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
3934
- const promptKey = `${timestamp}:${promptToSend.trim()}`;
3935
- setHistory((prevHistory) => __spreadProps(__spreadValues({}, prevHistory), {
3936
- [promptKey]: { content: "", callId: "" }
3937
- }));
3938
3945
  let fullPromptToSend = promptToSend.trim();
3939
- if (Object.keys(history).length === 0 && promptTemplate) {
3946
+ if (messagesAndHistory.length === 0 && promptTemplate) {
3940
3947
  fullPromptToSend = promptTemplate.replace("{{prompt}}", fullPromptToSend);
3941
3948
  }
3942
3949
  if (followOnPrompt) {
@@ -3963,17 +3970,12 @@ ${followOnPrompt}`;
3963
3970
  // Use the conversation ID from ensureConversation
3964
3971
  newController
3965
3972
  );
3966
- setLastPrompt(promptToSend.trim());
3967
3973
  setLastMessages(messagesAndHistory);
3968
- setLastKey(promptKey);
3969
3974
  if (convId && onConversationCreated) {
3970
3975
  setTimeout(() => {
3971
3976
  onConversationCreated(convId);
3972
3977
  }, 100);
3973
3978
  }
3974
- setTimeout(() => {
3975
- scrollToBottom();
3976
- }, 0);
3977
3979
  });
3978
3980
  }, [
3979
3981
  idle,
@@ -4128,50 +4130,11 @@ ${followOnPrompt}`;
4128
4130
  };
4129
4131
  }, []);
4130
4132
  (0, import_react11.useEffect)(() => {
4131
- const hasLoadedHistory = initialHistory && Object.keys(initialHistory).length > 0;
4132
- if (!project_id) {
4133
- return;
4134
- }
4135
- if (initialPrompt && initialPrompt !== "" && initialPrompt !== lastPrompt && !hasLoadedHistory) {
4136
- setIsLoading(true);
4137
- setThinkingBlocks([]);
4138
- setCurrentThinkingIndex(0);
4139
- setUserHasScrolled(false);
4140
- ensureConversation().then((convId) => {
4141
- const controller = new AbortController();
4142
- setLastController(controller);
4143
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
4144
- const promptKey = `${timestamp}:${initialPrompt}`;
4145
- setHistory({ [promptKey]: { content: "", callId: "" } });
4146
- let fullPrompt = initialPrompt;
4147
- if (promptTemplate) {
4148
- fullPrompt = promptTemplate.replace("{{prompt}}", initialPrompt);
4149
- }
4150
- send(
4151
- fullPrompt,
4152
- [],
4153
- [
4154
- ...dataWithExtras(),
4155
- { key: "--messages", data: "0" }
4156
- ],
4157
- true,
4158
- true,
4159
- service,
4160
- convId,
4161
- // Use conversation ID from ensureConversation
4162
- controller
4163
- );
4164
- setLastPrompt(initialPrompt);
4165
- setLastMessages([]);
4166
- setLastKey(promptKey);
4167
- if (convId && onConversationCreated) {
4168
- setTimeout(() => {
4169
- onConversationCreated(convId);
4170
- }, 100);
4171
- }
4172
- });
4133
+ if (initialPrompt && initialPrompt !== "" && !initialPromptSentRef.current) {
4134
+ initialPromptSentRef.current = true;
4135
+ continueChat(initialPrompt);
4173
4136
  }
4174
- }, [initialPrompt, initialHistory, ensureConversation, promptTemplate, send, dataWithExtras, service, lastPrompt, project_id, onConversationCreated]);
4137
+ }, [initialPrompt, continueChat]);
4175
4138
  const CodeBlock = (0, import_react11.useCallback)((_a) => {
4176
4139
  var _b = _a, { node, inline, className, children } = _b, props = __objRest(_b, ["node", "inline", "className", "children"]);
4177
4140
  const match = /language-(\w+)/.exec(className || "");
@@ -4688,6 +4651,9 @@ var ChatPanelWrapper = ({
4688
4651
  effectiveCustomer,
4689
4652
  showPoweredBy,
4690
4653
  actions,
4654
+ initialPrompt,
4655
+ initialMessage,
4656
+ hideInitialPrompt,
4691
4657
  followOnQuestions,
4692
4658
  followOnPrompt,
4693
4659
  agentOptions,
@@ -4698,7 +4664,8 @@ var ChatPanelWrapper = ({
4698
4664
  totalContextTokens,
4699
4665
  maxContextTokens,
4700
4666
  enableContextDetailView,
4701
- onConversationCreated
4667
+ onConversationCreated,
4668
+ conversationInitialPrompt
4702
4669
  }) => {
4703
4670
  var _a, _b;
4704
4671
  const convAgentProfile = getAgent(activeConv.agentId);
@@ -4734,6 +4701,7 @@ var ChatPanelWrapper = ({
4734
4701
  const mcpServers = (0, import_react13.useMemo)(() => {
4735
4702
  return (convAgentProfile == null ? void 0 : convAgentProfile.mcpServers) || EMPTY_ARRAY;
4736
4703
  }, [convAgentProfile == null ? void 0 : convAgentProfile.mcpServers]);
4704
+ const effectiveInitialPrompt = conversationInitialPrompt || initialPrompt;
4737
4705
  if (!convAgentMetadata) return null;
4738
4706
  return /* @__PURE__ */ import_react13.default.createElement(
4739
4707
  "div",
@@ -4750,10 +4718,10 @@ var ChatPanelWrapper = ({
4750
4718
  title: "",
4751
4719
  theme,
4752
4720
  promptTemplate: convAgentMetadata.displayPromptTemplate || "{{prompt}}",
4753
- initialMessage: convAgentMetadata.displayStartMessageOrPrompt === "message" ? convAgentMetadata.displayInitialMessageOrPrompt : void 0,
4754
- initialPrompt: convAgentMetadata.displayStartMessageOrPrompt === "prompt" ? convAgentMetadata.displayInitialMessageOrPrompt : void 0,
4721
+ initialMessage: initialMessage || (convAgentMetadata.displayStartMessageOrPrompt === "message" ? convAgentMetadata.displayInitialMessageOrPrompt : void 0),
4722
+ initialPrompt: effectiveInitialPrompt || (convAgentMetadata.displayStartMessageOrPrompt === "prompt" ? convAgentMetadata.displayInitialMessageOrPrompt : void 0),
4755
4723
  placeholder: convAgentMetadata.displayPlaceholder || "Type a message...",
4756
- hideInitialPrompt: (_a = convAgentMetadata.displayHideInitialPrompt) != null ? _a : true,
4724
+ hideInitialPrompt: (_a = hideInitialPrompt != null ? hideInitialPrompt : convAgentMetadata.displayHideInitialPrompt) != null ? _a : true,
4757
4725
  data: chatPanelData,
4758
4726
  agent: activeConv.agentId,
4759
4727
  conversation: activeConv.conversationId.startsWith("new-") ? void 0 : activeConv.conversationId,
@@ -4787,7 +4755,7 @@ var ChatPanelWrapper = ({
4787
4755
  );
4788
4756
  };
4789
4757
  ChatPanelWrapper.displayName = "ChatPanelWrapper";
4790
- var AIAgentPanel = ({
4758
+ var AIAgentPanel = import_react13.default.forwardRef(({
4791
4759
  agents,
4792
4760
  defaultAgent,
4793
4761
  customerId,
@@ -4819,11 +4787,14 @@ var AIAgentPanel = ({
4819
4787
  showPoweredBy = true,
4820
4788
  conversation,
4821
4789
  actions = [],
4790
+ initialPrompt,
4791
+ initialMessage,
4792
+ hideInitialPrompt,
4822
4793
  followOnQuestions = [],
4823
4794
  followOnPrompt = "",
4824
4795
  historyListLimit = 50,
4825
4796
  showConversationHistory = true
4826
- }) => {
4797
+ }, ref) => {
4827
4798
  var _a, _b, _c, _d;
4828
4799
  const [isCollapsed, setIsCollapsed] = (0, import_react13.useState)(defaultCollapsed);
4829
4800
  const [isHistoryCollapsed, setIsHistoryCollapsed] = (0, import_react13.useState)(() => {
@@ -4905,6 +4876,29 @@ var AIAgentPanel = ({
4905
4876
  activeConversationsRef.current = activeConversations;
4906
4877
  const currentConversationIdRef = (0, import_react13.useRef)(currentConversationId);
4907
4878
  currentConversationIdRef.current = currentConversationId;
4879
+ import_react13.default.useImperativeHandle(ref, () => ({
4880
+ startNewConversation: (prompt, agent) => {
4881
+ const targetAgent = agent || currentAgentId;
4882
+ const tempId = `new-${Date.now()}`;
4883
+ setActiveConversations((prev) => {
4884
+ const next = new Map(prev);
4885
+ next.set(tempId, {
4886
+ conversationId: tempId,
4887
+ stableKey: tempId,
4888
+ agentId: targetAgent,
4889
+ history: {},
4890
+ isLoading: false,
4891
+ title: "New conversation",
4892
+ conversationInitialPrompt: prompt
4893
+ });
4894
+ return next;
4895
+ });
4896
+ setCurrentConversationId(tempId);
4897
+ if (onConversationChange) {
4898
+ onConversationChange(tempId);
4899
+ }
4900
+ }
4901
+ }), [currentAgentId, onConversationChange]);
4908
4902
  const [showContextNotification, setShowContextNotification] = (0, import_react13.useState)(false);
4909
4903
  const prevContextRef = (0, import_react13.useRef)(null);
4910
4904
  const contextNotificationTimeoutRef = (0, import_react13.useRef)(null);
@@ -5248,15 +5242,17 @@ var AIAgentPanel = ({
5248
5242
  let filtered = apiConversations;
5249
5243
  if (searchQuery) {
5250
5244
  const query = searchQuery.toLowerCase();
5251
- filtered = filtered.filter(
5252
- (conv) => {
5253
- var _a2, _b2;
5254
- return ((_a2 = conv.title) == null ? void 0 : _a2.toLowerCase().includes(query)) || ((_b2 = conv.summary) == null ? void 0 : _b2.toLowerCase().includes(query));
5255
- }
5256
- );
5245
+ filtered = filtered.filter((conv) => {
5246
+ var _a2, _b2;
5247
+ if ((_a2 = conv.title) == null ? void 0 : _a2.toLowerCase().includes(query)) return true;
5248
+ if ((_b2 = conv.summary) == null ? void 0 : _b2.toLowerCase().includes(query)) return true;
5249
+ const firstPrompt = conversationFirstPrompts[conv.conversationId];
5250
+ if (firstPrompt == null ? void 0 : firstPrompt.toLowerCase().includes(query)) return true;
5251
+ return false;
5252
+ });
5257
5253
  }
5258
5254
  return groupConversationsByTime(filtered, true);
5259
- }, [apiConversations, searchQuery]);
5255
+ }, [apiConversations, searchQuery, conversationFirstPrompts]);
5260
5256
  const effectiveCustomer = (0, import_react13.useMemo)(() => {
5261
5257
  return __spreadProps(__spreadValues({}, customer), {
5262
5258
  customer_id: customerId
@@ -5865,6 +5861,9 @@ var AIAgentPanel = ({
5865
5861
  effectiveCustomer,
5866
5862
  showPoweredBy,
5867
5863
  actions,
5864
+ initialPrompt,
5865
+ initialMessage,
5866
+ hideInitialPrompt,
5868
5867
  followOnQuestions,
5869
5868
  followOnPrompt,
5870
5869
  agentOptions,
@@ -5875,7 +5874,8 @@ var AIAgentPanel = ({
5875
5874
  totalContextTokens: mergedContext.totalTokens || 0,
5876
5875
  maxContextTokens,
5877
5876
  enableContextDetailView,
5878
- onConversationCreated: handleConversationCreated
5877
+ onConversationCreated: handleConversationCreated,
5878
+ conversationInitialPrompt: activeConv.conversationInitialPrompt
5879
5879
  }
5880
5880
  )), loadingConversationId && /* @__PURE__ */ import_react13.default.createElement("div", { className: "ai-agent-panel__conversation-loading-overlay" }, /* @__PURE__ */ import_react13.default.createElement("div", { className: "ai-agent-panel__loading-spinner" }), /* @__PURE__ */ import_react13.default.createElement("p", null, "Loading conversation...")), currentAgentMetadata && activeConversationsList.length === 0 && !loadingConversationId && /* @__PURE__ */ import_react13.default.createElement("div", { className: "ai-agent-panel__empty-chat" }, /* @__PURE__ */ import_react13.default.createElement(MessageIcon, null), /* @__PURE__ */ import_react13.default.createElement("p", null, "Select a conversation or start a new one"), /* @__PURE__ */ import_react13.default.createElement(Button, { variant: "default", size: "sm", onClick: handleNewConversation }, "New Conversation")), agentsLoading && !currentAgentMetadata && /* @__PURE__ */ import_react13.default.createElement("div", { className: "ai-agent-panel__loading" }, /* @__PURE__ */ import_react13.default.createElement("div", { className: "ai-agent-panel__loading-spinner" }), /* @__PURE__ */ import_react13.default.createElement("p", null, "Loading agent..."))),
5881
5881
  /* @__PURE__ */ import_react13.default.createElement(
@@ -5889,7 +5889,8 @@ var AIAgentPanel = ({
5889
5889
  /* @__PURE__ */ import_react13.default.createElement(DialogFooter, null, /* @__PURE__ */ import_react13.default.createElement(Button, { variant: "outline", onClick: handleHandoffCancel }, "Stay with current agent"), /* @__PURE__ */ import_react13.default.createElement(Button, { onClick: handleHandoffConfirm }, "Switch agent"))
5890
5890
  )
5891
5891
  );
5892
- };
5892
+ });
5893
+ AIAgentPanel.displayName = "AIAgentPanel";
5893
5894
  var AIAgentPanel_default = AIAgentPanel;
5894
5895
 
5895
5896
  // src/hooks/useConversationStore.ts
package/dist/index.mjs CHANGED
@@ -3636,6 +3636,7 @@ var AIChatPanel = ({
3636
3636
  const prevIdleRef = useRef5(true);
3637
3637
  const hasNotifiedCompletionRef = useRef5(true);
3638
3638
  const latestHistoryRef = useRef5(initialHistory);
3639
+ const initialPromptSentRef = useRef5(false);
3639
3640
  useEffect7(() => {
3640
3641
  if (!initialHistory) return;
3641
3642
  setHistory((prev) => {
@@ -3880,11 +3881,22 @@ var AIChatPanel = ({
3880
3881
  const promptToSend = promptText;
3881
3882
  if (!promptToSend || !promptToSend.trim()) return;
3882
3883
  setIsLoading(true);
3884
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
3885
+ const promptKey = `${timestamp}:${promptToSend.trim()}`;
3886
+ setHistory((prevHistory) => __spreadProps(__spreadValues({}, prevHistory), {
3887
+ [promptKey]: { content: "", callId: "" }
3888
+ }));
3889
+ setLastPrompt(promptToSend.trim());
3890
+ setLastKey(promptKey);
3891
+ setTimeout(() => {
3892
+ scrollToBottom();
3893
+ }, 0);
3883
3894
  console.log("AIChatPanel.continueChat - about to call ensureConversation");
3884
3895
  ensureConversation().then((convId) => {
3885
3896
  console.log("AIChatPanel.continueChat - ensureConversation resolved with:", convId);
3886
3897
  const messagesAndHistory = [];
3887
3898
  Object.entries(history).forEach(([historyPrompt, historyEntry]) => {
3899
+ if (historyPrompt === promptKey) return;
3888
3900
  let promptForHistory = historyPrompt;
3889
3901
  const isoTimestampRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z:/;
3890
3902
  if (isoTimestampRegex.test(historyPrompt)) {
@@ -3897,13 +3909,8 @@ var AIChatPanel = ({
3897
3909
  messagesAndHistory.push({ role: "user", content: promptForHistory });
3898
3910
  messagesAndHistory.push({ role: "assistant", content: historyEntry.content });
3899
3911
  });
3900
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
3901
- const promptKey = `${timestamp}:${promptToSend.trim()}`;
3902
- setHistory((prevHistory) => __spreadProps(__spreadValues({}, prevHistory), {
3903
- [promptKey]: { content: "", callId: "" }
3904
- }));
3905
3912
  let fullPromptToSend = promptToSend.trim();
3906
- if (Object.keys(history).length === 0 && promptTemplate) {
3913
+ if (messagesAndHistory.length === 0 && promptTemplate) {
3907
3914
  fullPromptToSend = promptTemplate.replace("{{prompt}}", fullPromptToSend);
3908
3915
  }
3909
3916
  if (followOnPrompt) {
@@ -3930,17 +3937,12 @@ ${followOnPrompt}`;
3930
3937
  // Use the conversation ID from ensureConversation
3931
3938
  newController
3932
3939
  );
3933
- setLastPrompt(promptToSend.trim());
3934
3940
  setLastMessages(messagesAndHistory);
3935
- setLastKey(promptKey);
3936
3941
  if (convId && onConversationCreated) {
3937
3942
  setTimeout(() => {
3938
3943
  onConversationCreated(convId);
3939
3944
  }, 100);
3940
3945
  }
3941
- setTimeout(() => {
3942
- scrollToBottom();
3943
- }, 0);
3944
3946
  });
3945
3947
  }, [
3946
3948
  idle,
@@ -4095,50 +4097,11 @@ ${followOnPrompt}`;
4095
4097
  };
4096
4098
  }, []);
4097
4099
  useEffect7(() => {
4098
- const hasLoadedHistory = initialHistory && Object.keys(initialHistory).length > 0;
4099
- if (!project_id) {
4100
- return;
4101
- }
4102
- if (initialPrompt && initialPrompt !== "" && initialPrompt !== lastPrompt && !hasLoadedHistory) {
4103
- setIsLoading(true);
4104
- setThinkingBlocks([]);
4105
- setCurrentThinkingIndex(0);
4106
- setUserHasScrolled(false);
4107
- ensureConversation().then((convId) => {
4108
- const controller = new AbortController();
4109
- setLastController(controller);
4110
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
4111
- const promptKey = `${timestamp}:${initialPrompt}`;
4112
- setHistory({ [promptKey]: { content: "", callId: "" } });
4113
- let fullPrompt = initialPrompt;
4114
- if (promptTemplate) {
4115
- fullPrompt = promptTemplate.replace("{{prompt}}", initialPrompt);
4116
- }
4117
- send(
4118
- fullPrompt,
4119
- [],
4120
- [
4121
- ...dataWithExtras(),
4122
- { key: "--messages", data: "0" }
4123
- ],
4124
- true,
4125
- true,
4126
- service,
4127
- convId,
4128
- // Use conversation ID from ensureConversation
4129
- controller
4130
- );
4131
- setLastPrompt(initialPrompt);
4132
- setLastMessages([]);
4133
- setLastKey(promptKey);
4134
- if (convId && onConversationCreated) {
4135
- setTimeout(() => {
4136
- onConversationCreated(convId);
4137
- }, 100);
4138
- }
4139
- });
4100
+ if (initialPrompt && initialPrompt !== "" && !initialPromptSentRef.current) {
4101
+ initialPromptSentRef.current = true;
4102
+ continueChat(initialPrompt);
4140
4103
  }
4141
- }, [initialPrompt, initialHistory, ensureConversation, promptTemplate, send, dataWithExtras, service, lastPrompt, project_id, onConversationCreated]);
4104
+ }, [initialPrompt, continueChat]);
4142
4105
  const CodeBlock = useCallback2((_a) => {
4143
4106
  var _b = _a, { node, inline, className, children } = _b, props = __objRest(_b, ["node", "inline", "className", "children"]);
4144
4107
  const match = /language-(\w+)/.exec(className || "");
@@ -4655,6 +4618,9 @@ var ChatPanelWrapper = ({
4655
4618
  effectiveCustomer,
4656
4619
  showPoweredBy,
4657
4620
  actions,
4621
+ initialPrompt,
4622
+ initialMessage,
4623
+ hideInitialPrompt,
4658
4624
  followOnQuestions,
4659
4625
  followOnPrompt,
4660
4626
  agentOptions,
@@ -4665,7 +4631,8 @@ var ChatPanelWrapper = ({
4665
4631
  totalContextTokens,
4666
4632
  maxContextTokens,
4667
4633
  enableContextDetailView,
4668
- onConversationCreated
4634
+ onConversationCreated,
4635
+ conversationInitialPrompt
4669
4636
  }) => {
4670
4637
  var _a, _b;
4671
4638
  const convAgentProfile = getAgent(activeConv.agentId);
@@ -4701,6 +4668,7 @@ var ChatPanelWrapper = ({
4701
4668
  const mcpServers = useMemo4(() => {
4702
4669
  return (convAgentProfile == null ? void 0 : convAgentProfile.mcpServers) || EMPTY_ARRAY;
4703
4670
  }, [convAgentProfile == null ? void 0 : convAgentProfile.mcpServers]);
4671
+ const effectiveInitialPrompt = conversationInitialPrompt || initialPrompt;
4704
4672
  if (!convAgentMetadata) return null;
4705
4673
  return /* @__PURE__ */ React12.createElement(
4706
4674
  "div",
@@ -4717,10 +4685,10 @@ var ChatPanelWrapper = ({
4717
4685
  title: "",
4718
4686
  theme,
4719
4687
  promptTemplate: convAgentMetadata.displayPromptTemplate || "{{prompt}}",
4720
- initialMessage: convAgentMetadata.displayStartMessageOrPrompt === "message" ? convAgentMetadata.displayInitialMessageOrPrompt : void 0,
4721
- initialPrompt: convAgentMetadata.displayStartMessageOrPrompt === "prompt" ? convAgentMetadata.displayInitialMessageOrPrompt : void 0,
4688
+ initialMessage: initialMessage || (convAgentMetadata.displayStartMessageOrPrompt === "message" ? convAgentMetadata.displayInitialMessageOrPrompt : void 0),
4689
+ initialPrompt: effectiveInitialPrompt || (convAgentMetadata.displayStartMessageOrPrompt === "prompt" ? convAgentMetadata.displayInitialMessageOrPrompt : void 0),
4722
4690
  placeholder: convAgentMetadata.displayPlaceholder || "Type a message...",
4723
- hideInitialPrompt: (_a = convAgentMetadata.displayHideInitialPrompt) != null ? _a : true,
4691
+ hideInitialPrompt: (_a = hideInitialPrompt != null ? hideInitialPrompt : convAgentMetadata.displayHideInitialPrompt) != null ? _a : true,
4724
4692
  data: chatPanelData,
4725
4693
  agent: activeConv.agentId,
4726
4694
  conversation: activeConv.conversationId.startsWith("new-") ? void 0 : activeConv.conversationId,
@@ -4754,7 +4722,7 @@ var ChatPanelWrapper = ({
4754
4722
  );
4755
4723
  };
4756
4724
  ChatPanelWrapper.displayName = "ChatPanelWrapper";
4757
- var AIAgentPanel = ({
4725
+ var AIAgentPanel = React12.forwardRef(({
4758
4726
  agents,
4759
4727
  defaultAgent,
4760
4728
  customerId,
@@ -4786,11 +4754,14 @@ var AIAgentPanel = ({
4786
4754
  showPoweredBy = true,
4787
4755
  conversation,
4788
4756
  actions = [],
4757
+ initialPrompt,
4758
+ initialMessage,
4759
+ hideInitialPrompt,
4789
4760
  followOnQuestions = [],
4790
4761
  followOnPrompt = "",
4791
4762
  historyListLimit = 50,
4792
4763
  showConversationHistory = true
4793
- }) => {
4764
+ }, ref) => {
4794
4765
  var _a, _b, _c, _d;
4795
4766
  const [isCollapsed, setIsCollapsed] = useState8(defaultCollapsed);
4796
4767
  const [isHistoryCollapsed, setIsHistoryCollapsed] = useState8(() => {
@@ -4872,6 +4843,29 @@ var AIAgentPanel = ({
4872
4843
  activeConversationsRef.current = activeConversations;
4873
4844
  const currentConversationIdRef = useRef6(currentConversationId);
4874
4845
  currentConversationIdRef.current = currentConversationId;
4846
+ React12.useImperativeHandle(ref, () => ({
4847
+ startNewConversation: (prompt, agent) => {
4848
+ const targetAgent = agent || currentAgentId;
4849
+ const tempId = `new-${Date.now()}`;
4850
+ setActiveConversations((prev) => {
4851
+ const next = new Map(prev);
4852
+ next.set(tempId, {
4853
+ conversationId: tempId,
4854
+ stableKey: tempId,
4855
+ agentId: targetAgent,
4856
+ history: {},
4857
+ isLoading: false,
4858
+ title: "New conversation",
4859
+ conversationInitialPrompt: prompt
4860
+ });
4861
+ return next;
4862
+ });
4863
+ setCurrentConversationId(tempId);
4864
+ if (onConversationChange) {
4865
+ onConversationChange(tempId);
4866
+ }
4867
+ }
4868
+ }), [currentAgentId, onConversationChange]);
4875
4869
  const [showContextNotification, setShowContextNotification] = useState8(false);
4876
4870
  const prevContextRef = useRef6(null);
4877
4871
  const contextNotificationTimeoutRef = useRef6(null);
@@ -5215,15 +5209,17 @@ var AIAgentPanel = ({
5215
5209
  let filtered = apiConversations;
5216
5210
  if (searchQuery) {
5217
5211
  const query = searchQuery.toLowerCase();
5218
- filtered = filtered.filter(
5219
- (conv) => {
5220
- var _a2, _b2;
5221
- return ((_a2 = conv.title) == null ? void 0 : _a2.toLowerCase().includes(query)) || ((_b2 = conv.summary) == null ? void 0 : _b2.toLowerCase().includes(query));
5222
- }
5223
- );
5212
+ filtered = filtered.filter((conv) => {
5213
+ var _a2, _b2;
5214
+ if ((_a2 = conv.title) == null ? void 0 : _a2.toLowerCase().includes(query)) return true;
5215
+ if ((_b2 = conv.summary) == null ? void 0 : _b2.toLowerCase().includes(query)) return true;
5216
+ const firstPrompt = conversationFirstPrompts[conv.conversationId];
5217
+ if (firstPrompt == null ? void 0 : firstPrompt.toLowerCase().includes(query)) return true;
5218
+ return false;
5219
+ });
5224
5220
  }
5225
5221
  return groupConversationsByTime(filtered, true);
5226
- }, [apiConversations, searchQuery]);
5222
+ }, [apiConversations, searchQuery, conversationFirstPrompts]);
5227
5223
  const effectiveCustomer = useMemo4(() => {
5228
5224
  return __spreadProps(__spreadValues({}, customer), {
5229
5225
  customer_id: customerId
@@ -5832,6 +5828,9 @@ var AIAgentPanel = ({
5832
5828
  effectiveCustomer,
5833
5829
  showPoweredBy,
5834
5830
  actions,
5831
+ initialPrompt,
5832
+ initialMessage,
5833
+ hideInitialPrompt,
5835
5834
  followOnQuestions,
5836
5835
  followOnPrompt,
5837
5836
  agentOptions,
@@ -5842,7 +5841,8 @@ var AIAgentPanel = ({
5842
5841
  totalContextTokens: mergedContext.totalTokens || 0,
5843
5842
  maxContextTokens,
5844
5843
  enableContextDetailView,
5845
- onConversationCreated: handleConversationCreated
5844
+ onConversationCreated: handleConversationCreated,
5845
+ conversationInitialPrompt: activeConv.conversationInitialPrompt
5846
5846
  }
5847
5847
  )), loadingConversationId && /* @__PURE__ */ React12.createElement("div", { className: "ai-agent-panel__conversation-loading-overlay" }, /* @__PURE__ */ React12.createElement("div", { className: "ai-agent-panel__loading-spinner" }), /* @__PURE__ */ React12.createElement("p", null, "Loading conversation...")), currentAgentMetadata && activeConversationsList.length === 0 && !loadingConversationId && /* @__PURE__ */ React12.createElement("div", { className: "ai-agent-panel__empty-chat" }, /* @__PURE__ */ React12.createElement(MessageIcon, null), /* @__PURE__ */ React12.createElement("p", null, "Select a conversation or start a new one"), /* @__PURE__ */ React12.createElement(Button, { variant: "default", size: "sm", onClick: handleNewConversation }, "New Conversation")), agentsLoading && !currentAgentMetadata && /* @__PURE__ */ React12.createElement("div", { className: "ai-agent-panel__loading" }, /* @__PURE__ */ React12.createElement("div", { className: "ai-agent-panel__loading-spinner" }), /* @__PURE__ */ React12.createElement("p", null, "Loading agent..."))),
5848
5848
  /* @__PURE__ */ React12.createElement(
@@ -5856,7 +5856,8 @@ var AIAgentPanel = ({
5856
5856
  /* @__PURE__ */ React12.createElement(DialogFooter, null, /* @__PURE__ */ React12.createElement(Button, { variant: "outline", onClick: handleHandoffCancel }, "Stay with current agent"), /* @__PURE__ */ React12.createElement(Button, { onClick: handleHandoffConfirm }, "Switch agent"))
5857
5857
  )
5858
5858
  );
5859
- };
5859
+ });
5860
+ AIAgentPanel.displayName = "AIAgentPanel";
5860
5861
  var AIAgentPanel_default = AIAgentPanel;
5861
5862
 
5862
5863
  // src/hooks/useConversationStore.ts