@xinghunm/ai-chat 1.2.2 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  // src/components/ai-chat/index.tsx
2
+ import { useEffect as useEffect9 } from "react";
2
3
  import styled17 from "@emotion/styled";
3
4
  import { ConfigProvider } from "@xinghunm/compass-ui";
4
5
 
@@ -47,6 +48,9 @@ var DEFAULT_AI_CHAT_LABELS = {
47
48
  questionnaireMultiSelectHint: "Multiple choice",
48
49
  questionnaireOtherOptionLabel: "Other",
49
50
  questionnaireOtherPlaceholder: "Other",
51
+ modelLoading: "Loading models...",
52
+ modelLoadFailed: "Failed to load models",
53
+ modelUnavailable: "No model available",
50
54
  skillLoading: "Loading skills...",
51
55
  skillEmpty: "No matching skills",
52
56
  removeSkillAriaLabel: "Remove skill"
@@ -82,6 +86,9 @@ var resolveSessionTitleFromMessage = (message) => {
82
86
  if (trimmedContent) {
83
87
  return trimmedContent.slice(0, 30);
84
88
  }
89
+ if (message.skills?.length) {
90
+ return message.skills.join(", ").slice(0, 30);
91
+ }
85
92
  if ((message.attachments?.length ?? 0) > 0) {
86
93
  return IMAGE_MESSAGE_SESSION_TITLE;
87
94
  }
@@ -627,7 +634,7 @@ var createDefaultRequestBody = async ({
627
634
  attachments
628
635
  }) => {
629
636
  const hasAttachments = Boolean(attachments?.length);
630
- const skillPayload = skills?.length ? { skill: skills.length === 1 ? skills[0] : skills } : {};
637
+ const skillPayload = skills?.length ? { skills } : {};
631
638
  if (!hasAttachments) {
632
639
  return {
633
640
  model,
@@ -2823,7 +2830,7 @@ var areMessageBlocksEqual = (previousBlocks, nextBlocks) => {
2823
2830
  }
2824
2831
  });
2825
2832
  };
2826
- var isSameMessage = (previousMessage, nextMessage, previousMode, nextMode, previousConfirmationSubmit, nextConfirmationSubmit, previousQuestionnaireSubmit, nextQuestionnaireSubmit, previousRenderMessageBlock, nextRenderMessageBlock) => previousMessage.id === nextMessage.id && previousMessage.sessionId === nextMessage.sessionId && previousMessage.role === nextMessage.role && previousMessage.content === nextMessage.content && areMessageBlocksEqual(previousMessage.blocks, nextMessage.blocks) && previousMessage.localOnly === nextMessage.localOnly && areChatAttachmentsEqual(previousMessage.attachments, nextMessage.attachments) && previousMessage.status === nextMessage.status && previousMessage.createdAt === nextMessage.createdAt && previousMode === nextMode && previousConfirmationSubmit === nextConfirmationSubmit && previousQuestionnaireSubmit === nextQuestionnaireSubmit && previousRenderMessageBlock === nextRenderMessageBlock;
2833
+ var isSameMessage = (previousMessage, nextMessage, previousMode, nextMode, previousConfirmationSubmit, nextConfirmationSubmit, previousQuestionnaireSubmit, nextQuestionnaireSubmit, previousRenderMessageBlock, nextRenderMessageBlock) => previousMessage.id === nextMessage.id && previousMessage.sessionId === nextMessage.sessionId && previousMessage.role === nextMessage.role && previousMessage.content === nextMessage.content && areStringArraysEqual(previousMessage.skills ?? [], nextMessage.skills ?? []) && areMessageBlocksEqual(previousMessage.blocks, nextMessage.blocks) && previousMessage.localOnly === nextMessage.localOnly && areChatAttachmentsEqual(previousMessage.attachments, nextMessage.attachments) && previousMessage.status === nextMessage.status && previousMessage.createdAt === nextMessage.createdAt && previousMode === nextMode && previousConfirmationSubmit === nextConfirmationSubmit && previousQuestionnaireSubmit === nextQuestionnaireSubmit && previousRenderMessageBlock === nextRenderMessageBlock;
2827
2834
  var ChatMessageItemView = ({
2828
2835
  message,
2829
2836
  mode = "agent",
@@ -2843,6 +2850,7 @@ var ChatMessageItemView = ({
2843
2850
  } = useChatMessageReveal(message);
2844
2851
  const isStoppedAssistant = message.role === "assistant" && message.status === "stopped";
2845
2852
  const attachments = message.attachments ?? [];
2853
+ const skills = message.skills ?? [];
2846
2854
  const blocks = message.blocks ?? [];
2847
2855
  const hasStructuredBlocks = blocks.length > 0;
2848
2856
  const hasMarkdownOnlyBlocks = hasStructuredBlocks && blocks.every((block) => block.type === "markdown");
@@ -2884,6 +2892,7 @@ var ChatMessageItemView = ({
2884
2892
  freshContent,
2885
2893
  settledContent
2886
2894
  });
2895
+ const shouldRenderHeader = isAssistantStreaming || isUserMessageCollapsible || isStoppedAssistant;
2887
2896
  const renderMessageContent = (content) => messageRenderMode === "plain-text" ? renderPlainTextContent(content) : renderMarkdownContent(content);
2888
2897
  const renderChatMessageBlock = (block, index3) => {
2889
2898
  switch (block.type) {
@@ -3033,7 +3042,7 @@ var ChatMessageItemView = ({
3033
3042
  })();
3034
3043
  return /* @__PURE__ */ jsxs5(Fragment2, { children: [
3035
3044
  /* @__PURE__ */ jsxs5(Bubble, { "data-role": message.role, "data-status": message.status ?? "done", children: [
3036
- /* @__PURE__ */ jsxs5(Header2, { children: [
3045
+ shouldRenderHeader ? /* @__PURE__ */ jsxs5(Header2, { children: [
3037
3046
  isAssistantStreaming ? /* @__PURE__ */ jsxs5(
3038
3047
  StreamingIndicator,
3039
3048
  {
@@ -3045,7 +3054,6 @@ var ChatMessageItemView = ({
3045
3054
  ]
3046
3055
  }
3047
3056
  ) : null,
3048
- /* @__PURE__ */ jsx8(Role, { children: message.role === "user" ? labels.userRoleLabel : labels.assistantRoleLabel }),
3049
3057
  isUserMessageCollapsible ? /* @__PURE__ */ jsx8(
3050
3058
  CollapseToggle,
3051
3059
  {
@@ -3058,8 +3066,9 @@ var ChatMessageItemView = ({
3058
3066
  }
3059
3067
  ) : null,
3060
3068
  isStoppedAssistant ? /* @__PURE__ */ jsx8(StatusTag, { "data-testid": "chat-message-stopped-tag", children: labels.stoppedResponse }) : null
3061
- ] }),
3069
+ ] }) : null,
3062
3070
  /* @__PURE__ */ jsxs5(Content, { "data-testid": "chat-message-content", children: [
3071
+ skills.length ? /* @__PURE__ */ jsx8(SkillTagList, { "data-testid": "chat-message-skill-tags", children: skills.map((skill) => /* @__PURE__ */ jsx8(SkillTag, { children: skill }, skill)) }) : null,
3063
3072
  shouldRenderStructuredBlocks || hasTextContent ? /* @__PURE__ */ jsx8(
3064
3073
  ContentStack,
3065
3074
  {
@@ -3124,19 +3133,22 @@ var ChatMessageItem = memo(
3124
3133
  var Bubble = styled7.article`
3125
3134
  width: 100%;
3126
3135
  max-width: 100%;
3127
- padding: 14px 16px;
3128
- border-radius: 22px;
3129
- background: rgba(255, 255, 255, 0.04);
3130
- border: 1px solid rgba(255, 255, 255, 0.07);
3131
- box-shadow:
3132
- inset 0 1px 0 rgba(255, 255, 255, 0.03),
3133
- 0 12px 30px rgba(0, 0, 0, 0.18);
3136
+ padding: 0;
3137
+ background: transparent;
3138
+ border: none;
3139
+ box-shadow: none;
3134
3140
 
3135
3141
  &[data-role='user'] {
3136
3142
  width: auto;
3137
3143
  max-width: min(760px, 100%);
3138
3144
  margin-left: auto;
3145
+ padding: 14px 16px;
3146
+ border-radius: 22px;
3139
3147
  background: linear-gradient(180deg, rgba(59, 59, 63, 0.9) 0%, rgba(42, 43, 46, 0.92) 100%);
3148
+ border: 1px solid rgba(255, 255, 255, 0.07);
3149
+ box-shadow:
3150
+ inset 0 1px 0 rgba(255, 255, 255, 0.03),
3151
+ 0 12px 30px rgba(0, 0, 0, 0.18);
3140
3152
  }
3141
3153
  `;
3142
3154
  var Header2 = styled7.div`
@@ -3145,12 +3157,6 @@ var Header2 = styled7.div`
3145
3157
  gap: 10px;
3146
3158
  margin-bottom: 10px;
3147
3159
  `;
3148
- var Role = styled7.div`
3149
- font-size: 12px;
3150
- color: rgba(255, 255, 255, 0.42);
3151
- text-transform: capitalize;
3152
- letter-spacing: 0.08em;
3153
- `;
3154
3160
  var StatusTag = styled7.span`
3155
3161
  display: inline-flex;
3156
3162
  align-items: center;
@@ -3257,6 +3263,23 @@ var Content = styled7.div`
3257
3263
  margin: 0 0 8px;
3258
3264
  }
3259
3265
  `;
3266
+ var SkillTagList = styled7.div`
3267
+ display: flex;
3268
+ flex-wrap: wrap;
3269
+ gap: 8px;
3270
+ margin-bottom: 12px;
3271
+ `;
3272
+ var SkillTag = styled7.span`
3273
+ display: inline-flex;
3274
+ align-items: center;
3275
+ max-width: 100%;
3276
+ padding: 10px 18px;
3277
+ border-radius: 999px;
3278
+ background: rgba(65, 65, 63, 0.6);
3279
+ color: #c5c1ba;
3280
+ font-size: 14px;
3281
+ line-height: 1;
3282
+ `;
3260
3283
  var ContentStack = styled7.div`
3261
3284
  display: flex;
3262
3285
  flex-direction: column;
@@ -6515,6 +6538,7 @@ function useFloating2(options) {
6515
6538
  var createUserMessage = ({
6516
6539
  sessionId,
6517
6540
  content,
6541
+ skills,
6518
6542
  attachments,
6519
6543
  localOnly,
6520
6544
  createdAt,
@@ -6524,6 +6548,7 @@ var createUserMessage = ({
6524
6548
  sessionId,
6525
6549
  role: "user",
6526
6550
  content,
6551
+ skills,
6527
6552
  attachments,
6528
6553
  localOnly,
6529
6554
  createdAt
@@ -6543,16 +6568,20 @@ var createAssistantStreamingMessage = ({
6543
6568
  var canSendChatMessage = ({
6544
6569
  value,
6545
6570
  attachmentCount = 0,
6571
+ skillCount = 0,
6546
6572
  isModelsLoading,
6547
6573
  isModelsError,
6548
6574
  hasModels
6549
6575
  }) => {
6550
6576
  const hasText = Boolean(value.trim());
6551
6577
  const hasAttachments = attachmentCount > 0;
6552
- if (!hasText && !hasAttachments)
6578
+ const hasSkills = skillCount > 0;
6579
+ if (!hasText && !hasAttachments && !hasSkills)
6553
6580
  return false;
6554
6581
  if (!hasText && hasAttachments)
6555
6582
  return true;
6583
+ if (!hasText && !hasAttachments && hasSkills)
6584
+ return !isModelsLoading && !isModelsError && hasModels;
6556
6585
  return !isModelsLoading && !isModelsError && hasModels;
6557
6586
  };
6558
6587
  var shouldSubmitChatComposer = ({
@@ -6848,6 +6877,7 @@ var useChatComposer = () => {
6848
6877
  const abortControllerBySessionRef = useRef10(/* @__PURE__ */ new Map());
6849
6878
  const stopRequestBySessionRef = useRef10(/* @__PURE__ */ new Map());
6850
6879
  const lastRequestBySessionRef = useRef10(/* @__PURE__ */ new Map());
6880
+ const previousActiveSessionIdRef = useRef10(activeSessionId);
6851
6881
  useEffect7(() => {
6852
6882
  setSelectedModel(
6853
6883
  (current) => resolveSelectedChatModel({ currentModel: current, availableModels, isModelsLoading })
@@ -6860,6 +6890,12 @@ var useChatComposer = () => {
6860
6890
  }
6861
6891
  setSelectedModeLocal(preferredMode ?? DEFAULT_CHAT_AGENT_MODE);
6862
6892
  }, [activeSession, preferredMode]);
6893
+ useEffect7(() => {
6894
+ if (previousActiveSessionIdRef.current !== activeSessionId) {
6895
+ setSelectedSkills([]);
6896
+ previousActiveSessionIdRef.current = activeSessionId;
6897
+ }
6898
+ }, [activeSessionId]);
6863
6899
  useEffect7(() => {
6864
6900
  if (!attachmentNotice)
6865
6901
  return;
@@ -7051,6 +7087,7 @@ var useChatComposer = () => {
7051
7087
  if (!canSendChatMessage({
7052
7088
  value: content,
7053
7089
  attachmentCount: composerAttachmentCount,
7090
+ skillCount: messageSkills?.length ?? 0,
7054
7091
  isModelsLoading,
7055
7092
  isModelsError,
7056
7093
  hasModels
@@ -7078,6 +7115,7 @@ var useChatComposer = () => {
7078
7115
  const userMessage = createUserMessage({
7079
7116
  sessionId: localSessionId,
7080
7117
  content,
7118
+ skills: messageSkills,
7081
7119
  attachments: messageAttachments,
7082
7120
  localOnly: false,
7083
7121
  createdAt: nowIso(),
@@ -7120,6 +7158,19 @@ var useChatComposer = () => {
7120
7158
  store
7121
7159
  ]
7122
7160
  );
7161
+ const openSkillPicker = useCallback7(() => {
7162
+ setValue((current) => {
7163
+ const matchedSkillQuery = current.match(/(^|\s)\/([^\s/]*)$/);
7164
+ if (matchedSkillQuery && matchedSkillQuery.index !== void 0) {
7165
+ const queryStart = matchedSkillQuery.index + matchedSkillQuery[1].length;
7166
+ return current.slice(0, queryStart).replace(/\s+$/, "");
7167
+ }
7168
+ if (!current.trim()) {
7169
+ return "/";
7170
+ }
7171
+ return /\s$/.test(current) ? `${current}/` : `${current} /`;
7172
+ });
7173
+ }, []);
7123
7174
  const stopSession = useCallback7(
7124
7175
  async (sessionId) => {
7125
7176
  const storeState = store.getState();
@@ -7194,6 +7245,7 @@ var useChatComposer = () => {
7194
7245
  removeSkill: (skill) => {
7195
7246
  setSelectedSkills((current) => current.filter((item) => item !== skill));
7196
7247
  },
7248
+ openSkillPicker,
7197
7249
  setSelectedModel,
7198
7250
  setSelectedMode: (mode) => {
7199
7251
  setSelectedModeLocal(mode);
@@ -7388,12 +7440,42 @@ var CloseGlyph = styled10.span`
7388
7440
  import styled11 from "@emotion/styled";
7389
7441
  import { Select } from "@xinghunm/compass-ui";
7390
7442
  import { jsx as jsx13, jsxs as jsxs10 } from "@emotion/react/jsx-runtime";
7443
+ var ModelIcon = () => /* @__PURE__ */ jsx13(
7444
+ "svg",
7445
+ {
7446
+ "aria-hidden": "true",
7447
+ width: "14",
7448
+ height: "14",
7449
+ viewBox: "0 0 14 14",
7450
+ fill: "none",
7451
+ style: { display: "block" },
7452
+ xmlns: "http://www.w3.org/2000/svg",
7453
+ children: /* @__PURE__ */ jsxs10(
7454
+ "g",
7455
+ {
7456
+ transform: "translate(1.6545 1.0182)",
7457
+ stroke: "currentColor",
7458
+ strokeLinecap: "round",
7459
+ strokeLinejoin: "round",
7460
+ strokeWidth: "1.22181818",
7461
+ children: [
7462
+ /* @__PURE__ */ jsx13("path", { d: "M4.80808081 11.8021107C5.17998715 12.0158424 5.63819467 12.0158424 6.01010101 11.8021107L10.2171717 9.40913806C10.588697 9.19562567 10.8177418 8.8012024 10.8181818 8.37417739V3.58823209C10.8177418 3.16120709 10.588697 2.76678381 10.2171717 2.55327142L6.01010101 0.160298772C5.63819467 -0.0534329241 5.17998715 -0.0534329241 4.80808081 0.160298772L0.601010101 2.55327142C0.229484841 2.76678381 0.000440028788 3.16120709 0 3.58823209V8.37417739C0.000440028788 8.8012024 0.229484841 9.19562567 0.601010101 9.40913806L4.80808081 11.8021107Z" }),
7463
+ /* @__PURE__ */ jsx13("path", { d: "M5.40909091 11.9636364V5.98120474" }),
7464
+ /* @__PURE__ */ jsx13("path", { d: "M0.174292929 2.98998893L5.40909091 5.98120474L10.6438889 2.98998893" })
7465
+ ]
7466
+ }
7467
+ )
7468
+ }
7469
+ );
7391
7470
  var ChatModelControl = ({
7392
7471
  selectedModel,
7393
7472
  availableModels,
7394
7473
  isModelsLoading,
7395
7474
  isModelsError,
7396
7475
  hasModels,
7476
+ loadingLabel,
7477
+ loadFailedLabel,
7478
+ unavailableLabel,
7397
7479
  onSelectedModelChange,
7398
7480
  onReloadModels
7399
7481
  }) => {
@@ -7406,7 +7488,7 @@ var ChatModelControl = ({
7406
7488
  "aria-label": "Reload",
7407
7489
  onClick: onReloadModels,
7408
7490
  children: [
7409
- /* @__PURE__ */ jsx13("span", { children: "Failed to load models" }),
7491
+ /* @__PURE__ */ jsx13("span", { children: loadFailedLabel }),
7410
7492
  /* @__PURE__ */ jsxs10(
7411
7493
  ReloadIcon,
7412
7494
  {
@@ -7428,29 +7510,32 @@ var ChatModelControl = ({
7428
7510
  );
7429
7511
  }
7430
7512
  if (isModelsLoading) {
7431
- return /* @__PURE__ */ jsx13(ModelBadge, { children: "Loading models..." });
7513
+ return /* @__PURE__ */ jsx13(ModelBadge, { "data-testid": "chat-model-loading", children: loadingLabel });
7432
7514
  }
7433
7515
  if (hasModels && selectedModel) {
7434
- if (availableModels.length > 1) {
7435
- return /* @__PURE__ */ jsx13(
7436
- ModelSelect,
7437
- {
7438
- "data-testid": "chat-model-select",
7439
- "aria-label": "Select model",
7440
- value: selectedModel,
7441
- onChange: (value) => onSelectedModelChange(String(value)),
7442
- options: availableModels.map((model) => ({
7443
- label: model.id,
7444
- value: model.id
7445
- }))
7446
- }
7447
- );
7448
- }
7449
- return /* @__PURE__ */ jsx13(ModelBadge, { children: selectedModel });
7516
+ return /* @__PURE__ */ jsx13(
7517
+ ModelSelect,
7518
+ {
7519
+ "data-testid": "chat-model-select",
7520
+ "aria-label": "Select model",
7521
+ value: selectedModel,
7522
+ onChange: (value) => onSelectedModelChange(String(value)),
7523
+ options: availableModels.map((model) => ({
7524
+ label: model.id,
7525
+ value: model.id
7526
+ })),
7527
+ labelRender: () => /* @__PURE__ */ jsx13(ModelIcon, {})
7528
+ }
7529
+ );
7450
7530
  }
7451
- return /* @__PURE__ */ jsx13(ModelBadge, { children: "No model available" });
7531
+ return /* @__PURE__ */ jsx13(ModelBadge, { "data-testid": "chat-model-unavailable", children: unavailableLabel });
7452
7532
  };
7453
7533
  var ModelBadge = styled11.span`
7534
+ display: inline-flex;
7535
+ align-items: center;
7536
+ min-width: 0;
7537
+ max-width: 100%;
7538
+ overflow: hidden;
7454
7539
  border-radius: 999px;
7455
7540
  border: 1px solid var(--border-hover);
7456
7541
  padding: 5px 12px;
@@ -7458,6 +7543,9 @@ var ModelBadge = styled11.span`
7458
7543
  font-size: 12px;
7459
7544
  color: var(--text-secondary);
7460
7545
  line-height: 12px;
7546
+ white-space: nowrap;
7547
+ text-overflow: ellipsis;
7548
+ flex-shrink: 1;
7461
7549
  `;
7462
7550
  var ModelReloadButton = styled11.button`
7463
7551
  display: inline-flex;
@@ -7489,20 +7577,55 @@ var ReloadIcon = styled11.svg`
7489
7577
  `;
7490
7578
  var ModelSelect = styled11(Select)`
7491
7579
  && {
7492
- width: auto;
7580
+ width: 24px;
7581
+ min-width: 24px;
7582
+ max-width: 24px;
7583
+ flex: 0 0 24px;
7584
+ }
7585
+
7586
+ && .compass-select-selector {
7587
+ justify-content: center;
7588
+ border-radius: 999px;
7589
+ min-height: 24px;
7590
+ height: 24px;
7591
+ width: 24px;
7592
+ padding: 0;
7593
+ background: rgba(255, 255, 255, 0.06);
7594
+ border-color: rgba(255, 255, 255, 0.14);
7595
+ color: #c5c1ba;
7596
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
7597
+ margin-right: 0;
7598
+ }
7599
+
7600
+ && .compass-select-selector:hover {
7601
+ background: rgba(255, 255, 255, 0.1);
7602
+ border-color: rgba(255, 255, 255, 0.2);
7603
+ }
7604
+
7605
+ && .compass-select-selection-item {
7606
+ display: flex;
7607
+ width: 100%;
7608
+ margin-right: 0;
7493
7609
  min-width: 0;
7494
- max-width: 100%;
7610
+ min-height: 24px;
7611
+ align-items: center;
7612
+ justify-content: center;
7613
+ }
7495
7614
 
7496
- .compass-select-selector {
7497
- line-height: 1;
7498
- border-radius: 999px;
7499
- min-height: 24px;
7500
- height: 24px;
7501
- background: rgba(255, 255, 255, 0.04);
7502
- border-color: rgba(255, 255, 255, 0.12);
7503
- color: rgba(255, 255, 255, 0.82);
7504
- padding: 4px 12px;
7505
- }
7615
+ && .compass-select-selector > div:first-of-type {
7616
+ display: flex;
7617
+ width: 100%;
7618
+ align-items: center;
7619
+ justify-content: center;
7620
+ margin-right: 0;
7621
+ }
7622
+
7623
+ && .compass-select-selection-item svg {
7624
+ display: block;
7625
+ }
7626
+
7627
+ && .compass-select-selector > span:last-child {
7628
+ display: none;
7506
7629
  }
7507
7630
  `;
7508
7631
 
@@ -7533,21 +7656,27 @@ var ChatModeControl = ({
7533
7656
  };
7534
7657
  var ModeSelect = styled12(Select2)`
7535
7658
  && {
7536
- flex: 0 1 auto;
7537
- width: auto;
7538
- min-width: 0;
7539
- max-width: 100%;
7659
+ flex: 0 0 auto;
7660
+ width: fit-content;
7661
+ min-width: fit-content;
7662
+ max-width: none;
7663
+ }
7540
7664
 
7541
- .compass-select-selector {
7542
- line-height: 1;
7543
- border-radius: 999px;
7544
- min-height: 24px;
7545
- height: 24px;
7546
- background: rgba(255, 255, 255, 0.04);
7547
- border-color: rgba(255, 255, 255, 0.12);
7548
- color: rgba(255, 255, 255, 0.82);
7549
- padding: 4px 12px;
7550
- }
7665
+ && .compass-select-selector {
7666
+ width: fit-content;
7667
+ line-height: 1;
7668
+ border-radius: 999px;
7669
+ min-height: 24px;
7670
+ height: 24px;
7671
+ background: rgba(255, 255, 255, 0.04);
7672
+ border-color: rgba(255, 255, 255, 0.12);
7673
+ color: rgba(255, 255, 255, 0.82);
7674
+ padding: 4px 12px;
7675
+ }
7676
+
7677
+ && .compass-select-selector > div:first-of-type {
7678
+ width: auto;
7679
+ min-width: max-content;
7551
7680
  }
7552
7681
  `;
7553
7682
 
@@ -7722,6 +7851,31 @@ var PlusIcon = () => /* @__PURE__ */ jsx16(
7722
7851
  children: /* @__PURE__ */ jsx16("path", { d: "M8 3v10M3 8h10", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round" })
7723
7852
  }
7724
7853
  );
7854
+ var SkillIcon = () => /* @__PURE__ */ jsx16(
7855
+ "svg",
7856
+ {
7857
+ "aria-hidden": "true",
7858
+ width: "14",
7859
+ height: "14",
7860
+ viewBox: "0 0 14 14",
7861
+ fill: "none",
7862
+ xmlns: "http://www.w3.org/2000/svg",
7863
+ children: /* @__PURE__ */ jsxs11(
7864
+ "g",
7865
+ {
7866
+ transform: "translate(1.7818 2.2909)",
7867
+ stroke: "currentColor",
7868
+ strokeLinecap: "round",
7869
+ strokeLinejoin: "round",
7870
+ strokeWidth: "1.22181818",
7871
+ children: [
7872
+ /* @__PURE__ */ jsx16("path", { d: "M5.28181818 2.12121212V9.54545455" }),
7873
+ /* @__PURE__ */ jsx16("path", { d: "M0.528181818 7.95454545C0.236475055 7.95454545 0 7.7171207 0 7.42424242V0.53030303C0 0.237424754 0.236475055 0 0.528181818 0H3.16909091C4.33591796 0 5.28181818 0.949699016 5.28181818 2.12121212C5.28181818 0.949699016 6.2277184 0 7.39454545 0H10.0354545C10.3271613 0 10.5636364 0.237424754 10.5636364 0.53030303V7.42424242C10.5636364 7.7171207 10.3271613 7.95454545 10.0354545 7.95454545H6.86636364C5.99124335 7.95454545 5.28181818 8.66681972 5.28181818 9.54545455C5.28181818 8.66681972 4.57239302 7.95454545 3.69727273 7.95454545H0.528181818Z" })
7874
+ ]
7875
+ }
7876
+ )
7877
+ }
7878
+ );
7725
7879
  var ComposerExpandIcon = ({ expanded }) => /* @__PURE__ */ jsx16(
7726
7880
  "svg",
7727
7881
  {
@@ -7796,6 +7950,9 @@ var ChatComposerView = ({
7796
7950
  skillLoadingLabel,
7797
7951
  skillEmptyLabel,
7798
7952
  removeSkillAriaLabel,
7953
+ modelLoadingLabel,
7954
+ modelLoadFailedLabel,
7955
+ modelUnavailableLabel,
7799
7956
  onValueChange,
7800
7957
  onPickImages,
7801
7958
  onPasteImages,
@@ -7805,6 +7962,7 @@ var ChatComposerView = ({
7805
7962
  onSelectedModelChange,
7806
7963
  onSelectedModeChange,
7807
7964
  onReloadModels,
7965
+ onOpenSkillPicker,
7808
7966
  onStop,
7809
7967
  onSend
7810
7968
  }) => {
@@ -7819,6 +7977,7 @@ var ChatComposerView = ({
7819
7977
  const canSend = canSendChatMessage({
7820
7978
  value,
7821
7979
  attachmentCount: attachments.length,
7980
+ skillCount: selectedSkills.length,
7822
7981
  isModelsLoading,
7823
7982
  isModelsError,
7824
7983
  hasModels
@@ -7835,11 +7994,12 @@ var ChatComposerView = ({
7835
7994
  }) : [];
7836
7995
  const showSkillMenu = Boolean(skillQueryMatch);
7837
7996
  const activeSkillQueryKey = skillQueryMatch ? `${skillQueryMatch.start}:${skillQueryMatch.end}:${skillQueryMatch.query}:${selectedSkills.join("\0")}` : "";
7838
- const { refs, floatingStyles } = useFloating2({
7997
+ const { refs, floatingStyles, placement } = useFloating2({
7839
7998
  open: showSkillMenu,
7840
7999
  placement: "bottom-start",
8000
+ strategy: "fixed",
7841
8001
  middleware: [
7842
- offset3(8),
8002
+ offset3(3),
7843
8003
  flip3({ padding: 8 }),
7844
8004
  shift3({ padding: 8 }),
7845
8005
  size3({
@@ -7945,8 +8105,14 @@ var ChatComposerView = ({
7945
8105
  event.preventDefault();
7946
8106
  onPasteImages(imageFiles);
7947
8107
  };
8108
+ const handleOpenSkillPicker = () => {
8109
+ onOpenSkillPicker();
8110
+ requestAnimationFrame(() => {
8111
+ inputRef.current?.focus();
8112
+ });
8113
+ };
7948
8114
  return /* @__PURE__ */ jsxs11(Container2, { children: [
7949
- /* @__PURE__ */ jsxs11(Surface, { "data-testid": "chat-composer-surface", children: [
8115
+ /* @__PURE__ */ jsxs11(Surface, { ref: setSkillMenuReference, "data-testid": "chat-composer-surface", children: [
7950
8116
  enableImageAttachments ? /* @__PURE__ */ jsx16(
7951
8117
  "input",
7952
8118
  {
@@ -7967,7 +8133,7 @@ var ChatComposerView = ({
7967
8133
  }
7968
8134
  ),
7969
8135
  attachmentNotice === "limit_reached" ? /* @__PURE__ */ jsx16(AttachmentNotice, { "data-testid": "chat-composer-attachment-notice", children: attachmentLimitNotice }) : null,
7970
- selectedSkills.length ? /* @__PURE__ */ jsx16(SkillTagList, { "data-testid": "chat-composer-skill-tags", children: selectedSkills.map((skill) => /* @__PURE__ */ jsxs11(SkillTag, { children: [
8136
+ selectedSkills.length ? /* @__PURE__ */ jsx16(SkillTagList2, { "data-testid": "chat-composer-skill-tags", children: selectedSkills.map((skill) => /* @__PURE__ */ jsxs11(SkillTag2, { children: [
7971
8137
  /* @__PURE__ */ jsx16("span", { children: skill }),
7972
8138
  /* @__PURE__ */ jsx16(
7973
8139
  SkillTagRemoveButton,
@@ -7980,7 +8146,7 @@ var ChatComposerView = ({
7980
8146
  }
7981
8147
  )
7982
8148
  ] }, skill)) }) : null,
7983
- /* @__PURE__ */ jsxs11(InputArea, { ref: setSkillMenuReference, "data-testid": "chat-composer-input-area", children: [
8149
+ /* @__PURE__ */ jsxs11(InputArea, { "data-testid": "chat-composer-input-area", children: [
7984
8150
  isComposerExpanded || isComposerExpandable ? /* @__PURE__ */ jsx16(
7985
8151
  ComposerExpandButton,
7986
8152
  {
@@ -8007,17 +8173,27 @@ var ChatComposerView = ({
8007
8173
  )
8008
8174
  ] }),
8009
8175
  /* @__PURE__ */ jsxs11(Footer, { children: [
8010
- /* @__PURE__ */ jsx16(LeadingActions, { "data-testid": "chat-composer-leading-actions", children: enableImageAttachments ? /* @__PURE__ */ jsx16(
8011
- AttachButton,
8012
- {
8013
- type: "button",
8014
- "data-testid": "chat-composer-attach-image",
8015
- "aria-label": "Attach image",
8016
- onClick: () => imageInputRef.current?.click(),
8017
- children: /* @__PURE__ */ jsx16(PlusIcon, {})
8018
- }
8019
- ) : null }),
8020
- /* @__PURE__ */ jsxs11(TrailingActions, { "data-testid": "chat-composer-trailing-actions", children: [
8176
+ /* @__PURE__ */ jsxs11(LeadingActions, { "data-testid": "chat-composer-leading-actions", children: [
8177
+ enableImageAttachments ? /* @__PURE__ */ jsx16(
8178
+ AttachButton,
8179
+ {
8180
+ type: "button",
8181
+ "data-testid": "chat-composer-attach-image",
8182
+ "aria-label": "Attach image",
8183
+ onClick: () => imageInputRef.current?.click(),
8184
+ children: /* @__PURE__ */ jsx16(PlusIcon, {})
8185
+ }
8186
+ ) : null,
8187
+ /* @__PURE__ */ jsx16(
8188
+ SkillButton,
8189
+ {
8190
+ type: "button",
8191
+ "data-testid": "chat-composer-skill-trigger",
8192
+ "aria-label": "Open skill picker",
8193
+ onClick: handleOpenSkillPicker,
8194
+ children: /* @__PURE__ */ jsx16(SkillIcon, {})
8195
+ }
8196
+ ),
8021
8197
  /* @__PURE__ */ jsx16(
8022
8198
  ChatModeControl,
8023
8199
  {
@@ -8026,7 +8202,9 @@ var ChatComposerView = ({
8026
8202
  labels: modeLabels,
8027
8203
  onChange: onSelectedModeChange
8028
8204
  }
8029
- ),
8205
+ )
8206
+ ] }),
8207
+ /* @__PURE__ */ jsxs11(TrailingActions, { "data-testid": "chat-composer-trailing-actions", children: [
8030
8208
  /* @__PURE__ */ jsx16(
8031
8209
  ChatModelControl,
8032
8210
  {
@@ -8035,6 +8213,9 @@ var ChatComposerView = ({
8035
8213
  isModelsLoading,
8036
8214
  isModelsError,
8037
8215
  hasModels,
8216
+ loadingLabel: modelLoadingLabel,
8217
+ loadFailedLabel: modelLoadFailedLabel,
8218
+ unavailableLabel: modelUnavailableLabel,
8038
8219
  onSelectedModelChange,
8039
8220
  onReloadModels
8040
8221
  }
@@ -8058,6 +8239,8 @@ var ChatComposerView = ({
8058
8239
  ref: setSkillMenuFloating,
8059
8240
  style: floatingStyles,
8060
8241
  "data-testid": "chat-composer-skill-menu",
8242
+ "data-placement": placement,
8243
+ "data-floating-strategy": "fixed",
8061
8244
  role: "listbox",
8062
8245
  children: isSkillsLoading ? /* @__PURE__ */ jsx16(SkillMenuState, { "data-testid": "chat-composer-skill-loading", children: skillLoadingLabel }) : filteredSkills.length ? filteredSkills.map((skill, index3) => /* @__PURE__ */ jsx16(
8063
8246
  SkillMenuItem,
@@ -8119,6 +8302,9 @@ var ChatComposer = () => {
8119
8302
  skillLoadingLabel: labels.skillLoading,
8120
8303
  skillEmptyLabel: labels.skillEmpty,
8121
8304
  removeSkillAriaLabel: labels.removeSkillAriaLabel,
8305
+ modelLoadingLabel: labels.modelLoading,
8306
+ modelLoadFailedLabel: labels.modelLoadFailed,
8307
+ modelUnavailableLabel: labels.modelUnavailable,
8122
8308
  onValueChange: actions.setValue,
8123
8309
  onPickImages: actions.pickImages,
8124
8310
  onPasteImages: actions.pasteImages,
@@ -8128,6 +8314,7 @@ var ChatComposer = () => {
8128
8314
  onSelectedModelChange: actions.setSelectedModel,
8129
8315
  onSelectedModeChange: actions.setSelectedMode,
8130
8316
  onReloadModels: actions.reloadModels,
8317
+ onOpenSkillPicker: actions.openSkillPicker,
8131
8318
  onStop: actions.stop,
8132
8319
  onSend: send
8133
8320
  }
@@ -8166,31 +8353,55 @@ var AttachmentNotice = styled14.div`
8166
8353
  font-size: 12px;
8167
8354
  line-height: 1.4;
8168
8355
  `;
8169
- var SkillTagList = styled14.div`
8356
+ var SkillTagList2 = styled14.div`
8170
8357
  display: flex;
8171
8358
  flex-wrap: wrap;
8172
- gap: 8px;
8173
- padding: 12px 12px 0;
8359
+ gap: 9px;
8360
+ padding: 11px 16px;
8174
8361
  `;
8175
- var SkillTag = styled14.span`
8362
+ var SkillTag2 = styled14.span`
8363
+ position: relative;
8176
8364
  display: inline-flex;
8177
8365
  align-items: center;
8178
- gap: 6px;
8179
8366
  max-width: 100%;
8180
- border-radius: 999px;
8181
- padding: 8px 12px;
8182
- background: rgba(255, 255, 255, 0.06);
8183
- color: var(--text-primary);
8184
- font-size: 13px;
8367
+ padding: 11px 16px;
8368
+ background: rgba(65, 65, 63, 0.35);
8369
+ border-radius: 18px;
8370
+ font-weight: 400;
8371
+ font-size: 14px;
8372
+ color: #c5c1ba;
8185
8373
  line-height: 1;
8374
+
8375
+ :hover {
8376
+ background: #41413f;
8377
+ }
8378
+
8379
+ &:hover > button,
8380
+ &:focus-within > button {
8381
+ opacity: 1;
8382
+ pointer-events: auto;
8383
+ }
8186
8384
  `;
8187
8385
  var SkillTagRemoveButton = styled14.button`
8386
+ position: absolute;
8387
+ top: 0;
8388
+ right: 0;
8389
+ width: 14px;
8390
+ height: 14px;
8391
+ border-radius: 50%;
8392
+ background: #000000;
8393
+ display: grid;
8394
+ place-items: center;
8188
8395
  border: none;
8189
8396
  padding: 0;
8190
- background: transparent;
8191
8397
  color: inherit;
8192
8398
  cursor: pointer;
8193
8399
  line-height: 1;
8400
+ opacity: 0;
8401
+ pointer-events: none;
8402
+ transition:
8403
+ opacity 120ms ease,
8404
+ background-color 120ms ease;
8194
8405
  `;
8195
8406
  var InputArea = styled14.div`
8196
8407
  grid-area: input;
@@ -8251,18 +8462,21 @@ var SkillMenu = styled14.div`
8251
8462
  gap: 4px;
8252
8463
  max-height: 240px;
8253
8464
  overflow-y: auto;
8254
- padding: 8px;
8255
- border: 1px solid rgba(255, 255, 255, 0.12);
8256
- border-radius: 16px;
8465
+ padding: 4px;
8466
+ border-radius: 12px;
8257
8467
  background: rgba(28, 28, 28, 0.98);
8258
8468
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.28);
8259
8469
  z-index: 1000;
8470
+ background: #1c1c1c;
8471
+ box-shadow: 0px 4px 6px 0px rgba(14, 14, 14, 0.3);
8472
+ border-radius: 12px;
8473
+ border: 1px solid #282825;
8260
8474
  `;
8261
8475
  var SkillMenuItem = styled14.button`
8262
8476
  width: 100%;
8263
8477
  border: none;
8264
- border-radius: 12px;
8265
- padding: 12px 14px;
8478
+ border-radius: 8px;
8479
+ padding: 12px;
8266
8480
  background: transparent;
8267
8481
  color: var(--text-primary);
8268
8482
  text-align: left;
@@ -8270,7 +8484,7 @@ var SkillMenuItem = styled14.button`
8270
8484
 
8271
8485
  &[data-active='true'],
8272
8486
  &:hover {
8273
- background: rgba(255, 255, 255, 0.12);
8487
+ background: #41413f;
8274
8488
  }
8275
8489
  `;
8276
8490
  var SkillMenuState = styled14.div`
@@ -8300,9 +8514,8 @@ var ComposerExpandButton = styled14.button`
8300
8514
  `;
8301
8515
  var Footer = styled14.div`
8302
8516
  grid-area: footer;
8303
- display: grid;
8304
- grid-template-columns: auto minmax(0, 1fr);
8305
- align-items: flex-end;
8517
+ display: flex;
8518
+ align-items: center;
8306
8519
  gap: 8px;
8307
8520
  padding: 0 14px 14px;
8308
8521
  `;
@@ -8310,33 +8523,72 @@ var LeadingActions = styled14.div`
8310
8523
  display: flex;
8311
8524
  align-items: center;
8312
8525
  justify-content: flex-start;
8313
- gap: 8px;
8526
+ gap: 4px;
8314
8527
  min-width: 0;
8315
8528
  `;
8316
8529
  var TrailingActions = styled14.div`
8317
8530
  display: flex;
8318
8531
  align-items: center;
8319
- flex-wrap: wrap;
8532
+ flex-wrap: nowrap;
8320
8533
  min-width: 0;
8321
- width: fit-content;
8322
- max-width: 100%;
8323
- justify-self: end;
8534
+ margin-left: auto;
8324
8535
  justify-content: flex-end;
8325
8536
  gap: 8px;
8326
8537
  `;
8327
8538
  var AttachButton = styled14.button`
8328
- width: 28px;
8329
- height: 28px;
8539
+ width: 24px;
8540
+ height: 24px;
8330
8541
  display: grid;
8331
8542
  place-items: center;
8332
- border: none;
8333
8543
  border-radius: 999px;
8334
- background: transparent;
8335
- color: rgba(255, 255, 255, 0.82);
8544
+ border: 1px solid rgba(255, 255, 255, 0.14);
8545
+ background: rgba(255, 255, 255, 0.06);
8546
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
8547
+ padding: 0;
8548
+ color: #c5c1ba;
8336
8549
  cursor: pointer;
8550
+ flex: 0 0 24px;
8551
+
8552
+ transition:
8553
+ background 160ms ease,
8554
+ border-color 160ms ease,
8555
+ color 160ms ease;
8337
8556
 
8338
8557
  &:hover {
8339
- background: rgba(255, 255, 255, 0.08);
8558
+ background: rgba(255, 255, 255, 0.1);
8559
+ border-color: rgba(255, 255, 255, 0.2);
8560
+ }
8561
+
8562
+ svg {
8563
+ display: block;
8564
+ }
8565
+ `;
8566
+ var SkillButton = styled14.button`
8567
+ width: 24px;
8568
+ height: 24px;
8569
+ display: grid;
8570
+ place-items: center;
8571
+ border-radius: 999px;
8572
+ border: 1px solid rgba(255, 255, 255, 0.14);
8573
+ background: rgba(255, 255, 255, 0.06);
8574
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
8575
+ padding: 0;
8576
+ color: #c5c1ba;
8577
+ cursor: pointer;
8578
+ flex: 0 0 24px;
8579
+
8580
+ transition:
8581
+ background 160ms ease,
8582
+ border-color 160ms ease,
8583
+ color 160ms ease;
8584
+
8585
+ &:hover {
8586
+ background: rgba(255, 255, 255, 0.1);
8587
+ border-color: rgba(255, 255, 255, 0.2);
8588
+ }
8589
+
8590
+ svg {
8591
+ display: block;
8340
8592
  }
8341
8593
  `;
8342
8594
 
@@ -8469,6 +8721,76 @@ var List2 = styled16.div`
8469
8721
 
8470
8722
  // src/components/ai-chat/index.tsx
8471
8723
  import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs14 } from "@emotion/react/jsx-runtime";
8724
+ var NewTalkIcon = () => /* @__PURE__ */ jsx19(
8725
+ "svg",
8726
+ {
8727
+ "aria-hidden": "true",
8728
+ width: "16",
8729
+ height: "16",
8730
+ viewBox: "0 0 16 16",
8731
+ fill: "none",
8732
+ style: { display: "block" },
8733
+ xmlns: "http://www.w3.org/2000/svg",
8734
+ children: /* @__PURE__ */ jsxs14(
8735
+ "g",
8736
+ {
8737
+ transform: "translate(1.8909 2.0364)",
8738
+ stroke: "currentColor",
8739
+ strokeLinecap: "round",
8740
+ strokeLinejoin: "round",
8741
+ strokeWidth: "1.36533333",
8742
+ children: [
8743
+ /* @__PURE__ */ jsxs14("g", { transform: "translate(9.8909 2.3273) rotate(-315) translate(-9.8909 -2.3273) translate(8.2909 0.7273)", children: [
8744
+ /* @__PURE__ */ jsx19("path", { d: "M0 0C0 0 1.06666667 1.06666667 3.2 3.2" }),
8745
+ /* @__PURE__ */ jsx19("path", { d: "M3.2 0C3.2 0 2.13333333 1.06666667 0 3.2" })
8746
+ ] }),
8747
+ /* @__PURE__ */ jsx19("path", { d: "M12.2181818 6.15099432V7.31151515C12.2181818 8.25408112 11.4540811 9.01818182 10.5115152 9.01818182H4.19089868C4.07080994 9.01818182 3.95380126 9.05618401 3.85662972 9.12674601L0.903157852 11.2714364C0.648927541 11.4560481 0.293175841 11.399611 0.10856419 11.1453807C0.0380021898 11.0482092 0 10.9312005 0 10.8111117V1.70666667C0 0.764100694 0.764100694 0 1.70666667 0H6.07111268" })
8748
+ ]
8749
+ }
8750
+ )
8751
+ }
8752
+ );
8753
+ var hasStartedConversation = ({
8754
+ activeSessionId,
8755
+ messagesBySession,
8756
+ streamingMessageBySession,
8757
+ errorBySession
8758
+ }) => {
8759
+ if (!activeSessionId) {
8760
+ return false;
8761
+ }
8762
+ return Boolean(
8763
+ (messagesBySession[activeSessionId]?.length ?? 0) > 0 || streamingMessageBySession[activeSessionId] || errorBySession[activeSessionId]
8764
+ );
8765
+ };
8766
+ var AiChatWorkspaceContent = ({
8767
+ showConversationList,
8768
+ showNewChatButton,
8769
+ renderNewChatTrigger,
8770
+ showComposerOnlyBeforeFirstMessage = false,
8771
+ onConversationStartedChange
8772
+ }) => {
8773
+ const isConversationStarted = useChatStore(
8774
+ (state) => hasStartedConversation({
8775
+ activeSessionId: state.activeSessionId,
8776
+ messagesBySession: state.messagesBySession,
8777
+ streamingMessageBySession: state.streamingMessageBySession,
8778
+ errorBySession: state.errorBySession
8779
+ })
8780
+ );
8781
+ const shouldShowComposerOnly = showComposerOnlyBeforeFirstMessage && !showConversationList && !isConversationStarted;
8782
+ useEffect9(() => {
8783
+ onConversationStartedChange?.(isConversationStarted);
8784
+ }, [isConversationStarted, onConversationStartedChange]);
8785
+ return /* @__PURE__ */ jsxs14(Root, { "data-testid": "ai-chat", children: [
8786
+ showConversationList ? /* @__PURE__ */ jsx19(ChatConversationList, {}) : null,
8787
+ /* @__PURE__ */ jsxs14(Workspace, { children: [
8788
+ showNewChatButton && !showConversationList && !shouldShowComposerOnly ? /* @__PURE__ */ jsx19(QuickActions, { renderNewChatTrigger }) : null,
8789
+ shouldShowComposerOnly ? null : /* @__PURE__ */ jsx19(ChatThread, {}),
8790
+ /* @__PURE__ */ jsx19(ChatComposer, {})
8791
+ ] })
8792
+ ] });
8793
+ };
8472
8794
  var QuickActions = ({ renderNewChatTrigger }) => {
8473
8795
  const { labels, stopRef, store } = useChatContext();
8474
8796
  const startNewChat = useChatStore((state) => state.startNewChat);
@@ -8522,9 +8844,11 @@ var QuickActions = ({ renderNewChatTrigger }) => {
8522
8844
  {
8523
8845
  type: "button",
8524
8846
  "data-testid": "chat-start-new-session",
8847
+ "aria-label": labels.newChat,
8848
+ title: labels.newChat,
8525
8849
  onClick: () => void handleStartNewChat(),
8526
8850
  disabled: isActiveSessionStopping,
8527
- children: labels.newChat
8851
+ children: /* @__PURE__ */ jsx19(NewTalkIcon, {})
8528
8852
  }
8529
8853
  ) });
8530
8854
  };
@@ -8536,6 +8860,8 @@ var AiChat = ({
8536
8860
  showConversationList = false,
8537
8861
  showNewChatButton = false,
8538
8862
  renderNewChatTrigger,
8863
+ showComposerOnlyBeforeFirstMessage = false,
8864
+ onConversationStartedChange,
8539
8865
  ...providerProps
8540
8866
  }) => /* @__PURE__ */ jsx19(
8541
8867
  ConfigProvider,
@@ -8572,14 +8898,16 @@ var AiChat = ({
8572
8898
  }
8573
8899
  }
8574
8900
  },
8575
- children: /* @__PURE__ */ jsx19(AiChatProvider, { ...providerProps, children: /* @__PURE__ */ jsxs14(Root, { "data-testid": "ai-chat", children: [
8576
- showConversationList ? /* @__PURE__ */ jsx19(ChatConversationList, {}) : null,
8577
- /* @__PURE__ */ jsxs14(Workspace, { children: [
8578
- showNewChatButton && !showConversationList ? /* @__PURE__ */ jsx19(QuickActions, { renderNewChatTrigger }) : null,
8579
- /* @__PURE__ */ jsx19(ChatThread, {}),
8580
- /* @__PURE__ */ jsx19(ChatComposer, {})
8581
- ] })
8582
- ] }) })
8901
+ children: /* @__PURE__ */ jsx19(AiChatProvider, { ...providerProps, children: /* @__PURE__ */ jsx19(
8902
+ AiChatWorkspaceContent,
8903
+ {
8904
+ showConversationList,
8905
+ showNewChatButton,
8906
+ renderNewChatTrigger,
8907
+ showComposerOnlyBeforeFirstMessage,
8908
+ onConversationStartedChange
8909
+ }
8910
+ ) })
8583
8911
  }
8584
8912
  );
8585
8913
  var Root = styled17.div`
@@ -8603,12 +8931,26 @@ var QuickActionsRow = styled17.div`
8603
8931
  padding: 12px 12px 0;
8604
8932
  `;
8605
8933
  var QuickActionButton = styled17.button`
8606
- border: none;
8607
- border-radius: 12px;
8608
- padding: 10px 14px;
8934
+ width: 48px;
8935
+ height: 48px;
8936
+ display: grid;
8937
+ place-items: center;
8938
+ padding: 0;
8939
+ border: 1px solid rgba(255, 255, 255, 0.14);
8940
+ border-radius: 999px;
8609
8941
  background: rgba(255, 255, 255, 0.08);
8942
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
8610
8943
  color: var(--text-primary, #fcfbf8);
8611
8944
  cursor: pointer;
8945
+ transition:
8946
+ background 160ms ease,
8947
+ border-color 160ms ease,
8948
+ color 160ms ease;
8949
+
8950
+ &:hover:not(:disabled) {
8951
+ background: rgba(255, 255, 255, 0.12);
8952
+ border-color: rgba(255, 255, 255, 0.2);
8953
+ }
8612
8954
 
8613
8955
  &:disabled {
8614
8956
  opacity: 0.5;