@aphrody/m3-ai 3.3.6 → 3.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/A2APeerInspector.d.ts +1 -1
  2. package/dist/A2APeerInspector.d.ts.map +1 -1
  3. package/dist/A2ATaskTimeline.d.ts +1 -1
  4. package/dist/AgUiEventStream.d.ts +1 -1
  5. package/dist/AgUiEventStream.d.ts.map +1 -1
  6. package/dist/ChatComposer.d.ts +9 -1
  7. package/dist/ChatComposer.d.ts.map +1 -1
  8. package/dist/ConversationList.d.ts +32 -0
  9. package/dist/ConversationList.d.ts.map +1 -0
  10. package/dist/Markdown.d.ts +31 -1
  11. package/dist/Markdown.d.ts.map +1 -1
  12. package/dist/MemoryPanel.d.ts +26 -0
  13. package/dist/MemoryPanel.d.ts.map +1 -0
  14. package/dist/MessageBubble.d.ts +13 -1
  15. package/dist/MessageBubble.d.ts.map +1 -1
  16. package/dist/ModelSelector.d.ts +5 -1
  17. package/dist/ModelSelector.d.ts.map +1 -1
  18. package/dist/ModelUnavailable.d.ts +16 -0
  19. package/dist/ModelUnavailable.d.ts.map +1 -0
  20. package/dist/ToolCall.d.ts.map +1 -1
  21. package/dist/ag-ui.d.ts +13 -0
  22. package/dist/ag-ui.d.ts.map +1 -0
  23. package/dist/chatIcons.d.ts +34 -0
  24. package/dist/chatIcons.d.ts.map +1 -0
  25. package/dist/chatLabels.d.ts +71 -0
  26. package/dist/chatLabels.d.ts.map +1 -0
  27. package/dist/citations.d.ts +57 -0
  28. package/dist/citations.d.ts.map +1 -0
  29. package/dist/index.d.ts +20 -4
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1955 -654
  32. package/dist/index.js.map +20 -13
  33. package/dist/openaiChatStream.d.ts +140 -0
  34. package/dist/openaiChatStream.d.ts.map +1 -0
  35. package/dist/useOpenAIChat.d.ts +30 -0
  36. package/dist/useOpenAIChat.d.ts.map +1 -0
  37. package/package.json +11 -6
  38. package/src/AgUiEventStream.ts +1 -1
  39. package/src/ag-ui.ts +19 -0
  40. package/src/index.ts +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- // packages/m3-ai/src/types.ts
2
+ // m3/packages/m3-ai/src/types.ts
3
3
  var TASK_STATUS_ORDER = [
4
4
  "in_progress",
5
5
  "ready",
@@ -81,13 +81,13 @@ function pairTranscriptSteps(steps) {
81
81
  }
82
82
  return items;
83
83
  }
84
- // packages/m3-ai/src/ToolCall.tsx
84
+ // m3/packages/m3-ai/src/ToolCall.tsx
85
85
  import { useId, useState as useState2 } from "react";
86
86
  import { clsx as clsx3 } from "clsx";
87
87
  import { AnimatePresence, motion } from "motion/react";
88
88
  import { Icon } from "@aphrody/m3-primitives";
89
89
 
90
- // packages/m3-ai/src/internal.tsx
90
+ // m3/packages/m3-ai/src/internal.tsx
91
91
  import { m3Durations, m3Easings } from "@aphrody/m3-motion";
92
92
  import { clsx } from "clsx";
93
93
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -159,7 +159,7 @@ function StatusChip({
159
159
  });
160
160
  }
161
161
 
162
- // packages/m3-ai/src/McpAppCard.tsx
162
+ // m3/packages/m3-ai/src/McpAppCard.tsx
163
163
  import { useState, useRef, useMemo } from "react";
164
164
  import { clsx as clsx2 } from "clsx";
165
165
  import { AppRenderer } from "@aphrody/mcp-ui";
@@ -327,7 +327,7 @@ var McpAppCard = ({
327
327
  });
328
328
  };
329
329
 
330
- // packages/m3-ai/src/ToolCall.tsx
330
+ // m3/packages/m3-ai/src/ToolCall.tsx
331
331
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
332
332
  function firstArg(pair, keys) {
333
333
  for (const key of keys) {
@@ -956,15 +956,272 @@ function truncate(text, maxLen) {
956
956
  return text;
957
957
  return text.slice(0, maxLen) + "...";
958
958
  }
959
- // packages/m3-ai/src/Markdown.tsx
960
- import { Icon as Icon2 } from "@aphrody/m3-primitives";
961
- import { clsx as clsx4 } from "clsx";
959
+ // m3/packages/m3-ai/src/Markdown.tsx
960
+ import { clsx as clsx5 } from "clsx";
962
961
  import { forwardRef, isValidElement, useEffect, useRef as useRef2, useState as useState3 } from "react";
963
962
  import ReactMarkdown from "react-markdown";
964
963
  import rehypeRaw from "rehype-raw";
965
964
  import remarkGfm from "remark-gfm";
966
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
965
+
966
+ // m3/packages/m3-ai/src/chatLabels.ts
967
+ var chatLabelsEn = {
968
+ composerPlaceholder: "Ask something...",
969
+ send: "Send",
970
+ stop: "Stop",
971
+ openVoice: "Open Voice Input",
972
+ projects: "Projects",
973
+ models: "Models",
974
+ selectModel: "Select model...",
975
+ searchModels: "Search models...",
976
+ noModels: "No models found",
977
+ contextTokens: "{count} tokens",
978
+ copyMessage: "Copy Message",
979
+ copyStreamingMessage: "Copy Streaming Message",
980
+ dislike: "Dislike",
981
+ fork: "Fork",
982
+ assistantThinking: "Thinking",
983
+ copy: "Copy",
984
+ copyCode: "Copy code",
985
+ copied: "Copied!",
986
+ conversations: "Conversations",
987
+ newConversation: "New conversation",
988
+ searchConversations: "Search conversations",
989
+ noConversations: "No conversations yet",
990
+ noSearchResults: "No matching conversation",
991
+ untitledConversation: "Untitled conversation",
992
+ renameConversation: "Rename conversation",
993
+ deleteConversation: "Delete conversation",
994
+ modelUnavailable: "Model unavailable",
995
+ modelDownloading: "Downloading the model",
996
+ modelLoading: "Loading the model",
997
+ progressPercent: "{percent}%",
998
+ retry: "Retry",
999
+ sources: "Sources",
1000
+ citation: "Source {n}",
1001
+ openSource: "Open source",
1002
+ refusalTitle: "Not established in the sources",
1003
+ refusalBody: "The available sources do not support an answer to this question.",
1004
+ memory: "Memory",
1005
+ memoryEmpty: "No memories saved",
1006
+ memoryLoading: "Loading memories",
1007
+ deleteMemory: "Delete memory",
1008
+ clearMemory: "Clear all memories",
1009
+ clearMemoryConfirm: "Delete every saved memory? This cannot be undone.",
1010
+ confirm: "Confirm",
1011
+ cancel: "Cancel",
1012
+ loading: "Loading",
1013
+ errorGeneric: "Something went wrong"
1014
+ };
1015
+ var chatLabelsFr = {
1016
+ composerPlaceholder: "Posez une question...",
1017
+ send: "Envoyer",
1018
+ stop: "Arrêter",
1019
+ openVoice: "Saisie vocale",
1020
+ projects: "Projets",
1021
+ models: "Modèles",
1022
+ selectModel: "Choisir un modèle...",
1023
+ searchModels: "Rechercher un modèle...",
1024
+ noModels: "Aucun modèle trouvé",
1025
+ contextTokens: "{count} jetons",
1026
+ copyMessage: "Copier le message",
1027
+ copyStreamingMessage: "Copier le message en cours",
1028
+ dislike: "Je n'aime pas",
1029
+ fork: "Bifurquer à partir de ce tour",
1030
+ assistantThinking: "Réflexion",
1031
+ copy: "Copier",
1032
+ copyCode: "Copier le code",
1033
+ copied: "Copié !",
1034
+ conversations: "Conversations",
1035
+ newConversation: "Nouvelle conversation",
1036
+ searchConversations: "Rechercher une conversation",
1037
+ noConversations: "Aucune conversation pour l'instant",
1038
+ noSearchResults: "Aucune conversation ne correspond",
1039
+ untitledConversation: "Conversation sans titre",
1040
+ renameConversation: "Renommer la conversation",
1041
+ deleteConversation: "Supprimer la conversation",
1042
+ modelUnavailable: "Modèle indisponible",
1043
+ modelDownloading: "Téléchargement du modèle",
1044
+ modelLoading: "Chargement du modèle",
1045
+ progressPercent: "{percent} %",
1046
+ retry: "Réessayer",
1047
+ sources: "Sources",
1048
+ citation: "Source {n}",
1049
+ openSource: "Ouvrir la source",
1050
+ refusalTitle: "Non établi dans les sources",
1051
+ refusalBody: "Les sources disponibles ne permettent pas de répondre à cette question.",
1052
+ memory: "Mémoire",
1053
+ memoryEmpty: "Aucun souvenir enregistré",
1054
+ memoryLoading: "Chargement des souvenirs",
1055
+ deleteMemory: "Supprimer ce souvenir",
1056
+ clearMemory: "Effacer tous les souvenirs",
1057
+ clearMemoryConfirm: "Supprimer tous les souvenirs enregistrés ? Cette action est définitive.",
1058
+ confirm: "Confirmer",
1059
+ cancel: "Annuler",
1060
+ loading: "Chargement",
1061
+ errorGeneric: "Une erreur est survenue"
1062
+ };
1063
+ var chatLabelsJa = {
1064
+ composerPlaceholder: "質問を入力...",
1065
+ send: "送信",
1066
+ stop: "停止",
1067
+ openVoice: "音声入力",
1068
+ projects: "プロジェクト",
1069
+ models: "モデル",
1070
+ selectModel: "モデルを選択...",
1071
+ searchModels: "モデルを検索...",
1072
+ noModels: "モデルが見つかりません",
1073
+ contextTokens: "{count} トークン",
1074
+ copyMessage: "メッセージをコピー",
1075
+ copyStreamingMessage: "生成中のメッセージをコピー",
1076
+ dislike: "低評価",
1077
+ fork: "このターンから分岐",
1078
+ assistantThinking: "思考中",
1079
+ copy: "コピー",
1080
+ copyCode: "コードをコピー",
1081
+ copied: "コピーしました",
1082
+ conversations: "会話",
1083
+ newConversation: "新しい会話",
1084
+ searchConversations: "会話を検索",
1085
+ noConversations: "まだ会話はありません",
1086
+ noSearchResults: "一致する会話はありません",
1087
+ untitledConversation: "無題の会話",
1088
+ renameConversation: "会話の名前を変更",
1089
+ deleteConversation: "会話を削除",
1090
+ modelUnavailable: "モデルを利用できません",
1091
+ modelDownloading: "モデルをダウンロード中",
1092
+ modelLoading: "モデルを読み込み中",
1093
+ progressPercent: "{percent}%",
1094
+ retry: "再試行",
1095
+ sources: "出典",
1096
+ citation: "出典 {n}",
1097
+ openSource: "出典を開く",
1098
+ refusalTitle: "出典では確認できません",
1099
+ refusalBody: "利用できる出典では、この質問に回答できません。",
1100
+ memory: "メモリー",
1101
+ memoryEmpty: "保存されたメモリーはありません",
1102
+ memoryLoading: "メモリーを読み込み中",
1103
+ deleteMemory: "メモリーを削除",
1104
+ clearMemory: "すべてのメモリーを消去",
1105
+ clearMemoryConfirm: "保存されたすべてのメモリーを削除しますか?この操作は元に戻せません。",
1106
+ confirm: "確認",
1107
+ cancel: "キャンセル",
1108
+ loading: "読み込み中",
1109
+ errorGeneric: "エラーが発生しました"
1110
+ };
1111
+ var defaultChatLabels = chatLabelsEn;
1112
+ var chatLabelsByLang = { fr: chatLabelsFr, en: chatLabelsEn, ja: chatLabelsJa };
1113
+ function resolveChatLabels(partial, base = defaultChatLabels) {
1114
+ if (!partial)
1115
+ return base;
1116
+ const out = { ...base };
1117
+ for (const key of Object.keys(partial)) {
1118
+ const value = partial[key];
1119
+ if (typeof value === "string" && value.length > 0)
1120
+ out[key] = value;
1121
+ }
1122
+ return out;
1123
+ }
1124
+ function formatLabel(template, values) {
1125
+ return template.replace(/\{(\w+)\}/g, (match, name) => (name in values) ? String(values[name]) : match);
1126
+ }
1127
+
1128
+ // m3/packages/m3-ai/src/chatIcons.tsx
1129
+ import { clsx as clsx4 } from "clsx";
1130
+ import { jsx as jsx4 } from "react/jsx-runtime";
1131
+ var CHAT_ICON_PATHS = {
1132
+ arrow_upward: [
1133
+ "0 -960 960 960",
1134
+ "M450-160v-526L202-438l-42-42 320-320 320 320-42 42-248-248v526h-60Z"
1135
+ ],
1136
+ auto_awesome_filled: [
1137
+ "0 96 960 960",
1138
+ "m772 421-43-100-104-46 104-45 43-95 43 95 104 45-104 46-43 100Zm0 595-43-96-104-45 104-45 43-101 43 101 104 45-104 45-43 96ZM333 862l-92-197-201-90 201-90 92-196 93 196 200 90-200 90-93 197Z"
1139
+ ],
1140
+ auto_awesome: [
1141
+ "0 -960 960 960",
1142
+ "m772-635-43-100-104-46 104-45 43-95 43 95 104 45-104 46-43 100Zm0 595-43-96-104-45 104-45 43-101 43 101 104 45-104 45-43 96ZM333-194l-92-197-201-90 201-90 92-196 93 196 200 90-200 90-93 197Zm0-148 48-96 98-43-98-43-48-96-47 96-99 43 99 43 47 96Zm0-139Z"
1143
+ ],
1144
+ call_split: [
1145
+ "0 -960 960 960",
1146
+ "M452-160v-306L220-698v123h-60v-225h225v60H263l249 249v331h-60Zm113-364-42-42 174-174H575v-60h225v225h-60v-123L565-524Z"
1147
+ ],
1148
+ check: ["0 -960 960 960", "M378-246 154-470l43-43 181 181 384-384 43 43-427 427Z"],
1149
+ cloud_off: [
1150
+ "0 -960 960 960",
1151
+ "M818-56 703-171H248q-88 0-148-59T40-377q0-80 50.5-134T217-577q2-14 6.5-31.5T236-640L70-806l42-42L861-99l-43 43ZM248-231h397L285-591q-11 15-14.5 34t-3.5 37h-19q-62 0-105 39.5t-43 101q0 61.5 43 105T248-231Zm216-181Zm390 210-47-47q25-17 39-38t14-50q0-43-31-73.5T755-441h-67v-81q0-88-61-147.5T478.47-729q-28.47 0-60.97 9T358-691l-42-42q36-29 77.5-42.5T478-789q111 0 190.5 79T748-520v21q72-1 122 45t50 117q0 35-16.5 73.5T854-202ZM583-470Z"
1152
+ ],
1153
+ content_copy: [
1154
+ "0 -960 960 960",
1155
+ "M300-200q-24 0-42-18t-18-42v-560q0-24 18-42t42-18h440q24 0 42 18t18 42v560q0 24-18 42t-42 18H300Zm0-60h440v-560H300v560ZM180-80q-24 0-42-18t-18-42v-620h60v620h500v60H180Zm120-180v-560 560Z"
1156
+ ],
1157
+ delete: [
1158
+ "0 -960 960 960",
1159
+ "M261-120q-24.75 0-42.37-17.63Q201-155.25 201-180v-570h-41v-60h188v-30h264v30h188v60h-41v570q0 24-18 42t-42 18H261Zm438-630H261v570h438v-570ZM367-266h60v-399h-60v399Zm166 0h60v-399h-60v399ZM261-750v570-570Z"
1160
+ ],
1161
+ edit: [
1162
+ "0 -960 960 960",
1163
+ "M180-180h44l472-471-44-44-472 471v44Zm-60 60v-128l575-574q8-8 19-12.5t23-4.5q11 0 22 4.5t20 12.5l44 44q9 9 13 20t4 22q0 11-4.5 22.5T823-694L248-120H120Zm659-617-41-41 41 41Zm-105 64-22-22 44 44-22-22Z"
1164
+ ],
1165
+ edit_square: [
1166
+ "0 -960 960 960",
1167
+ "M180-120q-24 0-42-18t-18-42v-600q0-24 18-42t42-18h405l-60 60H180v600h600v-348l60-60v408q0 24-18 42t-42 18H180Zm300-360ZM360-360v-170l382-382q9-9 20-13t22-4q11 0 22.32 4.5Q817.63-920 827-911l83 84q8.61 8.96 13.3 19.78 4.7 10.83 4.7 22.02 0 11.2-4.5 22.7T910-742L530-360H360Zm508-425-84-84 84 84ZM420-420h85l253-253-43-42-43-42-252 251v86Zm295-295-43-42 43 42 43 42-43-42Z"
1168
+ ],
1169
+ expand_more: ["0 -960 960 960", "M480-345 240-585l43-43 197 198 197-197 43 43-240 239Z"],
1170
+ info: [
1171
+ "0 -960 960 960",
1172
+ "M453-280h60v-240h-60v240Zm50.5-323.2q9.5-9.2 9.5-22.8 0-14.45-9.48-24.22-9.48-9.78-23.5-9.78t-23.52 9.78Q447-640.45 447-626q0 13.6 9.48 22.8 9.48 9.2 23.5 9.2t23.52-9.2ZM480.27-80q-82.74 0-155.5-31.5Q252-143 197.5-197.5t-86-127.34Q80-397.68 80-480.5t31.5-155.66Q143-709 197.5-763t127.34-85.5Q397.68-880 480.5-880t155.66 31.5Q709-817 763-763t85.5 127Q880-563 880-480.27q0 82.74-31.5 155.5Q817-252 763-197.68q-54 54.31-127 86Q563-80 480.27-80Zm.23-60Q622-140 721-239.5t99-241Q820-622 721.19-721T480-820q-141 0-240.5 98.81T140-480q0 141 99.5 240.5t241 99.5Zm-.5-340Z"
1173
+ ],
1174
+ mic: [
1175
+ "0 -960 960 960",
1176
+ "M408-453.92q-29-30.91-29-75.08v-251q0-41.67 29.44-70.83Q437.88-880 479.94-880t71.56 29.17Q581-821.67 581-780v251q0 44.17-29 75.08Q523-423 480-423t-72-30.92ZM480-651Zm-30 531v-136q-106-11-178-89t-72-184h60q0 91 64.29 153t155.5 62q91.21 0 155.71-62Q700-438 700-529h60q0 106-72 184t-178 89v136h-60Zm59.5-376.5Q521-510 521-529v-251q0-17-11.79-28.5T480-820q-17.42 0-29.21 11.5T439-780v251q0 19 11.5 32.5T480-483q18 0 29.5-13.5Z"
1177
+ ],
1178
+ open_in_new: [
1179
+ "0 -960 960 960",
1180
+ "M180-120q-24 0-42-18t-18-42v-600q0-24 18-42t42-18h279v60H180v600h600v-279h60v279q0 24-18 42t-42 18H180Zm202-219-42-43 398-398H519v-60h321v321h-60v-218L382-339Z"
1181
+ ],
1182
+ refresh: [
1183
+ "0 -960 960 960",
1184
+ "M480-160q-133 0-226.5-93.5T160-480q0-133 93.5-226.5T480-800q85 0 149 34.5T740-671v-129h60v254H546v-60h168q-38-60-97-97t-137-37q-109 0-184.5 75.5T220-480q0 109 75.5 184.5T480-220q83 0 152-47.5T728-393h62q-29 105-115 169t-195 64Z"
1185
+ ],
1186
+ search: [
1187
+ "0 -960 960 960",
1188
+ "M796-121 533-384q-30 26-70 40.5T378-329q-108 0-183-75t-75-181q0-106 75-181t182-75q106 0 180.5 75T632-585q0 43-14 83t-42 75l264 262-44 44ZM377-389q81 0 138-57.5T572-585q0-81-57-138.5T377-781q-82 0-139.5 57.5T180-585q0 81 57.5 138.5T377-389Z"
1189
+ ],
1190
+ stop_filled: ["0 -960 960 960", "M240-240v-480h480v480H240Z"],
1191
+ stop: ["0 -960 960 960", "M300-660v360-360Zm-60 420v-480h480v480H240Zm60-60h360v-360H300v360Z"],
1192
+ thumb_down: [
1193
+ "0 -960 960 960",
1194
+ "M242-840h444v512L408-40l-39-31q-6-5-9-14t-3-22v-10l45-211H103q-24 0-42-18t-18-42v-81.84q0-7.16-1.5-14.66T43-499l126-290q8.88-21.25 29.59-36.13Q219.31-840 242-840Zm384 60H229L103-481v93h373l-53 249 203-214v-427Zm0 427v-427 427Zm60 25v-60h133v-392H686v-60h193v512H686Z"
1195
+ ]
1196
+ };
1197
+ var chatIconNames = Object.keys(CHAT_ICON_PATHS);
1198
+ function ChatIcon({ name, size = 24, className }) {
1199
+ const [viewBox, d] = CHAT_ICON_PATHS[name];
1200
+ return /* @__PURE__ */ jsx4("svg", {
1201
+ xmlns: "http://www.w3.org/2000/svg",
1202
+ viewBox,
1203
+ width: size,
1204
+ height: size,
1205
+ fill: "currentColor",
1206
+ "aria-hidden": "true",
1207
+ focusable: "false",
1208
+ "data-m3-icon": name,
1209
+ className: clsx4("m3-icon shrink-0", className),
1210
+ children: /* @__PURE__ */ jsx4("path", {
1211
+ d
1212
+ })
1213
+ });
1214
+ }
1215
+
1216
+ // m3/packages/m3-ai/src/Markdown.tsx
1217
+ import { jsx as jsx5, jsxs as jsxs4, Fragment } from "react/jsx-runtime";
967
1218
  "use client";
1219
+ function isExternalHref(href) {
1220
+ if (!href)
1221
+ return false;
1222
+ return /^[a-z][a-z0-9+.-]*:/i.test(href) || href.startsWith("//");
1223
+ }
1224
+ var externalLinkProps = { target: "_blank", rel: "noopener noreferrer" };
968
1225
  var bodyClass = {
969
1226
  small: "text-body-small",
970
1227
  medium: "text-body-medium",
@@ -1052,8 +1309,10 @@ function CodeBlock({
1052
1309
  onCopy,
1053
1310
  className,
1054
1311
  children,
1312
+ labels,
1055
1313
  ...restProps
1056
1314
  }) {
1315
+ const l = resolveChatLabels(labels);
1057
1316
  const { node: _node, ...props } = restProps;
1058
1317
  const [copied, setCopied] = useState3(false);
1059
1318
  const timeoutRef = useRef2(null);
@@ -1085,38 +1344,38 @@ function CodeBlock({
1085
1344
  }, 2000);
1086
1345
  };
1087
1346
  return /* @__PURE__ */ jsxs4("div", {
1088
- className: clsx4("my-3 overflow-hidden rounded-medium border border-outline-variant bg-surface-container-highest", className),
1347
+ className: clsx5("my-3 overflow-hidden rounded-medium border border-outline-variant bg-surface-container-highest", className),
1089
1348
  ...props,
1090
1349
  children: [
1091
1350
  /* @__PURE__ */ jsxs4("div", {
1092
1351
  className: "flex items-center justify-between border-b border-outline-variant bg-surface-container px-3 py-1.5",
1093
1352
  children: [
1094
- /* @__PURE__ */ jsx4("span", {
1353
+ /* @__PURE__ */ jsx5("span", {
1095
1354
  className: "inline-flex items-center rounded-extra-small bg-surface-container-high px-2 py-0.5 text-label-small font-medium text-on-surface-variant border border-outline-variant/60",
1096
1355
  children: languageLabel
1097
1356
  }),
1098
1357
  /* @__PURE__ */ jsxs4("button", {
1099
1358
  type: "button",
1100
1359
  onClick: handleCopy,
1101
- className: clsx4("inline-flex items-center gap-1.5 rounded-small px-2 py-1 text-label-small font-medium transition-colors duration-200", copied ? "text-success" : "text-on-surface-variant hover:bg-on-surface/8 hover:text-on-surface active:bg-on-surface/12", "focus-visible:outline-2 focus-visible:outline-primary"),
1102
- "aria-label": copied ? "Copied" : "Copy code",
1103
- title: copied ? "Copied!" : "Copy code",
1360
+ className: clsx5("inline-flex items-center gap-1.5 rounded-small px-2 py-1 text-label-small font-medium transition-colors duration-200", copied ? "text-success" : "text-on-surface-variant hover:bg-on-surface/8 hover:text-on-surface active:bg-on-surface/12", "focus-visible:outline-2 focus-visible:outline-primary"),
1361
+ "aria-label": copied ? l.copied : l.copyCode,
1362
+ title: copied ? l.copied : l.copyCode,
1104
1363
  children: [
1105
- /* @__PURE__ */ jsx4(Icon2, {
1364
+ /* @__PURE__ */ jsx5(ChatIcon, {
1106
1365
  name: copied ? "check" : "content_copy",
1107
1366
  size: 16,
1108
1367
  className: copied ? "text-success" : undefined
1109
1368
  }),
1110
- /* @__PURE__ */ jsx4("span", {
1111
- children: copied ? "Copied!" : "Copy"
1369
+ /* @__PURE__ */ jsx5("span", {
1370
+ children: copied ? l.copied : l.copy
1112
1371
  })
1113
1372
  ]
1114
1373
  })
1115
1374
  ]
1116
1375
  }),
1117
- /* @__PURE__ */ jsx4("pre", {
1376
+ /* @__PURE__ */ jsx5("pre", {
1118
1377
  className: "overflow-x-auto p-3 font-code text-body-small text-on-surface bg-surface-container-highest [&_code]:bg-transparent [&_code]:p-0 [&_code]:text-[length:inherit]",
1119
- children: /* @__PURE__ */ jsx4("code", {
1378
+ children: /* @__PURE__ */ jsx5("code", {
1120
1379
  className: rawLang ? `language-${rawLang}` : undefined,
1121
1380
  children: codeContent
1122
1381
  })
@@ -1205,14 +1464,14 @@ function formatSubSup(text) {
1205
1464
  const key = `${part}:${occurrence}`;
1206
1465
  if (part.startsWith("^")) {
1207
1466
  const val = part.startsWith("^{") && part.endsWith("}") ? part.slice(2, -1) : part.slice(1);
1208
- return /* @__PURE__ */ jsx4("sup", {
1467
+ return /* @__PURE__ */ jsx5("sup", {
1209
1468
  className: "text-[0.75em] leading-none",
1210
1469
  children: val
1211
1470
  }, key);
1212
1471
  }
1213
1472
  if (part.startsWith("_")) {
1214
1473
  const val = part.startsWith("_{") && part.endsWith("}") ? part.slice(2, -1) : part.slice(1);
1215
- return /* @__PURE__ */ jsx4("sub", {
1474
+ return /* @__PURE__ */ jsx5("sub", {
1216
1475
  className: "text-[0.75em] leading-none",
1217
1476
  children: val
1218
1477
  }, key);
@@ -1235,11 +1494,11 @@ function formatMathContent(math) {
1235
1494
  parts.push(/* @__PURE__ */ jsxs4("span", {
1236
1495
  className: "inline-flex flex-col items-center align-middle mx-1 text-center text-[0.85em] leading-none not-italic",
1237
1496
  children: [
1238
- /* @__PURE__ */ jsx4("span", {
1497
+ /* @__PURE__ */ jsx5("span", {
1239
1498
  className: "border-b border-current px-0.5 pb-0.5",
1240
1499
  children: formatSubSup(num)
1241
1500
  }),
1242
- /* @__PURE__ */ jsx4("span", {
1501
+ /* @__PURE__ */ jsx5("span", {
1243
1502
  className: "px-0.5 pt-0.5",
1244
1503
  children: formatSubSup(den)
1245
1504
  })
@@ -1256,15 +1515,15 @@ function formatMathContent(math) {
1256
1515
  return formatSubSup(text);
1257
1516
  }
1258
1517
  function InlineMath({ math, className, ...props }) {
1259
- return /* @__PURE__ */ jsx4("span", {
1260
- className: clsx4("inline-flex items-center px-1 font-serif italic font-medium text-primary", className),
1518
+ return /* @__PURE__ */ jsx5("span", {
1519
+ className: clsx5("inline-flex items-center px-1 font-serif italic font-medium text-primary", className),
1261
1520
  ...props,
1262
1521
  children: formatMathContent(math)
1263
1522
  });
1264
1523
  }
1265
1524
  function BlockMath({ math, className, ...props }) {
1266
- return /* @__PURE__ */ jsx4("div", {
1267
- className: clsx4("my-3 flex justify-center overflow-x-auto rounded-medium bg-surface-container-low/40 px-4 py-2 text-title-medium font-serif italic font-medium text-primary", className),
1525
+ return /* @__PURE__ */ jsx5("div", {
1526
+ className: clsx5("my-3 flex justify-center overflow-x-auto rounded-medium bg-surface-container-low/40 px-4 py-2 text-title-medium font-serif italic font-medium text-primary", className),
1268
1527
  ...props,
1269
1528
  children: formatMathContent(math)
1270
1529
  });
@@ -1359,118 +1618,133 @@ function transformMathTree(tree) {
1359
1618
  function remarkMathPlugin() {
1360
1619
  return transformMathTree;
1361
1620
  }
1362
- function m3Components(size) {
1621
+ function m3Components(size, link = {}) {
1363
1622
  const body = bodyClass[size];
1364
1623
  return {
1365
- h1: ({ node: _node, className, children, ...props }) => /* @__PURE__ */ jsx4("h1", {
1366
- className: clsx4("mt-4 mb-2 text-headline-small text-on-surface first:mt-0", className),
1624
+ h1: ({ node: _node, className, children, ...props }) => /* @__PURE__ */ jsx5("h1", {
1625
+ className: clsx5("mt-4 mb-2 text-headline-small text-on-surface first:mt-0", className),
1367
1626
  ...props,
1368
1627
  children
1369
1628
  }),
1370
- h2: ({ node: _node, className, children, ...props }) => /* @__PURE__ */ jsx4("h2", {
1371
- className: clsx4("mt-4 mb-2 text-title-large text-on-surface first:mt-0", className),
1629
+ h2: ({ node: _node, className, children, ...props }) => /* @__PURE__ */ jsx5("h2", {
1630
+ className: clsx5("mt-4 mb-2 text-title-large text-on-surface first:mt-0", className),
1372
1631
  ...props,
1373
1632
  children
1374
1633
  }),
1375
- h3: ({ node: _node, className, children, ...props }) => /* @__PURE__ */ jsx4("h3", {
1376
- className: clsx4("mt-3 mb-1.5 text-title-medium text-on-surface first:mt-0", className),
1634
+ h3: ({ node: _node, className, children, ...props }) => /* @__PURE__ */ jsx5("h3", {
1635
+ className: clsx5("mt-3 mb-1.5 text-title-medium text-on-surface first:mt-0", className),
1377
1636
  ...props,
1378
1637
  children
1379
1638
  }),
1380
- h4: ({ node: _node, className, children, ...props }) => /* @__PURE__ */ jsx4("h4", {
1381
- className: clsx4("mt-3 mb-1 text-title-small text-on-surface first:mt-0", className),
1639
+ h4: ({ node: _node, className, children, ...props }) => /* @__PURE__ */ jsx5("h4", {
1640
+ className: clsx5("mt-3 mb-1 text-title-small text-on-surface first:mt-0", className),
1382
1641
  ...props,
1383
1642
  children
1384
1643
  }),
1385
- h5: ({ node: _node, className, children, ...props }) => /* @__PURE__ */ jsx4("h5", {
1386
- className: clsx4("mt-3 mb-1 text-title-small text-on-surface-variant first:mt-0", className),
1644
+ h5: ({ node: _node, className, children, ...props }) => /* @__PURE__ */ jsx5("h5", {
1645
+ className: clsx5("mt-3 mb-1 text-title-small text-on-surface-variant first:mt-0", className),
1387
1646
  ...props,
1388
1647
  children
1389
1648
  }),
1390
- h6: ({ node: _node, className, children, ...props }) => /* @__PURE__ */ jsx4("h6", {
1391
- className: clsx4("mt-3 mb-1 text-label-large text-on-surface-variant first:mt-0", className),
1649
+ h6: ({ node: _node, className, children, ...props }) => /* @__PURE__ */ jsx5("h6", {
1650
+ className: clsx5("mt-3 mb-1 text-label-large text-on-surface-variant first:mt-0", className),
1392
1651
  ...props,
1393
1652
  children
1394
1653
  }),
1395
- p: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx4("p", {
1396
- className: clsx4("my-2 first:mt-0 last:mb-0", body, className),
1654
+ p: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx5("p", {
1655
+ className: clsx5("my-2 first:mt-0 last:mb-0", body, className),
1397
1656
  ...props
1398
1657
  }),
1399
- a: ({ node: _node, className, children, ...props }) => /* @__PURE__ */ jsx4("a", {
1400
- className: clsx4("text-primary underline underline-offset-2 hover:decoration-2", "rounded-extra-small outline-none focus-visible:outline-3 focus-visible:outline-secondary focus-visible:outline-offset-2", className),
1401
- ...props,
1402
- children
1403
- }),
1404
- strong: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx4("strong", {
1405
- className: clsx4("font-semibold text-on-surface", className),
1658
+ a: ({ node: _node, className, children, href, onClick, ...props }) => {
1659
+ const external = isExternalHref(href);
1660
+ if (link.renderLink)
1661
+ return /* @__PURE__ */ jsx5(Fragment, {
1662
+ children: link.renderLink({ href: href ?? "", children, external })
1663
+ });
1664
+ return /* @__PURE__ */ jsx5("a", {
1665
+ className: clsx5("text-primary underline underline-offset-2 hover:decoration-2", "rounded-extra-small outline-none focus-visible:outline-3 focus-visible:outline-secondary focus-visible:outline-offset-2", className),
1666
+ href,
1667
+ ...external ? externalLinkProps : {},
1668
+ onClick: (event) => {
1669
+ onClick?.(event);
1670
+ if (href)
1671
+ link.onLinkClick?.(href, event);
1672
+ },
1673
+ ...props,
1674
+ children
1675
+ });
1676
+ },
1677
+ strong: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx5("strong", {
1678
+ className: clsx5("font-semibold text-on-surface", className),
1406
1679
  ...props
1407
1680
  }),
1408
- ul: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx4("ul", {
1409
- className: clsx4("my-2 list-disc pl-6 marker:text-on-surface-variant", body, className),
1681
+ ul: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx5("ul", {
1682
+ className: clsx5("my-2 list-disc pl-6 marker:text-on-surface-variant", body, className),
1410
1683
  ...props
1411
1684
  }),
1412
- ol: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx4("ol", {
1413
- className: clsx4("my-2 list-decimal pl-6 marker:text-on-surface-variant", body, className),
1685
+ ol: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx5("ol", {
1686
+ className: clsx5("my-2 list-decimal pl-6 marker:text-on-surface-variant", body, className),
1414
1687
  ...props
1415
1688
  }),
1416
- li: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx4("li", {
1417
- className: clsx4("my-1", className),
1689
+ li: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx5("li", {
1690
+ className: clsx5("my-1", className),
1418
1691
  ...props
1419
1692
  }),
1420
- blockquote: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx4("blockquote", {
1421
- className: clsx4("my-3 border-l-4 border-outline-variant pl-4 text-on-surface-variant", className),
1693
+ blockquote: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx5("blockquote", {
1694
+ className: clsx5("my-3 border-l-4 border-outline-variant pl-4 text-on-surface-variant", className),
1422
1695
  ...props
1423
1696
  }),
1424
- code: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx4("code", {
1425
- className: clsx4("rounded-extra-small bg-surface-container-highest px-1 py-0.5 font-code text-[0.9em] text-on-surface", className),
1697
+ code: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx5("code", {
1698
+ className: clsx5("rounded-extra-small bg-surface-container-highest px-1 py-0.5 font-code text-[0.9em] text-on-surface", className),
1426
1699
  ...props
1427
1700
  }),
1428
- pre: ({ node: _node, children, className, style }) => /* @__PURE__ */ jsx4(CodeBlock, {
1701
+ pre: ({ node: _node, children, className, style }) => /* @__PURE__ */ jsx5(CodeBlock, {
1429
1702
  className,
1430
1703
  style,
1704
+ labels: link.labels,
1431
1705
  children
1432
1706
  }),
1433
- hr: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx4("hr", {
1434
- className: clsx4("my-4 border-outline-variant", className),
1707
+ hr: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx5("hr", {
1708
+ className: clsx5("my-4 border-outline-variant", className),
1435
1709
  ...props
1436
1710
  }),
1437
- table: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx4("div", {
1711
+ table: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx5("div", {
1438
1712
  className: "my-3 overflow-x-auto rounded-small border border-outline-variant",
1439
- children: /* @__PURE__ */ jsx4("table", {
1440
- className: clsx4("w-full border-collapse", body, className),
1713
+ children: /* @__PURE__ */ jsx5("table", {
1714
+ className: clsx5("w-full border-collapse", body, className),
1441
1715
  ...props
1442
1716
  })
1443
1717
  }),
1444
- thead: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx4("thead", {
1445
- className: clsx4("bg-surface-container", className),
1718
+ thead: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx5("thead", {
1719
+ className: clsx5("bg-surface-container", className),
1446
1720
  ...props
1447
1721
  }),
1448
- th: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx4("th", {
1449
- className: clsx4("border-b border-outline-variant px-3 py-2 text-left text-title-small text-on-surface", className),
1722
+ th: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx5("th", {
1723
+ className: clsx5("border-b border-outline-variant px-3 py-2 text-left text-title-small text-on-surface", className),
1450
1724
  ...props
1451
1725
  }),
1452
- td: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx4("td", {
1453
- className: clsx4("border-t border-outline-variant px-3 py-2 text-on-surface", className),
1726
+ td: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx5("td", {
1727
+ className: clsx5("border-t border-outline-variant px-3 py-2 text-on-surface", className),
1454
1728
  ...props
1455
1729
  }),
1456
- img: ({ node: _node, className, alt, ...props }) => /* @__PURE__ */ jsx4("img", {
1457
- className: clsx4("my-2 max-w-full rounded-medium", className),
1730
+ img: ({ node: _node, className, alt, ...props }) => /* @__PURE__ */ jsx5("img", {
1731
+ className: clsx5("my-2 max-w-full rounded-medium", className),
1458
1732
  alt: alt ?? "",
1459
1733
  ...props
1460
1734
  }),
1461
- input: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx4("input", {
1462
- className: clsx4("mr-2 accent-primary", className),
1735
+ input: ({ node: _node, className, ...props }) => /* @__PURE__ */ jsx5("input", {
1736
+ className: clsx5("mr-2 accent-primary", className),
1463
1737
  ...props
1464
1738
  }),
1465
1739
  div: ({ node: _node, className, children, ...props }) => {
1466
1740
  if (className?.includes("math-block")) {
1467
1741
  const math = props["data-math"] ?? extractText(children);
1468
- return /* @__PURE__ */ jsx4(BlockMath, {
1742
+ return /* @__PURE__ */ jsx5(BlockMath, {
1469
1743
  math,
1470
1744
  className
1471
1745
  });
1472
1746
  }
1473
- return /* @__PURE__ */ jsx4("div", {
1747
+ return /* @__PURE__ */ jsx5("div", {
1474
1748
  className,
1475
1749
  ...props,
1476
1750
  children
@@ -1479,12 +1753,12 @@ function m3Components(size) {
1479
1753
  span: ({ node: _node, className, children, ...props }) => {
1480
1754
  if (className?.includes("math-inline")) {
1481
1755
  const math = props["data-math"] ?? extractText(children);
1482
- return /* @__PURE__ */ jsx4(InlineMath, {
1756
+ return /* @__PURE__ */ jsx5(InlineMath, {
1483
1757
  math,
1484
1758
  className
1485
1759
  });
1486
1760
  }
1487
- return /* @__PURE__ */ jsx4("span", {
1761
+ return /* @__PURE__ */ jsx5("span", {
1488
1762
  className,
1489
1763
  ...props,
1490
1764
  children
@@ -1492,23 +1766,219 @@ function m3Components(size) {
1492
1766
  }
1493
1767
  };
1494
1768
  }
1495
- var Markdown = forwardRef(({ content, className, size = "medium", allowHtml = false }, ref) => {
1496
- return /* @__PURE__ */ jsx4("div", {
1769
+ var Markdown = forwardRef(({
1770
+ content,
1771
+ className,
1772
+ size = "medium",
1773
+ allowHtml = false,
1774
+ components,
1775
+ onLinkClick,
1776
+ renderLink,
1777
+ labels
1778
+ }, ref) => {
1779
+ const base = m3Components(size, { onLinkClick, renderLink, labels });
1780
+ return /* @__PURE__ */ jsx5("div", {
1497
1781
  ref,
1498
- className: clsx4("markdown min-w-0 text-on-surface", bodyClass[size], className),
1499
- children: /* @__PURE__ */ jsx4(ReactMarkdown, {
1782
+ className: clsx5("markdown min-w-0 text-on-surface", bodyClass[size], className),
1783
+ children: /* @__PURE__ */ jsx5(ReactMarkdown, {
1500
1784
  remarkPlugins: [remarkGfm, remarkMathPlugin],
1501
1785
  rehypePlugins: allowHtml ? [rehypeRaw] : undefined,
1502
- components: m3Components(size),
1786
+ components: components ? { ...base, ...components } : base,
1503
1787
  children: content
1504
1788
  })
1505
1789
  });
1506
1790
  });
1507
1791
  Markdown.displayName = "Markdown";
1508
- // packages/m3-ai/src/MessageBubble.tsx
1792
+ // m3/packages/m3-ai/src/MessageBubble.tsx
1509
1793
  import { CircleButton } from "@aphrody/m3-primitives";
1510
- import { clsx as clsx5 } from "clsx";
1511
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1794
+ import { clsx as clsx7 } from "clsx";
1795
+
1796
+ // m3/packages/m3-ai/src/citations.tsx
1797
+ import { clsx as clsx6 } from "clsx";
1798
+ import { useMemo as useMemo2 } from "react";
1799
+ import { jsx as jsx6, jsxs as jsxs5, Fragment as Fragment2 } from "react/jsx-runtime";
1800
+ "use client";
1801
+ var CITATION_HREF = "#citation-";
1802
+ var CODE_SPANS = /(```[\s\S]*?```|`[^`\n]*`)/;
1803
+ var MARKER = /(?<![\]\\!])\[(\d{1,4})\](?!\()/g;
1804
+ function linkCitationMarkers(content, citations) {
1805
+ if (citations.length === 0)
1806
+ return content;
1807
+ const known = new Set(citations.map((citation) => citation.n));
1808
+ return content.split(CODE_SPANS).map((part, index) => index % 2 === 1 ? part : part.replace(MARKER, (match, digits) => known.has(Number(digits)) ? `[\\[${digits}\\]](${CITATION_HREF}${digits})` : match)).join("");
1809
+ }
1810
+ function citedNumbers(content) {
1811
+ const seen = [];
1812
+ for (const part of content.split(CODE_SPANS).filter((_, index) => index % 2 === 0)) {
1813
+ for (const match of part.matchAll(MARKER)) {
1814
+ const n = Number(match[1]);
1815
+ if (!seen.includes(n))
1816
+ seen.push(n);
1817
+ }
1818
+ }
1819
+ return seen;
1820
+ }
1821
+ function CitationChip({ citation, labels, onSelect, className }) {
1822
+ const l = resolveChatLabels(labels);
1823
+ const label = `${formatLabel(l.citation, { n: citation.n })}: ${citation.title}`;
1824
+ const chipClass = clsx6("mx-0.5 inline-flex h-5 min-w-5 items-center justify-center rounded-small px-1 align-baseline", "bg-secondary-container text-label-small text-on-secondary-container no-underline", "transition-colors duration-200 ease-standard hover:bg-secondary-container/80", focusRing, className);
1825
+ if (!onSelect && citation.url) {
1826
+ return /* @__PURE__ */ jsx6("a", {
1827
+ href: citation.url,
1828
+ target: "_blank",
1829
+ rel: "noreferrer noopener",
1830
+ className: chipClass,
1831
+ "aria-label": label,
1832
+ title: citation.title,
1833
+ children: citation.n
1834
+ });
1835
+ }
1836
+ return /* @__PURE__ */ jsx6("button", {
1837
+ type: "button",
1838
+ className: chipClass,
1839
+ "aria-label": label,
1840
+ title: citation.title,
1841
+ onClick: () => onSelect?.(citation),
1842
+ children: citation.n
1843
+ });
1844
+ }
1845
+ function citationComponents(citations, labels, onCitationSelect, onLinkClick) {
1846
+ const byNumber = new Map(citations.map((citation) => [citation.n, citation]));
1847
+ return {
1848
+ a: ({ node: _node, href, children, onClick, ...props }) => {
1849
+ if (href?.startsWith(CITATION_HREF)) {
1850
+ const citation = byNumber.get(Number(href.slice(CITATION_HREF.length)));
1851
+ if (citation)
1852
+ return /* @__PURE__ */ jsx6(CitationChip, {
1853
+ citation,
1854
+ labels,
1855
+ onSelect: onCitationSelect
1856
+ });
1857
+ }
1858
+ return /* @__PURE__ */ jsx6("a", {
1859
+ href,
1860
+ ...isExternalHref(href) ? externalLinkProps : {},
1861
+ onClick: (event) => {
1862
+ onClick?.(event);
1863
+ if (href)
1864
+ onLinkClick?.(href, event);
1865
+ },
1866
+ className: clsx6("rounded-extra-small text-primary underline underline-offset-2 hover:decoration-2", focusRing),
1867
+ ...props,
1868
+ children
1869
+ });
1870
+ }
1871
+ };
1872
+ }
1873
+ function CitedMarkdown({
1874
+ content,
1875
+ citations,
1876
+ labels,
1877
+ onCitationSelect,
1878
+ onLinkClick,
1879
+ size = "large",
1880
+ className
1881
+ }) {
1882
+ const components = useMemo2(() => citationComponents(citations, labels, onCitationSelect, onLinkClick), [citations, labels, onCitationSelect, onLinkClick]);
1883
+ return /* @__PURE__ */ jsx6(Markdown, {
1884
+ content: linkCitationMarkers(content, citations),
1885
+ components,
1886
+ labels,
1887
+ size,
1888
+ className
1889
+ });
1890
+ }
1891
+ function CitationList({ citations, labels, onSelect, className }) {
1892
+ if (citations.length === 0)
1893
+ return null;
1894
+ const l = resolveChatLabels(labels);
1895
+ const sorted = [...citations];
1896
+ sorted.sort((a, b) => a.n - b.n);
1897
+ return /* @__PURE__ */ jsxs5("section", {
1898
+ "aria-label": l.sources,
1899
+ className: clsx6("m3-citation-list mt-2 rounded-medium bg-surface-container-low py-2", className),
1900
+ children: [
1901
+ /* @__PURE__ */ jsx6("h3", {
1902
+ className: "px-4 pb-1 text-label-large text-on-surface-variant",
1903
+ children: l.sources
1904
+ }),
1905
+ /* @__PURE__ */ jsx6("ol", {
1906
+ className: "m-0 list-none p-0",
1907
+ children: sorted.map((citation) => {
1908
+ const body = /* @__PURE__ */ jsxs5(Fragment2, {
1909
+ children: [
1910
+ /* @__PURE__ */ jsx6("span", {
1911
+ className: "flex size-6 shrink-0 items-center justify-center rounded-small bg-secondary-container text-label-small text-on-secondary-container",
1912
+ children: citation.n
1913
+ }),
1914
+ /* @__PURE__ */ jsx6("span", {
1915
+ className: "min-w-0 flex-1 truncate text-body-medium text-on-surface",
1916
+ children: citation.title
1917
+ }),
1918
+ citation.url || onSelect ? /* @__PURE__ */ jsx6(ChatIcon, {
1919
+ name: "open_in_new",
1920
+ size: 18,
1921
+ className: "text-on-surface-variant"
1922
+ }) : null
1923
+ ]
1924
+ });
1925
+ const rowClass = clsx6("flex min-h-12 w-full items-center gap-3 px-4 py-1 text-left", "transition-colors duration-200 ease-standard hover:bg-on-surface/8", focusRing, "focus-visible:outline-offset-[-3px]");
1926
+ const name = `${formatLabel(l.citation, { n: citation.n })}: ${citation.title}`;
1927
+ return /* @__PURE__ */ jsx6("li", {
1928
+ id: `citation-${citation.n}`,
1929
+ children: onSelect ? /* @__PURE__ */ jsx6("button", {
1930
+ type: "button",
1931
+ className: rowClass,
1932
+ "aria-label": name,
1933
+ onClick: () => onSelect(citation),
1934
+ children: body
1935
+ }) : citation.url ? /* @__PURE__ */ jsx6("a", {
1936
+ href: citation.url,
1937
+ target: "_blank",
1938
+ rel: "noreferrer noopener",
1939
+ className: rowClass,
1940
+ "aria-label": `${name} (${l.openSource})`,
1941
+ children: body
1942
+ }) : /* @__PURE__ */ jsx6("div", {
1943
+ className: "flex min-h-12 items-center gap-3 px-4 py-1",
1944
+ children: body
1945
+ })
1946
+ }, `${citation.n}-${citation.id ?? citation.title}`);
1947
+ })
1948
+ })
1949
+ ]
1950
+ });
1951
+ }
1952
+ function RefusalNotice({ labels, detail, className }) {
1953
+ const l = resolveChatLabels(labels);
1954
+ return /* @__PURE__ */ jsxs5("div", {
1955
+ role: "note",
1956
+ className: clsx6("m3-refusal-notice flex items-start gap-3 rounded-medium bg-surface-container-high px-4 py-3", className),
1957
+ children: [
1958
+ /* @__PURE__ */ jsx6(ChatIcon, {
1959
+ name: "info",
1960
+ size: 20,
1961
+ className: "mt-0.5 text-on-surface-variant"
1962
+ }),
1963
+ /* @__PURE__ */ jsxs5("div", {
1964
+ className: "min-w-0",
1965
+ children: [
1966
+ /* @__PURE__ */ jsx6("p", {
1967
+ className: "m-0 text-title-small text-on-surface",
1968
+ children: l.refusalTitle
1969
+ }),
1970
+ /* @__PURE__ */ jsx6("p", {
1971
+ className: "m-0 mt-0.5 text-body-medium text-on-surface-variant",
1972
+ children: detail || l.refusalBody
1973
+ })
1974
+ ]
1975
+ })
1976
+ ]
1977
+ });
1978
+ }
1979
+
1980
+ // m3/packages/m3-ai/src/MessageBubble.tsx
1981
+ import { jsx as jsx7, jsxs as jsxs6, Fragment as Fragment3 } from "react/jsx-runtime";
1512
1982
  "use client";
1513
1983
  function MessageBubble({
1514
1984
  content,
@@ -1518,62 +1988,102 @@ function MessageBubble({
1518
1988
  onDislike,
1519
1989
  onFork,
1520
1990
  variant = "default",
1521
- className
1991
+ className,
1992
+ labels,
1993
+ citations,
1994
+ refusal = false,
1995
+ onCitationSelect,
1996
+ onLinkClick
1522
1997
  }) {
1523
1998
  const isCodex = variant === "codex";
1524
- return /* @__PURE__ */ jsxs5("div", {
1525
- className: clsx5("group flex flex-col py-1.5 w-full", isUser ? "items-end" : "items-start", className),
1999
+ const l = resolveChatLabels(labels);
2000
+ const cited = !isUser && citations && citations.length > 0 ? citations : null;
2001
+ return /* @__PURE__ */ jsxs6("div", {
2002
+ className: clsx7("group flex flex-col py-1.5 w-full", isUser ? "items-end" : "items-start", className),
1526
2003
  children: [
1527
- /* @__PURE__ */ jsx5("div", {
1528
- className: clsx5("min-w-0", isUser ? isCodex ? "max-w-[75%] rounded-[28px] bg-surface-container-high px-5 py-3 text-body-large text-on-surface shadow-xs" : "max-w-[80%] rounded-large rounded-br-extra-small bg-secondary-container px-4 py-2.5 text-body-large text-on-secondary-container" : "w-full max-w-full bg-transparent text-body-large text-on-surface"),
2004
+ /* @__PURE__ */ jsx7("div", {
2005
+ className: clsx7("min-w-0", isUser ? isCodex ? "max-w-[75%] rounded-[28px] bg-surface-container-high px-5 py-3 text-body-large text-on-surface shadow-xs" : "max-w-[80%] rounded-large rounded-br-extra-small bg-secondary-container px-4 py-2.5 text-body-large text-on-secondary-container" : "w-full max-w-full bg-transparent text-body-large text-on-surface"),
1529
2006
  "aria-busy": isStreaming || undefined,
1530
- children: isUser ? /* @__PURE__ */ jsx5("div", {
2007
+ children: isUser ? /* @__PURE__ */ jsx7("div", {
1531
2008
  className: "whitespace-pre-wrap break-words",
1532
2009
  children: content
1533
- }) : /* @__PURE__ */ jsx5(Markdown, {
1534
- content,
1535
- size: "large",
1536
- className: "break-words font-sans"
2010
+ }) : /* @__PURE__ */ jsxs6(Fragment3, {
2011
+ children: [
2012
+ refusal && !content.trim() ? /* @__PURE__ */ jsx7(RefusalNotice, {
2013
+ labels
2014
+ }) : cited ? /* @__PURE__ */ jsx7(CitedMarkdown, {
2015
+ content,
2016
+ citations: cited,
2017
+ labels,
2018
+ onCitationSelect,
2019
+ onLinkClick,
2020
+ className: "break-words font-sans"
2021
+ }) : /* @__PURE__ */ jsx7(Markdown, {
2022
+ content,
2023
+ size: "large",
2024
+ labels,
2025
+ onLinkClick,
2026
+ className: "break-words font-sans"
2027
+ }),
2028
+ refusal && content.trim() ? /* @__PURE__ */ jsx7(RefusalNotice, {
2029
+ labels,
2030
+ className: "mt-2"
2031
+ }) : null,
2032
+ cited && !isStreaming ? /* @__PURE__ */ jsx7(CitationList, {
2033
+ citations: cited,
2034
+ labels,
2035
+ onSelect: onCitationSelect
2036
+ }) : null
2037
+ ]
1537
2038
  })
1538
2039
  }),
1539
- !isUser && (onCopy || onDislike || onFork) ? /* @__PURE__ */ jsxs5("div", {
2040
+ !isUser && (onCopy || onDislike || onFork) ? /* @__PURE__ */ jsxs6("div", {
1540
2041
  className: "mt-1.5 flex items-center gap-1 opacity-0 transition-opacity duration-200 ease-standard group-focus-within:opacity-100 group-hover:opacity-100",
1541
2042
  children: [
1542
- onCopy && /* @__PURE__ */ jsx5(CircleButton, {
1543
- icon: "content_copy",
2043
+ onCopy && /* @__PURE__ */ jsx7(CircleButton, {
2044
+ icon: /* @__PURE__ */ jsx7(ChatIcon, {
2045
+ name: "content_copy",
2046
+ size: 18
2047
+ }),
1544
2048
  variant: "standard",
1545
2049
  size: "sm",
1546
2050
  onClick: () => onCopy(content),
1547
- "aria-label": isStreaming ? "Copy Streaming Message" : "Copy Message",
1548
- title: isStreaming ? "Copy streaming message" : "Copier"
2051
+ "aria-label": isStreaming ? l.copyStreamingMessage : l.copyMessage,
2052
+ title: isStreaming ? l.copyStreamingMessage : l.copyMessage
1549
2053
  }),
1550
- onDislike && /* @__PURE__ */ jsx5(CircleButton, {
1551
- icon: "thumb_down",
2054
+ onDislike && /* @__PURE__ */ jsx7(CircleButton, {
2055
+ icon: /* @__PURE__ */ jsx7(ChatIcon, {
2056
+ name: "thumb_down",
2057
+ size: 18
2058
+ }),
1552
2059
  variant: "standard",
1553
2060
  size: "sm",
1554
2061
  onClick: () => onDislike(content),
1555
- "aria-label": "Dislike",
1556
- title: "Je n'aime pas"
2062
+ "aria-label": l.dislike,
2063
+ title: l.dislike
1557
2064
  }),
1558
- onFork && /* @__PURE__ */ jsx5(CircleButton, {
1559
- icon: "call_split",
2065
+ onFork && /* @__PURE__ */ jsx7(CircleButton, {
2066
+ icon: /* @__PURE__ */ jsx7(ChatIcon, {
2067
+ name: "call_split",
2068
+ size: 18
2069
+ }),
1560
2070
  variant: "standard",
1561
2071
  size: "sm",
1562
2072
  onClick: onFork,
1563
- "aria-label": "Fork",
1564
- title: "Bifurquer à partir de ce tour"
2073
+ "aria-label": l.fork,
2074
+ title: l.fork
1565
2075
  })
1566
2076
  ]
1567
2077
  }) : null
1568
2078
  ]
1569
2079
  });
1570
2080
  }
1571
- // packages/m3-ai/src/InlineWorkerCard.tsx
1572
- import { useId as useId2, useMemo as useMemo2, useState as useState4 } from "react";
1573
- import { clsx as clsx6 } from "clsx";
2081
+ // m3/packages/m3-ai/src/InlineWorkerCard.tsx
2082
+ import { useId as useId2, useMemo as useMemo3, useState as useState4 } from "react";
2083
+ import { clsx as clsx8 } from "clsx";
1574
2084
  import { AnimatePresence as AnimatePresence2, motion as motion2 } from "motion/react";
1575
- import { Button, Icon as Icon3 } from "@aphrody/m3-primitives";
1576
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
2085
+ import { Button, Icon as Icon2 } from "@aphrody/m3-primitives";
2086
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1577
2087
  function stripExcessWhitespace(text) {
1578
2088
  return text.replace(/ {3,}/g, " ");
1579
2089
  }
@@ -1605,76 +2115,76 @@ function InlineWorkerCard({
1605
2115
  }) {
1606
2116
  const [expanded, setExpanded] = useState4(defaultExpanded);
1607
2117
  const contentId = useId2();
1608
- const items = useMemo2(() => pairTranscriptSteps(transcript), [transcript]);
2118
+ const items = useMemo3(() => pairTranscriptSteps(transcript), [transcript]);
1609
2119
  const isRunning = status === "running";
1610
2120
  const isDone = status === "completed";
1611
2121
  const tone = statusTone(status);
1612
- return /* @__PURE__ */ jsxs6("div", {
1613
- className: clsx6("group flex min-w-0 flex-col items-start", className),
2122
+ return /* @__PURE__ */ jsxs7("div", {
2123
+ className: clsx8("group flex min-w-0 flex-col items-start", className),
1614
2124
  children: [
1615
- /* @__PURE__ */ jsxs6("div", {
2125
+ /* @__PURE__ */ jsxs7("div", {
1616
2126
  className: "min-w-0 max-w-full overflow-hidden rounded-medium bg-surface-container text-on-surface",
1617
2127
  children: [
1618
- /* @__PURE__ */ jsxs6("button", {
2128
+ /* @__PURE__ */ jsxs7("button", {
1619
2129
  type: "button",
1620
2130
  onClick: () => setExpanded((v) => !v),
1621
2131
  "aria-expanded": expanded,
1622
2132
  "aria-controls": contentId,
1623
- className: clsx6("flex w-full items-start gap-3 rounded-medium px-4 py-3 text-left transition-colors duration-200 ease-standard", "hover:bg-on-surface/8 active:bg-on-surface/10", focusRing),
2133
+ className: clsx8("flex w-full items-start gap-3 rounded-medium px-4 py-3 text-left transition-colors duration-200 ease-standard", "hover:bg-on-surface/8 active:bg-on-surface/10", focusRing),
1624
2134
  children: [
1625
- /* @__PURE__ */ jsx6("div", {
2135
+ /* @__PURE__ */ jsx8("div", {
1626
2136
  className: "flex size-8 shrink-0 items-center justify-center",
1627
- children: isRunning ? /* @__PURE__ */ jsx6(CircularIndicator, {
2137
+ children: isRunning ? /* @__PURE__ */ jsx8(CircularIndicator, {
1628
2138
  size: 20,
1629
2139
  label: "Worker running"
1630
- }) : isDone ? /* @__PURE__ */ jsx6("div", {
2140
+ }) : isDone ? /* @__PURE__ */ jsx8("div", {
1631
2141
  className: "flex size-8 items-center justify-center rounded-full bg-success-container text-on-success-container",
1632
- children: /* @__PURE__ */ jsx6(Icon3, {
2142
+ children: /* @__PURE__ */ jsx8(Icon2, {
1633
2143
  name: "check_circle",
1634
2144
  size: 18,
1635
2145
  filled: true
1636
2146
  })
1637
- }) : tone === "error" ? /* @__PURE__ */ jsx6("div", {
2147
+ }) : tone === "error" ? /* @__PURE__ */ jsx8("div", {
1638
2148
  className: "flex size-8 items-center justify-center rounded-full bg-error-container text-on-error-container",
1639
- children: /* @__PURE__ */ jsx6(Icon3, {
2149
+ children: /* @__PURE__ */ jsx8(Icon2, {
1640
2150
  name: "error",
1641
2151
  size: 18,
1642
2152
  filled: true
1643
2153
  })
1644
- }) : /* @__PURE__ */ jsx6("div", {
2154
+ }) : /* @__PURE__ */ jsx8("div", {
1645
2155
  className: "flex size-8 items-center justify-center rounded-full bg-surface-container-highest text-on-surface-variant",
1646
- children: /* @__PURE__ */ jsx6(Icon3, {
2156
+ children: /* @__PURE__ */ jsx8(Icon2, {
1647
2157
  name: "build",
1648
2158
  size: 18
1649
2159
  })
1650
2160
  })
1651
2161
  }),
1652
- /* @__PURE__ */ jsxs6("div", {
2162
+ /* @__PURE__ */ jsxs7("div", {
1653
2163
  className: "min-w-0 flex-1",
1654
2164
  children: [
1655
- /* @__PURE__ */ jsxs6("div", {
2165
+ /* @__PURE__ */ jsxs7("div", {
1656
2166
  className: "flex items-center gap-2",
1657
2167
  children: [
1658
- /* @__PURE__ */ jsx6("div", {
2168
+ /* @__PURE__ */ jsx8("div", {
1659
2169
  className: "line-clamp-2 min-w-0 flex-1 text-title-small text-on-surface",
1660
2170
  children: title
1661
2171
  }),
1662
- /* @__PURE__ */ jsx6(StatusChip, {
2172
+ /* @__PURE__ */ jsx8(StatusChip, {
1663
2173
  tone,
1664
2174
  children: status
1665
2175
  })
1666
2176
  ]
1667
2177
  }),
1668
- /* @__PURE__ */ jsxs6("div", {
2178
+ /* @__PURE__ */ jsxs7("div", {
1669
2179
  className: "mt-1 flex items-center gap-2 text-body-small text-on-surface-variant",
1670
2180
  children: [
1671
- /* @__PURE__ */ jsxs6("span", {
2181
+ /* @__PURE__ */ jsxs7("span", {
1672
2182
  children: [
1673
2183
  toolCallCount,
1674
2184
  " tool calls"
1675
2185
  ]
1676
2186
  }),
1677
- liveStatus ? /* @__PURE__ */ jsx6("span", {
2187
+ liveStatus ? /* @__PURE__ */ jsx8("span", {
1678
2188
  className: "truncate text-outline",
1679
2189
  children: liveStatus
1680
2190
  }) : null
@@ -1682,37 +2192,37 @@ function InlineWorkerCard({
1682
2192
  })
1683
2193
  ]
1684
2194
  }),
1685
- /* @__PURE__ */ jsx6(Icon3, {
2195
+ /* @__PURE__ */ jsx8(Icon2, {
1686
2196
  name: "expand_more",
1687
2197
  size: 20,
1688
- className: clsx6("mt-1.5 shrink-0 text-on-surface-variant transition-transform duration-300 ease-emphasized", expanded ? "rotate-180" : "")
2198
+ className: clsx8("mt-1.5 shrink-0 text-on-surface-variant transition-transform duration-300 ease-emphasized", expanded ? "rotate-180" : "")
1689
2199
  })
1690
2200
  ]
1691
2201
  }),
1692
- /* @__PURE__ */ jsx6(AnimatePresence2, {
2202
+ /* @__PURE__ */ jsx8(AnimatePresence2, {
1693
2203
  initial: false,
1694
- children: expanded ? /* @__PURE__ */ jsx6(motion2.div, {
2204
+ children: expanded ? /* @__PURE__ */ jsx8(motion2.div, {
1695
2205
  id: contentId,
1696
2206
  ...expandMotion,
1697
2207
  className: "overflow-hidden",
1698
- children: /* @__PURE__ */ jsx6("div", {
2208
+ children: /* @__PURE__ */ jsx8("div", {
1699
2209
  className: "flex flex-col gap-2 border-t border-outline-variant px-4 py-3",
1700
- children: isTranscriptLoading ? /* @__PURE__ */ jsxs6("div", {
2210
+ children: isTranscriptLoading ? /* @__PURE__ */ jsxs7("div", {
1701
2211
  className: "flex items-center gap-2 text-body-small text-on-surface-variant",
1702
2212
  children: [
1703
- /* @__PURE__ */ jsx6(CircularIndicator, {
2213
+ /* @__PURE__ */ jsx8(CircularIndicator, {
1704
2214
  size: 16,
1705
2215
  label: "Loading transcript"
1706
2216
  }),
1707
2217
  "Loading worker transcript..."
1708
2218
  ]
1709
- }) : items.length > 0 ? items.map((item) => item.kind === "tool" ? /* @__PURE__ */ jsx6(ToolCall, {
2219
+ }) : items.length > 0 ? items.map((item) => item.kind === "tool" ? /* @__PURE__ */ jsx8(ToolCall, {
1710
2220
  pair: item.pair
1711
- }, item.pair.id) : /* @__PURE__ */ jsx6(Markdown, {
2221
+ }, item.pair.id) : /* @__PURE__ */ jsx8(Markdown, {
1712
2222
  content: stripExcessWhitespace(item.text),
1713
2223
  size: "small",
1714
2224
  className: "text-on-surface-variant"
1715
- }, `text-${item.text}`)) : /* @__PURE__ */ jsx6("div", {
2225
+ }, `text-${item.text}`)) : /* @__PURE__ */ jsx8("div", {
1716
2226
  className: "text-body-small text-on-surface-variant",
1717
2227
  children: "No tool calls yet."
1718
2228
  })
@@ -1721,29 +2231,29 @@ function InlineWorkerCard({
1721
2231
  })
1722
2232
  ]
1723
2233
  }),
1724
- (onCopyLogs || onCancel && isRunning) && /* @__PURE__ */ jsxs6("div", {
2234
+ (onCopyLogs || onCancel && isRunning) && /* @__PURE__ */ jsxs7("div", {
1725
2235
  className: "mt-1 flex gap-1 opacity-0 transition-opacity duration-200 ease-standard group-focus-within:opacity-100 group-hover:opacity-100",
1726
2236
  children: [
1727
- onCopyLogs && /* @__PURE__ */ jsxs6(Button, {
2237
+ onCopyLogs && /* @__PURE__ */ jsxs7(Button, {
1728
2238
  variant: "text",
1729
2239
  size: "xs",
1730
2240
  onClick: onCopyLogs,
1731
2241
  title: "Copy logs",
1732
2242
  children: [
1733
- /* @__PURE__ */ jsx6(Icon3, {
2243
+ /* @__PURE__ */ jsx8(Icon2, {
1734
2244
  name: "content_copy",
1735
2245
  size: 18
1736
2246
  }),
1737
2247
  "Copy"
1738
2248
  ]
1739
2249
  }),
1740
- onCancel && isRunning && /* @__PURE__ */ jsxs6(Button, {
2250
+ onCancel && isRunning && /* @__PURE__ */ jsxs7(Button, {
1741
2251
  variant: "text",
1742
2252
  size: "xs",
1743
2253
  onClick: onCancel,
1744
2254
  title: "Cancel",
1745
2255
  children: [
1746
- /* @__PURE__ */ jsx6(Icon3, {
2256
+ /* @__PURE__ */ jsx8(Icon2, {
1747
2257
  name: "stop",
1748
2258
  size: 18
1749
2259
  }),
@@ -1755,12 +2265,12 @@ function InlineWorkerCard({
1755
2265
  ]
1756
2266
  });
1757
2267
  }
1758
- // packages/m3-ai/src/InlineBranchCard.tsx
2268
+ // m3/packages/m3-ai/src/InlineBranchCard.tsx
1759
2269
  import { useId as useId3, useState as useState5 } from "react";
1760
- import { clsx as clsx7 } from "clsx";
2270
+ import { clsx as clsx9 } from "clsx";
1761
2271
  import { AnimatePresence as AnimatePresence3, motion as motion3 } from "motion/react";
1762
- import { Icon as Icon4 } from "@aphrody/m3-primitives";
1763
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
2272
+ import { Icon as Icon3 } from "@aphrody/m3-primitives";
2273
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1764
2274
  function InlineBranchCard({
1765
2275
  description,
1766
2276
  completedAt,
@@ -1772,63 +2282,63 @@ function InlineBranchCard({
1772
2282
  const isRunning = !completedAt;
1773
2283
  const contentId = useId3();
1774
2284
  const canExpand = !!conclusion;
1775
- return /* @__PURE__ */ jsx7("div", {
1776
- className: clsx7("group flex min-w-0 flex-col items-start", className),
1777
- children: /* @__PURE__ */ jsxs7("div", {
2285
+ return /* @__PURE__ */ jsx9("div", {
2286
+ className: clsx9("group flex min-w-0 flex-col items-start", className),
2287
+ children: /* @__PURE__ */ jsxs8("div", {
1778
2288
  className: "min-w-0 max-w-full overflow-hidden rounded-medium bg-surface-container text-on-surface",
1779
2289
  children: [
1780
- /* @__PURE__ */ jsxs7("button", {
2290
+ /* @__PURE__ */ jsxs8("button", {
1781
2291
  type: "button",
1782
2292
  onClick: () => canExpand && setExpanded((v) => !v),
1783
2293
  "aria-expanded": canExpand ? expanded : undefined,
1784
2294
  "aria-controls": canExpand ? contentId : undefined,
1785
- className: clsx7("flex w-full items-start gap-3 rounded-medium px-4 py-3 text-left transition-colors duration-200 ease-standard", canExpand && "hover:bg-on-surface/8 active:bg-on-surface/10", focusRing),
2295
+ className: clsx9("flex w-full items-start gap-3 rounded-medium px-4 py-3 text-left transition-colors duration-200 ease-standard", canExpand && "hover:bg-on-surface/8 active:bg-on-surface/10", focusRing),
1786
2296
  children: [
1787
- /* @__PURE__ */ jsx7("div", {
2297
+ /* @__PURE__ */ jsx9("div", {
1788
2298
  className: "flex size-8 shrink-0 items-center justify-center",
1789
- children: isRunning ? /* @__PURE__ */ jsx7(CircularIndicator, {
2299
+ children: isRunning ? /* @__PURE__ */ jsx9(CircularIndicator, {
1790
2300
  size: 20,
1791
2301
  label: "Thinking"
1792
- }) : /* @__PURE__ */ jsx7("div", {
2302
+ }) : /* @__PURE__ */ jsx9("div", {
1793
2303
  className: "flex size-8 items-center justify-center rounded-full bg-primary-container text-on-primary-container",
1794
- children: /* @__PURE__ */ jsx7(Icon4, {
2304
+ children: /* @__PURE__ */ jsx9(Icon3, {
1795
2305
  name: "alt_route",
1796
2306
  size: 18
1797
2307
  })
1798
2308
  })
1799
2309
  }),
1800
- /* @__PURE__ */ jsx7("div", {
2310
+ /* @__PURE__ */ jsx9("div", {
1801
2311
  className: "min-w-0 flex-1 self-center",
1802
- children: /* @__PURE__ */ jsxs7("div", {
2312
+ children: /* @__PURE__ */ jsxs8("div", {
1803
2313
  className: "flex items-center gap-2",
1804
2314
  children: [
1805
- /* @__PURE__ */ jsx7("div", {
2315
+ /* @__PURE__ */ jsx9("div", {
1806
2316
  className: "line-clamp-2 min-w-0 flex-1 text-title-small text-on-surface",
1807
2317
  children: description
1808
2318
  }),
1809
- /* @__PURE__ */ jsx7(StatusChip, {
2319
+ /* @__PURE__ */ jsx9(StatusChip, {
1810
2320
  tone: isRunning ? "primary" : "success",
1811
2321
  children: isRunning ? "thinking" : "done"
1812
2322
  })
1813
2323
  ]
1814
2324
  })
1815
2325
  }),
1816
- canExpand && /* @__PURE__ */ jsx7(Icon4, {
2326
+ canExpand && /* @__PURE__ */ jsx9(Icon3, {
1817
2327
  name: "expand_more",
1818
2328
  size: 20,
1819
- className: clsx7("mt-1.5 shrink-0 text-on-surface-variant transition-transform duration-300 ease-emphasized", expanded ? "rotate-180" : "")
2329
+ className: clsx9("mt-1.5 shrink-0 text-on-surface-variant transition-transform duration-300 ease-emphasized", expanded ? "rotate-180" : "")
1820
2330
  })
1821
2331
  ]
1822
2332
  }),
1823
- /* @__PURE__ */ jsx7(AnimatePresence3, {
2333
+ /* @__PURE__ */ jsx9(AnimatePresence3, {
1824
2334
  initial: false,
1825
- children: expanded && conclusion ? /* @__PURE__ */ jsx7(motion3.div, {
2335
+ children: expanded && conclusion ? /* @__PURE__ */ jsx9(motion3.div, {
1826
2336
  id: contentId,
1827
2337
  ...expandMotion,
1828
2338
  className: "overflow-hidden",
1829
- children: /* @__PURE__ */ jsx7("div", {
2339
+ children: /* @__PURE__ */ jsx9("div", {
1830
2340
  className: "border-t border-outline-variant px-4 py-3",
1831
- children: /* @__PURE__ */ jsx7(Markdown, {
2341
+ children: /* @__PURE__ */ jsx9(Markdown, {
1832
2342
  content: conclusion,
1833
2343
  size: "small",
1834
2344
  className: "text-on-surface-variant"
@@ -1840,16 +2350,11 @@ function InlineBranchCard({
1840
2350
  })
1841
2351
  });
1842
2352
  }
1843
- // packages/m3-ai/src/ModelSelector.tsx
1844
- import {
1845
- Icon as Icon5,
1846
- Popover,
1847
- usePopover,
1848
- SelectPill
1849
- } from "@aphrody/m3-primitives";
1850
- import { clsx as clsx8 } from "clsx";
1851
- import { forwardRef as forwardRef2, useEffect as useEffect2, useMemo as useMemo3, useRef as useRef3, useState as useState6 } from "react";
1852
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
2353
+ // m3/packages/m3-ai/src/ModelSelector.tsx
2354
+ import { Popover, usePopover, SelectPill } from "@aphrody/m3-primitives";
2355
+ import { clsx as clsx10 } from "clsx";
2356
+ import { forwardRef as forwardRef2, useEffect as useEffect2, useMemo as useMemo4, useRef as useRef3, useState as useState6 } from "react";
2357
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1853
2358
  "use client";
1854
2359
  function groupModelsByProvider(models, search = "") {
1855
2360
  const q = search.trim().toLowerCase();
@@ -1861,14 +2366,21 @@ function groupModelsByProvider(models, search = "") {
1861
2366
  return acc;
1862
2367
  }, Object.create(null));
1863
2368
  }
1864
- function ModelOptionList({ grouped, value, onSelect, className }) {
2369
+ function ModelOptionList({
2370
+ grouped,
2371
+ value,
2372
+ onSelect,
2373
+ className,
2374
+ labels
2375
+ }) {
2376
+ const l = resolveChatLabels(labels);
1865
2377
  const providers = Object.entries(grouped);
1866
2378
  const models = providers.flatMap(([, providerModels]) => providerModels);
1867
2379
  const [focusedId, setFocusedId] = useState6(value);
1868
2380
  const focusId = models.some((model) => model.id === focusedId) ? focusedId : models.find((model) => model.id === value)?.id ?? models[0]?.id;
1869
- return /* @__PURE__ */ jsxs8("div", {
2381
+ return /* @__PURE__ */ jsxs9("div", {
1870
2382
  role: "listbox",
1871
- "aria-label": "Models",
2383
+ "aria-label": l.models,
1872
2384
  tabIndex: -1,
1873
2385
  onKeyDown: (event) => {
1874
2386
  if (event.defaultPrevented)
@@ -1897,66 +2409,64 @@ function ModelOptionList({ grouped, value, onSelect, className }) {
1897
2409
  event.preventDefault();
1898
2410
  options[next].focus();
1899
2411
  },
1900
- className: clsx8("flex flex-col", className),
2412
+ className: clsx10("flex flex-col", className),
1901
2413
  children: [
1902
- providers.map(([provider, providerModels], groupIndex) => /* @__PURE__ */ jsxs8("div", {
2414
+ providers.map(([provider, providerModels], groupIndex) => /* @__PURE__ */ jsxs9("div", {
1903
2415
  role: "group",
1904
2416
  "aria-label": provider,
1905
- className: clsx8(groupIndex > 0 && "mt-1 border-t border-outline-variant pt-1"),
2417
+ className: clsx10(groupIndex > 0 && "mt-1 border-t border-outline-variant pt-1"),
1906
2418
  children: [
1907
- /* @__PURE__ */ jsx8("div", {
2419
+ /* @__PURE__ */ jsx10("div", {
1908
2420
  className: "px-3 pt-2 pb-1 text-title-small text-on-surface-variant",
1909
2421
  children: provider
1910
2422
  }),
1911
2423
  providerModels.map((model) => {
1912
2424
  const selected = model.id === value;
1913
- return /* @__PURE__ */ jsxs8("button", {
2425
+ return /* @__PURE__ */ jsxs9("button", {
1914
2426
  type: "button",
1915
2427
  role: "option",
1916
2428
  "aria-selected": selected,
1917
2429
  tabIndex: model.id === focusId ? 0 : -1,
1918
2430
  onFocus: () => setFocusedId(model.id),
1919
2431
  onClick: () => onSelect(model.id),
1920
- className: clsx8("flex min-h-12 w-full items-center gap-3 px-3 py-2 text-left", "transition-colors duration-200 ease-standard", selected ? "bg-secondary-container text-on-secondary-container" : "text-on-surface hover:bg-on-surface/8 active:bg-on-surface/10", focusRing, "focus-visible:outline-offset-[-3px]"),
2432
+ className: clsx10("flex min-h-12 w-full items-center gap-3 px-3 py-2 text-left", "transition-colors duration-200 ease-standard", selected ? "bg-secondary-container text-on-secondary-container" : "text-on-surface hover:bg-on-surface/8 active:bg-on-surface/10", focusRing, "focus-visible:outline-offset-[-3px]"),
1921
2433
  children: [
1922
- /* @__PURE__ */ jsxs8("div", {
2434
+ /* @__PURE__ */ jsxs9("div", {
1923
2435
  className: "min-w-0 flex-1",
1924
2436
  children: [
1925
- /* @__PURE__ */ jsx8("div", {
2437
+ /* @__PURE__ */ jsx10("div", {
1926
2438
  className: "truncate text-label-large",
1927
2439
  children: model.name
1928
2440
  }),
1929
- model.context_window || model.capabilities?.length ? /* @__PURE__ */ jsxs8("div", {
2441
+ model.context_window || model.capabilities?.length ? /* @__PURE__ */ jsxs9("div", {
1930
2442
  className: "mt-0.5 flex flex-wrap items-center gap-1",
1931
2443
  children: [
1932
- model.context_window ? /* @__PURE__ */ jsxs8("span", {
1933
- className: clsx8("text-body-small", selected ? "text-on-secondary-container" : "text-on-surface-variant"),
1934
- children: [
1935
- model.context_window.toLocaleString(),
1936
- " tokens"
1937
- ]
2444
+ model.context_window ? /* @__PURE__ */ jsx10("span", {
2445
+ className: clsx10("text-body-small", selected ? "text-on-secondary-container" : "text-on-surface-variant"),
2446
+ children: formatLabel(l.contextTokens, {
2447
+ count: model.context_window.toLocaleString()
2448
+ })
1938
2449
  }) : null,
1939
- model.capabilities?.map((capability) => /* @__PURE__ */ jsx8("span", {
1940
- className: clsx8("inline-flex h-5 items-center rounded-small border border-outline-variant px-1.5 text-label-small", selected ? "text-on-secondary-container" : "text-on-surface-variant"),
2450
+ model.capabilities?.map((capability) => /* @__PURE__ */ jsx10("span", {
2451
+ className: clsx10("inline-flex h-5 items-center rounded-small border border-outline-variant px-1.5 text-label-small", selected ? "text-on-secondary-container" : "text-on-surface-variant"),
1941
2452
  children: capability
1942
2453
  }, capability))
1943
2454
  ]
1944
2455
  }) : null
1945
2456
  ]
1946
2457
  }),
1947
- selected && /* @__PURE__ */ jsx8(Icon5, {
2458
+ selected && /* @__PURE__ */ jsx10(ChatIcon, {
1948
2459
  name: "check",
1949
- size: 20,
1950
- className: "shrink-0"
2460
+ size: 20
1951
2461
  })
1952
2462
  ]
1953
2463
  }, model.id);
1954
2464
  })
1955
2465
  ]
1956
2466
  }, provider)),
1957
- providers.length === 0 && /* @__PURE__ */ jsx8("div", {
2467
+ providers.length === 0 && /* @__PURE__ */ jsx10("div", {
1958
2468
  className: "px-3 py-3 text-center text-body-small text-on-surface-variant",
1959
- children: "No models found"
2469
+ children: l.noModels
1960
2470
  })
1961
2471
  ]
1962
2472
  });
@@ -1970,17 +2480,16 @@ function ModelSearchField({
1970
2480
  useEffect2(() => {
1971
2481
  inputRef.current?.focus();
1972
2482
  }, []);
1973
- return /* @__PURE__ */ jsx8("div", {
2483
+ return /* @__PURE__ */ jsx10("div", {
1974
2484
  className: "px-2 pb-2",
1975
- children: /* @__PURE__ */ jsxs8("label", {
2485
+ children: /* @__PURE__ */ jsxs9("label", {
1976
2486
  className: "flex h-10 items-center gap-2 rounded-full bg-surface-container-high px-3 text-on-surface-variant focus-within:bg-surface-container-highest",
1977
2487
  children: [
1978
- /* @__PURE__ */ jsx8(Icon5, {
2488
+ /* @__PURE__ */ jsx10(ChatIcon, {
1979
2489
  name: "search",
1980
- size: 20,
1981
- className: "shrink-0"
2490
+ size: 20
1982
2491
  }),
1983
- /* @__PURE__ */ jsx8("input", {
2492
+ /* @__PURE__ */ jsx10("input", {
1984
2493
  ref: inputRef,
1985
2494
  value,
1986
2495
  onChange: (event) => onChange(event.target.value),
@@ -1996,20 +2505,22 @@ var ModelSelector = forwardRef2(({
1996
2505
  models,
1997
2506
  value,
1998
2507
  onChange,
1999
- placeholder = "Select model...",
2000
- searchPlaceholder = "Search models...",
2508
+ placeholder,
2509
+ searchPlaceholder,
2001
2510
  variant,
2002
2511
  size,
2003
2512
  popover: externalPopover,
2004
2513
  className,
2005
- disabled
2514
+ disabled,
2515
+ labels
2006
2516
  }, ref) => {
2517
+ const l = resolveChatLabels(labels);
2007
2518
  const internalPopover = usePopover();
2008
2519
  const popover = externalPopover ?? internalPopover;
2009
2520
  const [search, setSearch] = useState6("");
2010
2521
  const selectedModel = models.find((m) => m.id === value);
2011
- const grouped = useMemo3(() => groupModelsByProvider(models, search), [models, search]);
2012
- return /* @__PURE__ */ jsxs8(Popover.Root, {
2522
+ const grouped = useMemo4(() => groupModelsByProvider(models, search), [models, search]);
2523
+ return /* @__PURE__ */ jsxs9(Popover.Root, {
2013
2524
  open: popover.open,
2014
2525
  onOpenChange: (open) => {
2015
2526
  popover.setOpen(open);
@@ -2017,34 +2528,45 @@ var ModelSelector = forwardRef2(({
2017
2528
  setSearch("");
2018
2529
  },
2019
2530
  children: [
2020
- /* @__PURE__ */ jsx8(Popover.Trigger, {
2531
+ /* @__PURE__ */ jsx10(Popover.Trigger, {
2021
2532
  asChild: true,
2022
- children: /* @__PURE__ */ jsx8(SelectPill, {
2533
+ children: /* @__PURE__ */ jsxs9(SelectPill, {
2023
2534
  ref,
2024
2535
  variant,
2025
2536
  size,
2026
2537
  disabled,
2027
2538
  "aria-haspopup": "listbox",
2028
- className: clsx8("w-full", className),
2029
- children: selectedModel?.name ?? placeholder
2539
+ hideCaret: true,
2540
+ className: clsx10("w-full", className),
2541
+ children: [
2542
+ /* @__PURE__ */ jsx10("span", {
2543
+ className: "min-w-0 flex-1 truncate",
2544
+ children: selectedModel?.name ?? placeholder ?? l.selectModel
2545
+ }),
2546
+ /* @__PURE__ */ jsx10(ChatIcon, {
2547
+ name: "expand_more",
2548
+ size: 18
2549
+ })
2550
+ ]
2030
2551
  })
2031
2552
  }),
2032
- /* @__PURE__ */ jsxs8(Popover.Content, {
2553
+ /* @__PURE__ */ jsxs9(Popover.Content, {
2033
2554
  align: "end",
2034
2555
  sideOffset: 8,
2035
2556
  style: { width: 280 },
2036
2557
  className: "overflow-hidden rounded-extra-small! py-2",
2037
2558
  children: [
2038
- /* @__PURE__ */ jsx8(ModelSearchField, {
2559
+ /* @__PURE__ */ jsx10(ModelSearchField, {
2039
2560
  value: search,
2040
2561
  onChange: setSearch,
2041
- placeholder: searchPlaceholder
2562
+ placeholder: searchPlaceholder ?? l.searchModels
2042
2563
  }),
2043
- /* @__PURE__ */ jsx8("div", {
2564
+ /* @__PURE__ */ jsx10("div", {
2044
2565
  className: "max-h-[320px] overflow-y-auto",
2045
- children: /* @__PURE__ */ jsx8(ModelOptionList, {
2566
+ children: /* @__PURE__ */ jsx10(ModelOptionList, {
2046
2567
  grouped,
2047
2568
  value,
2569
+ labels,
2048
2570
  onSelect: (id) => {
2049
2571
  onChange(id);
2050
2572
  popover.setOpen(false);
@@ -2058,12 +2580,12 @@ var ModelSelector = forwardRef2(({
2058
2580
  });
2059
2581
  });
2060
2582
  ModelSelector.displayName = "ModelSelector";
2061
- // packages/m3-ai/src/ChatComposer.tsx
2062
- import { CircleButton as CircleButton2, Icon as Icon6, Popover as Popover2, SelectPill as SelectPill2 } from "@aphrody/m3-primitives";
2583
+ // m3/packages/m3-ai/src/ChatComposer.tsx
2584
+ import { CircleButton as CircleButton2, Popover as Popover2, SelectPill as SelectPill2 } from "@aphrody/m3-primitives";
2063
2585
  import { m3Durations as m3Durations2, m3Easings as m3Easings2 } from "@aphrody/m3-motion";
2064
- import { clsx as clsx9 } from "clsx";
2586
+ import { clsx as clsx11 } from "clsx";
2065
2587
  import { AnimatePresence as AnimatePresence4, motion as motion4 } from "motion/react";
2066
- import { jsx as jsx9, jsxs as jsxs9, Fragment } from "react/jsx-runtime";
2588
+ import { jsx as jsx11, jsxs as jsxs10, Fragment as Fragment4 } from "react/jsx-runtime";
2067
2589
  "use client";
2068
2590
  var iconButtonEnter = {
2069
2591
  initial: { scale: 0.6, opacity: 0 },
@@ -2082,76 +2604,92 @@ function ChatComposer({
2082
2604
  draft,
2083
2605
  onDraftChange,
2084
2606
  onSend,
2085
- placeholder = "Ask something...",
2607
+ placeholder,
2086
2608
  heading,
2087
2609
  isSending = false,
2610
+ disabled = false,
2088
2611
  projectSelector,
2089
2612
  modelSelector,
2090
2613
  onOpenVoice,
2091
2614
  toolbarExtra,
2092
2615
  onStop,
2093
- className
2616
+ className,
2617
+ labels
2094
2618
  }) {
2095
- const canSend = !isSending && draft.trim().length > 0;
2096
- const showStop = isSending && !!onStop;
2097
- return /* @__PURE__ */ jsxs9(Fragment, {
2619
+ const l = resolveChatLabels(labels);
2620
+ const hint = placeholder ?? l.composerPlaceholder;
2621
+ const canSend = !disabled && !isSending && draft.trim().length > 0;
2622
+ const showStop = !disabled && isSending && !!onStop;
2623
+ return /* @__PURE__ */ jsxs10(Fragment4, {
2098
2624
  children: [
2099
- heading && /* @__PURE__ */ jsxs9("div", {
2625
+ heading && /* @__PURE__ */ jsxs10("div", {
2100
2626
  className: "mb-3 flex items-center gap-2 px-1 text-title-small text-on-surface-variant",
2101
2627
  children: [
2102
- /* @__PURE__ */ jsx9(Icon6, {
2103
- name: "auto_awesome",
2628
+ /* @__PURE__ */ jsx11(ChatIcon, {
2629
+ name: "auto_awesome_filled",
2104
2630
  size: 18,
2105
- filled: true,
2106
2631
  className: "text-primary"
2107
2632
  }),
2108
2633
  heading
2109
2634
  ]
2110
2635
  }),
2111
- /* @__PURE__ */ jsxs9("div", {
2112
- className: clsx9("m3-chat-composer rounded-extra-large bg-surface-container-high px-4 pt-3 pb-2 text-on-surface", "transition-colors duration-200 ease-standard focus-within:bg-surface-container-highest", className),
2636
+ /* @__PURE__ */ jsxs10("div", {
2637
+ className: clsx11("m3-chat-composer rounded-extra-large bg-surface-container-high px-4 pt-3 pb-2 text-on-surface", "transition-colors duration-200 ease-standard focus-within:bg-surface-container-highest", className),
2113
2638
  children: [
2114
- /* @__PURE__ */ jsx9("textarea", {
2639
+ /* @__PURE__ */ jsx11("textarea", {
2115
2640
  value: draft,
2116
2641
  onChange: (event) => onDraftChange(event.target.value),
2117
2642
  onKeyDown: (event) => {
2118
2643
  if (event.key === "Enter" && !event.shiftKey) {
2119
2644
  event.preventDefault();
2120
- onSend();
2645
+ if (canSend)
2646
+ onSend();
2121
2647
  }
2122
2648
  },
2123
- placeholder,
2124
- "aria-label": placeholder,
2649
+ placeholder: hint,
2650
+ "aria-label": hint,
2125
2651
  rows: 2,
2652
+ disabled,
2126
2653
  className: "block w-full resize-none border-0 bg-transparent px-1 text-body-large text-on-surface caret-primary outline-none placeholder:text-on-surface-variant focus:outline-none focus:ring-0"
2127
2654
  }),
2128
- /* @__PURE__ */ jsxs9("div", {
2655
+ /* @__PURE__ */ jsxs10("div", {
2129
2656
  className: "mt-2 flex items-center justify-between gap-2",
2130
2657
  children: [
2131
- projectSelector ? /* @__PURE__ */ jsx9("div", {
2658
+ projectSelector ? /* @__PURE__ */ jsx11("div", {
2132
2659
  className: "w-[210px]",
2133
- children: /* @__PURE__ */ jsxs9(Popover2.Root, {
2660
+ children: /* @__PURE__ */ jsxs10(Popover2.Root, {
2134
2661
  open: projectSelector.popover.open,
2135
2662
  onOpenChange: projectSelector.popover.setOpen,
2136
2663
  children: [
2137
- /* @__PURE__ */ jsx9(Popover2.Trigger, {
2664
+ /* @__PURE__ */ jsx11(Popover2.Trigger, {
2138
2665
  asChild: true,
2139
- children: /* @__PURE__ */ jsx9(SelectPill2, {
2666
+ children: /* @__PURE__ */ jsxs10(SelectPill2, {
2140
2667
  className: "w-full",
2141
2668
  "aria-haspopup": "listbox",
2142
- children: projectSelector.value
2669
+ disabled,
2670
+ hideCaret: true,
2671
+ children: [
2672
+ /* @__PURE__ */ jsx11("span", {
2673
+ className: "min-w-0 flex-1 truncate",
2674
+ children: projectSelector.value
2675
+ }),
2676
+ /* @__PURE__ */ jsx11(ChatIcon, {
2677
+ name: "expand_more",
2678
+ size: 18
2679
+ })
2680
+ ]
2143
2681
  })
2144
2682
  }),
2145
- /* @__PURE__ */ jsx9(Popover2.Content, {
2683
+ /* @__PURE__ */ jsx11(Popover2.Content, {
2146
2684
  align: "start",
2147
2685
  sideOffset: 8,
2148
2686
  className: "min-w-[210px] overflow-hidden rounded-extra-small! py-2",
2149
- children: /* @__PURE__ */ jsx9("div", {
2687
+ children: /* @__PURE__ */ jsx11("div", {
2150
2688
  role: "listbox",
2151
- "aria-label": "Projects",
2689
+ "aria-label": l.projects,
2152
2690
  children: projectSelector.options.map((option) => {
2153
2691
  const selected = option === projectSelector.value;
2154
- return /* @__PURE__ */ jsxs9("button", {
2692
+ return /* @__PURE__ */ jsxs10("button", {
2155
2693
  type: "button",
2156
2694
  role: "option",
2157
2695
  "aria-selected": selected,
@@ -2159,13 +2697,13 @@ function ChatComposer({
2159
2697
  projectSelector.onChange(option);
2160
2698
  projectSelector.popover.setOpen(false);
2161
2699
  },
2162
- className: clsx9("flex h-12 w-full items-center gap-3 px-3 text-left text-label-large", "transition-colors duration-200 ease-standard", selected ? "bg-secondary-container text-on-secondary-container" : "text-on-surface hover:bg-on-surface/8", focusRing, "focus-visible:outline-offset-[-3px]"),
2700
+ className: clsx11("flex h-12 w-full items-center gap-3 px-3 text-left text-label-large", "transition-colors duration-200 ease-standard", selected ? "bg-secondary-container text-on-secondary-container" : "text-on-surface hover:bg-on-surface/8", focusRing, "focus-visible:outline-offset-[-3px]"),
2163
2701
  children: [
2164
- /* @__PURE__ */ jsx9("span", {
2702
+ /* @__PURE__ */ jsx11("span", {
2165
2703
  className: "min-w-0 flex-1 truncate",
2166
2704
  children: option
2167
2705
  }),
2168
- selected && /* @__PURE__ */ jsx9(Icon6, {
2706
+ selected && /* @__PURE__ */ jsx11(ChatIcon, {
2169
2707
  name: "check",
2170
2708
  size: 20
2171
2709
  })
@@ -2176,49 +2714,53 @@ function ChatComposer({
2176
2714
  })
2177
2715
  ]
2178
2716
  })
2179
- }) : /* @__PURE__ */ jsx9("div", {}),
2180
- /* @__PURE__ */ jsxs9(motion4.div, {
2717
+ }) : /* @__PURE__ */ jsx11("div", {}),
2718
+ /* @__PURE__ */ jsxs10(motion4.div, {
2181
2719
  layout: true,
2182
2720
  className: "flex items-center gap-1",
2183
2721
  children: [
2184
- modelSelector && /* @__PURE__ */ jsx9("div", {
2722
+ modelSelector && /* @__PURE__ */ jsx11("div", {
2185
2723
  className: "w-[180px]",
2186
- children: /* @__PURE__ */ jsx9(ModelSelector, {
2724
+ children: /* @__PURE__ */ jsx11(ModelSelector, {
2187
2725
  models: modelSelector.options,
2188
2726
  value: modelSelector.value,
2189
2727
  onChange: modelSelector.onChange,
2190
- size: "md"
2728
+ size: "md",
2729
+ disabled,
2730
+ labels
2191
2731
  })
2192
2732
  }),
2193
2733
  toolbarExtra,
2194
- onOpenVoice && /* @__PURE__ */ jsx9(CircleButton2, {
2195
- icon: "mic",
2734
+ onOpenVoice && /* @__PURE__ */ jsx11(CircleButton2, {
2735
+ icon: /* @__PURE__ */ jsx11(ChatIcon, {
2736
+ name: "mic",
2737
+ size: 20
2738
+ }),
2196
2739
  variant: "standard",
2197
2740
  onClick: onOpenVoice,
2198
- disabled: isSending,
2199
- "aria-label": "Open Voice Input"
2741
+ disabled: isSending || disabled,
2742
+ "aria-label": l.openVoice
2200
2743
  }),
2201
- /* @__PURE__ */ jsx9(AnimatePresence4, {
2744
+ /* @__PURE__ */ jsx11(AnimatePresence4, {
2202
2745
  initial: false,
2203
2746
  mode: "popLayout",
2204
- children: showStop ? /* @__PURE__ */ jsx9(motion4.button, {
2747
+ children: showStop ? /* @__PURE__ */ jsx11(motion4.button, {
2205
2748
  type: "button",
2206
2749
  ...iconButtonEnter,
2207
2750
  onClick: onStop,
2208
- "aria-label": "Stop",
2209
- className: clsx9("flex size-10 shrink-0 items-center justify-center rounded-full bg-primary text-on-primary", "transition-colors duration-200 ease-standard hover:bg-primary/92 active:bg-primary/90", focusRing),
2210
- children: /* @__PURE__ */ jsx9(Icon6, {
2211
- name: "stop",
2212
- size: 24,
2213
- filled: true
2751
+ "aria-label": l.stop,
2752
+ className: clsx11("flex size-10 shrink-0 items-center justify-center rounded-full bg-primary text-on-primary", "transition-colors duration-200 ease-standard hover:bg-primary/92 active:bg-primary/90", focusRing),
2753
+ children: /* @__PURE__ */ jsx11(ChatIcon, {
2754
+ name: "stop_filled",
2755
+ size: 24
2214
2756
  })
2215
- }, "stop") : canSend ? /* @__PURE__ */ jsx9(motion4.button, {
2757
+ }, "stop") : canSend ? /* @__PURE__ */ jsx11(motion4.button, {
2216
2758
  type: "button",
2217
2759
  ...iconButtonEnter,
2218
2760
  onClick: onSend,
2219
- "aria-label": "Send",
2220
- className: clsx9("flex size-10 shrink-0 items-center justify-center rounded-full bg-primary text-on-primary", "transition-colors duration-200 ease-standard hover:bg-primary/92 active:bg-primary/90", focusRing),
2221
- children: /* @__PURE__ */ jsx9(Icon6, {
2761
+ "aria-label": l.send,
2762
+ className: clsx11("flex size-10 shrink-0 items-center justify-center rounded-full bg-primary text-on-primary", "transition-colors duration-200 ease-standard hover:bg-primary/92 active:bg-primary/90", focusRing),
2763
+ children: /* @__PURE__ */ jsx11(ChatIcon, {
2222
2764
  name: "arrow_upward",
2223
2765
  size: 24
2224
2766
  })
@@ -2233,11 +2775,11 @@ function ChatComposer({
2233
2775
  ]
2234
2776
  });
2235
2777
  }
2236
- // packages/m3-ai/src/GoogleSpotlightBar.tsx
2237
- import { CircleButton as CircleButton3, Icon as Icon7 } from "@aphrody/m3-primitives";
2238
- import { clsx as clsx10 } from "clsx";
2778
+ // m3/packages/m3-ai/src/GoogleSpotlightBar.tsx
2779
+ import { CircleButton as CircleButton3, Icon as Icon4 } from "@aphrody/m3-primitives";
2780
+ import { clsx as clsx12 } from "clsx";
2239
2781
  import { useState as useState7 } from "react";
2240
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
2782
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
2241
2783
  "use client";
2242
2784
  function GoogleSpotlightBar({
2243
2785
  placeholder = "Ask anything or start typing...",
@@ -2264,38 +2806,38 @@ function GoogleSpotlightBar({
2264
2806
  onSubmit?.(query);
2265
2807
  }
2266
2808
  };
2267
- return /* @__PURE__ */ jsxs10("search", {
2809
+ return /* @__PURE__ */ jsxs11("search", {
2268
2810
  "aria-label": "Google Spotlight Assistant",
2269
- className: clsx10("google-spotlight-capsule relative mx-auto flex w-full max-w-[840px] items-center gap-3", "rounded-[var(--gemini-corner-prompt-bar,32px)] bg-surface-container-high/90 px-5 py-3.5 backdrop-blur-xl", "border border-outline-variant/30 text-on-surface shadow-md3-3 transition-all duration-200", "focus-within:border-primary/50 focus-within:bg-surface-container-highest/95 focus-within:shadow-md3-4", className),
2811
+ className: clsx12("google-spotlight-capsule relative mx-auto flex w-full max-w-[840px] items-center gap-3", "rounded-[var(--gemini-corner-prompt-bar,32px)] bg-surface-container-high/90 px-5 py-3.5 backdrop-blur-xl", "border border-outline-variant/30 text-on-surface shadow-md3-3 transition-all duration-200", "focus-within:border-primary/50 focus-within:bg-surface-container-highest/95 focus-within:shadow-md3-4", className),
2270
2812
  children: [
2271
- /* @__PURE__ */ jsx10("div", {
2813
+ /* @__PURE__ */ jsx12("div", {
2272
2814
  className: "flex h-9 w-9 shrink-0 items-center justify-center",
2273
- children: /* @__PURE__ */ jsxs10("svg", {
2815
+ children: /* @__PURE__ */ jsxs11("svg", {
2274
2816
  viewBox: "0 0 24 24",
2275
2817
  width: "24",
2276
2818
  height: "24",
2277
2819
  "aria-hidden": "true",
2278
2820
  children: [
2279
- /* @__PURE__ */ jsx10("path", {
2821
+ /* @__PURE__ */ jsx12("path", {
2280
2822
  fill: "#4285F4",
2281
2823
  d: "M23.745 12.27c0-.7-.06-1.4-.19-2.07H12v4.51h6.6c-.29 1.52-1.14 2.8-2.4 3.64v3.03h3.88c2.27-2.09 3.665-5.17 3.665-9.11z"
2282
2824
  }),
2283
- /* @__PURE__ */ jsx10("path", {
2825
+ /* @__PURE__ */ jsx12("path", {
2284
2826
  fill: "#34A853",
2285
2827
  d: "M12 24c3.24 0 5.95-1.08 7.93-2.91l-3.88-3.03c-1.08.72-2.45 1.16-4.05 1.16-3.12 0-5.77-2.1-6.72-4.93H1.25v3.13C3.28 21.43 7.33 24 12 24z"
2286
2828
  }),
2287
- /* @__PURE__ */ jsx10("path", {
2829
+ /* @__PURE__ */ jsx12("path", {
2288
2830
  fill: "#FBBC05",
2289
2831
  d: "M5.28 14.29c-.25-.72-.38-1.49-.38-2.29s.14-1.57.38-2.29V6.57H1.25C.45 8.16 0 9.98 0 12s.45 3.84 1.25 5.43l4.03-3.14z"
2290
2832
  }),
2291
- /* @__PURE__ */ jsx10("path", {
2833
+ /* @__PURE__ */ jsx12("path", {
2292
2834
  fill: "#EA4335",
2293
2835
  d: "M12 4.75c1.77 0 3.35.61 4.6 1.8l3.42-3.42C17.95 1.19 15.24 0 12 0 7.33 0 3.28 2.57 1.25 6.57l4.03 3.14c.95-2.83 3.6-4.96 6.72-4.96z"
2294
2836
  })
2295
2837
  ]
2296
2838
  })
2297
2839
  }),
2298
- /* @__PURE__ */ jsx10("input", {
2840
+ /* @__PURE__ */ jsx12("input", {
2299
2841
  type: "text",
2300
2842
  value: query,
2301
2843
  onChange: (e) => handleChange(e.target.value),
@@ -2304,49 +2846,49 @@ function GoogleSpotlightBar({
2304
2846
  "aria-label": placeholder,
2305
2847
  className: "block flex-1 border-0 bg-transparent px-1 text-body-large text-on-surface caret-primary outline-none placeholder:text-on-surface-variant focus:outline-none focus:ring-0"
2306
2848
  }),
2307
- /* @__PURE__ */ jsxs10("div", {
2849
+ /* @__PURE__ */ jsxs11("div", {
2308
2850
  className: "flex shrink-0 items-center gap-1.5",
2309
2851
  children: [
2310
- onAttach && /* @__PURE__ */ jsx10(CircleButton3, {
2852
+ onAttach && /* @__PURE__ */ jsx12(CircleButton3, {
2311
2853
  variant: "standard",
2312
2854
  size: "sm",
2313
2855
  onClick: onAttach,
2314
2856
  "aria-label": "Add attachments",
2315
2857
  title: "Attach file",
2316
- children: /* @__PURE__ */ jsx10(Icon7, {
2858
+ children: /* @__PURE__ */ jsx12(Icon4, {
2317
2859
  name: "add",
2318
2860
  size: 20
2319
2861
  })
2320
2862
  }),
2321
- onScreenCapture && /* @__PURE__ */ jsx10(CircleButton3, {
2863
+ onScreenCapture && /* @__PURE__ */ jsx12(CircleButton3, {
2322
2864
  variant: "standard",
2323
2865
  size: "sm",
2324
2866
  onClick: onScreenCapture,
2325
2867
  "aria-label": "Capture screen",
2326
2868
  title: "Share or capture screen",
2327
- children: /* @__PURE__ */ jsx10(Icon7, {
2869
+ children: /* @__PURE__ */ jsx12(Icon4, {
2328
2870
  name: "screenshot",
2329
2871
  size: 20
2330
2872
  })
2331
2873
  }),
2332
- onGoogleLens && /* @__PURE__ */ jsx10(CircleButton3, {
2874
+ onGoogleLens && /* @__PURE__ */ jsx12(CircleButton3, {
2333
2875
  variant: "standard",
2334
2876
  size: "sm",
2335
2877
  onClick: onGoogleLens,
2336
2878
  "aria-label": "Google Lens",
2337
2879
  title: "Search with Google Lens",
2338
2880
  className: "hover:text-primary",
2339
- children: /* @__PURE__ */ jsx10(Icon7, {
2881
+ children: /* @__PURE__ */ jsx12(Icon4, {
2340
2882
  name: "center_focus_strong",
2341
2883
  size: 20
2342
2884
  })
2343
2885
  }),
2344
- /* @__PURE__ */ jsx10("div", {
2886
+ /* @__PURE__ */ jsx12("div", {
2345
2887
  "aria-hidden": "true",
2346
2888
  className: "ml-1 hidden select-none items-center rounded-full bg-surface-container px-2.5 py-1 text-label-small font-medium text-on-surface-variant sm:flex",
2347
2889
  children: "Alt + Space"
2348
2890
  }),
2349
- avatar && /* @__PURE__ */ jsx10("div", {
2891
+ avatar && /* @__PURE__ */ jsx12("div", {
2350
2892
  className: "ml-1 shrink-0",
2351
2893
  children: avatar
2352
2894
  })
@@ -2355,10 +2897,10 @@ function GoogleSpotlightBar({
2355
2897
  ]
2356
2898
  });
2357
2899
  }
2358
- // packages/m3-ai/src/GeminiAccountMenu.tsx
2359
- import { Icon as Icon8, Popover as Popover3 } from "@aphrody/m3-primitives";
2360
- import { clsx as clsx11 } from "clsx";
2361
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
2900
+ // m3/packages/m3-ai/src/GeminiAccountMenu.tsx
2901
+ import { Icon as Icon5, Popover as Popover3 } from "@aphrody/m3-primitives";
2902
+ import { clsx as clsx13 } from "clsx";
2903
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
2362
2904
  "use client";
2363
2905
  var EMPTY_MENU_ITEMS = [];
2364
2906
  function GeminiAccountMenu({
@@ -2371,35 +2913,35 @@ function GeminiAccountMenu({
2371
2913
  children,
2372
2914
  className
2373
2915
  }) {
2374
- return /* @__PURE__ */ jsxs11(Popover3.Root, {
2916
+ return /* @__PURE__ */ jsxs12(Popover3.Root, {
2375
2917
  open,
2376
2918
  onOpenChange,
2377
2919
  children: [
2378
- /* @__PURE__ */ jsx11(Popover3.Trigger, {
2920
+ /* @__PURE__ */ jsx13(Popover3.Trigger, {
2379
2921
  asChild: true,
2380
2922
  children
2381
2923
  }),
2382
- /* @__PURE__ */ jsxs11(Popover3.Content, {
2924
+ /* @__PURE__ */ jsxs12(Popover3.Content, {
2383
2925
  align: "start",
2384
2926
  side: "top",
2385
2927
  sideOffset: 8,
2386
- className: clsx11("gemini-account-menu w-[300px] overflow-hidden rounded-[var(--gemini-corner-card,16px)]", "border border-outline-variant/40 bg-surface-container p-2 text-on-surface shadow-md3-3", className),
2928
+ className: clsx13("gemini-account-menu w-[300px] overflow-hidden rounded-[var(--gemini-corner-card,16px)]", "border border-outline-variant/40 bg-surface-container p-2 text-on-surface shadow-md3-3", className),
2387
2929
  children: [
2388
- /* @__PURE__ */ jsxs11("div", {
2930
+ /* @__PURE__ */ jsxs12("div", {
2389
2931
  className: "flex items-center gap-3 rounded-small bg-surface-container-high p-3",
2390
2932
  children: [
2391
- /* @__PURE__ */ jsx11("div", {
2933
+ /* @__PURE__ */ jsx13("div", {
2392
2934
  className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-primary-container text-title-medium text-on-primary-container",
2393
2935
  children: avatar ?? name.charAt(0).toUpperCase()
2394
2936
  }),
2395
- /* @__PURE__ */ jsxs11("div", {
2937
+ /* @__PURE__ */ jsxs12("div", {
2396
2938
  className: "min-w-0 flex-1",
2397
2939
  children: [
2398
- /* @__PURE__ */ jsx11("div", {
2940
+ /* @__PURE__ */ jsx13("div", {
2399
2941
  className: "truncate text-body-medium font-medium text-on-surface",
2400
2942
  children: name
2401
2943
  }),
2402
- /* @__PURE__ */ jsx11("div", {
2944
+ /* @__PURE__ */ jsx13("div", {
2403
2945
  className: "truncate text-body-small text-on-surface-variant",
2404
2946
  children: email
2405
2947
  })
@@ -2407,40 +2949,40 @@ function GeminiAccountMenu({
2407
2949
  })
2408
2950
  ]
2409
2951
  }),
2410
- /* @__PURE__ */ jsx11("div", {
2952
+ /* @__PURE__ */ jsx13("div", {
2411
2953
  className: "mt-2 space-y-0.5",
2412
2954
  role: "menu",
2413
- children: items.map((item) => /* @__PURE__ */ jsxs11("div", {
2955
+ children: items.map((item) => /* @__PURE__ */ jsxs12("div", {
2414
2956
  children: [
2415
- /* @__PURE__ */ jsxs11("button", {
2957
+ /* @__PURE__ */ jsxs12("button", {
2416
2958
  type: "button",
2417
2959
  role: "menuitem",
2418
2960
  onClick: () => {
2419
2961
  item.onClick?.();
2420
2962
  onOpenChange(false);
2421
2963
  },
2422
- className: clsx11("flex w-full items-center justify-between rounded-small px-3 py-2 text-body-medium transition-colors", "hover:bg-on-surface/8 active:bg-on-surface/12", item.destructive ? "text-error hover:bg-error/8" : "text-on-surface hover:text-on-surface"),
2964
+ className: clsx13("flex w-full items-center justify-between rounded-small px-3 py-2 text-body-medium transition-colors", "hover:bg-on-surface/8 active:bg-on-surface/12", item.destructive ? "text-error hover:bg-error/8" : "text-on-surface hover:text-on-surface"),
2423
2965
  children: [
2424
- /* @__PURE__ */ jsxs11("div", {
2966
+ /* @__PURE__ */ jsxs12("div", {
2425
2967
  className: "flex items-center gap-3",
2426
2968
  children: [
2427
- item.icon && /* @__PURE__ */ jsx11(Icon8, {
2969
+ item.icon && /* @__PURE__ */ jsx13(Icon5, {
2428
2970
  name: item.icon,
2429
2971
  size: 20,
2430
2972
  className: item.destructive ? "text-error" : "text-on-surface-variant"
2431
2973
  }),
2432
- /* @__PURE__ */ jsx11("span", {
2974
+ /* @__PURE__ */ jsx13("span", {
2433
2975
  children: item.label
2434
2976
  })
2435
2977
  ]
2436
2978
  }),
2437
- item.shortcut && /* @__PURE__ */ jsx11("span", {
2979
+ item.shortcut && /* @__PURE__ */ jsx13("span", {
2438
2980
  className: "text-label-small text-on-surface-variant",
2439
2981
  children: item.shortcut
2440
2982
  })
2441
2983
  ]
2442
2984
  }),
2443
- item.dividerAfter && /* @__PURE__ */ jsx11("div", {
2985
+ item.dividerAfter && /* @__PURE__ */ jsx13("div", {
2444
2986
  className: "my-1 border-t border-outline-variant/30"
2445
2987
  })
2446
2988
  ]
@@ -2458,26 +3000,26 @@ function ComposerMoreUploadsMenu({
2458
3000
  submenuItems,
2459
3001
  children
2460
3002
  }) {
2461
- return /* @__PURE__ */ jsxs11(Popover3.Root, {
3003
+ return /* @__PURE__ */ jsxs12(Popover3.Root, {
2462
3004
  open,
2463
3005
  onOpenChange,
2464
3006
  children: [
2465
- /* @__PURE__ */ jsx11(Popover3.Trigger, {
3007
+ /* @__PURE__ */ jsx13(Popover3.Trigger, {
2466
3008
  asChild: true,
2467
3009
  children
2468
3010
  }),
2469
- /* @__PURE__ */ jsxs11(Popover3.Content, {
3011
+ /* @__PURE__ */ jsxs12(Popover3.Content, {
2470
3012
  align: "start",
2471
3013
  side: "top",
2472
3014
  sideOffset: 10,
2473
3015
  className: "gemini-composer-uploads-menu flex gap-2 rounded-[var(--gemini-corner-card,16px)] border border-outline-variant/30 bg-surface-container p-1.5 shadow-md3-3",
2474
3016
  children: [
2475
- /* @__PURE__ */ jsx11("div", {
3017
+ /* @__PURE__ */ jsx13("div", {
2476
3018
  className: "w-[220px] space-y-0.5",
2477
3019
  role: "menu",
2478
- children: items.map((item) => /* @__PURE__ */ jsxs11("div", {
3020
+ children: items.map((item) => /* @__PURE__ */ jsxs12("div", {
2479
3021
  children: [
2480
- /* @__PURE__ */ jsxs11("button", {
3022
+ /* @__PURE__ */ jsxs12("button", {
2481
3023
  type: "button",
2482
3024
  role: "menuitem",
2483
3025
  onClick: () => {
@@ -2486,33 +3028,33 @@ function ComposerMoreUploadsMenu({
2486
3028
  },
2487
3029
  className: "flex w-full items-center gap-3 rounded-small px-3 py-2 text-body-medium text-on-surface transition-colors hover:bg-on-surface/8",
2488
3030
  children: [
2489
- item.icon && /* @__PURE__ */ jsx11(Icon8, {
3031
+ item.icon && /* @__PURE__ */ jsx13(Icon5, {
2490
3032
  name: item.icon,
2491
3033
  size: 20,
2492
3034
  className: "text-on-surface-variant"
2493
3035
  }),
2494
- /* @__PURE__ */ jsx11("span", {
3036
+ /* @__PURE__ */ jsx13("span", {
2495
3037
  className: "flex-1 text-left",
2496
3038
  children: item.label
2497
3039
  })
2498
3040
  ]
2499
3041
  }),
2500
- item.dividerAfter && /* @__PURE__ */ jsx11("div", {
3042
+ item.dividerAfter && /* @__PURE__ */ jsx13("div", {
2501
3043
  className: "my-1 border-t border-outline-variant/30"
2502
3044
  })
2503
3045
  ]
2504
3046
  }, item.id))
2505
3047
  }),
2506
- submenuItems && submenuItems.length > 0 && /* @__PURE__ */ jsxs11("div", {
3048
+ submenuItems && submenuItems.length > 0 && /* @__PURE__ */ jsxs12("div", {
2507
3049
  className: "w-[200px] border-l border-outline-variant/20 pl-2 space-y-0.5",
2508
3050
  role: "menu",
2509
3051
  "aria-label": "More uploads",
2510
3052
  children: [
2511
- /* @__PURE__ */ jsx11("div", {
3053
+ /* @__PURE__ */ jsx13("div", {
2512
3054
  className: "px-2 py-1 text-label-small font-medium text-on-surface-variant uppercase tracking-wider",
2513
3055
  children: "Cloud & Storage"
2514
3056
  }),
2515
- submenuItems.map((sub) => /* @__PURE__ */ jsxs11("button", {
3057
+ submenuItems.map((sub) => /* @__PURE__ */ jsxs12("button", {
2516
3058
  type: "button",
2517
3059
  role: "menuitem",
2518
3060
  onClick: () => {
@@ -2521,12 +3063,12 @@ function ComposerMoreUploadsMenu({
2521
3063
  },
2522
3064
  className: "flex w-full items-center gap-3 rounded-small px-3 py-2 text-body-medium text-on-surface transition-colors hover:bg-on-surface/8",
2523
3065
  children: [
2524
- sub.icon && /* @__PURE__ */ jsx11(Icon8, {
3066
+ sub.icon && /* @__PURE__ */ jsx13(Icon5, {
2525
3067
  name: sub.icon,
2526
3068
  size: 20,
2527
3069
  className: "text-primary"
2528
3070
  }),
2529
- /* @__PURE__ */ jsx11("span", {
3071
+ /* @__PURE__ */ jsx13("span", {
2530
3072
  className: "flex-1 text-left",
2531
3073
  children: sub.label
2532
3074
  })
@@ -2539,11 +3081,11 @@ function ComposerMoreUploadsMenu({
2539
3081
  ]
2540
3082
  });
2541
3083
  }
2542
- // packages/m3-ai/src/GeminiPersonalContextEdit.tsx
2543
- import { Button as Button2, DialogClose, DialogContent, DialogRoot, Icon as Icon9 } from "@aphrody/m3-primitives";
2544
- import { clsx as clsx12 } from "clsx";
3084
+ // m3/packages/m3-ai/src/GeminiPersonalContextEdit.tsx
3085
+ import { Button as Button2, DialogClose, DialogContent, DialogRoot, Icon as Icon6 } from "@aphrody/m3-primitives";
3086
+ import { clsx as clsx14 } from "clsx";
2545
3087
  import { useState as useState8 } from "react";
2546
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
3088
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
2547
3089
  "use client";
2548
3090
  function GeminiPersonalContextEdit({
2549
3091
  open,
@@ -2575,22 +3117,22 @@ function GeminiPersonalContextEdit({
2575
3117
  setIsSaving(false);
2576
3118
  }
2577
3119
  };
2578
- return /* @__PURE__ */ jsx12(DialogRoot, {
3120
+ return /* @__PURE__ */ jsx14(DialogRoot, {
2579
3121
  open,
2580
3122
  onOpenChange,
2581
- children: /* @__PURE__ */ jsxs12(DialogContent, {
2582
- className: clsx12("gemini-context-edit-dialog w-full max-w-[620px] rounded-[var(--gemini-corner-card,16px)]", "border border-outline-variant/30 bg-surface p-6 text-on-surface shadow-md3-3", className),
3123
+ children: /* @__PURE__ */ jsxs13(DialogContent, {
3124
+ className: clsx14("gemini-context-edit-dialog w-full max-w-[620px] rounded-[var(--gemini-corner-card,16px)]", "border border-outline-variant/30 bg-surface p-6 text-on-surface shadow-md3-3", className),
2583
3125
  children: [
2584
- /* @__PURE__ */ jsxs12("div", {
3126
+ /* @__PURE__ */ jsxs13("div", {
2585
3127
  className: "flex items-start justify-between gap-4",
2586
3128
  children: [
2587
- /* @__PURE__ */ jsxs12("div", {
3129
+ /* @__PURE__ */ jsxs13("div", {
2588
3130
  className: "space-y-1",
2589
3131
  children: [
2590
- /* @__PURE__ */ jsxs12("h2", {
3132
+ /* @__PURE__ */ jsxs13("h2", {
2591
3133
  className: "text-headline-small font-normal text-on-surface flex items-center gap-2",
2592
3134
  children: [
2593
- /* @__PURE__ */ jsx12(Icon9, {
3135
+ /* @__PURE__ */ jsx14(Icon6, {
2594
3136
  name: "psychology",
2595
3137
  size: 24,
2596
3138
  className: "text-primary"
@@ -2598,19 +3140,19 @@ function GeminiPersonalContextEdit({
2598
3140
  title
2599
3141
  ]
2600
3142
  }),
2601
- /* @__PURE__ */ jsx12("p", {
3143
+ /* @__PURE__ */ jsx14("p", {
2602
3144
  className: "text-body-medium text-on-surface-variant leading-relaxed",
2603
3145
  children: description
2604
3146
  })
2605
3147
  ]
2606
3148
  }),
2607
- /* @__PURE__ */ jsx12(DialogClose, {
3149
+ /* @__PURE__ */ jsx14(DialogClose, {
2608
3150
  asChild: true,
2609
- children: /* @__PURE__ */ jsx12("button", {
3151
+ children: /* @__PURE__ */ jsx14("button", {
2610
3152
  type: "button",
2611
3153
  className: "rounded-full p-1.5 text-on-surface-variant hover:bg-on-surface/8 transition-colors",
2612
3154
  "aria-label": "Close",
2613
- children: /* @__PURE__ */ jsx12(Icon9, {
3155
+ children: /* @__PURE__ */ jsx14(Icon6, {
2614
3156
  name: "close",
2615
3157
  size: 20
2616
3158
  })
@@ -2618,12 +3160,12 @@ function GeminiPersonalContextEdit({
2618
3160
  })
2619
3161
  ]
2620
3162
  }),
2621
- /* @__PURE__ */ jsxs12("div", {
3163
+ /* @__PURE__ */ jsxs13("div", {
2622
3164
  className: "mt-5 space-y-2",
2623
3165
  children: [
2624
- /* @__PURE__ */ jsx12("div", {
3166
+ /* @__PURE__ */ jsx14("div", {
2625
3167
  className: "relative rounded-medium border-2 border-primary/60 bg-surface-container-low transition-all focus-within:border-primary focus-within:ring-2 focus-within:ring-primary/20",
2626
- children: /* @__PURE__ */ jsx12("textarea", {
3168
+ children: /* @__PURE__ */ jsx14("textarea", {
2627
3169
  value: context,
2628
3170
  onChange: (e) => setContext(e.target.value),
2629
3171
  placeholder: "e.g. Always respond in concise bullet points, write modern TypeScript with Bun, favor pure functions...",
@@ -2632,16 +3174,16 @@ function GeminiPersonalContextEdit({
2632
3174
  className: "block w-full resize-y border-0 bg-transparent p-3.5 text-body-medium text-on-surface caret-primary outline-none placeholder:text-on-surface-variant/60"
2633
3175
  })
2634
3176
  }),
2635
- /* @__PURE__ */ jsxs12("div", {
3177
+ /* @__PURE__ */ jsxs13("div", {
2636
3178
  className: "flex justify-between px-1 text-label-small text-on-surface-variant",
2637
3179
  children: [
2638
- /* @__PURE__ */ jsxs12("span", {
3180
+ /* @__PURE__ */ jsxs13("span", {
2639
3181
  children: [
2640
3182
  context.length,
2641
3183
  " characters"
2642
3184
  ]
2643
3185
  }),
2644
- initialContext.length > 0 && onClear && /* @__PURE__ */ jsx12("button", {
3186
+ initialContext.length > 0 && onClear && /* @__PURE__ */ jsx14("button", {
2645
3187
  type: "button",
2646
3188
  onClick: () => {
2647
3189
  setContext("");
@@ -2654,18 +3196,18 @@ function GeminiPersonalContextEdit({
2654
3196
  })
2655
3197
  ]
2656
3198
  }),
2657
- /* @__PURE__ */ jsxs12("div", {
3199
+ /* @__PURE__ */ jsxs13("div", {
2658
3200
  className: "mt-6 flex items-center justify-end gap-3",
2659
3201
  children: [
2660
- /* @__PURE__ */ jsx12(DialogClose, {
3202
+ /* @__PURE__ */ jsx14(DialogClose, {
2661
3203
  asChild: true,
2662
- children: /* @__PURE__ */ jsx12(Button2, {
3204
+ children: /* @__PURE__ */ jsx14(Button2, {
2663
3205
  variant: "text",
2664
3206
  disabled: isSaving,
2665
3207
  children: "Cancel"
2666
3208
  })
2667
3209
  }),
2668
- /* @__PURE__ */ jsx12(Button2, {
3210
+ /* @__PURE__ */ jsx14(Button2, {
2669
3211
  variant: "filled",
2670
3212
  onClick: handleSave,
2671
3213
  disabled: !canSave,
@@ -2678,10 +3220,10 @@ function GeminiPersonalContextEdit({
2678
3220
  })
2679
3221
  });
2680
3222
  }
2681
- // packages/m3-ai/src/TaskStatusIcon.tsx
2682
- import { Icon as Icon10 } from "@aphrody/m3-primitives";
2683
- import { clsx as clsx13 } from "clsx";
2684
- import { jsx as jsx13 } from "react/jsx-runtime";
3223
+ // m3/packages/m3-ai/src/TaskStatusIcon.tsx
3224
+ import { Icon as Icon7 } from "@aphrody/m3-primitives";
3225
+ import { clsx as clsx15 } from "clsx";
3226
+ import { jsx as jsx15 } from "react/jsx-runtime";
2685
3227
  var config = {
2686
3228
  done: { icon: "check_circle", filled: true, color: "text-success" },
2687
3229
  in_progress: { icon: "clock_loader_40", filled: true, color: "text-primary" },
@@ -2691,19 +3233,19 @@ var config = {
2691
3233
  };
2692
3234
  function TaskStatusIcon({ status, size = 16, className, label }) {
2693
3235
  const { icon, filled, color } = config[status];
2694
- return /* @__PURE__ */ jsx13(Icon10, {
3236
+ return /* @__PURE__ */ jsx15(Icon7, {
2695
3237
  name: icon,
2696
3238
  size,
2697
3239
  filled,
2698
3240
  label: label ?? TASK_STATUS_LABEL[status],
2699
3241
  "data-status": status,
2700
- className: clsx13(color, className)
3242
+ className: clsx15(color, className)
2701
3243
  });
2702
3244
  }
2703
- // packages/m3-ai/src/TaskPriorityIcon.tsx
2704
- import { Icon as Icon11 } from "@aphrody/m3-primitives";
2705
- import { clsx as clsx14 } from "clsx";
2706
- import { jsx as jsx14 } from "react/jsx-runtime";
3245
+ // m3/packages/m3-ai/src/TaskPriorityIcon.tsx
3246
+ import { Icon as Icon8 } from "@aphrody/m3-primitives";
3247
+ import { clsx as clsx16 } from "clsx";
3248
+ import { jsx as jsx16 } from "react/jsx-runtime";
2707
3249
  var config2 = {
2708
3250
  critical: { icon: "priority_high", filled: true, color: "text-error" },
2709
3251
  high: { icon: "keyboard_double_arrow_up", filled: false, color: "text-warning" },
@@ -2712,20 +3254,20 @@ var config2 = {
2712
3254
  };
2713
3255
  function TaskPriorityIcon({ priority, size = 14, className, label }) {
2714
3256
  const { icon, filled, color } = config2[priority];
2715
- return /* @__PURE__ */ jsx14(Icon11, {
3257
+ return /* @__PURE__ */ jsx16(Icon8, {
2716
3258
  name: icon,
2717
3259
  size,
2718
3260
  filled,
2719
3261
  weight: 600,
2720
3262
  label: label ?? `${TASK_PRIORITY_LABEL[priority]} priority`,
2721
3263
  "data-priority": priority,
2722
- className: clsx14(color, className)
3264
+ className: clsx16(color, className)
2723
3265
  });
2724
3266
  }
2725
- // packages/m3-ai/src/TaskRow.tsx
2726
- import { DropdownMenu, Icon as Icon12 } from "@aphrody/m3-primitives";
2727
- import { clsx as clsx15 } from "clsx";
2728
- import { jsx as jsx15, jsxs as jsxs13, Fragment as Fragment2 } from "react/jsx-runtime";
3267
+ // m3/packages/m3-ai/src/TaskRow.tsx
3268
+ import { DropdownMenu, Icon as Icon9 } from "@aphrody/m3-primitives";
3269
+ import { clsx as clsx17 } from "clsx";
3270
+ import { jsx as jsx17, jsxs as jsxs14, Fragment as Fragment5 } from "react/jsx-runtime";
2729
3271
  var TASK_ROW_GRID = "20px 18px 72px 1fr 56px 96px 40px";
2730
3272
  var TASK_ROW_HEIGHT = 48;
2731
3273
  function TaskRow({
@@ -2741,7 +3283,7 @@ function TaskRow({
2741
3283
  const assigneeName = resolveAgentName?.(task.assigned_agent_id) ?? task.assigned_agent_id;
2742
3284
  const hasActions = onStatusChange || onDelete;
2743
3285
  const isRowInteractive = typeof onClick === "function";
2744
- const rowClassName = clsx15("task-row group grid w-full items-center border-b border-outline-variant text-left", "transition-colors duration-200 ease-standard", isActive ? "bg-secondary-container text-on-secondary-container" : "bg-transparent text-on-surface hover:bg-on-surface/8", isRowInteractive && !isActive && "active:bg-on-surface/10", className);
3286
+ const rowClassName = clsx17("task-row group grid w-full items-center border-b border-outline-variant text-left", "transition-colors duration-200 ease-standard", isActive ? "bg-secondary-container text-on-secondary-container" : "bg-transparent text-on-surface hover:bg-on-surface/8", isRowInteractive && !isActive && "active:bg-on-surface/10", className);
2745
3287
  const rowStyle = {
2746
3288
  gridTemplateColumns: TASK_ROW_GRID,
2747
3289
  minHeight: TASK_ROW_HEIGHT,
@@ -2749,84 +3291,84 @@ function TaskRow({
2749
3291
  paddingRight: 8,
2750
3292
  gap: 12
2751
3293
  };
2752
- const mainContent = /* @__PURE__ */ jsxs13(Fragment2, {
3294
+ const mainContent = /* @__PURE__ */ jsxs14(Fragment5, {
2753
3295
  children: [
2754
- /* @__PURE__ */ jsx15(TaskStatusIcon, {
3296
+ /* @__PURE__ */ jsx17(TaskStatusIcon, {
2755
3297
  status: task.status,
2756
3298
  size: 20
2757
3299
  }),
2758
- /* @__PURE__ */ jsx15(TaskPriorityIcon, {
3300
+ /* @__PURE__ */ jsx17(TaskPriorityIcon, {
2759
3301
  priority: task.priority,
2760
3302
  size: 18
2761
3303
  }),
2762
- /* @__PURE__ */ jsxs13("span", {
2763
- className: clsx15("truncate font-code text-body-small", isActive ? "text-on-secondary-container" : "text-on-surface-variant"),
3304
+ /* @__PURE__ */ jsxs14("span", {
3305
+ className: clsx17("truncate font-code text-body-small", isActive ? "text-on-secondary-container" : "text-on-surface-variant"),
2764
3306
  children: [
2765
3307
  "SPC-",
2766
3308
  task.task_number
2767
3309
  ]
2768
3310
  }),
2769
- /* @__PURE__ */ jsx15("span", {
3311
+ /* @__PURE__ */ jsx17("span", {
2770
3312
  className: "min-w-0 truncate text-body-large",
2771
3313
  children: task.title
2772
3314
  }),
2773
- /* @__PURE__ */ jsx15("span", {
2774
- className: clsx15("text-right text-body-small", isActive ? "text-on-secondary-container" : "text-on-surface-variant"),
3315
+ /* @__PURE__ */ jsx17("span", {
3316
+ className: clsx17("text-right text-body-small", isActive ? "text-on-secondary-container" : "text-on-surface-variant"),
2775
3317
  children: task.subtasks.length > 0 ? `${completedSubtasks}/${task.subtasks.length}` : ""
2776
3318
  }),
2777
- /* @__PURE__ */ jsx15("span", {
2778
- className: clsx15("truncate text-right text-body-small", isActive ? "text-on-secondary-container" : "text-on-surface-variant"),
3319
+ /* @__PURE__ */ jsx17("span", {
3320
+ className: clsx17("truncate text-right text-body-small", isActive ? "text-on-secondary-container" : "text-on-surface-variant"),
2779
3321
  children: assigneeName
2780
3322
  })
2781
3323
  ]
2782
3324
  });
2783
- const actions = /* @__PURE__ */ jsx15("span", {
3325
+ const actions = /* @__PURE__ */ jsx17("span", {
2784
3326
  className: "flex items-center justify-center",
2785
- children: hasActions ? /* @__PURE__ */ jsxs13(DropdownMenu.Root, {
3327
+ children: hasActions ? /* @__PURE__ */ jsxs14(DropdownMenu.Root, {
2786
3328
  children: [
2787
- /* @__PURE__ */ jsx15(DropdownMenu.Trigger, {
3329
+ /* @__PURE__ */ jsx17(DropdownMenu.Trigger, {
2788
3330
  asChild: true,
2789
- children: /* @__PURE__ */ jsx15("button", {
3331
+ children: /* @__PURE__ */ jsx17("button", {
2790
3332
  type: "button",
2791
3333
  "aria-label": "Task Actions",
2792
- className: clsx15("flex size-8 items-center justify-center rounded-full text-on-surface-variant", "opacity-0 transition-[opacity,background-color] duration-200 ease-standard", "hover:bg-on-surface/8 active:bg-on-surface/10", "group-hover:opacity-100 group-focus-within:opacity-100 focus-visible:opacity-100 data-popup-open:opacity-100", focusRing),
2793
- children: /* @__PURE__ */ jsx15(Icon12, {
3334
+ className: clsx17("flex size-8 items-center justify-center rounded-full text-on-surface-variant", "opacity-0 transition-[opacity,background-color] duration-200 ease-standard", "hover:bg-on-surface/8 active:bg-on-surface/10", "group-hover:opacity-100 group-focus-within:opacity-100 focus-visible:opacity-100 data-popup-open:opacity-100", focusRing),
3335
+ children: /* @__PURE__ */ jsx17(Icon9, {
2794
3336
  name: "more_vert",
2795
3337
  size: 20
2796
3338
  })
2797
3339
  })
2798
3340
  }),
2799
- /* @__PURE__ */ jsxs13(DropdownMenu.Content, {
3341
+ /* @__PURE__ */ jsxs14(DropdownMenu.Content, {
2800
3342
  align: "end",
2801
3343
  sideOffset: 4,
2802
3344
  children: [
2803
- onStatusChange && TASK_STATUS_ORDER.filter((s) => s !== task.status).map((s) => /* @__PURE__ */ jsxs13(DropdownMenu.Item, {
3345
+ onStatusChange && TASK_STATUS_ORDER.filter((s) => s !== task.status).map((s) => /* @__PURE__ */ jsxs14(DropdownMenu.Item, {
2804
3346
  onClick: () => {
2805
3347
  onStatusChange(task, s);
2806
3348
  },
2807
3349
  children: [
2808
- /* @__PURE__ */ jsx15(TaskStatusIcon, {
3350
+ /* @__PURE__ */ jsx17(TaskStatusIcon, {
2809
3351
  status: s,
2810
3352
  size: 20,
2811
3353
  label: ""
2812
3354
  }),
2813
- /* @__PURE__ */ jsx15("span", {
3355
+ /* @__PURE__ */ jsx17("span", {
2814
3356
  children: TASK_STATUS_LABEL[s]
2815
3357
  })
2816
3358
  ]
2817
3359
  }, s)),
2818
- onStatusChange && onDelete && /* @__PURE__ */ jsx15(DropdownMenu.Separator, {}),
2819
- onDelete && /* @__PURE__ */ jsxs13(DropdownMenu.Item, {
3360
+ onStatusChange && onDelete && /* @__PURE__ */ jsx17(DropdownMenu.Separator, {}),
3361
+ onDelete && /* @__PURE__ */ jsxs14(DropdownMenu.Item, {
2820
3362
  onClick: () => {
2821
3363
  onDelete(task);
2822
3364
  },
2823
3365
  className: "text-error",
2824
3366
  children: [
2825
- /* @__PURE__ */ jsx15(Icon12, {
3367
+ /* @__PURE__ */ jsx17(Icon9, {
2826
3368
  name: "delete",
2827
3369
  size: 20
2828
3370
  }),
2829
- /* @__PURE__ */ jsx15("span", {
3371
+ /* @__PURE__ */ jsx17("span", {
2830
3372
  children: "Delete"
2831
3373
  })
2832
3374
  ]
@@ -2837,7 +3379,7 @@ function TaskRow({
2837
3379
  }) : null
2838
3380
  });
2839
3381
  if (!isRowInteractive) {
2840
- return /* @__PURE__ */ jsxs13("div", {
3382
+ return /* @__PURE__ */ jsxs14("div", {
2841
3383
  "aria-current": isActive ? "true" : undefined,
2842
3384
  className: rowClassName,
2843
3385
  style: rowStyle,
@@ -2847,26 +3389,26 @@ function TaskRow({
2847
3389
  ]
2848
3390
  });
2849
3391
  }
2850
- return /* @__PURE__ */ jsxs13("div", {
3392
+ return /* @__PURE__ */ jsxs14("div", {
2851
3393
  className: rowClassName,
2852
3394
  style: rowStyle,
2853
3395
  children: [
2854
- /* @__PURE__ */ jsx15("button", {
3396
+ /* @__PURE__ */ jsx17("button", {
2855
3397
  type: "button",
2856
3398
  "aria-current": isActive ? "true" : undefined,
2857
3399
  onClick: () => onClick(task),
2858
- className: clsx15("col-span-6 grid grid-cols-subgrid items-center border-0 bg-transparent p-0 text-left font-inherit", focusRing, "focus-visible:outline-offset-[-3px]"),
3400
+ className: clsx17("col-span-6 grid grid-cols-subgrid items-center border-0 bg-transparent p-0 text-left font-inherit", focusRing, "focus-visible:outline-offset-[-3px]"),
2859
3401
  children: mainContent
2860
3402
  }),
2861
3403
  actions
2862
3404
  ]
2863
3405
  });
2864
3406
  }
2865
- // packages/m3-ai/src/TaskList.tsx
2866
- import { Collapsible, CollapsibleContent, CollapsibleTrigger, Icon as Icon13 } from "@aphrody/m3-primitives";
2867
- import { clsx as clsx16 } from "clsx";
2868
- import { useMemo as useMemo4 } from "react";
2869
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
3407
+ // m3/packages/m3-ai/src/TaskList.tsx
3408
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger, Icon as Icon10 } from "@aphrody/m3-primitives";
3409
+ import { clsx as clsx18 } from "clsx";
3410
+ import { useMemo as useMemo5 } from "react";
3411
+ import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
2870
3412
  var GRID_STYLE = {
2871
3413
  gridTemplateColumns: TASK_ROW_GRID,
2872
3414
  paddingLeft: 16,
@@ -2885,7 +3427,7 @@ function TaskList({
2885
3427
  resolveAgentName,
2886
3428
  className
2887
3429
  }) {
2888
- const grouped = useMemo4(() => {
3430
+ const grouped = useMemo5(() => {
2889
3431
  const map = new Map;
2890
3432
  for (const status of groups)
2891
3433
  map.set(status, []);
@@ -2896,64 +3438,64 @@ function TaskList({
2896
3438
  }
2897
3439
  return map;
2898
3440
  }, [tasks, groups]);
2899
- return /* @__PURE__ */ jsxs14("div", {
2900
- className: clsx16("flex flex-col bg-surface text-on-surface", className),
3441
+ return /* @__PURE__ */ jsxs15("div", {
3442
+ className: clsx18("flex flex-col bg-surface text-on-surface", className),
2901
3443
  children: [
2902
- /* @__PURE__ */ jsxs14("div", {
3444
+ /* @__PURE__ */ jsxs15("div", {
2903
3445
  className: "grid items-center border-b border-outline-variant text-label-medium text-on-surface-variant",
2904
3446
  style: { ...GRID_STYLE, height: 32 },
2905
3447
  children: [
2906
- /* @__PURE__ */ jsx16("span", {}),
2907
- /* @__PURE__ */ jsx16("span", {}),
2908
- /* @__PURE__ */ jsx16("span", {
3448
+ /* @__PURE__ */ jsx18("span", {}),
3449
+ /* @__PURE__ */ jsx18("span", {}),
3450
+ /* @__PURE__ */ jsx18("span", {
2909
3451
  children: "ID"
2910
3452
  }),
2911
- /* @__PURE__ */ jsx16("span", {
3453
+ /* @__PURE__ */ jsx18("span", {
2912
3454
  children: "Title"
2913
3455
  }),
2914
- /* @__PURE__ */ jsx16("span", {
3456
+ /* @__PURE__ */ jsx18("span", {
2915
3457
  className: "text-right",
2916
3458
  children: "Subs"
2917
3459
  }),
2918
- /* @__PURE__ */ jsx16("span", {
3460
+ /* @__PURE__ */ jsx18("span", {
2919
3461
  className: "text-right",
2920
3462
  children: "Assignee"
2921
3463
  }),
2922
- /* @__PURE__ */ jsx16("span", {})
3464
+ /* @__PURE__ */ jsx18("span", {})
2923
3465
  ]
2924
3466
  }),
2925
3467
  groups.map((status) => {
2926
3468
  const items = grouped.get(status) ?? [];
2927
3469
  const isOpen = !collapsedGroups?.has(status);
2928
- return /* @__PURE__ */ jsxs14(Collapsible, {
3470
+ return /* @__PURE__ */ jsxs15(Collapsible, {
2929
3471
  open: isOpen,
2930
3472
  onOpenChange: () => onToggleGroup?.(status),
2931
3473
  children: [
2932
- /* @__PURE__ */ jsxs14(CollapsibleTrigger, {
2933
- className: clsx16("grid w-full items-center rounded-none border-b border-outline-variant bg-surface-container-low", "text-title-small text-on-surface transition-colors duration-200 ease-standard", "hover:bg-on-surface/8 active:bg-on-surface/10", focusRing, "focus-visible:outline-offset-[-3px]"),
3474
+ /* @__PURE__ */ jsxs15(CollapsibleTrigger, {
3475
+ className: clsx18("grid w-full items-center rounded-none border-b border-outline-variant bg-surface-container-low", "text-title-small text-on-surface transition-colors duration-200 ease-standard", "hover:bg-on-surface/8 active:bg-on-surface/10", focusRing, "focus-visible:outline-offset-[-3px]"),
2934
3476
  style: { ...GRID_STYLE, height: 40 },
2935
3477
  children: [
2936
- /* @__PURE__ */ jsx16("span", {
3478
+ /* @__PURE__ */ jsx18("span", {
2937
3479
  className: "flex items-center justify-center text-on-surface-variant",
2938
- children: /* @__PURE__ */ jsx16(Icon13, {
3480
+ children: /* @__PURE__ */ jsx18(Icon10, {
2939
3481
  name: "chevron_right",
2940
3482
  size: 20,
2941
- className: clsx16("shrink-0 transition-transform duration-300 ease-emphasized", isOpen && "rotate-90")
3483
+ className: clsx18("shrink-0 transition-transform duration-300 ease-emphasized", isOpen && "rotate-90")
2942
3484
  })
2943
3485
  }),
2944
- /* @__PURE__ */ jsx16("span", {
3486
+ /* @__PURE__ */ jsx18("span", {
2945
3487
  className: "flex items-center justify-center",
2946
- children: /* @__PURE__ */ jsx16(TaskStatusIcon, {
3488
+ children: /* @__PURE__ */ jsx18(TaskStatusIcon, {
2947
3489
  status,
2948
3490
  size: 18,
2949
3491
  label: ""
2950
3492
  })
2951
3493
  }),
2952
- /* @__PURE__ */ jsxs14("span", {
3494
+ /* @__PURE__ */ jsxs15("span", {
2953
3495
  className: "col-span-5 flex items-center gap-1.5 text-left",
2954
3496
  children: [
2955
3497
  TASK_STATUS_LABEL[status],
2956
- /* @__PURE__ */ jsxs14("span", {
3498
+ /* @__PURE__ */ jsxs15("span", {
2957
3499
  className: "text-body-small text-on-surface-variant",
2958
3500
  children: [
2959
3501
  "(",
@@ -2965,15 +3507,15 @@ function TaskList({
2965
3507
  })
2966
3508
  ]
2967
3509
  }),
2968
- /* @__PURE__ */ jsx16(CollapsibleContent, {
2969
- children: items.length > 0 ? items.map((task) => /* @__PURE__ */ jsx16(TaskRow, {
3510
+ /* @__PURE__ */ jsx18(CollapsibleContent, {
3511
+ children: items.length > 0 ? items.map((task) => /* @__PURE__ */ jsx18(TaskRow, {
2970
3512
  task,
2971
3513
  isActive: task.id === activeTaskId,
2972
3514
  onClick: onTaskClick,
2973
3515
  onStatusChange,
2974
3516
  onDelete,
2975
3517
  resolveAgentName
2976
- }, task.id)) : /* @__PURE__ */ jsx16("div", {
3518
+ }, task.id)) : /* @__PURE__ */ jsx18("div", {
2977
3519
  className: "border-b border-outline-variant px-4 py-3 text-body-small text-on-surface-variant",
2978
3520
  children: "No tasks"
2979
3521
  })
@@ -2984,10 +3526,10 @@ function TaskList({
2984
3526
  ]
2985
3527
  });
2986
3528
  }
2987
- // packages/m3-ai/src/TaskDetail.tsx
2988
- import { Button as Button3, CircleButton as CircleButton4, Icon as Icon14, Select, SelectOption } from "@aphrody/m3-primitives";
2989
- import { clsx as clsx17 } from "clsx";
2990
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
3529
+ // m3/packages/m3-ai/src/TaskDetail.tsx
3530
+ import { Button as Button3, CircleButton as CircleButton4, Icon as Icon11, Select, SelectOption } from "@aphrody/m3-primitives";
3531
+ import { clsx as clsx19 } from "clsx";
3532
+ import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
2991
3533
  function formatDate(iso) {
2992
3534
  return new Date(iso).toLocaleDateString(undefined, {
2993
3535
  year: "numeric",
@@ -2998,14 +3540,14 @@ function formatDate(iso) {
2998
3540
  });
2999
3541
  }
3000
3542
  function Property({ label, children }) {
3001
- return /* @__PURE__ */ jsxs15("div", {
3543
+ return /* @__PURE__ */ jsxs16("div", {
3002
3544
  className: "flex min-w-0 flex-col gap-0.5",
3003
3545
  children: [
3004
- /* @__PURE__ */ jsx17("span", {
3546
+ /* @__PURE__ */ jsx19("span", {
3005
3547
  className: "text-label-medium text-on-surface-variant",
3006
3548
  children: label
3007
3549
  }),
3008
- /* @__PURE__ */ jsx17("span", {
3550
+ /* @__PURE__ */ jsx19("span", {
3009
3551
  className: "flex min-h-8 items-center gap-1.5 text-body-medium text-on-surface",
3010
3552
  children
3011
3553
  })
@@ -3024,27 +3566,27 @@ function TaskDetail({
3024
3566
  const ownerName = resolveAgentName?.(task.owner_agent_id) ?? task.owner_agent_id;
3025
3567
  const assigneeName = resolveAgentName?.(task.assigned_agent_id) ?? task.assigned_agent_id;
3026
3568
  const completedCount = task.subtasks.filter((s) => s.completed).length;
3027
- return /* @__PURE__ */ jsxs15("div", {
3028
- className: clsx17("flex flex-col gap-6 bg-surface p-6 text-on-surface", className),
3569
+ return /* @__PURE__ */ jsxs16("div", {
3570
+ className: clsx19("flex flex-col gap-6 bg-surface p-6 text-on-surface", className),
3029
3571
  children: [
3030
- /* @__PURE__ */ jsxs15("div", {
3572
+ /* @__PURE__ */ jsxs16("div", {
3031
3573
  className: "flex flex-col gap-2",
3032
3574
  children: [
3033
- /* @__PURE__ */ jsxs15("div", {
3575
+ /* @__PURE__ */ jsxs16("div", {
3034
3576
  className: "flex items-center gap-2",
3035
3577
  children: [
3036
- /* @__PURE__ */ jsxs15("div", {
3578
+ /* @__PURE__ */ jsxs16("div", {
3037
3579
  className: "flex flex-1 items-center gap-2",
3038
3580
  children: [
3039
- /* @__PURE__ */ jsx17(TaskStatusIcon, {
3581
+ /* @__PURE__ */ jsx19(TaskStatusIcon, {
3040
3582
  status: task.status,
3041
3583
  size: 20
3042
3584
  }),
3043
- /* @__PURE__ */ jsx17(TaskPriorityIcon, {
3585
+ /* @__PURE__ */ jsx19(TaskPriorityIcon, {
3044
3586
  priority: task.priority,
3045
3587
  size: 18
3046
3588
  }),
3047
- /* @__PURE__ */ jsxs15("span", {
3589
+ /* @__PURE__ */ jsxs16("span", {
3048
3590
  className: "font-code text-body-small text-on-surface-variant",
3049
3591
  children: [
3050
3592
  "SPC-",
@@ -3053,7 +3595,7 @@ function TaskDetail({
3053
3595
  })
3054
3596
  ]
3055
3597
  }),
3056
- onClose && /* @__PURE__ */ jsx17(CircleButton4, {
3598
+ onClose && /* @__PURE__ */ jsx19(CircleButton4, {
3057
3599
  icon: "close",
3058
3600
  variant: "standard",
3059
3601
  onClick: onClose,
@@ -3061,31 +3603,31 @@ function TaskDetail({
3061
3603
  })
3062
3604
  ]
3063
3605
  }),
3064
- /* @__PURE__ */ jsx17("h2", {
3606
+ /* @__PURE__ */ jsx19("h2", {
3065
3607
  className: "text-headline-small text-on-surface",
3066
3608
  children: task.title
3067
3609
  })
3068
3610
  ]
3069
3611
  }),
3070
- /* @__PURE__ */ jsxs15("div", {
3612
+ /* @__PURE__ */ jsxs16("div", {
3071
3613
  className: "grid grid-cols-2 gap-x-6 gap-y-4 medium:grid-cols-4",
3072
3614
  children: [
3073
- /* @__PURE__ */ jsx17(Property, {
3615
+ /* @__PURE__ */ jsx19(Property, {
3074
3616
  label: "Status",
3075
- children: onStatusChange ? /* @__PURE__ */ jsx17(Select, {
3617
+ children: onStatusChange ? /* @__PURE__ */ jsx19(Select, {
3076
3618
  value: task.status,
3077
3619
  size: "md",
3078
3620
  onChange: (value) => onStatusChange(task, value),
3079
- children: TASK_STATUS_ORDER.map((s) => /* @__PURE__ */ jsx17(SelectOption, {
3621
+ children: TASK_STATUS_ORDER.map((s) => /* @__PURE__ */ jsx19(SelectOption, {
3080
3622
  value: s,
3081
3623
  children: TASK_STATUS_LABEL[s]
3082
3624
  }, s))
3083
3625
  }) : TASK_STATUS_LABEL[task.status]
3084
3626
  }),
3085
- /* @__PURE__ */ jsxs15(Property, {
3627
+ /* @__PURE__ */ jsxs16(Property, {
3086
3628
  label: "Priority",
3087
3629
  children: [
3088
- /* @__PURE__ */ jsx17(TaskPriorityIcon, {
3630
+ /* @__PURE__ */ jsx19(TaskPriorityIcon, {
3089
3631
  priority: task.priority,
3090
3632
  size: 18,
3091
3633
  label: ""
@@ -3093,33 +3635,33 @@ function TaskDetail({
3093
3635
  TASK_PRIORITY_LABEL[task.priority]
3094
3636
  ]
3095
3637
  }),
3096
- /* @__PURE__ */ jsx17(Property, {
3638
+ /* @__PURE__ */ jsx19(Property, {
3097
3639
  label: "Owner",
3098
- children: /* @__PURE__ */ jsx17("span", {
3640
+ children: /* @__PURE__ */ jsx19("span", {
3099
3641
  className: "truncate",
3100
3642
  children: ownerName
3101
3643
  })
3102
3644
  }),
3103
- /* @__PURE__ */ jsx17(Property, {
3645
+ /* @__PURE__ */ jsx19(Property, {
3104
3646
  label: "Assigned",
3105
- children: /* @__PURE__ */ jsx17("span", {
3647
+ children: /* @__PURE__ */ jsx19("span", {
3106
3648
  className: "truncate",
3107
3649
  children: assigneeName
3108
3650
  })
3109
3651
  })
3110
3652
  ]
3111
3653
  }),
3112
- task.subtasks.length > 0 && /* @__PURE__ */ jsxs15("section", {
3654
+ task.subtasks.length > 0 && /* @__PURE__ */ jsxs16("section", {
3113
3655
  className: "flex flex-col gap-2",
3114
3656
  children: [
3115
- /* @__PURE__ */ jsxs15("div", {
3657
+ /* @__PURE__ */ jsxs16("div", {
3116
3658
  className: "flex items-center justify-between",
3117
3659
  children: [
3118
- /* @__PURE__ */ jsx17("h3", {
3660
+ /* @__PURE__ */ jsx19("h3", {
3119
3661
  className: "text-title-small text-on-surface",
3120
3662
  children: "Subtasks"
3121
3663
  }),
3122
- /* @__PURE__ */ jsxs15("span", {
3664
+ /* @__PURE__ */ jsxs16("span", {
3123
3665
  className: "text-body-small text-on-surface-variant",
3124
3666
  children: [
3125
3667
  completedCount,
@@ -3129,26 +3671,26 @@ function TaskDetail({
3129
3671
  })
3130
3672
  ]
3131
3673
  }),
3132
- /* @__PURE__ */ jsx17("ul", {
3674
+ /* @__PURE__ */ jsx19("ul", {
3133
3675
  className: "m-0 list-none overflow-hidden rounded-medium border border-outline-variant p-0",
3134
- children: task.subtasks.map((subtask, i) => /* @__PURE__ */ jsx17("li", {
3135
- children: /* @__PURE__ */ jsxs15("button", {
3676
+ children: task.subtasks.map((subtask, i) => /* @__PURE__ */ jsx19("li", {
3677
+ children: /* @__PURE__ */ jsxs16("button", {
3136
3678
  type: "button",
3137
3679
  role: "checkbox",
3138
3680
  "aria-checked": subtask.completed,
3139
3681
  onClick: () => onSubtaskToggle?.(task, i, !subtask.completed),
3140
- className: clsx17("flex min-h-12 w-full items-center gap-4 px-4 py-2 text-left text-body-large", "transition-colors duration-200 ease-standard hover:bg-on-surface/8 active:bg-on-surface/10", focusRing, "focus-visible:outline-offset-[-3px]", i > 0 && "border-t border-outline-variant"),
3682
+ className: clsx19("flex min-h-12 w-full items-center gap-4 px-4 py-2 text-left text-body-large", "transition-colors duration-200 ease-standard hover:bg-on-surface/8 active:bg-on-surface/10", focusRing, "focus-visible:outline-offset-[-3px]", i > 0 && "border-t border-outline-variant"),
3141
3683
  children: [
3142
- /* @__PURE__ */ jsx17("span", {
3143
- className: clsx17("flex size-[18px] shrink-0 items-center justify-center rounded-[2px] transition-colors duration-200 ease-standard", subtask.completed ? "bg-primary text-on-primary" : "border-2 border-on-surface-variant"),
3144
- children: subtask.completed && /* @__PURE__ */ jsx17(Icon14, {
3684
+ /* @__PURE__ */ jsx19("span", {
3685
+ className: clsx19("flex size-[18px] shrink-0 items-center justify-center rounded-[2px] transition-colors duration-200 ease-standard", subtask.completed ? "bg-primary text-on-primary" : "border-2 border-on-surface-variant"),
3686
+ children: subtask.completed && /* @__PURE__ */ jsx19(Icon11, {
3145
3687
  name: "check",
3146
3688
  size: 16,
3147
3689
  weight: 700
3148
3690
  })
3149
3691
  }),
3150
- /* @__PURE__ */ jsx17("span", {
3151
- className: clsx17("min-w-0 flex-1", subtask.completed ? "text-on-surface-variant line-through" : "text-on-surface"),
3692
+ /* @__PURE__ */ jsx19("span", {
3693
+ className: clsx19("min-w-0 flex-1", subtask.completed ? "text-on-surface-variant line-through" : "text-on-surface"),
3152
3694
  children: subtask.title
3153
3695
  })
3154
3696
  ]
@@ -3157,38 +3699,38 @@ function TaskDetail({
3157
3699
  })
3158
3700
  ]
3159
3701
  }),
3160
- /* @__PURE__ */ jsxs15("section", {
3702
+ /* @__PURE__ */ jsxs16("section", {
3161
3703
  className: "flex flex-col gap-2",
3162
3704
  children: [
3163
- /* @__PURE__ */ jsx17("h3", {
3705
+ /* @__PURE__ */ jsx19("h3", {
3164
3706
  className: "text-title-small text-on-surface",
3165
3707
  children: "Description"
3166
3708
  }),
3167
- task.description ? /* @__PURE__ */ jsx17(Markdown, {
3709
+ task.description ? /* @__PURE__ */ jsx19(Markdown, {
3168
3710
  content: task.description,
3169
3711
  size: "medium"
3170
- }) : /* @__PURE__ */ jsx17("p", {
3712
+ }) : /* @__PURE__ */ jsx19("p", {
3171
3713
  className: "text-body-medium text-on-surface-variant",
3172
3714
  children: "No description"
3173
3715
  })
3174
3716
  ]
3175
3717
  }),
3176
- /* @__PURE__ */ jsxs15("div", {
3718
+ /* @__PURE__ */ jsxs16("div", {
3177
3719
  className: "flex flex-col gap-1 text-body-small text-on-surface-variant",
3178
3720
  children: [
3179
- /* @__PURE__ */ jsxs15("span", {
3721
+ /* @__PURE__ */ jsxs16("span", {
3180
3722
  children: [
3181
3723
  "Created ",
3182
3724
  formatDate(task.created_at)
3183
3725
  ]
3184
3726
  }),
3185
- /* @__PURE__ */ jsxs15("span", {
3727
+ /* @__PURE__ */ jsxs16("span", {
3186
3728
  children: [
3187
3729
  "Updated ",
3188
3730
  formatDate(task.updated_at)
3189
3731
  ]
3190
3732
  }),
3191
- task.completed_at && /* @__PURE__ */ jsxs15("span", {
3733
+ task.completed_at && /* @__PURE__ */ jsxs16("span", {
3192
3734
  children: [
3193
3735
  "Completed ",
3194
3736
  formatDate(task.completed_at)
@@ -3196,39 +3738,39 @@ function TaskDetail({
3196
3738
  })
3197
3739
  ]
3198
3740
  }),
3199
- (onStatusChange || onDelete) && /* @__PURE__ */ jsxs15("div", {
3741
+ (onStatusChange || onDelete) && /* @__PURE__ */ jsxs16("div", {
3200
3742
  className: "flex flex-wrap items-center gap-2",
3201
3743
  children: [
3202
- onStatusChange && task.status === "pending_approval" && /* @__PURE__ */ jsx17(Button3, {
3744
+ onStatusChange && task.status === "pending_approval" && /* @__PURE__ */ jsx19(Button3, {
3203
3745
  variant: "filled",
3204
3746
  size: "lg",
3205
3747
  onClick: () => onStatusChange(task, "ready"),
3206
3748
  children: "Approve"
3207
3749
  }),
3208
- onStatusChange && task.status === "backlog" && /* @__PURE__ */ jsx17(Button3, {
3750
+ onStatusChange && task.status === "backlog" && /* @__PURE__ */ jsx19(Button3, {
3209
3751
  variant: "filled",
3210
3752
  size: "lg",
3211
3753
  onClick: () => onStatusChange(task, "in_progress"),
3212
3754
  children: "Execute"
3213
3755
  }),
3214
- onStatusChange && (task.status === "in_progress" || task.status === "ready") && /* @__PURE__ */ jsx17(Button3, {
3756
+ onStatusChange && (task.status === "in_progress" || task.status === "ready") && /* @__PURE__ */ jsx19(Button3, {
3215
3757
  variant: "filled",
3216
3758
  size: "lg",
3217
3759
  onClick: () => onStatusChange(task, "done"),
3218
3760
  children: "Mark Done"
3219
3761
  }),
3220
- onStatusChange && task.status === "done" && /* @__PURE__ */ jsx17(Button3, {
3762
+ onStatusChange && task.status === "done" && /* @__PURE__ */ jsx19(Button3, {
3221
3763
  variant: "text",
3222
3764
  size: "lg",
3223
3765
  onClick: () => onStatusChange(task, "ready"),
3224
3766
  children: "Reopen"
3225
3767
  }),
3226
- onDelete && /* @__PURE__ */ jsxs15("button", {
3768
+ onDelete && /* @__PURE__ */ jsxs16("button", {
3227
3769
  type: "button",
3228
3770
  onClick: () => onDelete(task),
3229
- className: clsx17("inline-flex h-10 items-center justify-center gap-2 rounded-full px-3 text-label-large text-error", "transition-colors duration-200 ease-standard hover:bg-error/8 active:bg-error/10", focusRing),
3771
+ className: clsx19("inline-flex h-10 items-center justify-center gap-2 rounded-full px-3 text-label-large text-error", "transition-colors duration-200 ease-standard hover:bg-error/8 active:bg-error/10", focusRing),
3230
3772
  children: [
3231
- /* @__PURE__ */ jsx17(Icon14, {
3773
+ /* @__PURE__ */ jsx19(Icon11, {
3232
3774
  name: "delete",
3233
3775
  size: 18
3234
3776
  }),
@@ -3240,11 +3782,11 @@ function TaskDetail({
3240
3782
  ]
3241
3783
  });
3242
3784
  }
3243
- // packages/m3-ai/src/TaskCreateForm.tsx
3785
+ // m3/packages/m3-ai/src/TaskCreateForm.tsx
3244
3786
  import { Button as Button4, Input, Select as Select2, SelectOption as SelectOption2, TextArea } from "@aphrody/m3-primitives";
3245
- import { clsx as clsx18 } from "clsx";
3787
+ import { clsx as clsx20 } from "clsx";
3246
3788
  import { useCallback, useEffect as useEffect3, useId as useId4, useRef as useRef4, useState as useState9 } from "react";
3247
- import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
3789
+ import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
3248
3790
  var PRIORITIES = ["critical", "high", "medium", "low"];
3249
3791
  function TaskCreateForm({
3250
3792
  onSubmit,
@@ -3271,18 +3813,18 @@ function TaskCreateForm({
3271
3813
  setDescription("");
3272
3814
  setPriority(defaultPriority);
3273
3815
  }, [canSubmit, onSubmit, title, description, priority, defaultPriority]);
3274
- return /* @__PURE__ */ jsxs16("div", {
3275
- className: clsx18("flex flex-col gap-3 rounded-medium bg-surface-container-low p-4 text-on-surface", className),
3816
+ return /* @__PURE__ */ jsxs17("div", {
3817
+ className: clsx20("flex flex-col gap-3 rounded-medium bg-surface-container-low p-4 text-on-surface", className),
3276
3818
  children: [
3277
- /* @__PURE__ */ jsxs16("div", {
3819
+ /* @__PURE__ */ jsxs17("div", {
3278
3820
  className: "flex items-center gap-2",
3279
3821
  children: [
3280
- /* @__PURE__ */ jsx18("label", {
3822
+ /* @__PURE__ */ jsx20("label", {
3281
3823
  htmlFor: titleInputId,
3282
3824
  className: "sr-only",
3283
3825
  children: "Task Title"
3284
3826
  }),
3285
- /* @__PURE__ */ jsx18(Input, {
3827
+ /* @__PURE__ */ jsx20(Input, {
3286
3828
  ref: titleInputRef,
3287
3829
  id: titleInputId,
3288
3830
  type: "text",
@@ -3299,24 +3841,24 @@ function TaskCreateForm({
3299
3841
  className: "min-w-0 flex-1",
3300
3842
  disabled: isSubmitting
3301
3843
  }),
3302
- /* @__PURE__ */ jsx18(Select2, {
3844
+ /* @__PURE__ */ jsx20(Select2, {
3303
3845
  value: priority,
3304
3846
  size: "lg",
3305
3847
  onChange: (value) => setPriority(value),
3306
3848
  disabled: isSubmitting,
3307
- children: PRIORITIES.map((p) => /* @__PURE__ */ jsx18(SelectOption2, {
3849
+ children: PRIORITIES.map((p) => /* @__PURE__ */ jsx20(SelectOption2, {
3308
3850
  value: p,
3309
3851
  children: TASK_PRIORITY_LABEL[p]
3310
3852
  }, p))
3311
3853
  })
3312
3854
  ]
3313
3855
  }),
3314
- /* @__PURE__ */ jsx18("label", {
3856
+ /* @__PURE__ */ jsx20("label", {
3315
3857
  htmlFor: descriptionInputId,
3316
3858
  className: "sr-only",
3317
3859
  children: "Description"
3318
3860
  }),
3319
- /* @__PURE__ */ jsx18(TextArea, {
3861
+ /* @__PURE__ */ jsx20(TextArea, {
3320
3862
  id: descriptionInputId,
3321
3863
  value: description,
3322
3864
  onChange: (e) => setDescription(e.target.value),
@@ -3325,17 +3867,17 @@ function TaskCreateForm({
3325
3867
  className: "w-full resize-none",
3326
3868
  disabled: isSubmitting
3327
3869
  }),
3328
- /* @__PURE__ */ jsxs16("div", {
3870
+ /* @__PURE__ */ jsxs17("div", {
3329
3871
  className: "flex items-center justify-end gap-2",
3330
3872
  children: [
3331
- onCancel && /* @__PURE__ */ jsx18(Button4, {
3873
+ onCancel && /* @__PURE__ */ jsx20(Button4, {
3332
3874
  variant: "text",
3333
3875
  size: "lg",
3334
3876
  onClick: onCancel,
3335
3877
  disabled: isSubmitting,
3336
3878
  children: "Cancel"
3337
3879
  }),
3338
- /* @__PURE__ */ jsx18(Button4, {
3880
+ /* @__PURE__ */ jsx20(Button4, {
3339
3881
  variant: "filled",
3340
3882
  size: "lg",
3341
3883
  disabled: !canSubmit,
@@ -3347,14 +3889,7 @@ function TaskCreateForm({
3347
3889
  ]
3348
3890
  });
3349
3891
  }
3350
-
3351
- // packages/m3-ai/src/index.ts
3352
- import { EventType as EventType2 } from "@aphrody/ag-ui";
3353
-
3354
- // packages/m3-ai/src/AgUiEventStream.ts
3355
- import {
3356
- EventType
3357
- } from "@aphrody/ag-ui";
3892
+ // m3/packages/m3-ai/src/AgUiEventStream.ts
3358
3893
  class AgUiEventAccumulator {
3359
3894
  steps = [];
3360
3895
  activeText = "";
@@ -3368,19 +3903,19 @@ class AgUiEventAccumulator {
3368
3903
  errorMessage;
3369
3904
  push(event) {
3370
3905
  switch (event.type) {
3371
- case EventType.RUN_STARTED: {
3906
+ case exports_ag_ui.EventType.RUN_STARTED: {
3372
3907
  this.isFinished = false;
3373
3908
  this.hasError = false;
3374
3909
  break;
3375
3910
  }
3376
- case EventType.TEXT_MESSAGE_CONTENT: {
3911
+ case exports_ag_ui.EventType.TEXT_MESSAGE_CONTENT: {
3377
3912
  const textEvent = event;
3378
3913
  if (textEvent.delta) {
3379
3914
  this.activeText += textEvent.delta;
3380
3915
  }
3381
3916
  break;
3382
3917
  }
3383
- case EventType.TEXT_MESSAGE_END: {
3918
+ case exports_ag_ui.EventType.TEXT_MESSAGE_END: {
3384
3919
  if (this.activeText.length > 0) {
3385
3920
  this.steps.push({
3386
3921
  type: "action",
@@ -3390,14 +3925,14 @@ class AgUiEventAccumulator {
3390
3925
  }
3391
3926
  break;
3392
3927
  }
3393
- case EventType.REASONING_MESSAGE_CONTENT: {
3928
+ case exports_ag_ui.EventType.REASONING_MESSAGE_CONTENT: {
3394
3929
  const reasoningEvent = event;
3395
3930
  if (reasoningEvent.delta) {
3396
3931
  this.activeReasoning += reasoningEvent.delta;
3397
3932
  }
3398
3933
  break;
3399
3934
  }
3400
- case EventType.TOOL_CALL_START: {
3935
+ case exports_ag_ui.EventType.TOOL_CALL_START: {
3401
3936
  const tcStart = event;
3402
3937
  this.pendingToolCalls.set(tcStart.toolCallId, {
3403
3938
  name: tcStart.toolCallName,
@@ -3406,7 +3941,7 @@ class AgUiEventAccumulator {
3406
3941
  this.toolCallNames.set(tcStart.toolCallId, tcStart.toolCallName);
3407
3942
  break;
3408
3943
  }
3409
- case EventType.TOOL_CALL_ARGS: {
3944
+ case exports_ag_ui.EventType.TOOL_CALL_ARGS: {
3410
3945
  const tcArgs = event;
3411
3946
  const pending = this.pendingToolCalls.get(tcArgs.toolCallId);
3412
3947
  if (pending && tcArgs.delta) {
@@ -3414,7 +3949,7 @@ class AgUiEventAccumulator {
3414
3949
  }
3415
3950
  break;
3416
3951
  }
3417
- case EventType.TOOL_CALL_END: {
3952
+ case exports_ag_ui.EventType.TOOL_CALL_END: {
3418
3953
  const tcEnd = event;
3419
3954
  const pending = this.pendingToolCalls.get(tcEnd.toolCallId);
3420
3955
  if (pending) {
@@ -3433,7 +3968,7 @@ class AgUiEventAccumulator {
3433
3968
  }
3434
3969
  break;
3435
3970
  }
3436
- case EventType.TOOL_CALL_RESULT: {
3971
+ case exports_ag_ui.EventType.TOOL_CALL_RESULT: {
3437
3972
  const tcResult = event;
3438
3973
  const resultContent = typeof tcResult.content === "string" ? tcResult.content : JSON.stringify(tcResult.content);
3439
3974
  this.inspectA2uiOperations(tcResult.content);
@@ -3446,7 +3981,7 @@ class AgUiEventAccumulator {
3446
3981
  });
3447
3982
  break;
3448
3983
  }
3449
- case EventType.SUBAGENT_STARTED: {
3984
+ case exports_ag_ui.EventType.SUBAGENT_STARTED: {
3450
3985
  const subEvent = event;
3451
3986
  this.subagents.set(subEvent.subagentRunId, {
3452
3987
  id: subEvent.subagentRunId,
@@ -3456,7 +3991,7 @@ class AgUiEventAccumulator {
3456
3991
  });
3457
3992
  break;
3458
3993
  }
3459
- case EventType.SUBAGENT_FINISHED: {
3994
+ case exports_ag_ui.EventType.SUBAGENT_FINISHED: {
3460
3995
  const subEvent = event;
3461
3996
  const existing = this.subagents.get(subEvent.subagentRunId);
3462
3997
  if (existing) {
@@ -3464,7 +3999,7 @@ class AgUiEventAccumulator {
3464
3999
  }
3465
4000
  break;
3466
4001
  }
3467
- case EventType.SUBAGENT_ERROR: {
4002
+ case exports_ag_ui.EventType.SUBAGENT_ERROR: {
3468
4003
  const subEvent = event;
3469
4004
  const existing = this.subagents.get(subEvent.subagentRunId);
3470
4005
  if (existing) {
@@ -3473,7 +4008,7 @@ class AgUiEventAccumulator {
3473
4008
  }
3474
4009
  break;
3475
4010
  }
3476
- case EventType.RUN_FINISHED: {
4011
+ case exports_ag_ui.EventType.RUN_FINISHED: {
3477
4012
  if (this.activeText.length > 0) {
3478
4013
  this.steps.push({
3479
4014
  type: "action",
@@ -3484,7 +4019,7 @@ class AgUiEventAccumulator {
3484
4019
  this.isFinished = true;
3485
4020
  break;
3486
4021
  }
3487
- case EventType.RUN_ERROR: {
4022
+ case exports_ag_ui.EventType.RUN_ERROR: {
3488
4023
  const errEvent = event;
3489
4024
  this.hasError = true;
3490
4025
  this.errorMessage = errEvent.message;
@@ -3578,7 +4113,7 @@ function coordEnvelopeToAgUiEvent(envelope) {
3578
4113
  switch (envelope.kind) {
3579
4114
  case "ask":
3580
4115
  return {
3581
- type: EventType.CUSTOM,
4116
+ type: exports_ag_ui.EventType.CUSTOM,
3582
4117
  name: "a2a_ask",
3583
4118
  value: {
3584
4119
  id: envelope.id,
@@ -3592,7 +4127,7 @@ function coordEnvelopeToAgUiEvent(envelope) {
3592
4127
  };
3593
4128
  case "fact":
3594
4129
  return {
3595
- type: EventType.CUSTOM,
4130
+ type: exports_ag_ui.EventType.CUSTOM,
3596
4131
  name: "a2a_fact",
3597
4132
  value: {
3598
4133
  id: envelope.id,
@@ -3605,7 +4140,7 @@ function coordEnvelopeToAgUiEvent(envelope) {
3605
4140
  };
3606
4141
  case "ack":
3607
4142
  return {
3608
- type: EventType.CUSTOM,
4143
+ type: exports_ag_ui.EventType.CUSTOM,
3609
4144
  name: "a2a_ack",
3610
4145
  value: {
3611
4146
  id: envelope.id,
@@ -3617,13 +4152,13 @@ function coordEnvelopeToAgUiEvent(envelope) {
3617
4152
  };
3618
4153
  case "error":
3619
4154
  return {
3620
- type: EventType.RUN_ERROR,
4155
+ type: exports_ag_ui.EventType.RUN_ERROR,
3621
4156
  message: envelope.body || envelope.topic || "Coordination error",
3622
4157
  code: envelope.id
3623
4158
  };
3624
4159
  case "ping":
3625
4160
  return {
3626
- type: EventType.CUSTOM,
4161
+ type: exports_ag_ui.EventType.CUSTOM,
3627
4162
  name: "a2a_ping",
3628
4163
  value: {
3629
4164
  id: envelope.id,
@@ -3633,7 +4168,7 @@ function coordEnvelopeToAgUiEvent(envelope) {
3633
4168
  };
3634
4169
  default:
3635
4170
  return {
3636
- type: EventType.CUSTOM,
4171
+ type: exports_ag_ui.EventType.CUSTOM,
3637
4172
  name: `a2a_${envelope.kind}`,
3638
4173
  value: envelope
3639
4174
  };
@@ -3642,7 +4177,7 @@ function coordEnvelopeToAgUiEvent(envelope) {
3642
4177
  function agUiEventToCoordEnvelope(event, from, to = "fleet") {
3643
4178
  const ts = new Date().toISOString();
3644
4179
  const id = `env-${Date.now().toString(16)}`;
3645
- if (event.type === EventType.CUSTOM && event.name?.startsWith("a2a_")) {
4180
+ if (event.type === exports_ag_ui.EventType.CUSTOM && event.name?.startsWith("a2a_")) {
3646
4181
  const val = event.value || {};
3647
4182
  const kind = event.name.replace(/^a2a_/, "");
3648
4183
  return {
@@ -3658,7 +4193,7 @@ function agUiEventToCoordEnvelope(event, from, to = "fleet") {
3658
4193
  channel_hint: val.channel_hint
3659
4194
  };
3660
4195
  }
3661
- if (event.type === EventType.RUN_ERROR) {
4196
+ if (event.type === exports_ag_ui.EventType.RUN_ERROR) {
3662
4197
  const err = event;
3663
4198
  return {
3664
4199
  v: 1,
@@ -3671,7 +4206,7 @@ function agUiEventToCoordEnvelope(event, from, to = "fleet") {
3671
4206
  body: err.message
3672
4207
  };
3673
4208
  }
3674
- if (event.type === EventType.TOOL_CALL_RESULT) {
4209
+ if (event.type === exports_ag_ui.EventType.TOOL_CALL_RESULT) {
3675
4210
  const res = event;
3676
4211
  return {
3677
4212
  v: 1,
@@ -3696,10 +4231,10 @@ function agUiEventToCoordEnvelope(event, from, to = "fleet") {
3696
4231
  body: JSON.stringify(event)
3697
4232
  };
3698
4233
  }
3699
- // packages/m3-ai/src/A2APeerInspector.tsx
4234
+ // m3/packages/m3-ai/src/A2APeerInspector.tsx
3700
4235
  import { useState as useState10 } from "react";
3701
- import { clsx as clsx19 } from "clsx";
3702
- import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
4236
+ import { clsx as clsx21 } from "clsx";
4237
+ import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
3703
4238
  var EMPTY_ENVELOPES = [];
3704
4239
  var DEFAULT_PEERS = [
3705
4240
  {
@@ -3726,14 +4261,6 @@ var DEFAULT_PEERS = [
3726
4261
  status: "idle",
3727
4262
  version: "3.7.0",
3728
4263
  skills: ["design-tokens", "docs-audit", "review"]
3729
- },
3730
- {
3731
- id: "shenron",
3732
- name: "Shenron Daemon",
3733
- role: "Database & RAG Pipeline Gate",
3734
- status: "idle",
3735
- version: "2.1.0",
3736
- skills: ["rag-index", "manga-publish", "embeddings"]
3737
4264
  }
3738
4265
  ];
3739
4266
  var KIND_COLORS = {
@@ -3796,33 +4323,33 @@ var A2APeerInspector = ({
3796
4323
  setComposeBody("");
3797
4324
  };
3798
4325
  const filteredEnvelopes = envelopes.filter((env) => env.from === selectedPeerId || env.to === selectedPeerId || env.to === "fleet");
3799
- return /* @__PURE__ */ jsxs17("div", {
3800
- className: clsx19("flex flex-col gap-4 rounded-3xl p-5 border", "bg-[var(--md-sys-color-surface-container-lowest,#ffffff)]", "border-[var(--md-sys-color-outline-variant,#cac4d0)]", "text-[var(--md-sys-color-on-surface,#1d1b20)]", className),
4326
+ return /* @__PURE__ */ jsxs18("div", {
4327
+ className: clsx21("flex flex-col gap-4 rounded-3xl p-5 border", "bg-[var(--md-sys-color-surface-container-lowest,#ffffff)]", "border-[var(--md-sys-color-outline-variant,#cac4d0)]", "text-[var(--md-sys-color-on-surface,#1d1b20)]", className),
3801
4328
  children: [
3802
- /* @__PURE__ */ jsxs17("div", {
4329
+ /* @__PURE__ */ jsxs18("div", {
3803
4330
  className: "flex flex-col gap-3",
3804
4331
  children: [
3805
- /* @__PURE__ */ jsxs17("div", {
4332
+ /* @__PURE__ */ jsxs18("div", {
3806
4333
  className: "flex items-center justify-between",
3807
4334
  children: [
3808
- /* @__PURE__ */ jsxs17("div", {
4335
+ /* @__PURE__ */ jsxs18("div", {
3809
4336
  className: "flex items-center gap-2",
3810
4337
  children: [
3811
- /* @__PURE__ */ jsx19("span", {
4338
+ /* @__PURE__ */ jsx21("span", {
3812
4339
  className: "material-symbols-outlined text-xl text-[var(--md-sys-color-primary,#6750a4)]",
3813
4340
  children: "hub"
3814
4341
  }),
3815
- /* @__PURE__ */ jsx19("h2", {
4342
+ /* @__PURE__ */ jsx21("h2", {
3816
4343
  className: "text-base font-semibold tracking-tight",
3817
4344
  children: "A2A Fleet Coordinator"
3818
4345
  }),
3819
- /* @__PURE__ */ jsx19("span", {
4346
+ /* @__PURE__ */ jsx21("span", {
3820
4347
  className: "rounded-full bg-[var(--md-sys-color-surface-container-high,#ece6f0)] px-2 py-0.5 text-xs font-mono text-[var(--md-sys-color-on-surface-variant,#49454f)]",
3821
4348
  children: "v1.0 (JSONL + RPC)"
3822
4349
  })
3823
4350
  ]
3824
4351
  }),
3825
- /* @__PURE__ */ jsxs17("span", {
4352
+ /* @__PURE__ */ jsxs18("span", {
3826
4353
  className: "text-xs text-[var(--md-sys-color-outline,#79747e)]",
3827
4354
  children: [
3828
4355
  peers.length,
@@ -3831,22 +4358,22 @@ var A2APeerInspector = ({
3831
4358
  })
3832
4359
  ]
3833
4360
  }),
3834
- /* @__PURE__ */ jsx19("div", {
4361
+ /* @__PURE__ */ jsx21("div", {
3835
4362
  className: "flex items-center gap-2 overflow-x-auto pb-1",
3836
4363
  children: peers.map((peer) => {
3837
4364
  const isSelected = peer.id === selectedPeerId;
3838
- return /* @__PURE__ */ jsxs17("button", {
4365
+ return /* @__PURE__ */ jsxs18("button", {
3839
4366
  type: "button",
3840
4367
  onClick: () => handleSelect(peer.id),
3841
- className: clsx19("flex items-center gap-2 rounded-full px-3.5 py-1.5 text-xs font-medium transition-colors shrink-0", isSelected ? "bg-[var(--md-sys-color-secondary-container,#e8def8)] text-[var(--md-sys-color-on-secondary-container,#1d192b)] shadow-sm" : "bg-[var(--md-sys-color-surface-container,#f3edf7)] text-[var(--md-sys-color-on-surface-variant,#49454f)] hover:bg-[var(--md-sys-color-surface-container-high,#ece6f0)]"),
4368
+ className: clsx21("flex items-center gap-2 rounded-full px-3.5 py-1.5 text-xs font-medium transition-colors shrink-0", isSelected ? "bg-[var(--md-sys-color-secondary-container,#e8def8)] text-[var(--md-sys-color-on-secondary-container,#1d192b)] shadow-sm" : "bg-[var(--md-sys-color-surface-container,#f3edf7)] text-[var(--md-sys-color-on-surface-variant,#49454f)] hover:bg-[var(--md-sys-color-surface-container-high,#ece6f0)]"),
3842
4369
  children: [
3843
- /* @__PURE__ */ jsx19("span", {
3844
- className: clsx19("h-2 w-2 rounded-full", peer.status === "busy" ? "bg-amber-500 animate-pulse" : peer.status === "idle" ? "bg-emerald-500" : "bg-slate-400")
4370
+ /* @__PURE__ */ jsx21("span", {
4371
+ className: clsx21("h-2 w-2 rounded-full", peer.status === "busy" ? "bg-amber-500 animate-pulse" : peer.status === "idle" ? "bg-emerald-500" : "bg-slate-400")
3845
4372
  }),
3846
- /* @__PURE__ */ jsx19("span", {
4373
+ /* @__PURE__ */ jsx21("span", {
3847
4374
  children: peer.name
3848
4375
  }),
3849
- /* @__PURE__ */ jsxs17("span", {
4376
+ /* @__PURE__ */ jsxs18("span", {
3850
4377
  className: "text-[10px] opacity-60",
3851
4378
  children: [
3852
4379
  "@",
@@ -3859,22 +4386,22 @@ var A2APeerInspector = ({
3859
4386
  })
3860
4387
  ]
3861
4388
  }),
3862
- currentPeer && /* @__PURE__ */ jsxs17("div", {
4389
+ currentPeer && /* @__PURE__ */ jsxs18("div", {
3863
4390
  className: "flex flex-col gap-2 rounded-2xl bg-[var(--md-sys-color-surface-container-low,#f7f2fa)] p-4 border border-[var(--md-sys-color-outline-variant,#cac4d0)]/50",
3864
4391
  children: [
3865
- /* @__PURE__ */ jsxs17("div", {
4392
+ /* @__PURE__ */ jsxs18("div", {
3866
4393
  className: "flex items-start justify-between",
3867
4394
  children: [
3868
- /* @__PURE__ */ jsxs17("div", {
4395
+ /* @__PURE__ */ jsxs18("div", {
3869
4396
  children: [
3870
- /* @__PURE__ */ jsxs17("div", {
4397
+ /* @__PURE__ */ jsxs18("div", {
3871
4398
  className: "flex items-center gap-2",
3872
4399
  children: [
3873
- /* @__PURE__ */ jsx19("span", {
4400
+ /* @__PURE__ */ jsx21("span", {
3874
4401
  className: "font-semibold text-sm",
3875
4402
  children: currentPeer.name
3876
4403
  }),
3877
- /* @__PURE__ */ jsxs17("span", {
4404
+ /* @__PURE__ */ jsxs18("span", {
3878
4405
  className: "text-xs text-[var(--md-sys-color-on-surface-variant,#49454f)]",
3879
4406
  children: [
3880
4407
  "(",
@@ -3884,11 +4411,11 @@ var A2APeerInspector = ({
3884
4411
  })
3885
4412
  ]
3886
4413
  }),
3887
- /* @__PURE__ */ jsxs17("div", {
4414
+ /* @__PURE__ */ jsxs18("div", {
3888
4415
  className: "text-xs text-[var(--md-sys-color-outline,#79747e)] mt-0.5",
3889
4416
  children: [
3890
4417
  "Peer ID: ",
3891
- /* @__PURE__ */ jsx19("code", {
4418
+ /* @__PURE__ */ jsx21("code", {
3892
4419
  className: "font-mono text-xs",
3893
4420
  children: currentPeer.id
3894
4421
  }),
@@ -3899,14 +4426,14 @@ var A2APeerInspector = ({
3899
4426
  })
3900
4427
  ]
3901
4428
  }),
3902
- currentPeer.activeClaim && /* @__PURE__ */ jsxs17("div", {
4429
+ currentPeer.activeClaim && /* @__PURE__ */ jsxs18("div", {
3903
4430
  className: "flex items-center gap-1.5 rounded-lg bg-amber-500/10 px-2 py-1 text-xs text-amber-700 dark:text-amber-400 border border-amber-500/20",
3904
4431
  children: [
3905
- /* @__PURE__ */ jsx19("span", {
4432
+ /* @__PURE__ */ jsx21("span", {
3906
4433
  className: "material-symbols-outlined text-sm",
3907
4434
  children: "lock"
3908
4435
  }),
3909
- /* @__PURE__ */ jsx19("span", {
4436
+ /* @__PURE__ */ jsx21("span", {
3910
4437
  className: "font-mono text-[11px]",
3911
4438
  children: currentPeer.activeClaim
3912
4439
  })
@@ -3914,9 +4441,9 @@ var A2APeerInspector = ({
3914
4441
  })
3915
4442
  ]
3916
4443
  }),
3917
- currentPeer.skills && currentPeer.skills.length > 0 && /* @__PURE__ */ jsx19("div", {
4444
+ currentPeer.skills && currentPeer.skills.length > 0 && /* @__PURE__ */ jsx21("div", {
3918
4445
  className: "flex flex-wrap gap-1.5 mt-1",
3919
- children: currentPeer.skills.map((skill) => /* @__PURE__ */ jsxs17("span", {
4446
+ children: currentPeer.skills.map((skill) => /* @__PURE__ */ jsxs18("span", {
3920
4447
  className: "rounded-md bg-[var(--md-sys-color-surface-container-highest,#e6e0e9)] px-2 py-0.5 text-[11px] font-mono text-[var(--md-sys-color-on-surface-variant,#49454f)]",
3921
4448
  children: [
3922
4449
  "#",
@@ -3926,13 +4453,13 @@ var A2APeerInspector = ({
3926
4453
  })
3927
4454
  ]
3928
4455
  }),
3929
- /* @__PURE__ */ jsxs17("div", {
4456
+ /* @__PURE__ */ jsxs18("div", {
3930
4457
  className: "flex flex-col gap-2",
3931
4458
  children: [
3932
- /* @__PURE__ */ jsxs17("div", {
4459
+ /* @__PURE__ */ jsxs18("div", {
3933
4460
  className: "flex items-center justify-between",
3934
4461
  children: [
3935
- /* @__PURE__ */ jsxs17("h3", {
4462
+ /* @__PURE__ */ jsxs18("h3", {
3936
4463
  className: "text-xs font-semibold uppercase tracking-wider text-[var(--md-sys-color-on-surface-variant,#49454f)]",
3937
4464
  children: [
3938
4465
  "Coordination Envelopes (",
@@ -3940,16 +4467,16 @@ var A2APeerInspector = ({
3940
4467
  ")"
3941
4468
  ]
3942
4469
  }),
3943
- /* @__PURE__ */ jsx19("span", {
4470
+ /* @__PURE__ */ jsx21("span", {
3944
4471
  className: "text-[11px] text-[var(--md-sys-color-outline,#79747e)]",
3945
4472
  children: ".coord/inbox & .coord/outbox"
3946
4473
  })
3947
4474
  ]
3948
4475
  }),
3949
- filteredEnvelopes.length === 0 ? /* @__PURE__ */ jsxs17("div", {
4476
+ filteredEnvelopes.length === 0 ? /* @__PURE__ */ jsxs18("div", {
3950
4477
  className: "flex flex-col items-center justify-center p-6 rounded-2xl bg-[var(--md-sys-color-surface-container-lowest,#ffffff)] border border-dashed border-[var(--md-sys-color-outline-variant,#cac4d0)] text-xs text-[var(--md-sys-color-outline,#79747e)]",
3951
4478
  children: [
3952
- /* @__PURE__ */ jsx19("span", {
4479
+ /* @__PURE__ */ jsx21("span", {
3953
4480
  className: "material-symbols-outlined text-2xl mb-1 opacity-50",
3954
4481
  children: "mark_email_read"
3955
4482
  }),
@@ -3957,31 +4484,31 @@ var A2APeerInspector = ({
3957
4484
  selectedPeerId,
3958
4485
  ". Fleet mailbox is synchronized."
3959
4486
  ]
3960
- }) : /* @__PURE__ */ jsx19("div", {
4487
+ }) : /* @__PURE__ */ jsx21("div", {
3961
4488
  className: "flex flex-col gap-2 max-h-60 overflow-y-auto pr-1",
3962
4489
  children: filteredEnvelopes.map((env) => {
3963
4490
  const kind = env.kind in KIND_COLORS ? env.kind : "ping";
3964
4491
  const style = KIND_COLORS[kind];
3965
- return /* @__PURE__ */ jsxs17("div", {
3966
- className: clsx19("flex flex-col gap-1.5 rounded-xl p-3 border text-xs transition-shadow", "bg-[var(--md-sys-color-surface-container-low,#f7f2fa)]", style.border),
4492
+ return /* @__PURE__ */ jsxs18("div", {
4493
+ className: clsx21("flex flex-col gap-1.5 rounded-xl p-3 border text-xs transition-shadow", "bg-[var(--md-sys-color-surface-container-low,#f7f2fa)]", style.border),
3967
4494
  children: [
3968
- /* @__PURE__ */ jsxs17("div", {
4495
+ /* @__PURE__ */ jsxs18("div", {
3969
4496
  className: "flex items-center justify-between",
3970
4497
  children: [
3971
- /* @__PURE__ */ jsxs17("div", {
4498
+ /* @__PURE__ */ jsxs18("div", {
3972
4499
  className: "flex items-center gap-2",
3973
4500
  children: [
3974
- /* @__PURE__ */ jsx19("span", {
3975
- className: clsx19("rounded-md px-1.5 py-0.5 text-[10px] font-bold uppercase", style.bg, style.text),
4501
+ /* @__PURE__ */ jsx21("span", {
4502
+ className: clsx21("rounded-md px-1.5 py-0.5 text-[10px] font-bold uppercase", style.bg, style.text),
3976
4503
  children: env.kind
3977
4504
  }),
3978
- /* @__PURE__ */ jsx19("span", {
4505
+ /* @__PURE__ */ jsx21("span", {
3979
4506
  className: "font-semibold",
3980
4507
  children: env.topic
3981
4508
  })
3982
4509
  ]
3983
4510
  }),
3984
- /* @__PURE__ */ jsxs17("span", {
4511
+ /* @__PURE__ */ jsxs18("span", {
3985
4512
  className: "text-[10px] font-mono text-[var(--md-sys-color-outline,#79747e)]",
3986
4513
  children: [
3987
4514
  env.from,
@@ -3991,26 +4518,26 @@ var A2APeerInspector = ({
3991
4518
  })
3992
4519
  ]
3993
4520
  }),
3994
- /* @__PURE__ */ jsx19("p", {
4521
+ /* @__PURE__ */ jsx21("p", {
3995
4522
  className: "line-clamp-2 text-xs text-[var(--md-sys-color-on-surface-variant,#49454f)] font-mono whitespace-pre-wrap",
3996
4523
  children: env.body
3997
4524
  }),
3998
- /* @__PURE__ */ jsxs17("div", {
4525
+ /* @__PURE__ */ jsxs18("div", {
3999
4526
  className: "flex items-center justify-between pt-1 border-t border-[var(--md-sys-color-outline-variant,#cac4d0)]/30 text-[10px] text-[var(--md-sys-color-outline,#79747e)] font-mono",
4000
4527
  children: [
4001
- /* @__PURE__ */ jsxs17("span", {
4528
+ /* @__PURE__ */ jsxs18("span", {
4002
4529
  children: [
4003
4530
  "id: ",
4004
4531
  env.id
4005
4532
  ]
4006
4533
  }),
4007
- env.re && /* @__PURE__ */ jsxs17("span", {
4534
+ env.re && /* @__PURE__ */ jsxs18("span", {
4008
4535
  children: [
4009
4536
  "re: ",
4010
4537
  env.re
4011
4538
  ]
4012
4539
  }),
4013
- /* @__PURE__ */ jsx19("span", {
4540
+ /* @__PURE__ */ jsx21("span", {
4014
4541
  children: new Date(env.ts).toLocaleTimeString()
4015
4542
  })
4016
4543
  ]
@@ -4021,41 +4548,41 @@ var A2APeerInspector = ({
4021
4548
  })
4022
4549
  ]
4023
4550
  }),
4024
- /* @__PURE__ */ jsxs17("form", {
4551
+ /* @__PURE__ */ jsxs18("form", {
4025
4552
  onSubmit: handleSend,
4026
4553
  className: "flex flex-col gap-2.5 pt-2 border-t border-[var(--md-sys-color-outline-variant,#cac4d0)]/50",
4027
4554
  children: [
4028
- /* @__PURE__ */ jsxs17("div", {
4555
+ /* @__PURE__ */ jsxs18("div", {
4029
4556
  className: "flex items-center gap-2",
4030
4557
  children: [
4031
- /* @__PURE__ */ jsxs17("select", {
4558
+ /* @__PURE__ */ jsxs18("select", {
4032
4559
  value: composeKind,
4033
4560
  onChange: (e) => setComposeKind(e.target.value),
4034
4561
  className: "rounded-xl border border-[var(--md-sys-color-outline-variant,#cac4d0)] bg-[var(--md-sys-color-surface-container-low,#f7f2fa)] px-2.5 py-1.5 text-xs font-medium text-[var(--md-sys-color-on-surface,#1d1b20)] focus:outline-none focus:ring-1 focus:ring-[var(--md-sys-color-primary,#6750a4)]",
4035
4562
  children: [
4036
- /* @__PURE__ */ jsx19("option", {
4563
+ /* @__PURE__ */ jsx21("option", {
4037
4564
  value: "ask",
4038
4565
  children: "ASK"
4039
4566
  }),
4040
- /* @__PURE__ */ jsx19("option", {
4567
+ /* @__PURE__ */ jsx21("option", {
4041
4568
  value: "fact",
4042
4569
  children: "FACT"
4043
4570
  }),
4044
- /* @__PURE__ */ jsx19("option", {
4571
+ /* @__PURE__ */ jsx21("option", {
4045
4572
  value: "ack",
4046
4573
  children: "ACK"
4047
4574
  }),
4048
- /* @__PURE__ */ jsx19("option", {
4575
+ /* @__PURE__ */ jsx21("option", {
4049
4576
  value: "ping",
4050
4577
  children: "PING"
4051
4578
  }),
4052
- /* @__PURE__ */ jsx19("option", {
4579
+ /* @__PURE__ */ jsx21("option", {
4053
4580
  value: "error",
4054
4581
  children: "ERROR"
4055
4582
  })
4056
4583
  ]
4057
4584
  }),
4058
- /* @__PURE__ */ jsx19("input", {
4585
+ /* @__PURE__ */ jsx21("input", {
4059
4586
  type: "text",
4060
4587
  placeholder: "Topic (e.g. work, claim-check, verification)...",
4061
4588
  value: composeTopic,
@@ -4064,25 +4591,25 @@ var A2APeerInspector = ({
4064
4591
  })
4065
4592
  ]
4066
4593
  }),
4067
- /* @__PURE__ */ jsxs17("div", {
4594
+ /* @__PURE__ */ jsxs18("div", {
4068
4595
  className: "flex items-center gap-2",
4069
4596
  children: [
4070
- /* @__PURE__ */ jsx19("input", {
4597
+ /* @__PURE__ */ jsx21("input", {
4071
4598
  type: "text",
4072
4599
  placeholder: `Message body to @${selectedPeerId}...`,
4073
4600
  value: composeBody,
4074
4601
  onChange: (e) => setComposeBody(e.target.value),
4075
4602
  className: "flex-1 rounded-xl border border-[var(--md-sys-color-outline-variant,#cac4d0)] bg-[var(--md-sys-color-surface-container-low,#f7f2fa)] px-3 py-1.5 text-xs text-[var(--md-sys-color-on-surface,#1d1b20)] placeholder-[var(--md-sys-color-outline,#79747e)] focus:outline-none focus:ring-1 focus:ring-[var(--md-sys-color-primary,#6750a4)]"
4076
4603
  }),
4077
- /* @__PURE__ */ jsxs17("button", {
4604
+ /* @__PURE__ */ jsxs18("button", {
4078
4605
  type: "submit",
4079
4606
  disabled: !composeTopic.trim() || !composeBody.trim(),
4080
- className: clsx19("flex items-center gap-1.5 rounded-xl px-4 py-1.5 text-xs font-semibold transition-all", composeTopic.trim() && composeBody.trim() ? "bg-[var(--md-sys-color-primary,#6750a4)] text-[var(--md-sys-color-on-primary,#ffffff)] hover:opacity-90 shadow-sm" : "bg-[var(--md-sys-color-surface-container-high,#ece6f0)] text-[var(--md-sys-color-outline,#79747e)] cursor-not-allowed"),
4607
+ className: clsx21("flex items-center gap-1.5 rounded-xl px-4 py-1.5 text-xs font-semibold transition-all", composeTopic.trim() && composeBody.trim() ? "bg-[var(--md-sys-color-primary,#6750a4)] text-[var(--md-sys-color-on-primary,#ffffff)] hover:opacity-90 shadow-sm" : "bg-[var(--md-sys-color-surface-container-high,#ece6f0)] text-[var(--md-sys-color-outline,#79747e)] cursor-not-allowed"),
4081
4608
  children: [
4082
- /* @__PURE__ */ jsx19("span", {
4609
+ /* @__PURE__ */ jsx21("span", {
4083
4610
  children: "Dispatch"
4084
4611
  }),
4085
- /* @__PURE__ */ jsx19("span", {
4612
+ /* @__PURE__ */ jsx21("span", {
4086
4613
  className: "material-symbols-outlined text-sm",
4087
4614
  children: "send"
4088
4615
  })
@@ -4095,10 +4622,10 @@ var A2APeerInspector = ({
4095
4622
  ]
4096
4623
  });
4097
4624
  };
4098
- // packages/m3-ai/src/A2ATaskTimeline.tsx
4625
+ // m3/packages/m3-ai/src/A2ATaskTimeline.tsx
4099
4626
  import { useId as useId5, useState as useState11 } from "react";
4100
- import { clsx as clsx20 } from "clsx";
4101
- import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
4627
+ import { clsx as clsx22 } from "clsx";
4628
+ import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
4102
4629
  var DEFAULT_TIMELINE_STEPS = [
4103
4630
  {
4104
4631
  id: "step-agy-lead",
@@ -4130,26 +4657,26 @@ var A2ATaskTimeline = ({
4130
4657
  const toggleExpand = (id) => {
4131
4658
  setExpandedStepId((current) => current === id ? null : id);
4132
4659
  };
4133
- return /* @__PURE__ */ jsxs18("div", {
4134
- className: clsx20("flex flex-col gap-3 rounded-3xl p-5 border", "bg-[var(--md-sys-color-surface-container-lowest,#ffffff)]", "border-[var(--md-sys-color-outline-variant,#cac4d0)]", "text-[var(--md-sys-color-on-surface,#1d1b20)]", className),
4660
+ return /* @__PURE__ */ jsxs19("div", {
4661
+ className: clsx22("flex flex-col gap-3 rounded-3xl p-5 border", "bg-[var(--md-sys-color-surface-container-lowest,#ffffff)]", "border-[var(--md-sys-color-outline-variant,#cac4d0)]", "text-[var(--md-sys-color-on-surface,#1d1b20)]", className),
4135
4662
  children: [
4136
- /* @__PURE__ */ jsxs18("div", {
4663
+ /* @__PURE__ */ jsxs19("div", {
4137
4664
  className: "flex items-center justify-between border-b border-[var(--md-sys-color-outline-variant,#cac4d0)]/40 pb-3",
4138
4665
  children: [
4139
- /* @__PURE__ */ jsxs18("div", {
4666
+ /* @__PURE__ */ jsxs19("div", {
4140
4667
  className: "flex items-center gap-2",
4141
4668
  children: [
4142
- /* @__PURE__ */ jsx20("span", {
4669
+ /* @__PURE__ */ jsx22("span", {
4143
4670
  className: "material-symbols-outlined text-lg text-[var(--md-sys-color-primary,#6750a4)]",
4144
4671
  children: "timeline"
4145
4672
  }),
4146
- /* @__PURE__ */ jsx20("h3", {
4673
+ /* @__PURE__ */ jsx22("h3", {
4147
4674
  className: "text-sm font-semibold tracking-tight",
4148
4675
  children: "A2A Task Delegation Timeline"
4149
4676
  })
4150
4677
  ]
4151
4678
  }),
4152
- /* @__PURE__ */ jsxs18("span", {
4679
+ /* @__PURE__ */ jsxs19("span", {
4153
4680
  className: "text-xs text-[var(--md-sys-color-outline,#79747e)]",
4154
4681
  children: [
4155
4682
  steps.length,
@@ -4158,10 +4685,10 @@ var A2ATaskTimeline = ({
4158
4685
  })
4159
4686
  ]
4160
4687
  }),
4161
- /* @__PURE__ */ jsxs18("div", {
4688
+ /* @__PURE__ */ jsxs19("div", {
4162
4689
  className: "relative flex flex-col gap-4 pl-4 pt-1",
4163
4690
  children: [
4164
- /* @__PURE__ */ jsx20("div", {
4691
+ /* @__PURE__ */ jsx22("div", {
4165
4692
  className: "absolute left-[27px] top-4 bottom-4 w-0.5 bg-[var(--md-sys-color-outline-variant,#cac4d0)]/60"
4166
4693
  }),
4167
4694
  steps.map((step) => {
@@ -4172,20 +4699,20 @@ var A2ATaskTimeline = ({
4172
4699
  const time = Number.isNaN(date.getTime()) ? step.timestamp : date.toLocaleTimeString();
4173
4700
  const statusIcon = step.status === "completed" ? "check_circle" : step.status === "running" ? "sync" : step.status === "error" ? "error" : "radio_button_unchecked";
4174
4701
  const statusColor = step.status === "completed" ? "text-emerald-500" : step.status === "running" ? "text-[var(--md-sys-color-primary,#6750a4)] animate-spin motion-reduce:animate-none" : step.status === "error" ? "text-rose-500" : "text-slate-400";
4175
- return /* @__PURE__ */ jsxs18("div", {
4176
- className: clsx20("relative flex items-start gap-3 transition-all", isCurrent && "font-medium"),
4702
+ return /* @__PURE__ */ jsxs19("div", {
4703
+ className: clsx22("relative flex items-start gap-3 transition-all", isCurrent && "font-medium"),
4177
4704
  children: [
4178
- /* @__PURE__ */ jsx20("div", {
4179
- className: clsx20("relative z-10 flex h-7 w-7 items-center justify-center rounded-full border-2 bg-[var(--md-sys-color-surface-container-lowest,#ffffff)]", step.status === "completed" ? "border-emerald-500" : step.status === "running" ? "border-[var(--md-sys-color-primary,#6750a4)] ring-4 ring-[var(--md-sys-color-primary,#6750a4)]/20" : step.status === "error" ? "border-rose-500" : "border-[var(--md-sys-color-outline-variant,#cac4d0)]"),
4180
- children: /* @__PURE__ */ jsx20("span", {
4181
- className: clsx20("material-symbols-outlined text-sm", statusColor),
4705
+ /* @__PURE__ */ jsx22("div", {
4706
+ className: clsx22("relative z-10 flex h-7 w-7 items-center justify-center rounded-full border-2 bg-[var(--md-sys-color-surface-container-lowest,#ffffff)]", step.status === "completed" ? "border-emerald-500" : step.status === "running" ? "border-[var(--md-sys-color-primary,#6750a4)] ring-4 ring-[var(--md-sys-color-primary,#6750a4)]/20" : step.status === "error" ? "border-rose-500" : "border-[var(--md-sys-color-outline-variant,#cac4d0)]"),
4707
+ children: /* @__PURE__ */ jsx22("span", {
4708
+ className: clsx22("material-symbols-outlined text-sm", statusColor),
4182
4709
  children: statusIcon
4183
4710
  })
4184
4711
  }),
4185
- /* @__PURE__ */ jsxs18("div", {
4186
- className: clsx20("flex-1 cursor-pointer rounded-2xl border p-3 text-xs transition-all", "bg-[var(--md-sys-color-surface-container-low,#f7f2fa)] hover:bg-[var(--md-sys-color-surface-container,#f3edf7)]", isCurrent ? "border-[var(--md-sys-color-primary,#6750a4)] shadow-sm" : "border-[var(--md-sys-color-outline-variant,#cac4d0)]/60"),
4712
+ /* @__PURE__ */ jsxs19("div", {
4713
+ className: clsx22("flex-1 cursor-pointer rounded-2xl border p-3 text-xs transition-all", "bg-[var(--md-sys-color-surface-container-low,#f7f2fa)] hover:bg-[var(--md-sys-color-surface-container,#f3edf7)]", isCurrent ? "border-[var(--md-sys-color-primary,#6750a4)] shadow-sm" : "border-[var(--md-sys-color-outline-variant,#cac4d0)]/60"),
4187
4714
  children: [
4188
- /* @__PURE__ */ jsxs18("button", {
4715
+ /* @__PURE__ */ jsxs19("button", {
4189
4716
  type: "button",
4190
4717
  "aria-expanded": step.envelope ? isExpanded : undefined,
4191
4718
  "aria-controls": step.envelope ? detailsId : undefined,
@@ -4195,17 +4722,17 @@ var A2ATaskTimeline = ({
4195
4722
  },
4196
4723
  className: "block w-full rounded-medium text-left outline-none focus-visible:ring-2 focus-visible:ring-primary",
4197
4724
  children: [
4198
- /* @__PURE__ */ jsxs18("span", {
4725
+ /* @__PURE__ */ jsxs19("span", {
4199
4726
  className: "flex items-center justify-between gap-2",
4200
4727
  children: [
4201
- /* @__PURE__ */ jsxs18("span", {
4728
+ /* @__PURE__ */ jsxs19("span", {
4202
4729
  className: "flex items-center gap-1.5",
4203
4730
  children: [
4204
- /* @__PURE__ */ jsx20("span", {
4731
+ /* @__PURE__ */ jsx22("span", {
4205
4732
  className: "font-semibold text-xs text-[var(--md-sys-color-on-surface,#1d1b20)]",
4206
4733
  children: step.title
4207
4734
  }),
4208
- /* @__PURE__ */ jsxs18("span", {
4735
+ /* @__PURE__ */ jsxs19("span", {
4209
4736
  className: "rounded-md bg-[var(--md-sys-color-surface-container-highest,#e6e0e9)] px-1.5 py-0.2 text-[10px] font-mono text-[var(--md-sys-color-on-surface-variant,#49454f)]",
4210
4737
  children: [
4211
4738
  "@",
@@ -4216,24 +4743,24 @@ var A2ATaskTimeline = ({
4216
4743
  })
4217
4744
  ]
4218
4745
  }),
4219
- /* @__PURE__ */ jsx20("span", {
4746
+ /* @__PURE__ */ jsx22("span", {
4220
4747
  className: "text-[10px] font-mono text-[var(--md-sys-color-outline,#79747e)]",
4221
4748
  children: time
4222
4749
  })
4223
4750
  ]
4224
4751
  }),
4225
- step.description && /* @__PURE__ */ jsx20("span", {
4752
+ step.description && /* @__PURE__ */ jsx22("span", {
4226
4753
  className: "mt-1 block text-xs text-[var(--md-sys-color-on-surface-variant,#49454f)]",
4227
4754
  children: step.description
4228
4755
  }),
4229
- step.claim && /* @__PURE__ */ jsxs18("span", {
4756
+ step.claim && /* @__PURE__ */ jsxs19("span", {
4230
4757
  className: "mt-2 flex items-center gap-1.5 text-[11px] font-mono text-amber-700 dark:text-amber-400",
4231
4758
  children: [
4232
- /* @__PURE__ */ jsx20("span", {
4759
+ /* @__PURE__ */ jsx22("span", {
4233
4760
  className: "material-symbols-outlined text-xs",
4234
4761
  children: "lock"
4235
4762
  }),
4236
- /* @__PURE__ */ jsxs18("span", {
4763
+ /* @__PURE__ */ jsxs19("span", {
4237
4764
  children: [
4238
4765
  "claim: ",
4239
4766
  step.claim
@@ -4243,25 +4770,25 @@ var A2ATaskTimeline = ({
4243
4770
  })
4244
4771
  ]
4245
4772
  }),
4246
- step.envelope && /* @__PURE__ */ jsxs18("div", {
4773
+ step.envelope && /* @__PURE__ */ jsxs19("div", {
4247
4774
  id: detailsId,
4248
4775
  hidden: !isExpanded,
4249
4776
  className: "mt-2.5 pt-2 border-t border-[var(--md-sys-color-outline-variant,#cac4d0)]/40 font-mono text-[11px] text-[var(--md-sys-color-on-surface-variant,#49454f)]",
4250
4777
  children: [
4251
- /* @__PURE__ */ jsxs18("div", {
4778
+ /* @__PURE__ */ jsxs19("div", {
4252
4779
  className: "flex items-center gap-2 mb-1",
4253
4780
  children: [
4254
- /* @__PURE__ */ jsxs18("span", {
4781
+ /* @__PURE__ */ jsxs19("span", {
4255
4782
  className: "font-semibold",
4256
4783
  children: [
4257
4784
  "Kind: ",
4258
4785
  step.envelope.kind
4259
4786
  ]
4260
4787
  }),
4261
- /* @__PURE__ */ jsx20("span", {
4788
+ /* @__PURE__ */ jsx22("span", {
4262
4789
  children: "·"
4263
4790
  }),
4264
- /* @__PURE__ */ jsxs18("span", {
4791
+ /* @__PURE__ */ jsxs19("span", {
4265
4792
  children: [
4266
4793
  "Topic: ",
4267
4794
  step.envelope.topic
@@ -4269,7 +4796,7 @@ var A2ATaskTimeline = ({
4269
4796
  })
4270
4797
  ]
4271
4798
  }),
4272
- step.envelope.body && /* @__PURE__ */ jsx20("pre", {
4799
+ step.envelope.body && /* @__PURE__ */ jsx22("pre", {
4273
4800
  className: "rounded-lg bg-[var(--md-sys-color-surface-container-highest,#e6e0e9)]/50 p-2 overflow-x-auto whitespace-pre-wrap",
4274
4801
  children: step.envelope.body
4275
4802
  })
@@ -4285,15 +4812,761 @@ var A2ATaskTimeline = ({
4285
4812
  ]
4286
4813
  });
4287
4814
  };
4815
+ // m3/packages/m3-ai/src/openaiChatStream.ts
4816
+ class ChatStreamError extends Error {
4817
+ kind;
4818
+ status;
4819
+ unavailable;
4820
+ constructor(kind, message, options = {}) {
4821
+ super(message, options.cause === undefined ? undefined : { cause: options.cause });
4822
+ this.name = "ChatStreamError";
4823
+ this.kind = kind;
4824
+ this.status = options.status;
4825
+ this.unavailable = kind === "network" || isUnavailableStatus(options.status);
4826
+ }
4827
+ }
4828
+ function isUnavailableStatus(status) {
4829
+ return status === 404 || status === 502 || status === 503 || status === 504;
4830
+ }
4831
+ function createSseParser(onData) {
4832
+ let buffer = "";
4833
+ let data = [];
4834
+ const dispatch = () => {
4835
+ if (data.length > 0)
4836
+ onData(data.join(`
4837
+ `));
4838
+ data = [];
4839
+ };
4840
+ const line = (raw) => {
4841
+ const text = raw.endsWith("\r") ? raw.slice(0, -1) : raw;
4842
+ if (text === "")
4843
+ return dispatch();
4844
+ if (text.startsWith(":"))
4845
+ return;
4846
+ const colon = text.indexOf(":");
4847
+ const field = colon === -1 ? text : text.slice(0, colon);
4848
+ let value = colon === -1 ? "" : text.slice(colon + 1);
4849
+ if (value.startsWith(" "))
4850
+ value = value.slice(1);
4851
+ if (field === "data")
4852
+ data.push(value);
4853
+ };
4854
+ return {
4855
+ push(chunk) {
4856
+ buffer += chunk;
4857
+ let newline = buffer.indexOf(`
4858
+ `);
4859
+ while (newline !== -1) {
4860
+ line(buffer.slice(0, newline));
4861
+ buffer = buffer.slice(newline + 1);
4862
+ newline = buffer.indexOf(`
4863
+ `);
4864
+ }
4865
+ },
4866
+ flush() {
4867
+ if (buffer.length > 0)
4868
+ line(buffer);
4869
+ buffer = "";
4870
+ dispatch();
4871
+ }
4872
+ };
4873
+ }
4874
+ function parseChatCompletionChunk(payload) {
4875
+ const trimmed = payload.trim();
4876
+ if (trimmed === "")
4877
+ return [];
4878
+ if (trimmed === "[DONE]")
4879
+ return [{ type: "done" }];
4880
+ let chunk;
4881
+ try {
4882
+ chunk = JSON.parse(trimmed);
4883
+ } catch (cause) {
4884
+ throw new ChatStreamError("parse", "invalid chat-completions chunk", { cause });
4885
+ }
4886
+ if (chunk.error) {
4887
+ const message = typeof chunk.error === "string" ? chunk.error : chunk.error.message;
4888
+ throw new ChatStreamError("stream", message || "stream error");
4889
+ }
4890
+ const events = [];
4891
+ for (const choice of chunk.choices ?? []) {
4892
+ const delta = choice.delta;
4893
+ if (delta?.reasoning_content)
4894
+ events.push({ type: "reasoning", text: delta.reasoning_content });
4895
+ if (delta?.content)
4896
+ events.push({ type: "content", text: delta.content });
4897
+ if (delta?.refusal)
4898
+ events.push({ type: "refusal", text: delta.refusal });
4899
+ for (const call of delta?.tool_calls ?? []) {
4900
+ events.push({
4901
+ type: "tool_call_delta",
4902
+ index: call.index ?? 0,
4903
+ id: call.id,
4904
+ name: call.function?.name,
4905
+ arguments: call.function?.arguments
4906
+ });
4907
+ }
4908
+ if (choice.finish_reason)
4909
+ events.push({ type: "finish", reason: choice.finish_reason });
4910
+ }
4911
+ if (Array.isArray(chunk.citations))
4912
+ events.push({ type: "citations", citations: chunk.citations });
4913
+ if (chunk.refusal === true)
4914
+ events.push({ type: "refusal" });
4915
+ return events;
4916
+ }
4917
+ function accumulateToolCall(calls, delta) {
4918
+ const next = calls.slice();
4919
+ const current = next[delta.index] ?? {
4920
+ id: "",
4921
+ type: "function",
4922
+ function: { name: "", arguments: "" }
4923
+ };
4924
+ next[delta.index] = {
4925
+ id: delta.id ?? current.id,
4926
+ type: "function",
4927
+ function: {
4928
+ name: current.function.name + (delta.name ?? ""),
4929
+ arguments: current.function.arguments + (delta.arguments ?? "")
4930
+ }
4931
+ };
4932
+ return next;
4933
+ }
4934
+ function toOpenAIMessages(messages) {
4935
+ return messages.map((message) => {
4936
+ const wire = { role: message.role, content: message.content };
4937
+ if (message.toolCalls?.length)
4938
+ wire.tool_calls = message.toolCalls;
4939
+ if (message.toolCallId)
4940
+ wire.tool_call_id = message.toolCallId;
4941
+ return wire;
4942
+ });
4943
+ }
4944
+ function chatCompletionsUrl(baseUrl) {
4945
+ return `${baseUrl.replace(/\/+$/, "")}/chat/completions`;
4946
+ }
4947
+ async function* streamChatCompletion(options) {
4948
+ const doFetch = options.fetch ?? globalThis.fetch;
4949
+ let response;
4950
+ try {
4951
+ response = await doFetch(chatCompletionsUrl(options.baseUrl), {
4952
+ method: "POST",
4953
+ headers: {
4954
+ "content-type": "application/json",
4955
+ accept: "text/event-stream",
4956
+ ...options.headers
4957
+ },
4958
+ body: JSON.stringify({
4959
+ ...options.body,
4960
+ ...options.model ? { model: options.model } : {},
4961
+ messages: toOpenAIMessages(options.messages),
4962
+ stream: true
4963
+ }),
4964
+ signal: options.signal
4965
+ });
4966
+ } catch (cause) {
4967
+ if (options.signal?.aborted)
4968
+ throw new ChatStreamError("aborted", "request aborted", { cause });
4969
+ throw new ChatStreamError("network", "chat endpoint unreachable", { cause });
4970
+ }
4971
+ if (!response.ok) {
4972
+ let detail = "";
4973
+ try {
4974
+ detail = (await response.text()).slice(0, 500);
4975
+ } catch {}
4976
+ throw new ChatStreamError("http", detail || `HTTP ${response.status}`, {
4977
+ status: response.status
4978
+ });
4979
+ }
4980
+ if (!response.body)
4981
+ throw new ChatStreamError("stream", "response has no body");
4982
+ const queue = [];
4983
+ const parser = createSseParser((data) => queue.push(data));
4984
+ const reader = response.body.getReader();
4985
+ const decoder = new TextDecoder;
4986
+ try {
4987
+ for (;; ) {
4988
+ let result;
4989
+ try {
4990
+ result = await reader.read();
4991
+ } catch (cause) {
4992
+ if (options.signal?.aborted)
4993
+ throw new ChatStreamError("aborted", "request aborted", { cause });
4994
+ throw new ChatStreamError("stream", "stream interrupted", { cause });
4995
+ }
4996
+ if (result.done) {
4997
+ parser.push(decoder.decode());
4998
+ parser.flush();
4999
+ } else {
5000
+ parser.push(decoder.decode(result.value, { stream: true }));
5001
+ }
5002
+ while (queue.length > 0) {
5003
+ for (const event of parseChatCompletionChunk(queue.shift())) {
5004
+ yield event;
5005
+ if (event.type === "done")
5006
+ return;
5007
+ }
5008
+ }
5009
+ if (result.done)
5010
+ return;
5011
+ }
5012
+ } finally {
5013
+ reader.releaseLock();
5014
+ }
5015
+ }
5016
+ function initialChatState(messages = []) {
5017
+ return { messages, status: "idle", error: null };
5018
+ }
5019
+ function applyEvent(message, event) {
5020
+ switch (event.type) {
5021
+ case "content":
5022
+ return { ...message, content: message.content + event.text };
5023
+ case "reasoning":
5024
+ return { ...message, reasoning: (message.reasoning ?? "") + event.text };
5025
+ case "tool_call_delta":
5026
+ return { ...message, toolCalls: accumulateToolCall(message.toolCalls ?? [], event) };
5027
+ case "citations":
5028
+ return { ...message, citations: event.citations };
5029
+ case "refusal":
5030
+ return { ...message, refusal: true };
5031
+ case "finish":
5032
+ return { ...message, finishReason: event.reason };
5033
+ case "done":
5034
+ return message;
5035
+ }
5036
+ }
5037
+ function chatReducer(state, action) {
5038
+ switch (action.type) {
5039
+ case "start":
5040
+ return {
5041
+ status: "streaming",
5042
+ error: null,
5043
+ messages: [
5044
+ ...state.messages,
5045
+ action.user,
5046
+ { id: action.assistantId, role: "assistant", content: "" }
5047
+ ]
5048
+ };
5049
+ case "event":
5050
+ return {
5051
+ ...state,
5052
+ messages: state.messages.map((message) => message.id === action.assistantId ? applyEvent(message, action.event) : message)
5053
+ };
5054
+ case "finish":
5055
+ case "stop":
5056
+ return { ...state, status: "idle" };
5057
+ case "fail": {
5058
+ const last = state.messages.at(-1);
5059
+ const messages = last && last.role === "assistant" && !last.content && !last.toolCalls?.length ? state.messages.slice(0, -1) : state.messages;
5060
+ return {
5061
+ messages,
5062
+ status: action.error.unavailable ? "unavailable" : "error",
5063
+ error: action.error
5064
+ };
5065
+ }
5066
+ case "reset":
5067
+ return initialChatState(action.messages ?? []);
5068
+ case "set":
5069
+ return { ...state, messages: action.messages };
5070
+ }
5071
+ }
5072
+ var counter = 0;
5073
+ function newMessageId() {
5074
+ const uuid = globalThis.crypto?.randomUUID?.();
5075
+ if (uuid)
5076
+ return uuid;
5077
+ counter += 1;
5078
+ return `msg-${Date.now().toString(36)}-${counter}`;
5079
+ }
5080
+ // m3/packages/m3-ai/src/useOpenAIChat.ts
5081
+ import { useCallback as useCallback2, useEffect as useEffect4, useReducer, useRef as useRef5 } from "react";
5082
+ "use client";
5083
+ function useOpenAIChat(options) {
5084
+ const [state, dispatch] = useReducer(chatReducer, options.initialMessages, initialChatState);
5085
+ const controller = useRef5(null);
5086
+ const latest = useRef5({ options, state });
5087
+ useEffect4(() => {
5088
+ latest.current = { options, state };
5089
+ });
5090
+ useEffect4(() => () => controller.current?.abort(), []);
5091
+ const send = useCallback2(async (content) => {
5092
+ const { options: o, state: s } = latest.current;
5093
+ if (s.status === "streaming" || controller.current || !content.trim())
5094
+ return;
5095
+ const user = { id: newMessageId(), role: "user", content };
5096
+ const assistantId = newMessageId();
5097
+ const abort = new AbortController;
5098
+ controller.current = abort;
5099
+ dispatch({ type: "start", user, assistantId });
5100
+ let assistant = { id: assistantId, role: "assistant", content: "" };
5101
+ try {
5102
+ for await (const event of streamChatCompletion({
5103
+ baseUrl: o.baseUrl,
5104
+ model: o.model,
5105
+ messages: [...o.preamble ?? [], ...s.messages, user],
5106
+ body: o.body,
5107
+ headers: o.headers,
5108
+ fetch: o.fetch,
5109
+ signal: abort.signal
5110
+ })) {
5111
+ dispatch({ type: "event", assistantId, event });
5112
+ assistant = chatReducer({ messages: [assistant], status: "streaming", error: null }, { type: "event", assistantId, event }).messages[0];
5113
+ }
5114
+ dispatch({ type: "finish" });
5115
+ o.onFinish?.(assistant);
5116
+ } catch (cause) {
5117
+ const error = cause instanceof ChatStreamError ? cause : new ChatStreamError("stream", String(cause), { cause });
5118
+ if (error.kind === "aborted" || abort.signal.aborted) {
5119
+ dispatch({ type: "stop" });
5120
+ } else {
5121
+ dispatch({ type: "fail", error });
5122
+ o.onError?.(error);
5123
+ }
5124
+ } finally {
5125
+ if (controller.current === abort)
5126
+ controller.current = null;
5127
+ }
5128
+ }, []);
5129
+ const stop = useCallback2(() => {
5130
+ controller.current?.abort();
5131
+ controller.current = null;
5132
+ dispatch({ type: "stop" });
5133
+ }, []);
5134
+ const reset = useCallback2((messages) => {
5135
+ controller.current?.abort();
5136
+ controller.current = null;
5137
+ dispatch({ type: "reset", messages });
5138
+ }, []);
5139
+ const setMessages = useCallback2((messages) => {
5140
+ dispatch({ type: "set", messages });
5141
+ }, []);
5142
+ return {
5143
+ messages: state.messages,
5144
+ status: state.status,
5145
+ error: state.error,
5146
+ send,
5147
+ stop,
5148
+ reset,
5149
+ setMessages
5150
+ };
5151
+ }
5152
+ // m3/packages/m3-ai/src/ConversationList.tsx
5153
+ import { CircleButton as CircleButton5 } from "@aphrody/m3-primitives";
5154
+ import { clsx as clsx23 } from "clsx";
5155
+ import { useMemo as useMemo6, useState as useState12 } from "react";
5156
+ import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
5157
+ "use client";
5158
+ function toDate(value) {
5159
+ return value instanceof Date ? value : new Date(value);
5160
+ }
5161
+ function isoDate(value) {
5162
+ const date = toDate(value);
5163
+ return Number.isNaN(date.getTime()) ? undefined : date.toISOString();
5164
+ }
5165
+ function filterConversations(conversations, query) {
5166
+ const needle = query.trim().toLocaleLowerCase();
5167
+ if (!needle)
5168
+ return [...conversations];
5169
+ return conversations.filter((conversation) => `${conversation.title}
5170
+ ${conversation.preview ?? ""}`.toLocaleLowerCase().includes(needle));
5171
+ }
5172
+ function ConversationList({
5173
+ conversations,
5174
+ selectedId,
5175
+ onSelect,
5176
+ onNew,
5177
+ onRename,
5178
+ onDelete,
5179
+ searchable = false,
5180
+ loading = false,
5181
+ labels,
5182
+ locale,
5183
+ formatDate,
5184
+ className
5185
+ }) {
5186
+ const l = resolveChatLabels(labels);
5187
+ const [query, setQuery] = useState12("");
5188
+ const visible = useMemo6(() => filterConversations(conversations, query), [conversations, query]);
5189
+ const dateFormat = useMemo6(() => new Intl.DateTimeFormat(locale, { dateStyle: "short" }), [locale]);
5190
+ const format = (value) => {
5191
+ const date = toDate(value);
5192
+ if (Number.isNaN(date.getTime()))
5193
+ return "";
5194
+ return formatDate ? formatDate(date) : dateFormat.format(date);
5195
+ };
5196
+ return /* @__PURE__ */ jsxs20("nav", {
5197
+ "aria-label": l.conversations,
5198
+ className: clsx23("m3-conversation-list flex h-full min-h-0 flex-col gap-2 bg-surface-container-low px-3 py-3 text-on-surface", className),
5199
+ children: [
5200
+ /* @__PURE__ */ jsx23("div", {
5201
+ className: "flex items-center justify-between gap-2 px-1",
5202
+ children: /* @__PURE__ */ jsx23("h2", {
5203
+ className: "m-0 text-title-small text-on-surface-variant",
5204
+ children: l.conversations
5205
+ })
5206
+ }),
5207
+ onNew ? /* @__PURE__ */ jsxs20("button", {
5208
+ type: "button",
5209
+ onClick: onNew,
5210
+ className: clsx23("flex h-14 items-center gap-3 rounded-large bg-primary-container px-4 text-label-large text-on-primary-container", "transition-colors duration-200 ease-standard hover:bg-primary-container/92", focusRing),
5211
+ children: [
5212
+ /* @__PURE__ */ jsx23(ChatIcon, {
5213
+ name: "edit_square",
5214
+ size: 24
5215
+ }),
5216
+ /* @__PURE__ */ jsx23("span", {
5217
+ children: l.newConversation
5218
+ })
5219
+ ]
5220
+ }) : null,
5221
+ searchable ? /* @__PURE__ */ jsxs20("label", {
5222
+ className: "flex h-12 items-center gap-3 rounded-extra-large bg-surface-container-high px-4 focus-within:bg-surface-container-highest",
5223
+ children: [
5224
+ /* @__PURE__ */ jsx23(ChatIcon, {
5225
+ name: "search",
5226
+ size: 20,
5227
+ className: "text-on-surface-variant"
5228
+ }),
5229
+ /* @__PURE__ */ jsx23("input", {
5230
+ type: "search",
5231
+ value: query,
5232
+ onChange: (event) => setQuery(event.target.value),
5233
+ placeholder: l.searchConversations,
5234
+ "aria-label": l.searchConversations,
5235
+ className: "min-w-0 flex-1 border-0 bg-transparent text-body-large text-on-surface caret-primary outline-none placeholder:text-on-surface-variant"
5236
+ })
5237
+ ]
5238
+ }) : null,
5239
+ loading ? /* @__PURE__ */ jsx23("div", {
5240
+ className: "flex justify-center py-6",
5241
+ children: /* @__PURE__ */ jsx23(CircularIndicator, {
5242
+ size: 24,
5243
+ label: l.loading
5244
+ })
5245
+ }) : visible.length === 0 ? /* @__PURE__ */ jsx23("p", {
5246
+ className: "m-0 px-4 py-6 text-center text-body-medium text-on-surface-variant",
5247
+ children: query.trim() ? l.noSearchResults : l.noConversations
5248
+ }) : /* @__PURE__ */ jsx23("ul", {
5249
+ className: "m-0 flex min-h-0 flex-1 list-none flex-col gap-0.5 overflow-y-auto p-0",
5250
+ children: visible.map((conversation) => {
5251
+ const active = conversation.id === selectedId;
5252
+ const title = conversation.title.trim() || l.untitledConversation;
5253
+ return /* @__PURE__ */ jsxs20("li", {
5254
+ className: "group relative",
5255
+ children: [
5256
+ /* @__PURE__ */ jsxs20("button", {
5257
+ type: "button",
5258
+ onClick: () => onSelect(conversation.id),
5259
+ "aria-current": active ? "page" : undefined,
5260
+ className: clsx23("flex min-h-14 w-full flex-col justify-center rounded-extra-large px-4 py-2 text-left", "transition-colors duration-200 ease-standard", active ? "bg-secondary-container text-on-secondary-container" : "text-on-surface-variant hover:bg-on-surface/8", (onRename || onDelete) && "pr-24", focusRing, "focus-visible:outline-offset-[-3px]"),
5261
+ children: [
5262
+ /* @__PURE__ */ jsxs20("span", {
5263
+ className: "flex w-full items-baseline gap-2",
5264
+ children: [
5265
+ /* @__PURE__ */ jsx23("span", {
5266
+ className: "min-w-0 flex-1 truncate text-label-large",
5267
+ children: title
5268
+ }),
5269
+ /* @__PURE__ */ jsx23("time", {
5270
+ className: "shrink-0 text-label-small opacity-80",
5271
+ dateTime: isoDate(conversation.updatedAt),
5272
+ children: format(conversation.updatedAt)
5273
+ })
5274
+ ]
5275
+ }),
5276
+ conversation.preview ? /* @__PURE__ */ jsx23("span", {
5277
+ className: "mt-0.5 w-full truncate text-body-small opacity-80",
5278
+ children: conversation.preview
5279
+ }) : null
5280
+ ]
5281
+ }),
5282
+ onRename || onDelete ? /* @__PURE__ */ jsxs20("span", {
5283
+ className: "absolute top-1/2 right-2 flex -translate-y-1/2 gap-0.5 opacity-0 transition-opacity duration-200 ease-standard group-focus-within:opacity-100 group-hover:opacity-100",
5284
+ children: [
5285
+ onRename ? /* @__PURE__ */ jsx23(CircleButton5, {
5286
+ icon: /* @__PURE__ */ jsx23(ChatIcon, {
5287
+ name: "edit",
5288
+ size: 18
5289
+ }),
5290
+ variant: "standard",
5291
+ size: "sm",
5292
+ onClick: () => onRename(conversation.id),
5293
+ "aria-label": `${l.renameConversation}: ${title}`,
5294
+ title: l.renameConversation
5295
+ }) : null,
5296
+ onDelete ? /* @__PURE__ */ jsx23(CircleButton5, {
5297
+ icon: /* @__PURE__ */ jsx23(ChatIcon, {
5298
+ name: "delete",
5299
+ size: 18
5300
+ }),
5301
+ variant: "standard",
5302
+ size: "sm",
5303
+ onClick: () => onDelete(conversation.id),
5304
+ "aria-label": `${l.deleteConversation}: ${title}`,
5305
+ title: l.deleteConversation
5306
+ }) : null
5307
+ ]
5308
+ }) : null
5309
+ ]
5310
+ }, conversation.id);
5311
+ })
5312
+ })
5313
+ ]
5314
+ });
5315
+ }
5316
+ // m3/packages/m3-ai/src/ModelUnavailable.tsx
5317
+ import { clsx as clsx24 } from "clsx";
5318
+ import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
5319
+ "use client";
5320
+ function clampProgress(progress) {
5321
+ if (progress === null || progress === undefined || !Number.isFinite(progress))
5322
+ return null;
5323
+ return Math.min(1, Math.max(0, progress));
5324
+ }
5325
+ function ModelUnavailable({
5326
+ phase = "unavailable",
5327
+ reason,
5328
+ progress,
5329
+ onRetry,
5330
+ labels,
5331
+ className
5332
+ }) {
5333
+ const l = resolveChatLabels(labels);
5334
+ const value = clampProgress(progress);
5335
+ const busy = phase !== "unavailable";
5336
+ const title = phase === "downloading" ? l.modelDownloading : phase === "loading" ? l.modelLoading : l.modelUnavailable;
5337
+ const percent = value === null ? null : Math.round(value * 100);
5338
+ return /* @__PURE__ */ jsxs21("div", {
5339
+ role: "status",
5340
+ "aria-live": "polite",
5341
+ "aria-busy": busy || undefined,
5342
+ className: clsx24("m3-model-unavailable flex flex-col gap-3 rounded-large px-4 py-4", busy ? "bg-surface-container-high text-on-surface" : "bg-error-container text-on-error-container", className),
5343
+ children: [
5344
+ /* @__PURE__ */ jsxs21("div", {
5345
+ className: "flex items-start gap-3",
5346
+ children: [
5347
+ busy ? /* @__PURE__ */ jsx24(CircularIndicator, {
5348
+ size: 24,
5349
+ label: title,
5350
+ className: "mt-0.5"
5351
+ }) : /* @__PURE__ */ jsx24(ChatIcon, {
5352
+ name: "cloud_off",
5353
+ size: 24,
5354
+ className: "mt-0.5"
5355
+ }),
5356
+ /* @__PURE__ */ jsxs21("div", {
5357
+ className: "min-w-0 flex-1",
5358
+ children: [
5359
+ /* @__PURE__ */ jsx24("p", {
5360
+ className: "m-0 text-title-medium",
5361
+ children: title
5362
+ }),
5363
+ reason ? /* @__PURE__ */ jsx24("p", {
5364
+ className: "m-0 mt-1 text-body-medium opacity-90",
5365
+ children: reason
5366
+ }) : null
5367
+ ]
5368
+ }),
5369
+ percent !== null ? /* @__PURE__ */ jsx24("span", {
5370
+ className: "shrink-0 text-label-large",
5371
+ children: formatLabel(l.progressPercent, { percent })
5372
+ }) : null
5373
+ ]
5374
+ }),
5375
+ busy && value !== null ? /* @__PURE__ */ jsxs21("div", {
5376
+ role: "progressbar",
5377
+ "aria-label": title,
5378
+ "aria-valuemin": 0,
5379
+ "aria-valuemax": 100,
5380
+ "aria-valuenow": percent ?? undefined,
5381
+ className: "flex h-1 w-full items-center gap-1",
5382
+ children: [
5383
+ /* @__PURE__ */ jsx24("span", {
5384
+ className: "h-1 rounded-full bg-primary transition-[width] duration-300 ease-standard",
5385
+ style: { width: `${(value * 100).toFixed(1)}%` }
5386
+ }),
5387
+ /* @__PURE__ */ jsx24("span", {
5388
+ className: "h-1 flex-1 rounded-full bg-secondary-container"
5389
+ })
5390
+ ]
5391
+ }) : null,
5392
+ onRetry && !busy ? /* @__PURE__ */ jsx24("div", {
5393
+ className: "flex justify-end",
5394
+ children: /* @__PURE__ */ jsxs21("button", {
5395
+ type: "button",
5396
+ onClick: onRetry,
5397
+ className: clsx24("inline-flex h-10 items-center gap-2 rounded-full bg-error px-6 text-label-large text-on-error", "transition-colors duration-200 ease-standard hover:bg-error/92", focusRing),
5398
+ children: [
5399
+ /* @__PURE__ */ jsx24(ChatIcon, {
5400
+ name: "refresh",
5401
+ size: 18
5402
+ }),
5403
+ /* @__PURE__ */ jsx24("span", {
5404
+ children: l.retry
5405
+ })
5406
+ ]
5407
+ })
5408
+ }) : null
5409
+ ]
5410
+ });
5411
+ }
5412
+ // m3/packages/m3-ai/src/MemoryPanel.tsx
5413
+ import { CircleButton as CircleButton6 } from "@aphrody/m3-primitives";
5414
+ import { clsx as clsx25 } from "clsx";
5415
+ import { useMemo as useMemo7, useState as useState13 } from "react";
5416
+ import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
5417
+ "use client";
5418
+ var textButton = clsx25("inline-flex h-10 items-center rounded-full px-3 text-label-large", "transition-colors duration-200 ease-standard", focusRing);
5419
+ function MemoryPanel({
5420
+ memories,
5421
+ loading = false,
5422
+ onDelete,
5423
+ onClear,
5424
+ confirmClear,
5425
+ labels,
5426
+ locale,
5427
+ formatDate,
5428
+ className
5429
+ }) {
5430
+ const l = resolveChatLabels(labels);
5431
+ const [confirming, setConfirming] = useState13(false);
5432
+ const dateFormat = useMemo7(() => new Intl.DateTimeFormat(locale, { dateStyle: "medium" }), [locale]);
5433
+ const format = (value) => {
5434
+ const date = value instanceof Date ? value : new Date(value);
5435
+ if (Number.isNaN(date.getTime()))
5436
+ return "";
5437
+ return formatDate ? formatDate(date) : dateFormat.format(date);
5438
+ };
5439
+ const requestClear = async () => {
5440
+ if (!onClear)
5441
+ return;
5442
+ if (confirmClear) {
5443
+ if (await confirmClear())
5444
+ onClear();
5445
+ return;
5446
+ }
5447
+ setConfirming(true);
5448
+ };
5449
+ return /* @__PURE__ */ jsxs22("section", {
5450
+ "aria-label": l.memory,
5451
+ "aria-busy": loading || undefined,
5452
+ className: clsx25("m3-memory-panel flex min-h-0 flex-col gap-2 rounded-large bg-surface-container-low py-3 text-on-surface", className),
5453
+ children: [
5454
+ /* @__PURE__ */ jsxs22("header", {
5455
+ className: "flex items-center justify-between gap-2 px-4",
5456
+ children: [
5457
+ /* @__PURE__ */ jsx25("h2", {
5458
+ className: "m-0 text-title-medium",
5459
+ children: l.memory
5460
+ }),
5461
+ onClear && memories.length > 0 && !confirming ? /* @__PURE__ */ jsx25("button", {
5462
+ type: "button",
5463
+ onClick: () => void requestClear(),
5464
+ className: clsx25(textButton, "text-error hover:bg-error/8"),
5465
+ children: l.clearMemory
5466
+ }) : null
5467
+ ]
5468
+ }),
5469
+ confirming ? /* @__PURE__ */ jsxs22("div", {
5470
+ role: "alertdialog",
5471
+ "aria-label": l.clearMemory,
5472
+ className: "mx-4 flex flex-col gap-2 rounded-medium bg-error-container px-4 py-3 text-on-error-container",
5473
+ children: [
5474
+ /* @__PURE__ */ jsx25("p", {
5475
+ className: "m-0 text-body-medium",
5476
+ children: l.clearMemoryConfirm
5477
+ }),
5478
+ /* @__PURE__ */ jsxs22("div", {
5479
+ className: "flex justify-end gap-2",
5480
+ children: [
5481
+ /* @__PURE__ */ jsx25("button", {
5482
+ type: "button",
5483
+ onClick: () => setConfirming(false),
5484
+ className: clsx25(textButton, "hover:bg-on-error-container/8"),
5485
+ children: l.cancel
5486
+ }),
5487
+ /* @__PURE__ */ jsx25("button", {
5488
+ type: "button",
5489
+ onClick: () => {
5490
+ setConfirming(false);
5491
+ onClear?.();
5492
+ },
5493
+ className: clsx25(textButton, "bg-error px-4 text-on-error hover:bg-error/92"),
5494
+ children: l.confirm
5495
+ })
5496
+ ]
5497
+ })
5498
+ ]
5499
+ }) : null,
5500
+ loading ? /* @__PURE__ */ jsx25("div", {
5501
+ className: "flex justify-center py-6",
5502
+ children: /* @__PURE__ */ jsx25(CircularIndicator, {
5503
+ size: 24,
5504
+ label: l.memoryLoading
5505
+ })
5506
+ }) : memories.length === 0 ? /* @__PURE__ */ jsx25("p", {
5507
+ className: "m-0 px-4 py-6 text-center text-body-medium text-on-surface-variant",
5508
+ children: l.memoryEmpty
5509
+ }) : /* @__PURE__ */ jsx25("ul", {
5510
+ className: "m-0 flex min-h-0 list-none flex-col overflow-y-auto p-0",
5511
+ children: memories.map((memory) => /* @__PURE__ */ jsxs22("li", {
5512
+ className: "group flex items-start gap-3 px-4 py-2 transition-colors duration-200 ease-standard hover:bg-on-surface/8",
5513
+ children: [
5514
+ /* @__PURE__ */ jsxs22("div", {
5515
+ className: "min-w-0 flex-1",
5516
+ children: [
5517
+ /* @__PURE__ */ jsx25("p", {
5518
+ className: "m-0 text-body-medium break-words whitespace-pre-wrap text-on-surface",
5519
+ children: memory.content
5520
+ }),
5521
+ /* @__PURE__ */ jsxs22("div", {
5522
+ className: "mt-1 flex flex-wrap items-center gap-1.5",
5523
+ children: [
5524
+ /* @__PURE__ */ jsx25("time", {
5525
+ className: "text-label-small text-on-surface-variant",
5526
+ children: format(memory.createdAt)
5527
+ }),
5528
+ memory.tags?.map((tag) => /* @__PURE__ */ jsx25("span", {
5529
+ className: "inline-flex h-6 items-center rounded-small border border-outline-variant px-2 text-label-small text-on-surface-variant",
5530
+ children: tag
5531
+ }, tag))
5532
+ ]
5533
+ })
5534
+ ]
5535
+ }),
5536
+ onDelete ? /* @__PURE__ */ jsx25(CircleButton6, {
5537
+ icon: /* @__PURE__ */ jsx25(ChatIcon, {
5538
+ name: "delete",
5539
+ size: 18
5540
+ }),
5541
+ variant: "standard",
5542
+ size: "sm",
5543
+ onClick: () => onDelete(memory.id),
5544
+ "aria-label": l.deleteMemory,
5545
+ title: l.deleteMemory
5546
+ }) : null
5547
+ ]
5548
+ }, memory.id))
5549
+ })
5550
+ ]
5551
+ });
5552
+ }
5553
+ var export_EventType = exports_ag_ui.EventType;
5554
+
4288
5555
  export {
4289
5556
  A2APeerInspector,
4290
5557
  A2ATaskTimeline,
4291
5558
  AgUiEventAccumulator,
4292
5559
  BlockMath,
4293
5560
  ChatComposer,
5561
+ ChatIcon,
5562
+ ChatStreamError,
5563
+ CitationChip,
5564
+ CitationList,
5565
+ CitedMarkdown,
4294
5566
  CodeBlock,
4295
5567
  ComposerMoreUploadsMenu,
4296
- EventType2 as EventType,
5568
+ ConversationList,
5569
+ export_EventType as EventType,
4297
5570
  GeminiAccountMenu,
4298
5571
  GeminiPersonalContextEdit,
4299
5572
  GoogleSpotlightBar,
@@ -4302,9 +5575,12 @@ export {
4302
5575
  InlineWorkerCard,
4303
5576
  Markdown,
4304
5577
  McpAppCard,
5578
+ MemoryPanel,
4305
5579
  MessageBubble,
4306
5580
  ModelOptionList,
4307
5581
  ModelSelector,
5582
+ ModelUnavailable,
5583
+ RefusalNotice,
4308
5584
  TASK_PRIORITY_LABEL,
4309
5585
  TASK_STATUS_LABEL,
4310
5586
  TASK_STATUS_ORDER,
@@ -4315,14 +5591,39 @@ export {
4315
5591
  TaskRow,
4316
5592
  TaskStatusIcon,
4317
5593
  ToolCall,
5594
+ accumulateToolCall,
4318
5595
  agUiEventToCoordEnvelope,
4319
5596
  agUiEventsToTranscriptItems,
4320
5597
  agUiEventsToTranscriptSteps,
5598
+ chatCompletionsUrl,
5599
+ chatIconNames,
5600
+ chatLabelsByLang,
5601
+ chatLabelsEn,
5602
+ chatLabelsFr,
5603
+ chatLabelsJa,
5604
+ chatReducer,
5605
+ citedNumbers,
5606
+ clampProgress,
4321
5607
  coordEnvelopeToAgUiEvent,
5608
+ createSseParser,
5609
+ defaultChatLabels,
5610
+ externalLinkProps,
5611
+ filterConversations,
5612
+ formatLabel,
4322
5613
  groupModelsByProvider,
5614
+ initialChatState,
4323
5615
  isErrorResult,
5616
+ isExternalHref,
5617
+ isUnavailableStatus,
5618
+ linkCitationMarkers,
5619
+ newMessageId,
4324
5620
  pairTranscriptSteps,
4325
- tryParseJson
5621
+ parseChatCompletionChunk,
5622
+ resolveChatLabels,
5623
+ streamChatCompletion,
5624
+ toOpenAIMessages,
5625
+ tryParseJson,
5626
+ useOpenAIChat
4326
5627
  };
4327
5628
 
4328
- //# debugId=92ED95EDB5C4988E64756E2164756E21
5629
+ //# debugId=F6F1D6A7A43F22CE64756E2164756E21