@yieldfabric/terminal 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,10 +1,17 @@
1
1
  "use client";
2
+ /*!
3
+ * Copyright (c) 2026 YieldFabric Technologies Ltd, DIFC, UAE.
4
+ * All rights reserved. Proprietary and confidential.
5
+ * Source review requires written authorization; see package LICENSE.md and NOTICE.md.
6
+ * Runtime use requires a separate express license.
7
+ */
2
8
  'use strict';
3
9
 
4
- var React12 = require('react');
10
+ var React15 = require('react');
5
11
  var lucideReact = require('lucide-react');
6
12
  var jsxRuntime = require('react/jsx-runtime');
7
13
  var ReactMarkdown = require('react-markdown');
14
+ var remarkGfm = require('remark-gfm');
8
15
  var core = require('@dicebear/core');
9
16
  var collection = require('@dicebear/collection');
10
17
  var framerMotion = require('framer-motion');
@@ -16,8 +23,9 @@ var dagre = require('dagre');
16
23
 
17
24
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
18
25
 
19
- var React12__default = /*#__PURE__*/_interopDefault(React12);
26
+ var React15__default = /*#__PURE__*/_interopDefault(React15);
20
27
  var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
28
+ var remarkGfm__default = /*#__PURE__*/_interopDefault(remarkGfm);
21
29
  var dagre__default = /*#__PURE__*/_interopDefault(dagre);
22
30
 
23
31
  // src/core/StandardTerminal.tsx
@@ -76,6 +84,7 @@ var BUILT_IN_COMMANDS = [
76
84
  { id: "files", label: "/files", description: "List uploaded files for this page working group", category: "built-in" },
77
85
  { id: "ask", label: "/ask", description: "Ask the AI assistant for analysis (streaming)", category: "built-in" },
78
86
  { id: "note", label: "/note", description: "Save a free-form note in this workspace. Type @name to link an entity.", category: "built-in" },
87
+ { id: "log", label: "/log", description: "Capture what you did or decided as a work item on this workspace\u2019s board.", category: "built-in" },
79
88
  { id: "personal", label: "/personal", description: "Save a free-form note in your personal notebook (visible only to you, even from a team workspace).", category: "built-in" }
80
89
  ];
81
90
  function getBuiltInCommands() {
@@ -97,23 +106,45 @@ function processStreamLines(buffer, onJsonLine) {
97
106
  for (const line of lines) {
98
107
  const trimmed = line.trim();
99
108
  if (!trimmed) continue;
100
- if (trimmed.startsWith("data: ")) {
101
- const jsonStr = trimmed.substring(6);
109
+ if (trimmed.startsWith("data:")) {
110
+ const jsonStr = trimmed.substring(5).trimStart();
111
+ let parsed2;
102
112
  try {
103
- onJsonLine(JSON.parse(jsonStr));
113
+ parsed2 = JSON.parse(jsonStr);
104
114
  } catch {
115
+ continue;
105
116
  }
117
+ onJsonLine(parsed2);
106
118
  continue;
107
119
  }
108
120
  if (trimmed.startsWith(":")) continue;
121
+ let parsed;
109
122
  try {
110
- onJsonLine(JSON.parse(trimmed));
123
+ parsed = JSON.parse(trimmed);
111
124
  } catch {
125
+ continue;
112
126
  }
127
+ onJsonLine(parsed);
113
128
  }
114
129
  return remainder;
115
130
  }
116
131
 
132
+ // src/utils/streamStall.ts
133
+ var SSE_KEEPALIVE_MS = 15e3;
134
+ var SSE_STALL_MS = SSE_KEEPALIVE_MS * 3;
135
+ async function withStallTimeout(work, ms = SSE_STALL_MS, sleep = (d) => new Promise((wake) => setTimeout(wake, d))) {
136
+ let done = false;
137
+ const settled = work.then((value) => {
138
+ done = true;
139
+ return value;
140
+ });
141
+ const stalled = sleep(ms).then(() => {
142
+ if (!done) throw new Error("the connection went quiet");
143
+ return void 0;
144
+ });
145
+ return Promise.race([settled, stalled]);
146
+ }
147
+
117
148
  // src/utils/streamingHandler.ts
118
149
  async function handleStreamingResponse(url, requestBody, onChunk, onComplete, onError) {
119
150
  try {
@@ -155,6 +186,14 @@ async function handleStreamingResponse(url, requestBody, onChunk, onComplete, on
155
186
  var handleSSEStream = async (url, body, onChunk, onComplete, onError, options) => {
156
187
  const signal = options?.signal;
157
188
  const method = options?.method || "POST";
189
+ const stallMs = options?.stallMs ?? SSE_STALL_MS;
190
+ const stallAbort = new AbortController();
191
+ const abortFromCaller = () => stallAbort.abort();
192
+ let reader;
193
+ if (signal) {
194
+ if (signal.aborted) stallAbort.abort();
195
+ else signal.addEventListener("abort", abortFromCaller, { once: true });
196
+ }
158
197
  try {
159
198
  const requestHeaders = {
160
199
  Accept: "text/event-stream",
@@ -162,12 +201,12 @@ var handleSSEStream = async (url, body, onChunk, onComplete, onError, options) =
162
201
  ...method !== "GET" && method !== "HEAD" ? { "Content-Type": "application/json" } : {},
163
202
  ...options?.headers
164
203
  };
165
- const response = await fetch(url, {
204
+ const response = await (options?.fetcher ?? fetch)(url, {
166
205
  method,
167
206
  headers: requestHeaders,
168
207
  body: method === "GET" || method === "HEAD" ? void 0 : JSON.stringify(body),
169
208
  cache: "no-store",
170
- signal
209
+ signal: stallAbort.signal
171
210
  });
172
211
  if (response.status === 410 && options?.onGone) {
173
212
  options.onGone(await response.text());
@@ -177,19 +216,32 @@ var handleSSEStream = async (url, body, onChunk, onComplete, onError, options) =
177
216
  const errorText = await response.text();
178
217
  throw new Error(`HTTP ${response.status}: ${errorText}`);
179
218
  }
180
- const reader = response.body?.getReader();
219
+ reader = response.body?.getReader();
181
220
  if (!reader) {
182
221
  throw new Error("No response body reader available");
183
222
  }
184
223
  const decoder = new TextDecoder();
185
224
  let buffer = "";
186
225
  let receivedData = false;
226
+ let finalSeen = false;
227
+ let failed = false;
228
+ const dispatch = (chunk) => {
229
+ if (failed) return;
230
+ if (chunk.error) {
231
+ failed = true;
232
+ onError(typeof chunk.error === "string" ? chunk.error : "The assistant could not finish this answer.");
233
+ return;
234
+ }
235
+ if (chunk.is_final === true) finalSeen = true;
236
+ onChunk(chunk);
237
+ };
187
238
  while (true) {
188
239
  let readResult;
189
240
  try {
190
- readResult = await reader.read();
241
+ readResult = stallMs > 0 ? await withStallTimeout(reader.read(), stallMs) : await reader.read();
191
242
  } catch (readError) {
192
243
  if (signal?.aborted) return;
244
+ stallAbort.abort();
193
245
  console.warn(
194
246
  "SSE reader error (connection may have been interrupted):",
195
247
  readError.message
@@ -203,16 +255,31 @@ var handleSSEStream = async (url, body, onChunk, onComplete, onError, options) =
203
255
  }
204
256
  const { done, value } = readResult;
205
257
  if (done) {
206
- onComplete();
258
+ buffer += decoder.decode();
259
+ if (buffer.trim()) processStreamLines(buffer + "\n", dispatch);
260
+ if (failed) return;
261
+ if ((options?.requireFinal ?? true) && !finalSeen) {
262
+ onError("Connection interrupted before the answer was complete. The assistant may still be working.");
263
+ } else onComplete();
207
264
  break;
208
265
  }
209
266
  buffer += decoder.decode(value, { stream: true });
210
267
  receivedData = true;
211
- buffer = processStreamLines(buffer, onChunk);
268
+ buffer = processStreamLines(buffer, dispatch);
269
+ if (failed) return;
212
270
  }
213
271
  } catch (error) {
214
272
  if (signal?.aborted) return;
215
273
  onError(error.message || "Streaming error");
274
+ } finally {
275
+ signal?.removeEventListener("abort", abortFromCaller);
276
+ if (reader) {
277
+ try {
278
+ await reader.cancel();
279
+ } catch {
280
+ }
281
+ reader.releaseLock();
282
+ }
216
283
  }
217
284
  };
218
285
 
@@ -849,32 +916,32 @@ function dispatchProgressEvent(progress, options = {}) {
849
916
  };
850
917
  window.dispatchEvent(new CustomEvent(PROGRESS_EVENT_NAME, { detail }));
851
918
  }
852
- var ScopedReasoningContext = React12.createContext(null);
919
+ var ScopedReasoningContext = React15.createContext(null);
853
920
  function ScopedReasoningProvider({
854
921
  hasOwnedKgId,
855
922
  children
856
923
  }) {
857
- const value = React12.useMemo(
924
+ const value = React15.useMemo(
858
925
  () => ({ hasOwnedKgId }),
859
926
  [hasOwnedKgId]
860
927
  );
861
- return React12__default.default.createElement(
928
+ return React15__default.default.createElement(
862
929
  ScopedReasoningContext.Provider,
863
930
  { value },
864
931
  children
865
932
  );
866
933
  }
867
934
  function useScopedProgressEvent(ownKgId, handler, enabled = true) {
868
- const ctx = React12.useContext(ScopedReasoningContext);
869
- const handlerRef = React12.useRef(handler);
870
- const ownKgIdRef = React12.useRef(ownKgId);
871
- React12.useEffect(() => {
935
+ const ctx = React15.useContext(ScopedReasoningContext);
936
+ const handlerRef = React15.useRef(handler);
937
+ const ownKgIdRef = React15.useRef(ownKgId);
938
+ React15.useEffect(() => {
872
939
  handlerRef.current = handler;
873
940
  }, [handler]);
874
- React12.useEffect(() => {
941
+ React15.useEffect(() => {
875
942
  ownKgIdRef.current = ownKgId;
876
943
  }, [ownKgId]);
877
- React12.useEffect(() => {
944
+ React15.useEffect(() => {
878
945
  if (!enabled) return;
879
946
  const listener = (e) => {
880
947
  const detail = e.detail;
@@ -979,10 +1046,10 @@ var defaultTheme = {
979
1046
  // Cursor
980
1047
  cursor: "#f97316"
981
1048
  };
982
- var ThemeContext = React12.createContext(defaultTheme);
1049
+ var ThemeContext = React15.createContext(defaultTheme);
983
1050
  var TerminalThemeProvider = ThemeContext.Provider;
984
1051
  function useTheme() {
985
- return React12.useContext(ThemeContext);
1052
+ return React15.useContext(ThemeContext);
986
1053
  }
987
1054
  function mergeTheme(overrides) {
988
1055
  if (!overrides) return defaultTheme;
@@ -1058,8 +1125,8 @@ var hostApp = {
1058
1125
  };
1059
1126
  function ShareButton({ content, title }) {
1060
1127
  const t = useTheme();
1061
- const [state, setState] = React12.useState("idle");
1062
- const handleShare = React12.useCallback(
1128
+ const [state, setState] = React15.useState("idle");
1129
+ const handleShare = React15.useCallback(
1063
1130
  async (e) => {
1064
1131
  e.stopPropagation();
1065
1132
  const shareText = content.slice(0, 500);
@@ -1087,12 +1154,13 @@ function ShareButton({ content, title }) {
1087
1154
  "button",
1088
1155
  {
1089
1156
  onClick: handleShare,
1090
- className: "p-1 rounded-md transition-all duration-200 hover:scale-110",
1157
+ className: "inline-flex h-6 w-6 items-center justify-center rounded-md transition-all duration-200 hover:scale-110",
1091
1158
  style: {
1092
1159
  backgroundColor: done ? "rgba(74,222,128,0.15)" : t.bgRaisedHover,
1093
1160
  color: done ? t.success : t.textMuted
1094
1161
  },
1095
1162
  title: state === "copied" ? "Copied!" : state === "shared" ? "Shared!" : "Share",
1163
+ "aria-label": state === "copied" ? "Link copied" : state === "shared" ? "Shared" : "Share message",
1096
1164
  children: done ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 12l5 5L20 7" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1097
1165
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 12v7a2 2 0 002 2h12a2 2 0 002-2v-7" }),
1098
1166
  /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "16 6 12 2 8 6" }),
@@ -1101,11 +1169,30 @@ function ShareButton({ content, title }) {
1101
1169
  }
1102
1170
  );
1103
1171
  }
1172
+
1173
+ // src/utils/stripInternalIds.ts
1174
+ var UUID = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}";
1175
+ var PREFIXED = `(?:KG|DOC|FRAME|SET|NODE|CHUNK):${UUID}`;
1176
+ var WRAP = "[*_`]*";
1177
+ var PAREN_PREFIXED = new RegExp(`\\s*\\(\\s*${WRAP}${PREFIXED}${WRAP}\\s*\\)`, "g");
1178
+ var PAREN_BARE = new RegExp(`\\s*\\(\\s*${WRAP}${UUID}${WRAP}\\s*\\)`, "g");
1179
+ var BARE_PREFIXED = new RegExp(`${WRAP}${PREFIXED}${WRAP}`, "g");
1180
+ var ID_PHRASE = new RegExp(
1181
+ `\\s*(?:\\(\\s*)?(?:for\\s+|with\\s+)?(?:suggestion|proposal|item|thread|entity|message|document)\\s+id[:\\s]+${WRAP}${UUID}${WRAP}(?:\\s*\\))?`,
1182
+ "gi"
1183
+ );
1184
+ var BARE_UUID = new RegExp(`${WRAP}${UUID}${WRAP}`, "g");
1185
+ function stripInternalIds(text) {
1186
+ if (!text || !/(?:KG|DOC|FRAME|SET|NODE|CHUNK):|-[0-9a-fA-F]{4}-/.test(text)) return text;
1187
+ return text.split(/(```[\s\S]*?```)/g).map(
1188
+ (part) => part.startsWith("```") ? part : part.replace(PAREN_PREFIXED, "").replace(PAREN_BARE, "").replace(BARE_PREFIXED, "").replace(ID_PHRASE, "").replace(BARE_UUID, "").replace(/[ \t]+([,.;:)])/g, "$1").replace(/([^\n ]) {2,}(?=\S)/g, "$1 ")
1189
+ ).join("");
1190
+ }
1104
1191
  function TimestampRenderer({ timestamp }) {
1105
1192
  const t = useTheme();
1106
- const [timeString, setTimeString] = React12.useState("");
1107
- React12.useEffect(() => {
1108
- setTimeString(timestamp.toLocaleTimeString());
1193
+ const [timeString, setTimeString] = React15.useState("");
1194
+ React15.useEffect(() => {
1195
+ setTimeString(timestamp.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }));
1109
1196
  }, [timestamp]);
1110
1197
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs ml-6 mt-1", style: { color: t.textMuted }, children: timeString });
1111
1198
  }
@@ -1126,36 +1213,36 @@ async function gql(url, token, query, variables) {
1126
1213
  return res.json();
1127
1214
  }
1128
1215
  function InteractiveActionCard({
1129
- action,
1216
+ action: action2,
1130
1217
  onExecute,
1131
1218
  graphqlUrl = "",
1132
1219
  authToken = ""
1133
1220
  }) {
1134
1221
  const t = useTheme();
1135
- const initialValues = React12.useMemo(() => {
1136
- const amount2 = action.metadata?.formatted_amount || (action.payload?.arguments?.amount && action.payload.arguments.amount !== "0" ? action.payload.arguments.amount : "") || "";
1137
- const assetId = action.payload?.arguments?.asset_id || "";
1138
- const entityId = action.payload?.arguments?.destination_id || "";
1139
- const walletId = action.payload?.arguments?.destination_wallet_id || "";
1222
+ const initialValues = React15.useMemo(() => {
1223
+ const amount2 = action2.metadata?.formatted_amount || (action2.payload?.arguments?.amount && action2.payload.arguments.amount !== "0" ? action2.payload.arguments.amount : "") || "";
1224
+ const assetId = action2.payload?.arguments?.asset_id || "";
1225
+ const entityId = action2.payload?.arguments?.destination_id || "";
1226
+ const walletId = action2.payload?.arguments?.destination_wallet_id || "";
1140
1227
  return { amount: amount2, assetId, entityId, walletId };
1141
- }, [action]);
1142
- const [editedAction, setEditedAction] = React12.useState(action);
1143
- const [entities, setEntities] = React12.useState([]);
1144
- const [wallets, setWallets] = React12.useState([]);
1145
- const [assets, setAssets] = React12.useState([]);
1146
- const [loadingEntities, setLoadingEntities] = React12.useState(false);
1147
- const [loadingWallets, setLoadingWallets] = React12.useState(false);
1148
- const [loadingAssets, setLoadingAssets] = React12.useState(false);
1149
- const [errorEntities, setErrorEntities] = React12.useState(null);
1150
- const [errorWallets, setErrorWallets] = React12.useState(null);
1151
- const [errorAssets, setErrorAssets] = React12.useState(null);
1152
- const [selectedEntityId, setSelectedEntityId] = React12.useState(initialValues.entityId);
1153
- const [selectedWalletId, setSelectedWalletId] = React12.useState(initialValues.walletId);
1154
- const [selectedAssetId, setSelectedAssetId] = React12.useState(initialValues.assetId);
1155
- const [amount, setAmount] = React12.useState(initialValues.amount);
1156
- const [obligorEntity, setObligorEntity] = React12.useState(null);
1157
- const [loadingObligor, setLoadingObligor] = React12.useState(false);
1158
- const fetchEntities = React12.useCallback(async () => {
1228
+ }, [action2]);
1229
+ const [editedAction, setEditedAction] = React15.useState(action2);
1230
+ const [entities, setEntities] = React15.useState([]);
1231
+ const [wallets, setWallets] = React15.useState([]);
1232
+ const [assets, setAssets] = React15.useState([]);
1233
+ const [loadingEntities, setLoadingEntities] = React15.useState(false);
1234
+ const [loadingWallets, setLoadingWallets] = React15.useState(false);
1235
+ const [loadingAssets, setLoadingAssets] = React15.useState(false);
1236
+ const [errorEntities, setErrorEntities] = React15.useState(null);
1237
+ const [errorWallets, setErrorWallets] = React15.useState(null);
1238
+ const [errorAssets, setErrorAssets] = React15.useState(null);
1239
+ const [selectedEntityId, setSelectedEntityId] = React15.useState(initialValues.entityId);
1240
+ const [selectedWalletId, setSelectedWalletId] = React15.useState(initialValues.walletId);
1241
+ const [selectedAssetId, setSelectedAssetId] = React15.useState(initialValues.assetId);
1242
+ const [amount, setAmount] = React15.useState(initialValues.amount);
1243
+ const [obligorEntity, setObligorEntity] = React15.useState(null);
1244
+ const [loadingObligor, setLoadingObligor] = React15.useState(false);
1245
+ const fetchEntities = React15.useCallback(async () => {
1159
1246
  if (!graphqlUrl) return;
1160
1247
  setLoadingEntities(true);
1161
1248
  try {
@@ -1176,7 +1263,7 @@ function InteractiveActionCard({
1176
1263
  setLoadingEntities(false);
1177
1264
  }
1178
1265
  }, [graphqlUrl, authToken]);
1179
- const fetchWallets = React12.useCallback(
1266
+ const fetchWallets = React15.useCallback(
1180
1267
  async (entityId) => {
1181
1268
  if (!entityId || !graphqlUrl) return;
1182
1269
  setLoadingWallets(true);
@@ -1201,7 +1288,7 @@ function InteractiveActionCard({
1201
1288
  },
1202
1289
  [graphqlUrl, authToken]
1203
1290
  );
1204
- const fetchAssets = React12.useCallback(async () => {
1291
+ const fetchAssets = React15.useCallback(async () => {
1205
1292
  if (!graphqlUrl) return;
1206
1293
  setLoadingAssets(true);
1207
1294
  try {
@@ -1222,7 +1309,7 @@ function InteractiveActionCard({
1222
1309
  setLoadingAssets(false);
1223
1310
  }
1224
1311
  }, [graphqlUrl, authToken]);
1225
- const updateActionField = React12.useCallback(
1312
+ const updateActionField = React15.useCallback(
1226
1313
  (field, value) => {
1227
1314
  setEditedAction((prev) => {
1228
1315
  const updated = { ...prev };
@@ -1252,15 +1339,15 @@ function InteractiveActionCard({
1252
1339
  },
1253
1340
  [assets, entities, wallets]
1254
1341
  );
1255
- React12.useEffect(() => {
1256
- if (action.payload?.tool_name === "yieldfabric/send_instant_payment") {
1342
+ React15.useEffect(() => {
1343
+ if (action2.payload?.tool_name === "yieldfabric/send_instant_payment") {
1257
1344
  fetchEntities();
1258
1345
  fetchAssets();
1259
1346
  if (initialValues.entityId) fetchWallets(initialValues.entityId);
1260
1347
  }
1261
1348
  }, []);
1262
- React12.useEffect(() => {
1263
- if (selectedEntityId && action.payload?.tool_name === "yieldfabric/send_instant_payment") {
1349
+ React15.useEffect(() => {
1350
+ if (selectedEntityId && action2.payload?.tool_name === "yieldfabric/send_instant_payment") {
1264
1351
  const shouldFetch = selectedEntityId !== initialValues.entityId || wallets.length === 0;
1265
1352
  if (shouldFetch) fetchWallets(selectedEntityId);
1266
1353
  if (selectedEntityId !== initialValues.entityId) {
@@ -1269,15 +1356,15 @@ function InteractiveActionCard({
1269
1356
  }
1270
1357
  }
1271
1358
  }, [selectedEntityId]);
1272
- React12.useEffect(() => {
1273
- if (action.payload?.tool_name !== "yieldfabric/send_instant_payment") return;
1359
+ React15.useEffect(() => {
1360
+ if (action2.payload?.tool_name !== "yieldfabric/send_instant_payment") return;
1274
1361
  if (initialValues.assetId && assets.length > 0) {
1275
1362
  const match = assets.find((a) => a.id === initialValues.assetId) || assets.find(
1276
1363
  (a) => a.id.toUpperCase() === initialValues.assetId.toUpperCase()
1277
1364
  ) || assets.find(
1278
1365
  (a) => initialValues.assetId.toUpperCase() === "CBDC" && a.name?.toUpperCase().includes("CBDC")
1279
- ) || action.metadata?.asset_id && assets.find(
1280
- (a) => a.id === action.metadata.asset_id || a.id.toUpperCase() === action.metadata.asset_id.toUpperCase()
1366
+ ) || action2.metadata?.asset_id && assets.find(
1367
+ (a) => a.id === action2.metadata.asset_id || a.id.toUpperCase() === action2.metadata.asset_id.toUpperCase()
1281
1368
  );
1282
1369
  if (match && selectedAssetId !== match.id) {
1283
1370
  setSelectedAssetId(match.id);
@@ -1301,11 +1388,11 @@ function InteractiveActionCard({
1301
1388
  updateActionField("amount", initialValues.amount);
1302
1389
  }
1303
1390
  }, [assets, entities, wallets]);
1304
- if (action.payload?.tool_name === "yieldfabric/swap_credit_for_cash") {
1391
+ if (action2.payload?.tool_name === "yieldfabric/swap_credit_for_cash") {
1305
1392
  return /* @__PURE__ */ jsxRuntime.jsx(
1306
1393
  RedeemCreditCard,
1307
1394
  {
1308
- action,
1395
+ action: action2,
1309
1396
  onExecute,
1310
1397
  graphqlUrl,
1311
1398
  authToken,
@@ -1316,20 +1403,20 @@ function InteractiveActionCard({
1316
1403
  }
1317
1404
  );
1318
1405
  }
1319
- if (action.payload?.tool_name === "yieldfabric/complete_swap") {
1320
- return /* @__PURE__ */ jsxRuntime.jsx(CompleteSwapCard, { action, onExecute });
1406
+ if (action2.payload?.tool_name === "yieldfabric/complete_swap") {
1407
+ return /* @__PURE__ */ jsxRuntime.jsx(CompleteSwapCard, { action: action2, onExecute });
1321
1408
  }
1322
- if (action.payload?.tool_name === "yieldfabric/accept_payment") {
1323
- return /* @__PURE__ */ jsxRuntime.jsx(AcceptPaymentCard, { action, onExecute });
1409
+ if (action2.payload?.tool_name === "yieldfabric/accept_payment") {
1410
+ return /* @__PURE__ */ jsxRuntime.jsx(AcceptPaymentCard, { action: action2, onExecute });
1324
1411
  }
1325
- if (action.action_type === "file_controls") {
1326
- return /* @__PURE__ */ jsxRuntime.jsx(FileControlsCard, { action, onExecute });
1412
+ if (action2.action_type === "file_controls") {
1413
+ return /* @__PURE__ */ jsxRuntime.jsx(FileControlsCard, { action: action2, onExecute });
1327
1414
  }
1328
- if (action.action_type === "download_source") {
1329
- return /* @__PURE__ */ jsxRuntime.jsx(DownloadSourceCard, { action, onExecute });
1415
+ if (action2.action_type === "download_source") {
1416
+ return /* @__PURE__ */ jsxRuntime.jsx(DownloadSourceCard, { action: action2, onExecute });
1330
1417
  }
1331
- if (action.payload?.tool_name !== "yieldfabric/send_instant_payment") {
1332
- return /* @__PURE__ */ jsxRuntime.jsx(GenericActionCard, { action, onExecute });
1418
+ if (action2.payload?.tool_name !== "yieldfabric/send_instant_payment") {
1419
+ return /* @__PURE__ */ jsxRuntime.jsx(GenericActionCard, { action: action2, onExecute });
1333
1420
  }
1334
1421
  return /* @__PURE__ */ jsxRuntime.jsxs(
1335
1422
  "div",
@@ -1476,7 +1563,7 @@ function InteractiveActionCard({
1476
1563
  );
1477
1564
  }
1478
1565
  function RedeemCreditCard({
1479
- action,
1566
+ action: action2,
1480
1567
  onExecute,
1481
1568
  graphqlUrl,
1482
1569
  authToken,
@@ -1486,14 +1573,14 @@ function RedeemCreditCard({
1486
1573
  setLoadingObligor
1487
1574
  }) {
1488
1575
  const t = useTheme();
1489
- const metadata = action.metadata || {};
1576
+ const metadata = action2.metadata || {};
1490
1577
  const formattedAmount = metadata.formatted_amount || metadata.amount || "0.00";
1491
1578
  const currency = metadata.currency || "Unknown";
1492
1579
  const obligor = metadata.obligor || metadata.obligor_id || "Unknown";
1493
1580
  const obligorId = metadata.obligor_id || obligor;
1494
1581
  const assetDisplay = formatAssetDisplay(metadata, currency);
1495
- React12.useEffect(() => {
1496
- if (action.payload?.tool_name !== "yieldfabric/swap_credit_for_cash") return;
1582
+ React15.useEffect(() => {
1583
+ if (action2.payload?.tool_name !== "yieldfabric/swap_credit_for_cash") return;
1497
1584
  if (obligorId === "Unknown" || obligor.includes("@")) return;
1498
1585
  if (metadata.obligor_name && metadata.obligor_name !== obligorId && !obligorId.includes("-"))
1499
1586
  return;
@@ -1524,7 +1611,7 @@ function RedeemCreditCard({
1524
1611
  setLoadingObligor(false);
1525
1612
  }
1526
1613
  })();
1527
- }, [obligorId, action.payload?.tool_name]);
1614
+ }, [obligorId, action2.payload?.tool_name]);
1528
1615
  const obligorDisplay = (() => {
1529
1616
  if (obligorEntity?.name) return obligorEntity.name;
1530
1617
  if (metadata.obligor_name && metadata.obligor_name !== obligorId && metadata.obligor_name !== obligor)
@@ -1576,7 +1663,7 @@ function RedeemCreditCard({
1576
1663
  onClick: (e) => {
1577
1664
  e.preventDefault();
1578
1665
  e.stopPropagation();
1579
- onExecute(action);
1666
+ onExecute(action2);
1580
1667
  },
1581
1668
  className: "w-full py-2 px-4 text-sm font-medium rounded transition-colors flex items-center justify-center gap-2",
1582
1669
  style: { backgroundColor: t.success, color: t.textInverse },
@@ -1591,12 +1678,12 @@ function RedeemCreditCard({
1591
1678
  );
1592
1679
  }
1593
1680
  function CompleteSwapCard({
1594
- action,
1681
+ action: action2,
1595
1682
  onExecute
1596
1683
  }) {
1597
1684
  const t = useTheme();
1598
- const metadata = action.metadata || {};
1599
- const swapId = metadata.swap_id || action.payload?.arguments?.swap_id || "Unknown";
1685
+ const metadata = action2.metadata || {};
1686
+ const swapId = metadata.swap_id || action2.payload?.arguments?.swap_id || "Unknown";
1600
1687
  const initiator = metadata.initiator || "Unknown";
1601
1688
  const status = metadata.status || "PENDING";
1602
1689
  const deadline = metadata.deadline ? new Date(metadata.deadline).toLocaleString() : "N/A";
@@ -1658,7 +1745,7 @@ function CompleteSwapCard({
1658
1745
  onClick: (e) => {
1659
1746
  e.preventDefault();
1660
1747
  e.stopPropagation();
1661
- onExecute(action);
1748
+ onExecute(action2);
1662
1749
  },
1663
1750
  className: "w-full py-2 px-4 text-sm font-medium rounded transition-colors flex items-center justify-center gap-2",
1664
1751
  style: { backgroundColor: t.success, color: t.textInverse },
@@ -1700,11 +1787,11 @@ function PaymentLeg({
1700
1787
  ] });
1701
1788
  }
1702
1789
  function AcceptPaymentCard({
1703
- action,
1790
+ action: action2,
1704
1791
  onExecute
1705
1792
  }) {
1706
1793
  const t = useTheme();
1707
- const metadata = action.metadata || {};
1794
+ const metadata = action2.metadata || {};
1708
1795
  const formattedAmount = metadata.formatted_amount || metadata.amount || "0.00";
1709
1796
  const currency = metadata.currency || "Unknown";
1710
1797
  const from = metadata.from || "Unknown";
@@ -1764,7 +1851,7 @@ function AcceptPaymentCard({
1764
1851
  onClick: (e) => {
1765
1852
  e.preventDefault();
1766
1853
  e.stopPropagation();
1767
- onExecute(action);
1854
+ onExecute(action2);
1768
1855
  },
1769
1856
  className: "w-full py-1.5 px-3 text-xs font-medium rounded transition-colors flex items-center justify-center gap-1.5 mt-auto",
1770
1857
  style: { backgroundColor: t.success, color: t.textInverse },
@@ -1779,12 +1866,12 @@ function AcceptPaymentCard({
1779
1866
  );
1780
1867
  }
1781
1868
  function FileControlsCard({
1782
- action,
1869
+ action: action2,
1783
1870
  onExecute
1784
1871
  }) {
1785
1872
  const t = useTheme();
1786
- const title = action.payload?.title || "Document";
1787
- const documentId = action.payload?.document_id;
1873
+ const title = action2.payload?.title || "Document";
1874
+ const documentId = action2.payload?.document_id;
1788
1875
  const doDownload = (e) => {
1789
1876
  e.preventDefault();
1790
1877
  e.stopPropagation();
@@ -1843,18 +1930,18 @@ function FileControlsCard({
1843
1930
  );
1844
1931
  }
1845
1932
  function DownloadSourceCard({
1846
- action,
1933
+ action: action2,
1847
1934
  onExecute
1848
1935
  }) {
1849
1936
  const t = useTheme();
1850
- const title = action.payload?.title || action.metadata?.display_text || action.description || "Document";
1937
+ const title = action2.payload?.title || action2.metadata?.display_text || action2.description || "Document";
1851
1938
  return /* @__PURE__ */ jsxRuntime.jsx(
1852
1939
  "button",
1853
1940
  {
1854
1941
  onClick: (e) => {
1855
1942
  e.preventDefault();
1856
1943
  e.stopPropagation();
1857
- onExecute(action);
1944
+ onExecute(action2);
1858
1945
  },
1859
1946
  className: "relative overflow-hidden w-full p-3 rounded-lg transition-all duration-200 text-left group",
1860
1947
  style: { backgroundColor: t.buttonBg, border: `1px solid ${t.border}` },
@@ -1874,7 +1961,7 @@ function DownloadSourceCard({
1874
1961
  );
1875
1962
  }
1876
1963
  function GenericActionCard({
1877
- action,
1964
+ action: action2,
1878
1965
  onExecute
1879
1966
  }) {
1880
1967
  const t = useTheme();
@@ -1884,14 +1971,14 @@ function GenericActionCard({
1884
1971
  onClick: (e) => {
1885
1972
  e.preventDefault();
1886
1973
  e.stopPropagation();
1887
- onExecute(action);
1974
+ onExecute(action2);
1888
1975
  },
1889
1976
  className: "flex items-center space-x-3 p-3 rounded-lg transition-colors text-left group",
1890
1977
  style: { backgroundColor: GREEN_ACTION.bg, border: GREEN_ACTION.borderStyle },
1891
1978
  onMouseEnter: (e) => e.currentTarget.style.backgroundColor = GREEN_ACTION.bgHover,
1892
1979
  onMouseLeave: (e) => e.currentTarget.style.backgroundColor = GREEN_ACTION.bg,
1893
1980
  children: [
1894
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-sm mb-1.5", style: { color: t.success }, children: action.metadata?.display_text || action.description || `Execute ${action.action_type}` }) }),
1981
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-sm mb-1.5", style: { color: t.success }, children: action2.metadata?.display_text || action2.description || `Execute ${action2.action_type}` }) }),
1895
1982
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { className: "w-5 h-5 transition-colors flex-shrink-0 ml-2", style: { color: t.success } })
1896
1983
  ]
1897
1984
  }
@@ -1957,7 +2044,7 @@ function PipelineDraftCard({
1957
2044
  className: externalClassName
1958
2045
  }) {
1959
2046
  const t = useTheme();
1960
- const [submitting, setSubmitting] = React12.useState(false);
2047
+ const [submitting, setSubmitting] = React15.useState(false);
1961
2048
  return /* @__PURE__ */ jsxRuntime.jsxs(
1962
2049
  "div",
1963
2050
  {
@@ -2088,7 +2175,7 @@ function CollapsibleSection({
2088
2175
  defaultExpanded = false
2089
2176
  }) {
2090
2177
  const t = useTheme();
2091
- const [expanded, setExpanded] = React12.useState(defaultExpanded);
2178
+ const [expanded, setExpanded] = React15.useState(defaultExpanded);
2092
2179
  return /* @__PURE__ */ jsxRuntime.jsxs(
2093
2180
  "div",
2094
2181
  {
@@ -2122,8 +2209,8 @@ function CollapsibleSection({
2122
2209
  }
2123
2210
  function CopyButton({ content }) {
2124
2211
  const t = useTheme();
2125
- const [copied, setCopied] = React12.useState(false);
2126
- const handleCopy = React12.useCallback(
2212
+ const [copied, setCopied] = React15.useState(false);
2213
+ const handleCopy = React15.useCallback(
2127
2214
  async (e) => {
2128
2215
  e.stopPropagation();
2129
2216
  try {
@@ -2139,13 +2226,29 @@ function CopyButton({ content }) {
2139
2226
  "button",
2140
2227
  {
2141
2228
  onClick: handleCopy,
2142
- className: "p-1 rounded transition-colors hover:scale-110",
2229
+ className: "inline-flex h-6 w-6 items-center justify-center rounded transition-colors hover:scale-110",
2143
2230
  style: { backgroundColor: t.bgRaisedHover, color: t.textSecondary },
2144
2231
  title: "Copy",
2232
+ "aria-label": copied ? "Copied" : "Copy message",
2145
2233
  children: copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "w-3.5 h-3.5", style: { color: t.success } }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "w-3.5 h-3.5" })
2146
2234
  }
2147
2235
  );
2148
2236
  }
2237
+ function AgentCompletionNotice({ completion }) {
2238
+ const t = useTheme();
2239
+ if (!completion || completion.stop_reason === "answered") return null;
2240
+ const message = {
2241
+ rounds_exhausted: "Partial answer \u2014 I reached the step limit. Ask a narrower follow-up to continue.",
2242
+ budget_exhausted: "Partial answer \u2014 this question needs more context than fits in one answer. Try narrowing the question.",
2243
+ awaiting_tool_results: "This answer paused before its next step. Ask again to review a fresh answer.",
2244
+ empty: "No answer was returned. Please try again.",
2245
+ failed: "The answer could not be completed. What arrived so far is kept here.",
2246
+ interrupted: "Connection interrupted. The assistant may still be working; check the conversation before sending again.",
2247
+ cancelled: "Stopped. You can change your question and ask again."
2248
+ }[completion.stop_reason];
2249
+ if (!message) return null;
2250
+ return /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", className: "mt-2 rounded-md px-3 py-2 text-xs", style: { color: t.textSecondary, backgroundColor: t.bgRaisedAlt, border: `1px solid ${t.border}` }, children: message });
2251
+ }
2149
2252
  var AGENT_PALETTE = [
2150
2253
  "a78bfa",
2151
2254
  // violet-400
@@ -2194,7 +2297,7 @@ var AgentAvatar = ({
2194
2297
  }) => {
2195
2298
  const px = typeof size === "number" ? size : SIZE_PX[size];
2196
2299
  const seed = canonicalSeed(name);
2197
- const uri = React12.useMemo(() => {
2300
+ const uri = React15.useMemo(() => {
2198
2301
  const bg = AGENT_PALETTE[paletteIndex(seed)];
2199
2302
  return core.createAvatar(collection.avataaars, {
2200
2303
  seed,
@@ -2219,9 +2322,9 @@ var AgentAvatar = ({
2219
2322
  };
2220
2323
  function TimeLabel({ timestamp }) {
2221
2324
  const t = useTheme();
2222
- const [timeStr, setTimeStr] = React12.useState("");
2223
- React12.useEffect(() => {
2224
- setTimeStr(timestamp.toLocaleTimeString());
2325
+ const [timeStr, setTimeStr] = React15.useState("");
2326
+ React15.useEffect(() => {
2327
+ setTimeStr(timestamp.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }));
2225
2328
  }, [timestamp]);
2226
2329
  return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] mt-0.5", style: { color: t.textSecondary }, children: timeStr });
2227
2330
  }
@@ -2539,21 +2642,36 @@ function hashTypeColor(type) {
2539
2642
  for (let i = 0; i < type.length; i++) h = (h << 5) - h + type.charCodeAt(i) | 0;
2540
2643
  return SOURCE_TYPE_PALETTE[Math.abs(h) % SOURCE_TYPE_PALETTE.length];
2541
2644
  }
2542
- function SourceCard({ source }) {
2645
+ function SourceCard({
2646
+ source,
2647
+ onActivate
2648
+ }) {
2543
2649
  const t = useTheme();
2544
- const [expanded, setExpanded] = React12.useState(false);
2650
+ const [expanded, setExpanded] = React15.useState(false);
2545
2651
  const showType = source.type && source.type.toLowerCase() !== "unknown";
2546
2652
  const badgeColor = source.typeColor || (showType ? hashTypeColor(source.type) : t.textMuted);
2547
2653
  const displayLabel = formatSourceLabel(source.label);
2548
2654
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded", style: { border: `1px solid ${t.border}`, backgroundColor: t.bgRaisedAlt }, children: [
2549
2655
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 px-2.5 py-1.5", children: [
2550
- source.description ? /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setExpanded(!expanded), className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
2551
- lucideReact.ChevronRight,
2656
+ source.description ? /* @__PURE__ */ jsxRuntime.jsx(
2657
+ "button",
2552
2658
  {
2553
- className: "w-3 h-3 transition-transform",
2554
- style: { color: t.textMuted, transform: expanded ? "rotate(90deg)" : "none" }
2659
+ type: "button",
2660
+ onClick: (event) => {
2661
+ event.stopPropagation();
2662
+ setExpanded(!expanded);
2663
+ },
2664
+ className: "flex-shrink-0 rounded-sm focus:outline-none focus-visible:ring-2",
2665
+ "aria-label": expanded ? `Collapse ${displayLabel} details` : `Expand ${displayLabel} details`,
2666
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2667
+ lucideReact.ChevronRight,
2668
+ {
2669
+ className: "w-3 h-3 transition-transform",
2670
+ style: { color: t.textMuted, transform: expanded ? "rotate(90deg)" : "none" }
2671
+ }
2672
+ )
2555
2673
  }
2556
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-3 h-3 flex-shrink-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-1.5 h-1.5 rounded-full", style: { backgroundColor: badgeColor } }) }),
2674
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-3 h-3 flex-shrink-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-1.5 h-1.5 rounded-full", style: { backgroundColor: badgeColor } }) }),
2557
2675
  showType && /* @__PURE__ */ jsxRuntime.jsx(
2558
2676
  "span",
2559
2677
  {
@@ -2562,11 +2680,28 @@ function SourceCard({ source }) {
2562
2680
  children: source.type
2563
2681
  }
2564
2682
  ),
2565
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] truncate flex-1", style: { color: t.text }, children: displayLabel })
2683
+ onActivate ? /* @__PURE__ */ jsxRuntime.jsx(
2684
+ "button",
2685
+ {
2686
+ type: "button",
2687
+ className: "text-[11px] truncate flex-1 cursor-pointer text-left rounded-sm hover:underline focus:outline-none focus-visible:ring-2",
2688
+ style: { color: t.text },
2689
+ onClick: (event) => {
2690
+ event.stopPropagation();
2691
+ onActivate(source);
2692
+ },
2693
+ "aria-label": `Open ${displayLabel}`,
2694
+ children: displayLabel
2695
+ }
2696
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] truncate flex-1", style: { color: t.text }, children: displayLabel })
2566
2697
  ] }),
2567
2698
  expanded && source.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2.5 pb-2 text-[10px] leading-relaxed", style: { color: t.textSecondary, borderTop: `1px solid ${t.border}` }, children: source.description })
2568
2699
  ] });
2569
2700
  }
2701
+ var REMARK_PLUGINS = [remarkGfm__default.default];
2702
+ function isBlockCode(className, text) {
2703
+ return /language-/.test(typeof className === "string" ? className : "") || text.includes("\n");
2704
+ }
2570
2705
  function getMarkdownComponents(t) {
2571
2706
  return {
2572
2707
  h1: ({ node, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-bold mt-4 mb-2", style: { color: t.headingText }, ...props }),
@@ -2578,10 +2713,38 @@ function getMarkdownComponents(t) {
2578
2713
  li: ({ node, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "ml-2", ...props }),
2579
2714
  strong: ({ node, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "font-bold", style: { color: t.text }, ...props }),
2580
2715
  em: ({ node, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("em", { className: "italic", style: { color: t.textSecondary }, ...props }),
2581
- code: ({ node, inline, children, ...props }) => inline ? /* @__PURE__ */ jsxRuntime.jsx("code", { className: "px-1 py-0.5 rounded font-mono text-xs", style: { backgroundColor: t.codeBg, color: t.codeText }, ...props, children }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group/code", children: [
2582
- /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: String(children || "") }),
2583
- /* @__PURE__ */ jsxRuntime.jsx("code", { className: "block p-2 rounded my-2 font-mono text-xs overflow-x-auto", style: { backgroundColor: t.codeBg, color: t.codeText }, ...props, children })
2584
- ] })
2716
+ code: ({ node, inline, children, ...props }) => {
2717
+ const text = String(children ?? "");
2718
+ const isInline = inline ?? !isBlockCode(props.className, text);
2719
+ return isInline ? /* @__PURE__ */ jsxRuntime.jsx("code", { className: "px-1 py-0.5 rounded font-mono text-xs", style: { backgroundColor: t.codeBg, color: t.codeText }, ...props, children }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group/code", children: [
2720
+ /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: text }),
2721
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: "block p-2 rounded my-2 font-mono text-xs overflow-x-auto", style: { backgroundColor: t.codeBg, color: t.codeText }, ...props, children })
2722
+ ] });
2723
+ },
2724
+ // Tables are why remark-gfm is here. The wrapper is not decoration:
2725
+ // this renders inside a chat rail the user can drag down to ~360px,
2726
+ // and a table holding a term plus a few numbers will exceed that. It
2727
+ // has to scroll INSIDE its own box — without the wrapper the reply
2728
+ // column itself widens and every other line in the conversation
2729
+ // starts scrolling sideways along with it.
2730
+ table: ({ node, ...p }) => /* @__PURE__ */ jsxRuntime.jsx(
2731
+ "div",
2732
+ {
2733
+ className: "my-2 max-w-full overflow-x-auto rounded",
2734
+ style: { border: `1px solid ${t.codeBg}` },
2735
+ children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full border-collapse text-xs", ...p })
2736
+ }
2737
+ ),
2738
+ thead: ({ node, ...p }) => /* @__PURE__ */ jsxRuntime.jsx("thead", { style: { backgroundColor: t.codeBg }, ...p }),
2739
+ th: ({ node, ...p }) => /* @__PURE__ */ jsxRuntime.jsx(
2740
+ "th",
2741
+ {
2742
+ className: "px-2.5 py-1.5 text-left font-semibold whitespace-nowrap",
2743
+ style: { color: t.headingText, borderBottom: `1px solid ${t.codeBg}` },
2744
+ ...p
2745
+ }
2746
+ ),
2747
+ td: ({ node, ...p }) => /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-2.5 py-1.5 align-top", style: { borderBottom: `1px solid ${t.codeBg}` }, ...p })
2585
2748
  };
2586
2749
  }
2587
2750
  function TerminalEntryRenderer({
@@ -2596,6 +2759,7 @@ function TerminalEntryRenderer({
2596
2759
  authToken,
2597
2760
  onPageNavigation,
2598
2761
  onSourcesActivate,
2762
+ onSourceActivate,
2599
2763
  renderEntryExtra,
2600
2764
  renderEntry,
2601
2765
  widgets,
@@ -2613,7 +2777,7 @@ function TerminalEntryRenderer({
2613
2777
  const isError = entry.type === "error";
2614
2778
  const isSuccess = entry.type === "success";
2615
2779
  const isEmpty = !entry.content || entry.content.trim() === "";
2616
- const useAttribution = isCollaborative && entry.sender && !isSystem && !isEmpty;
2780
+ const useAttribution = (isCollaborative || entry.sender?.type === "agent") && entry.sender && !isSystem && !isEmpty;
2617
2781
  const isGrouped = useAttribution && !!prevEntry?.sender && !!entry.sender && prevEntry.sender.entity_id === entry.sender.entity_id && prevEntry.sender.type === entry.sender.type && !(!prevEntry.content || prevEntry.content.trim() === "") && entry.timestamp.getTime() - prevEntry.timestamp.getTime() < 5 * 60 * 1e3 && prevEntry.type !== "system";
2618
2782
  const beforeWidgets = widgets?.filter((w) => w.position === "before" && w.match(entry)) || [];
2619
2783
  const afterWidgets = widgets?.filter((w) => (!w.position || w.position === "after") && w.match(entry)) || [];
@@ -2626,12 +2790,12 @@ function TerminalEntryRenderer({
2626
2790
  timestamp: entry.timestamp,
2627
2791
  isOwnMessage: entry.sender.entity_id === currentUser?.entity_id,
2628
2792
  grouped: isGrouped,
2629
- children: entry.sender?.type === "agent" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm prose prose-invert prose-sm max-w-none group relative", style: { color: t.text }, children: [
2793
+ children: entry.sender?.type === "agent" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm prose prose-invert prose-sm max-w-[72ch] group relative", style: { color: t.text }, children: [
2630
2794
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute -top-9 right-0 flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity z-10", children: [
2631
2795
  /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: entry.content }),
2632
2796
  /* @__PURE__ */ jsxRuntime.jsx(ShareButton, { content: entry.content })
2633
2797
  ] }),
2634
- /* @__PURE__ */ jsxRuntime.jsx(ReactMarkdown__default.default, { components: markdownComponents, children: entry.content })
2798
+ /* @__PURE__ */ jsxRuntime.jsx(ReactMarkdown__default.default, { remarkPlugins: REMARK_PLUGINS, components: markdownComponents, children: stripInternalIds(entry.content) })
2635
2799
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm whitespace-pre-wrap group relative", style: { color: isError ? t.error : t.text }, children: [
2636
2800
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute -top-9 right-0 flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity z-10", children: [
2637
2801
  /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: entry.content }),
@@ -2642,7 +2806,6 @@ function TerminalEntryRenderer({
2642
2806
  }
2643
2807
  ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start space-x-2", children: [
2644
2808
  isSystem && !isEmpty && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Terminal, { className: "w-4 h-4 mt-0.5 flex-shrink-0", style: { color: t.textSystem } }),
2645
- isCommand && !isEmpty && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Brain, { className: "w-4 h-4 mt-0.5 flex-shrink-0", style: { color: t.info } }),
2646
2809
  isInfo && !isEmpty && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle, { className: "w-4 h-4 mt-0.5 flex-shrink-0", style: { color: t.info } }),
2647
2810
  isSuccess && !isEmpty && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle, { className: "w-4 h-4 mt-0.5 flex-shrink-0", style: { color: t.success } }),
2648
2811
  isError && !isEmpty && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircle, { className: "w-4 h-4 mt-0.5 flex-shrink-0", style: { color: t.error } }),
@@ -2655,12 +2818,30 @@ function TerminalEntryRenderer({
2655
2818
  /* @__PURE__ */ jsxRuntime.jsx(
2656
2819
  ReactMarkdown__default.default,
2657
2820
  {
2821
+ remarkPlugins: REMARK_PLUGINS,
2658
2822
  components: markdownComponents,
2659
- children: entry.content
2823
+ children: stripInternalIds(entry.content)
2660
2824
  },
2661
2825
  `${entry.id || index}-${entry.content.length}`
2662
2826
  )
2663
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group relative", children: [
2827
+ ] }) : isCommand && !isSystem ? (
2828
+ // What the person typed: a quiet bubble on the right, the way the
2829
+ // console shows it — not a monospace line that reads as a log.
2830
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group relative flex w-full flex-1 justify-end", children: [
2831
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute -top-5 right-0 flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity z-10", children: [
2832
+ /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: entry.content }),
2833
+ /* @__PURE__ */ jsxRuntime.jsx(ShareButton, { content: entry.content })
2834
+ ] }),
2835
+ /* @__PURE__ */ jsxRuntime.jsx(
2836
+ "p",
2837
+ {
2838
+ className: "max-w-[80%] whitespace-pre-wrap rounded-lg border px-4 py-2.5 text-sm leading-relaxed",
2839
+ style: { color: t.text, borderColor: t.borderStrong, backgroundColor: "rgba(255,255,255,0.05)" },
2840
+ children: entry.content
2841
+ }
2842
+ )
2843
+ ] })
2844
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group relative", children: [
2664
2845
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute -top-5 right-0 flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity z-10", children: [
2665
2846
  /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { content: entry.content }),
2666
2847
  /* @__PURE__ */ jsxRuntime.jsx(ShareButton, { content: entry.content })
@@ -2668,9 +2849,9 @@ function TerminalEntryRenderer({
2668
2849
  /* @__PURE__ */ jsxRuntime.jsx(
2669
2850
  "pre",
2670
2851
  {
2671
- className: "font-mono text-sm whitespace-pre-wrap",
2852
+ className: "font-mono text-sm whitespace-pre-wrap max-w-[72ch]",
2672
2853
  style: {
2673
- color: isSystem ? t.textSystem : isCommand ? t.textCommand : isSuccess ? t.success : isError ? t.error : t.text
2854
+ color: isSystem ? t.textSystem : isSuccess ? t.success : isError ? t.error : t.text
2674
2855
  },
2675
2856
  children: entry.content
2676
2857
  }
@@ -2801,7 +2982,14 @@ function TerminalEntryRenderer({
2801
2982
  {
2802
2983
  summary: `${entry.sources.length} source${entry.sources.length !== 1 ? "s" : ""}`,
2803
2984
  defaultExpanded: false,
2804
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1 py-1", children: entry.sources.map((src) => /* @__PURE__ */ jsxRuntime.jsx(SourceCard, { source: src }, src.id)) })
2985
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1 py-1", children: entry.sources.map((src) => /* @__PURE__ */ jsxRuntime.jsx(
2986
+ SourceCard,
2987
+ {
2988
+ source: src,
2989
+ onActivate: onSourceActivate ? () => onSourceActivate(src, entry) : void 0
2990
+ },
2991
+ src.id
2992
+ )) })
2805
2993
  }
2806
2994
  )
2807
2995
  }
@@ -2821,11 +3009,11 @@ function TerminalEntryRenderer({
2821
3009
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-sm", style: { color: t.success }, children: "Actions" }),
2822
3010
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", style: { color: t.textMuted }, children: "click to execute" })
2823
3011
  ] }),
2824
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-2", children: entry.suggested_actions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3012
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-2", children: entry.suggested_actions.map((action2, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2825
3013
  /* @__PURE__ */ jsxRuntime.jsx(
2826
3014
  InteractiveActionCard,
2827
3015
  {
2828
- action,
3016
+ action: action2,
2829
3017
  graphqlUrl: config.graphqlUrl,
2830
3018
  authToken: authToken || "",
2831
3019
  onExecute: (updatedAction) => {
@@ -2834,15 +3022,15 @@ function TerminalEntryRenderer({
2834
3022
  }
2835
3023
  }
2836
3024
  ),
2837
- action.approval && /* @__PURE__ */ jsxRuntime.jsx(
3025
+ action2.approval && /* @__PURE__ */ jsxRuntime.jsx(
2838
3026
  ApprovalTracker,
2839
3027
  {
2840
- approval: action.approval,
3028
+ approval: action2.approval,
2841
3029
  currentUserId: currentUser?.entity_id,
2842
3030
  onApprove: () => {
2843
3031
  window.dispatchEvent(
2844
3032
  new CustomEvent("terminal-approval-decision", {
2845
- detail: { action, decision: "approved", entity_id: currentUser?.entity_id },
3033
+ detail: { action: action2, decision: "approved", entity_id: currentUser?.entity_id },
2846
3034
  bubbles: true
2847
3035
  })
2848
3036
  );
@@ -2850,7 +3038,7 @@ function TerminalEntryRenderer({
2850
3038
  onReject: () => {
2851
3039
  window.dispatchEvent(
2852
3040
  new CustomEvent("terminal-approval-decision", {
2853
- detail: { action, decision: "rejected", entity_id: currentUser?.entity_id },
3041
+ detail: { action: action2, decision: "rejected", entity_id: currentUser?.entity_id },
2854
3042
  bubbles: true
2855
3043
  })
2856
3044
  );
@@ -2898,9 +3086,10 @@ function TerminalEntryRenderer({
2898
3086
  ] });
2899
3087
  const isTurnStart = !!prevEntry && isCommand && prevEntry.type !== "system";
2900
3088
  const defaultRender = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${isGrouped ? "" : "mb-5"} ${isTurnStart ? "mt-6" : ""}`, children: [
2901
- beforeWidgets.map((w) => /* @__PURE__ */ jsxRuntime.jsx(React12__default.default.Fragment, { children: w.render({ entry, index }) }, w.name)),
2902
- replaceWidget ? /* @__PURE__ */ jsxRuntime.jsx(React12__default.default.Fragment, { children: replaceWidget.render({ entry, index }) }, replaceWidget.name) : builtInContent,
2903
- afterWidgets.map((w) => /* @__PURE__ */ jsxRuntime.jsx(React12__default.default.Fragment, { children: w.render({ entry, index }) }, w.name)),
3089
+ beforeWidgets.map((w) => /* @__PURE__ */ jsxRuntime.jsx(React15__default.default.Fragment, { children: w.render({ entry, index }) }, w.name)),
3090
+ replaceWidget ? /* @__PURE__ */ jsxRuntime.jsx(React15__default.default.Fragment, { children: replaceWidget.render({ entry, index }) }, replaceWidget.name) : builtInContent,
3091
+ afterWidgets.map((w) => /* @__PURE__ */ jsxRuntime.jsx(React15__default.default.Fragment, { children: w.render({ entry, index }) }, w.name)),
3092
+ /* @__PURE__ */ jsxRuntime.jsx(AgentCompletionNotice, { completion: entry.metadata?.completion }),
2904
3093
  renderEntryExtra?.(entry, index)
2905
3094
  ] });
2906
3095
  if (renderEntry) {
@@ -2909,20 +3098,23 @@ function TerminalEntryRenderer({
2909
3098
  }
2910
3099
  return defaultRender();
2911
3100
  }
3101
+
3102
+ // src/types/terminal.types.ts
3103
+ var DEFAULT_AGENT_LABEL = "YieldFabric Agent";
2912
3104
  function LiveKGBridge({ progressState, onLiveKGUpdate }) {
2913
- const onUpdateRef = React12.useRef(onLiveKGUpdate);
3105
+ const onUpdateRef = React15.useRef(onLiveKGUpdate);
2914
3106
  onUpdateRef.current = onLiveKGUpdate;
2915
- const prevGkgRef = React12.useRef(null);
3107
+ const prevGkgRef = React15.useRef(null);
2916
3108
  const gkg = progressState?.genericKG;
2917
- React12.useEffect(() => {
3109
+ React15.useEffect(() => {
2918
3110
  if (!gkg || !onUpdateRef.current) return;
2919
3111
  if (gkg !== prevGkgRef.current) {
2920
3112
  prevGkgRef.current = gkg;
2921
3113
  onUpdateRef.current(gkg);
2922
3114
  }
2923
3115
  }, [gkg]);
2924
- const hasEmitted = React12.useRef(false);
2925
- React12.useEffect(() => {
3116
+ const hasEmitted = React15.useRef(false);
3117
+ React15.useEffect(() => {
2926
3118
  if (progressState && !hasEmitted.current && !gkg && onUpdateRef.current) {
2927
3119
  if (!prevGkgRef.current) {
2928
3120
  hasEmitted.current = true;
@@ -2937,14 +3129,17 @@ function TerminalShell({
2937
3129
  className = "",
2938
3130
  style,
2939
3131
  showHeader = true,
3132
+ agentLabel = DEFAULT_AGENT_LABEL,
2940
3133
  focusInput,
2941
3134
  setTerminalHistory,
2942
3135
  terminalBodyRef,
2943
3136
  workingGroupContext,
3137
+ showWorkingGroupBanner = true,
2944
3138
  progressState,
2945
3139
  streamTransparency,
2946
3140
  streamNowMs,
2947
3141
  isExecuting,
3142
+ showBusyIndicator,
2948
3143
  handleCancelReasoning,
2949
3144
  onViewKnowledgeGraph,
2950
3145
  onLiveKGUpdate,
@@ -2962,6 +3157,9 @@ function TerminalShell({
2962
3157
  className: `border-0 flex flex-col ${className}`,
2963
3158
  style: { minHeight: "300px", borderRadius: "12px", backgroundColor: "transparent", ...style },
2964
3159
  onClick: () => {
3160
+ if (typeof window !== "undefined" && window.matchMedia?.("(pointer: coarse)").matches) {
3161
+ return;
3162
+ }
2965
3163
  const sel = window.getSelection();
2966
3164
  if (!sel || sel.toString().length === 0) focusInput();
2967
3165
  },
@@ -2980,7 +3178,7 @@ function TerminalShell({
2980
3178
  "button",
2981
3179
  {
2982
3180
  onClick: () => setTerminalHistory([
2983
- { type: "system", content: "YieldFabric Agent", timestamp: /* @__PURE__ */ new Date() },
3181
+ { type: "system", content: agentLabel, timestamp: /* @__PURE__ */ new Date() },
2984
3182
  { type: "system", content: "Terminal cleared.", timestamp: /* @__PURE__ */ new Date() }
2985
3183
  ]),
2986
3184
  className: "hover:opacity-80",
@@ -2998,7 +3196,7 @@ function TerminalShell({
2998
3196
  className: "p-6 flex-1 overflow-y-auto scrollbar-thin scrollbar-thumb-gray-700 scrollbar-track-transparent",
2999
3197
  style: { minHeight: "200px", display: "flex", flexDirection: "column", backgroundColor: "transparent" },
3000
3198
  children: [
3001
- workingGroupContext && /* @__PURE__ */ jsxRuntime.jsxs(
3199
+ workingGroupContext && showWorkingGroupBanner && /* @__PURE__ */ jsxRuntime.jsxs(
3002
3200
  "div",
3003
3201
  {
3004
3202
  className: "mb-3 ml-1 mr-1 px-3 py-2 rounded-md text-xs flex items-center justify-between",
@@ -3023,7 +3221,7 @@ function TerminalShell({
3023
3221
  }
3024
3222
  ),
3025
3223
  /* @__PURE__ */ jsxRuntime.jsx(LiveKGBridge, { progressState, onLiveKGUpdate }),
3026
- isExecuting && !progressState && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2 px-6 py-2 flex-shrink-0 border-t", style: { color: t.text, borderColor: t.border }, children: [
3224
+ isExecuting && !progressState && showBusyIndicator !== false && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2 px-6 py-2 flex-shrink-0 border-t", style: { color: t.text, borderColor: t.border }, children: [
3027
3225
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex space-x-1", children: [
3028
3226
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 rounded-full animate-pulse", style: { backgroundColor: t.info } }),
3029
3227
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 rounded-full animate-pulse", style: { backgroundColor: t.info, animationDelay: "150ms" } }),
@@ -3039,9 +3237,9 @@ function TerminalShell({
3039
3237
  }
3040
3238
  function KGScopeDropdown({ items, onSelect, compact = false }) {
3041
3239
  const t = useTheme();
3042
- const [open, setOpen] = React12.useState(false);
3043
- const ref = React12.useRef(null);
3044
- React12.useEffect(() => {
3240
+ const [open, setOpen] = React15.useState(false);
3241
+ const ref = React15.useRef(null);
3242
+ React15.useEffect(() => {
3045
3243
  if (!open) return;
3046
3244
  const handleClick = (e) => {
3047
3245
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -3098,7 +3296,7 @@ function KGScopeDropdown({ items, onSelect, compact = false }) {
3098
3296
  }
3099
3297
  function ReasoningModeSelector({ current, onChange, compact = false }) {
3100
3298
  const t = useTheme();
3101
- const isLight = t.bgRaised === "#ffffff";
3299
+ const isLight = t.mode ? t.mode === "light" : t.bgRaised === "#ffffff";
3102
3300
  const isReason = current === "reason";
3103
3301
  const label = isReason ? "Reason" : "Auto";
3104
3302
  const title = isReason ? "Force deep reasoning \u2014 click to let the AI decide" : "AI decides \u2014 click to force deep reasoning";
@@ -3153,11 +3351,24 @@ function splitInputByMentions(command, knownMentionNames) {
3153
3351
  segments.push({ kind: "text", value: command.slice(cursor) });
3154
3352
  return segments;
3155
3353
  }
3354
+ var INPUT_MAX_HEIGHT = 120;
3355
+ function fitToContent(input) {
3356
+ resetHeight(input);
3357
+ if (!input.value.trim()) return;
3358
+ const needed = input.scrollHeight;
3359
+ input.style.height = `${Math.min(needed, INPUT_MAX_HEIGHT)}px`;
3360
+ if (needed > INPUT_MAX_HEIGHT) input.style.overflowY = "auto";
3361
+ }
3362
+ function resetHeight(input) {
3363
+ input.style.height = "auto";
3364
+ input.style.overflowY = "";
3365
+ }
3156
3366
  function TerminalInputBar({
3157
3367
  inputRef,
3158
3368
  fileInputRef,
3159
3369
  currentCommand,
3160
3370
  isExecuting,
3371
+ disabled = false,
3161
3372
  placeholder = "Ask anything...",
3162
3373
  onInputChange,
3163
3374
  onKeyDown,
@@ -3180,50 +3391,58 @@ function TerminalInputBar({
3180
3391
  inputBarExtra,
3181
3392
  modeSelector,
3182
3393
  compactToolbar = false,
3183
- submitTitle = "Send"
3394
+ submitTitle = "Send",
3395
+ autoFocus = true
3184
3396
  }) {
3185
3397
  const t = useTheme();
3186
- const isLight = t.bgRaised === "#ffffff";
3398
+ React15.useEffect(() => {
3399
+ if (!autoFocus) return;
3400
+ inputRef.current?.focus({ preventScroll: true });
3401
+ }, []);
3402
+ const [focused, setFocused] = React15__default.default.useState(false);
3403
+ const chipsVisible = focused || currentCommand.trim().length > 0;
3404
+ const isTouch = typeof window !== "undefined" && "ontouchstart" in window;
3405
+ const isLight = t.mode ? t.mode === "light" : t.bgRaised === "#ffffff";
3187
3406
  const hasCommand = Boolean(currentCommand.trim());
3188
- const placeholderColor = isLight ? "rgba(30,30,58,0.44)" : "rgba(255,255,255,0.40)";
3189
- const panelBorder = isLight ? "rgba(30,30,58,0.12)" : "rgba(255,255,255,0.10)";
3190
- const panelBg = isLight ? "rgba(255,255,255,0.82)" : "rgba(24,24,24,0.82)";
3191
- const toolbarButtonBg = isLight ? "rgba(30,30,58,0.06)" : "rgba(255,255,255,0.05)";
3192
- const toolbarButtonHover = isLight ? "rgba(30,30,58,0.11)" : "rgba(255,255,255,0.14)";
3193
- const toolbarButtonText = isLight ? "rgba(30,30,58,0.58)" : "rgba(255,255,255,0.42)";
3407
+ const placeholderColor = isLight ? t.textMuted : "rgba(255,255,255,0.52)";
3408
+ const panelBorder = isLight ? t.border : "rgba(255,255,255,0.10)";
3409
+ const panelBg = t.bgInput;
3410
+ const toolbarButtonBg = isLight ? "rgba(255,255,255,0.72)" : "rgba(255,255,255,0.05)";
3411
+ const toolbarButtonHover = isLight ? t.bgRaised : "rgba(255,255,255,0.14)";
3412
+ const toolbarButtonText = isLight ? t.textSecondary : "rgba(255,255,255,0.52)";
3194
3413
  const toolbarButtonStyle = {
3195
3414
  backgroundColor: toolbarButtonBg,
3196
- border: `1px solid ${isLight ? "rgba(30,30,58,0.08)" : "rgba(255,255,255,0.08)"}`,
3415
+ border: `1px solid ${isLight ? t.border : "rgba(255,255,255,0.08)"}`,
3197
3416
  boxShadow: "none",
3198
3417
  color: toolbarButtonText
3199
3418
  };
3200
- const toolbarRef = React12.useRef(null);
3201
- const [compact, setCompact] = React12.useState(false);
3202
- React12.useEffect(() => {
3419
+ const toolbarRef = React15.useRef(null);
3420
+ const [compact, setCompact] = React15.useState(false);
3421
+ React15.useEffect(() => {
3203
3422
  if (compactToolbar) {
3204
3423
  setCompact(true);
3205
3424
  return;
3206
3425
  }
3207
3426
  const el = toolbarRef.current;
3208
3427
  if (!el || typeof ResizeObserver === "undefined") return;
3428
+ let lastWidth = -1;
3209
3429
  const ro = new ResizeObserver((entries) => {
3210
- const w = entries[0]?.contentRect.width ?? 0;
3430
+ const w = Math.round(entries[0]?.contentRect.width ?? 0);
3431
+ if (w === lastWidth) return;
3432
+ lastWidth = w;
3211
3433
  setCompact((prev) => prev ? w < 520 : w < 480);
3212
3434
  });
3213
3435
  ro.observe(el);
3214
3436
  return () => ro.disconnect();
3215
3437
  }, [compactToolbar]);
3216
3438
  const toolbarIsCompact = compactToolbar || compact;
3217
- React12.useEffect(() => {
3439
+ React15.useEffect(() => {
3218
3440
  const input = inputRef.current;
3219
3441
  if (!input) return;
3220
- input.style.height = "auto";
3221
- if (currentCommand.trim()) {
3222
- input.style.height = Math.min(input.scrollHeight, 120) + "px";
3223
- }
3442
+ fitToContent(input);
3224
3443
  }, [currentCommand, inputRef]);
3225
3444
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3226
- /* @__PURE__ */ jsxRuntime.jsx("style", { children: `.yf-input-bar::placeholder { color: ${placeholderColor}; }` }),
3445
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: `.yf-input-bar::placeholder { color: ${placeholderColor}; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }` }),
3227
3446
  commandPaletteItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
3228
3447
  "div",
3229
3448
  {
@@ -3262,17 +3481,24 @@ function TerminalInputBar({
3262
3481
  /* @__PURE__ */ jsxRuntime.jsx(
3263
3482
  "div",
3264
3483
  {
3265
- className: `relative z-20 flex-shrink-0 px-3 pb-3 pt-2 transition-opacity duration-300 sm:px-4 ${isExecuting ? "opacity-40 pointer-events-none" : ""}`,
3484
+ className: `relative z-20 flex-shrink-0 px-3 pb-3 pt-2 transition-opacity duration-300 sm:px-4 ${isExecuting || disabled ? "opacity-40 pointer-events-none" : ""}`,
3266
3485
  children: /* @__PURE__ */ jsxRuntime.jsxs(
3267
3486
  "div",
3268
3487
  {
3269
- className: "rounded-xl border px-3 transition-colors focus-within:border-white/20 sm:px-4",
3488
+ className: `rounded-xl border px-3 transition-[box-shadow,border-color] sm:px-4 ${focused ? "yf-input-focused" : ""}`,
3270
3489
  style: {
3271
3490
  backgroundColor: panelBg,
3272
- backdropFilter: "blur(18px)",
3273
- borderColor: panelBorder,
3274
- boxShadow: isLight ? "0 18px 70px -38px rgba(30,30,58,0.45)" : "0 18px 70px -38px rgba(0,0,0,0.95)",
3275
- WebkitBackdropFilter: "blur(18px)"
3491
+ // No backdrop blur on a touch screen. It is the one compositing
3492
+ // layer between the textarea and the page, and on iPhone the
3493
+ // caret was drawn a line below and a character right of where
3494
+ // typing lands — the caret rect resolved against the wrong
3495
+ // layer — while WebKit's own layout (checked in WebKit 26) puts
3496
+ // it on the line. The box keeps its colour; only the frosted
3497
+ // fabric behind it goes, which at this size is barely a change.
3498
+ backdropFilter: isTouch ? void 0 : "blur(18px)",
3499
+ borderColor: focused ? t.primary : panelBorder,
3500
+ boxShadow: focused ? `0 0 0 3px ${t.primaryMuted || "rgba(5,78,146,0.18)"}` : isLight ? "0 18px 70px -38px rgba(30,30,58,0.45)" : "0 18px 70px -38px rgba(0,0,0,0.95)",
3501
+ WebkitBackdropFilter: isTouch ? void 0 : "blur(18px)"
3276
3502
  },
3277
3503
  children: [
3278
3504
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -3341,8 +3567,7 @@ function TerminalInputBar({
3341
3567
  onInputChange(`${prefixRaw}${e.target.value}`);
3342
3568
  onCaretChange?.(prefixRaw.length + (e.target.selectionStart ?? e.target.value.length));
3343
3569
  onTyping?.();
3344
- e.target.style.height = "auto";
3345
- e.target.style.height = Math.min(e.target.scrollHeight, 120) + "px";
3570
+ fitToContent(e.target);
3346
3571
  },
3347
3572
  onSelect: (e) => {
3348
3573
  const ta = e.currentTarget;
@@ -3369,17 +3594,34 @@ function TerminalInputBar({
3369
3594
  if (e.key === "Enter" && !e.shiftKey && !e.defaultPrevented) {
3370
3595
  e.preventDefault();
3371
3596
  onSubmit();
3372
- if (inputRef.current) inputRef.current.style.height = "auto";
3597
+ if (inputRef.current) resetHeight(inputRef.current);
3373
3598
  }
3374
3599
  },
3375
- disabled: isExecuting,
3600
+ disabled: isExecuting || disabled,
3601
+ "aria-label": placeholder ?? "Message",
3376
3602
  placeholder: isExecuting ? "Processing..." : placeholder,
3377
3603
  rows: 1,
3378
- className: "yf-input-bar flex-1 min-w-[100px] bg-transparent focus:outline-none text-[16px] leading-6 resize-none overflow-hidden sm:text-[13px] sm:leading-normal",
3604
+ className: "yf-input-bar flex-1 min-w-[100px] bg-transparent focus:outline-none text-[16px] leading-6 resize-none overflow-hidden sm:text-sm sm:leading-5",
3605
+ onFocus: () => {
3606
+ setFocused(true);
3607
+ if (!("ontouchstart" in window)) return;
3608
+ window.setTimeout(() => {
3609
+ const ta = inputRef.current;
3610
+ if (!ta || document.activeElement !== ta) return;
3611
+ let scroller = ta.parentElement;
3612
+ while (scroller && !/(auto|scroll)/.test(getComputedStyle(scroller).overflowY)) scroller = scroller.parentElement;
3613
+ window.scrollBy(0, 1);
3614
+ if (scroller) scroller.scrollTop += 1;
3615
+ window.requestAnimationFrame(() => {
3616
+ window.scrollBy(0, -1);
3617
+ if (scroller) scroller.scrollTop -= 1;
3618
+ });
3619
+ }, 400);
3620
+ },
3621
+ onBlur: () => setFocused(false),
3379
3622
  style: { color: t.text, caretColor: t.cursor },
3380
3623
  spellCheck: false,
3381
3624
  autoComplete: "off",
3382
- autoFocus: true,
3383
3625
  tabIndex: 0
3384
3626
  }
3385
3627
  )
@@ -3388,67 +3630,85 @@ function TerminalInputBar({
3388
3630
  "button",
3389
3631
  {
3390
3632
  type: "submit",
3391
- disabled: !hasCommand || isExecuting,
3392
- className: "h-10 w-10 rounded-xl disabled:opacity-45 disabled:cursor-not-allowed flex items-center justify-center transition-all duration-200 shrink-0 sm:h-8 sm:w-8",
3633
+ disabled: !hasCommand || isExecuting || disabled,
3634
+ className: "h-10 w-10 rounded-xl disabled:opacity-60 disabled:cursor-not-allowed flex items-center justify-center transition-all duration-200 shrink-0 sm:h-8 sm:w-8",
3393
3635
  style: {
3394
- backgroundColor: hasCommand ? "rgba(255,140,66,0.95)" : isLight ? "rgba(30,30,58,0.07)" : "rgba(255,255,255,0.08)",
3395
- color: hasCommand ? "#181818" : isLight ? "rgba(30,30,58,0.58)" : "rgba(255,255,255,0.72)"
3636
+ backgroundColor: isLight ? t.primary : hasCommand ? t.primary : "rgba(255,255,255,0.08)",
3637
+ // `textInverse` is the theme's "text on a filled button".
3638
+ // `bgBase` was used here before and is `transparent` in
3639
+ // every app theme — so the chevron vanished the moment
3640
+ // there was something to send.
3641
+ // In LIGHT mode this is always a solid accent fill with white
3642
+ // on it (6.1:1). It is the app's primary verb and the single
3643
+ // most-pressed control; a pale disc — grey, or a 10% tint —
3644
+ // read as disabled even when it was not. The empty state is
3645
+ // already expressed by `disabled:opacity-60`, so the fill does
3646
+ // not also have to whisper. Dark keeps its white-alpha rest,
3647
+ // where a solid orange disc would shout on near-black.
3648
+ color: isLight ? t.textInverse : hasCommand ? t.textInverse : "rgba(255,255,255,0.72)"
3396
3649
  },
3397
3650
  onMouseEnter: (e) => {
3398
- e.currentTarget.style.backgroundColor = hasCommand ? "#ffb37a" : toolbarButtonHover;
3651
+ if (hasCommand) {
3652
+ e.currentTarget.style.filter = "brightness(1.15)";
3653
+ } else {
3654
+ e.currentTarget.style.backgroundColor = toolbarButtonHover;
3655
+ }
3399
3656
  },
3400
3657
  onMouseLeave: (e) => {
3401
- e.currentTarget.style.backgroundColor = hasCommand ? "rgba(255,140,66,0.95)" : isLight ? "rgba(30,30,58,0.07)" : "rgba(255,255,255,0.08)";
3658
+ e.currentTarget.style.filter = "";
3659
+ e.currentTarget.style.backgroundColor = isLight ? t.primary : hasCommand ? t.primary : "rgba(255,255,255,0.08)";
3402
3660
  },
3403
3661
  title: submitTitle,
3404
3662
  "aria-label": submitTitle,
3405
- children: isExecuting ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-3 h-3 rounded-full animate-spin", style: { border: `1.5px solid ${hasCommand ? "rgba(24,24,24,0.7)" : t.textMuted}`, borderTopColor: "transparent" } }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-5 w-5 sm:h-4 sm:w-4" })
3663
+ children: isExecuting ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-3 h-3 rounded-full animate-spin", style: { border: `1.5px solid ${hasCommand ? t.textInverse : t.textMuted}`, borderTopColor: "transparent" } }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-5 w-5 sm:h-4 sm:w-4" })
3406
3664
  }
3407
3665
  )
3408
3666
  ] });
3409
3667
  })(),
3410
3668
  /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: toolbarRef, className: "flex items-center justify-between pt-2.5 gap-2", children: [
3411
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] min-w-0 flex-wrap", children: [
3412
- /* @__PURE__ */ jsxRuntime.jsx(
3413
- "button",
3414
- {
3415
- type: "button",
3416
- onClick: () => {
3417
- onInputChange("@");
3418
- inputRef.current?.focus();
3419
- },
3420
- title: "Insert @ mention",
3421
- className: `${toolbarIsCompact ? "px-2" : "px-2.5"} py-1 rounded-lg transition-colors font-medium flex-shrink-0`,
3422
- style: toolbarButtonStyle,
3423
- onMouseEnter: (e) => {
3424
- e.currentTarget.style.backgroundColor = toolbarButtonHover;
3425
- },
3426
- onMouseLeave: (e) => {
3427
- e.currentTarget.style.backgroundColor = toolbarButtonBg;
3428
- },
3429
- children: toolbarIsCompact ? "@" : "@ mention"
3430
- }
3431
- ),
3432
- /* @__PURE__ */ jsxRuntime.jsx(
3433
- "button",
3434
- {
3435
- type: "button",
3436
- onClick: () => {
3437
- onInputChange("/");
3438
- inputRef.current?.focus();
3439
- },
3440
- title: "Insert / command",
3441
- className: `${toolbarIsCompact ? "px-2" : "px-2.5"} py-1 rounded-lg transition-colors font-medium flex-shrink-0`,
3442
- style: toolbarButtonStyle,
3443
- onMouseEnter: (e) => {
3444
- e.currentTarget.style.backgroundColor = toolbarButtonHover;
3445
- },
3446
- onMouseLeave: (e) => {
3447
- e.currentTarget.style.backgroundColor = toolbarButtonBg;
3448
- },
3449
- children: toolbarIsCompact ? "/" : "/ commands"
3450
- }
3451
- ),
3669
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-[11px] min-w-0 flex-wrap", children: [
3670
+ chipsVisible && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3671
+ /* @__PURE__ */ jsxRuntime.jsx(
3672
+ "button",
3673
+ {
3674
+ type: "button",
3675
+ onClick: () => {
3676
+ onInputChange("@");
3677
+ inputRef.current?.focus();
3678
+ },
3679
+ title: "Insert @ mention",
3680
+ className: `${toolbarIsCompact ? "px-2" : "px-2.5"} py-1 min-h-[40px] sm:min-h-0 inline-flex items-center rounded-lg transition-colors font-semibold flex-shrink-0`,
3681
+ style: toolbarButtonStyle,
3682
+ onMouseEnter: (e) => {
3683
+ e.currentTarget.style.backgroundColor = toolbarButtonHover;
3684
+ },
3685
+ onMouseLeave: (e) => {
3686
+ e.currentTarget.style.backgroundColor = toolbarButtonBg;
3687
+ },
3688
+ children: toolbarIsCompact ? "@" : "@ mention"
3689
+ }
3690
+ ),
3691
+ /* @__PURE__ */ jsxRuntime.jsx(
3692
+ "button",
3693
+ {
3694
+ type: "button",
3695
+ onClick: () => {
3696
+ onInputChange("/");
3697
+ inputRef.current?.focus();
3698
+ },
3699
+ title: "Insert / command",
3700
+ className: `${toolbarIsCompact ? "px-2" : "px-2.5"} py-1 min-h-[40px] sm:min-h-0 inline-flex items-center rounded-lg transition-colors font-semibold flex-shrink-0`,
3701
+ style: toolbarButtonStyle,
3702
+ onMouseEnter: (e) => {
3703
+ e.currentTarget.style.backgroundColor = toolbarButtonHover;
3704
+ },
3705
+ onMouseLeave: (e) => {
3706
+ e.currentTarget.style.backgroundColor = toolbarButtonBg;
3707
+ },
3708
+ children: toolbarIsCompact ? "/" : "/ commands"
3709
+ }
3710
+ )
3711
+ ] }),
3452
3712
  availableKGs && availableKGs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: activeKGScope ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 px-2 py-0.5 rounded-md text-[10px] min-w-0", title: activeKGScope.label, style: { backgroundColor: "rgba(255,140,66,0.08)", border: "1px solid rgba(255,140,66,0.15)", color: "rgba(255,140,66,0.8)" }, children: [
3453
3713
  /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "w-3 h-3 opacity-60 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: [
3454
3714
  /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101" }),
@@ -3462,7 +3722,7 @@ function TerminalInputBar({
3462
3722
  ] }),
3463
3723
  /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => onKGScopeChange?.(null), className: "ml-0.5 opacity-40 hover:opacity-100 transition-opacity", children: "\u2715" })
3464
3724
  ] }) : /* @__PURE__ */ jsxRuntime.jsx(KGScopeDropdown, { items: availableKGs, onSelect: (scope) => onKGScopeChange?.(scope), compact: toolbarIsCompact }) }),
3465
- modeSelector ?? (onReasoningModeChange && /* @__PURE__ */ jsxRuntime.jsx(ReasoningModeSelector, { current: reasoningMode || null, onChange: onReasoningModeChange, compact: toolbarIsCompact }))
3725
+ chipsVisible && (modeSelector ?? (onReasoningModeChange && /* @__PURE__ */ jsxRuntime.jsx(ReasoningModeSelector, { current: reasoningMode || null, onChange: onReasoningModeChange, compact: toolbarIsCompact })))
3466
3726
  ] }),
3467
3727
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 flex-shrink-0", children: [
3468
3728
  inputBarExtra,
@@ -3470,8 +3730,8 @@ function TerminalInputBar({
3470
3730
  "button",
3471
3731
  {
3472
3732
  type: "button",
3473
- disabled: isExecuting,
3474
- className: "h-8 w-8 rounded-xl disabled:opacity-30 disabled:cursor-not-allowed flex items-center justify-center transition-all duration-200",
3733
+ disabled: isExecuting || disabled,
3734
+ className: "h-10 w-10 sm:h-8 sm:w-8 rounded-xl disabled:opacity-30 disabled:cursor-not-allowed flex items-center justify-center transition-all duration-200",
3475
3735
  style: toolbarButtonStyle,
3476
3736
  title: "Upload files",
3477
3737
  onClick: () => fileInputRef.current?.click(),
@@ -3488,8 +3748,8 @@ function TerminalInputBar({
3488
3748
  "button",
3489
3749
  {
3490
3750
  type: "button",
3491
- disabled: isExecuting,
3492
- className: "h-8 w-8 rounded-xl disabled:opacity-30 disabled:cursor-not-allowed flex items-center justify-center transition-all duration-200",
3751
+ disabled: isExecuting || disabled,
3752
+ className: "h-10 w-10 sm:h-8 sm:w-8 rounded-xl disabled:opacity-30 disabled:cursor-not-allowed flex items-center justify-center transition-all duration-200",
3493
3753
  style: toolbarButtonStyle,
3494
3754
  title: "List files",
3495
3755
  onClick: () => onListFilesCommand(),
@@ -3520,7 +3780,7 @@ var KIND_DOT = {
3520
3780
  };
3521
3781
  function SlashMentionPicker({ candidates, selectedIndex, onPick }) {
3522
3782
  const t = useTheme();
3523
- const isLight = t.bgRaised === "#ffffff";
3783
+ const isLight = t.mode ? t.mode === "light" : t.bgRaised === "#ffffff";
3524
3784
  if (candidates.length === 0) return null;
3525
3785
  return /* @__PURE__ */ jsxRuntime.jsxs(
3526
3786
  "div",
@@ -3575,13 +3835,13 @@ function SlashMentionPicker({ candidates, selectedIndex, onPick }) {
3575
3835
  );
3576
3836
  }
3577
3837
  function useCommandHistory() {
3578
- const [commandHistory, setCommandHistory] = React12.useState([]);
3579
- const [historyIndex, setHistoryIndex] = React12.useState(-1);
3580
- const pushCommand = React12.useCallback((cmd) => {
3838
+ const [commandHistory, setCommandHistory] = React15.useState([]);
3839
+ const [historyIndex, setHistoryIndex] = React15.useState(-1);
3840
+ const pushCommand = React15.useCallback((cmd) => {
3581
3841
  setCommandHistory((prev) => [...prev, cmd]);
3582
3842
  setHistoryIndex(-1);
3583
3843
  }, []);
3584
- const navigateUp = React12.useCallback(
3844
+ const navigateUp = React15.useCallback(
3585
3845
  (setCurrentCommand) => {
3586
3846
  if (commandHistory.length === 0) return;
3587
3847
  const newIndex = historyIndex === -1 ? commandHistory.length - 1 : Math.max(0, historyIndex - 1);
@@ -3590,7 +3850,7 @@ function useCommandHistory() {
3590
3850
  },
3591
3851
  [commandHistory, historyIndex]
3592
3852
  );
3593
- const navigateDown = React12.useCallback(
3853
+ const navigateDown = React15.useCallback(
3594
3854
  (setCurrentCommand) => {
3595
3855
  if (historyIndex === -1) return;
3596
3856
  const newIndex = historyIndex + 1;
@@ -3604,21 +3864,20 @@ function useCommandHistory() {
3604
3864
  },
3605
3865
  [commandHistory, historyIndex]
3606
3866
  );
3607
- const resetIndex = React12.useCallback(() => {
3867
+ const resetIndex = React15.useCallback(() => {
3608
3868
  setHistoryIndex(-1);
3609
3869
  }, []);
3610
3870
  return { commandHistory, historyIndex, pushCommand, navigateUp, navigateDown, resetIndex };
3611
3871
  }
3612
- function useFocusManagement() {
3613
- const inputRef = React12.useRef(null);
3614
- const focusInput = React12.useCallback(() => {
3872
+ function useFocusManagement(autoFocus = true) {
3873
+ const inputRef = React15.useRef(null);
3874
+ const focusInput = React15.useCallback(() => {
3615
3875
  const selection = window.getSelection();
3616
3876
  if (selection && selection.toString().length > 0) return;
3617
- if (inputRef.current) {
3618
- inputRef.current.focus();
3619
- }
3877
+ inputRef.current?.focus({ preventScroll: true });
3620
3878
  }, []);
3621
- React12.useEffect(() => {
3879
+ React15.useEffect(() => {
3880
+ if (!autoFocus) return;
3622
3881
  const timer = setTimeout(focusInput, 100);
3623
3882
  const handleVisibilityChange = () => {
3624
3883
  if (!document.hidden) {
@@ -3630,11 +3889,12 @@ function useFocusManagement() {
3630
3889
  clearTimeout(timer);
3631
3890
  document.removeEventListener("visibilitychange", handleVisibilityChange);
3632
3891
  };
3633
- }, [focusInput]);
3892
+ }, [focusInput, autoFocus]);
3634
3893
  return { inputRef, focusInput };
3635
3894
  }
3636
3895
  function useStreamingChat({
3637
3896
  config,
3897
+ authToken,
3638
3898
  onStreamRequest,
3639
3899
  reasoningMode,
3640
3900
  setTerminalHistory,
@@ -3643,35 +3903,47 @@ function useStreamingChat({
3643
3903
  currentUser,
3644
3904
  sourceKGNodes
3645
3905
  }) {
3646
- const sourceKGNodesRef = React12.useRef(sourceKGNodes);
3906
+ const authTokenRef = React15.useRef(authToken);
3907
+ authTokenRef.current = authToken;
3908
+ const sourceKGNodesRef = React15.useRef(sourceKGNodes);
3647
3909
  sourceKGNodesRef.current = sourceKGNodes;
3648
- const reasoningModeRef = React12.useRef(reasoningMode);
3910
+ const reasoningModeRef = React15.useRef(reasoningMode);
3649
3911
  reasoningModeRef.current = reasoningMode;
3650
- const [isExecuting, setIsExecuting] = React12.useState(false);
3651
- const [isStreaming, setIsStreaming] = React12.useState(false);
3652
- const [progressState, setProgressState] = React12.useState(null);
3653
- const [activityEvents, setActivityEvents] = React12.useState([]);
3654
- const [streamTransparency, setStreamTransparency] = React12.useState(null);
3655
- const [streamNowMs, setStreamNowMs] = React12.useState(Date.now());
3656
- const [collaborationState, setCollaborationState] = React12.useState(null);
3657
- const [liveKgId, setLiveKgId] = React12.useState(null);
3658
- const [liveRunId, setLiveRunId] = React12.useState(null);
3659
- const [liveThreadId, setLiveThreadId] = React12.useState(null);
3660
- const progressStateRef = React12.useRef(null);
3661
- const lastExecutedCommand = React12.useRef(null);
3662
- const isProcessingRef = React12.useRef(false);
3663
- const currentStreamingLineId = React12.useRef(null);
3664
- const liveRunIdRef = React12.useRef(null);
3912
+ const [isExecuting, setIsExecuting] = React15.useState(false);
3913
+ const turnSequence = React15.useRef(0);
3914
+ const [isStreaming, setIsStreaming] = React15.useState(false);
3915
+ const [progressState, setProgressState] = React15.useState(null);
3916
+ const [activityEvents, setActivityEvents] = React15.useState([]);
3917
+ const [streamTransparency, setStreamTransparency] = React15.useState(null);
3918
+ const [streamNowMs, setStreamNowMs] = React15.useState(Date.now());
3919
+ const [collaborationState, setCollaborationState] = React15.useState(null);
3920
+ const [liveKgId, setLiveKgId] = React15.useState(null);
3921
+ const [liveRunId, setLiveRunId] = React15.useState(null);
3922
+ const [liveThreadId, setLiveThreadId] = React15.useState(null);
3923
+ const progressStateRef = React15.useRef(null);
3924
+ const lastExecutedCommand = React15.useRef(null);
3925
+ const isProcessingRef = React15.useRef(false);
3926
+ const currentStreamingLineId = React15.useRef(null);
3927
+ const liveRunIdRef = React15.useRef(null);
3665
3928
  liveRunIdRef.current = liveRunId;
3666
- React12.useEffect(() => {
3929
+ const mountEpoch = React15.useRef(0);
3930
+ React15.useEffect(() => {
3931
+ const epoch = ++mountEpoch.current;
3932
+ return () => {
3933
+ void Promise.resolve().then(() => {
3934
+ if (mountEpoch.current === epoch) currentStreamingLineId.current = null;
3935
+ });
3936
+ };
3937
+ }, []);
3938
+ React15.useEffect(() => {
3667
3939
  progressStateRef.current = progressState;
3668
3940
  }, [progressState]);
3669
- React12.useEffect(() => {
3941
+ React15.useEffect(() => {
3670
3942
  if (!isExecuting && !isStreaming) return;
3671
3943
  const t = setInterval(() => setStreamNowMs(Date.now()), 1e3);
3672
3944
  return () => clearInterval(t);
3673
3945
  }, [isExecuting, isStreaming]);
3674
- const setStreamingLineSender = React12.useCallback(
3946
+ const setStreamingLineSender = React15.useCallback(
3675
3947
  (lineId, sender) => {
3676
3948
  setTerminalHistory((prev) => {
3677
3949
  const idx = prev.findIndex((line) => line.id === lineId);
@@ -3684,7 +3956,7 @@ function useStreamingChat({
3684
3956
  },
3685
3957
  [setTerminalHistory]
3686
3958
  );
3687
- const updateStreamingLine = React12.useCallback(
3959
+ const updateStreamingLine = React15.useCallback(
3688
3960
  (lineId, newContent, suggestions, suggestedActions, reasoningSnapshot, pipelineDraft, sources, kgId, runId) => {
3689
3961
  setTerminalHistory((prev) => {
3690
3962
  const idx = prev.findIndex((line) => line.id === lineId);
@@ -3706,7 +3978,7 @@ function useStreamingChat({
3706
3978
  },
3707
3979
  [setTerminalHistory]
3708
3980
  );
3709
- const resetStreamState = React12.useCallback(() => {
3981
+ const resetStreamState = React15.useCallback(() => {
3710
3982
  setIsStreaming(false);
3711
3983
  setStreamTransparency(null);
3712
3984
  setIsExecuting(false);
@@ -3715,46 +3987,55 @@ function useStreamingChat({
3715
3987
  currentStreamingLineId.current = null;
3716
3988
  setTimeout(() => focusInput(), 50);
3717
3989
  }, [focusInput]);
3718
- const handleHilSubmit = React12.useCallback(
3719
- async (message) => {
3720
- const runId = liveRunIdRef.current;
3721
- if (!runId) return;
3722
- const apiUrl = config.agentsApiUrl || "http://localhost:3001";
3723
- try {
3724
- if (message && message.trim().length > 0) {
3725
- await fetch(`${apiUrl}/pipelines/${runId}/input`, {
3726
- method: "POST",
3727
- headers: { "Content-Type": "application/json" },
3728
- body: JSON.stringify({ kind: "guidance", content: message })
3729
- });
3730
- }
3731
- await fetch(`${apiUrl}/pipelines/${runId}/input`, {
3732
- method: "POST",
3733
- headers: { "Content-Type": "application/json" },
3734
- body: JSON.stringify({ kind: "proceed" })
3735
- });
3736
- } catch (e) {
3737
- console.error("Failed to send pipeline input:", e);
3738
- }
3739
- },
3740
- [config.agentsApiUrl]
3741
- );
3742
- const handleCancelReasoning = React12.useCallback(async () => {
3990
+ const postPipelineAction = React15.useCallback(async (runId, action2, body) => {
3991
+ const headers = config.getAuthHeaders?.() ?? (authTokenRef.current ? { Authorization: `Bearer ${authTokenRef.current}` } : {});
3992
+ const response = await fetch(`${config.agentsApiUrl || "http://localhost:3001"}/pipelines/${runId}/${action2}`, {
3993
+ method: "POST",
3994
+ headers: { "Content-Type": "application/json", ...headers },
3995
+ body: body === void 0 ? void 0 : JSON.stringify(body)
3996
+ });
3997
+ if (!response.ok) throw new Error(`The request was not accepted (${response.status}). Please try again.`);
3998
+ }, [config]);
3999
+ const handleHilSubmit = React15.useCallback(async (message) => {
3743
4000
  const runId = liveRunIdRef.current;
3744
4001
  if (!runId) return;
3745
- const apiUrl = config.agentsApiUrl || "http://localhost:3001";
3746
- setProgressState(null);
3747
- resetStreamState();
3748
4002
  try {
3749
- await fetch(`${apiUrl}/pipelines/${runId}/cancel`, {
3750
- method: "POST",
3751
- headers: { "Content-Type": "application/json" }
3752
- });
3753
- } catch (e) {
3754
- console.error("Failed to cancel pipeline:", e);
4003
+ if (message.trim()) await postPipelineAction(runId, "input", { kind: "guidance", content: message });
4004
+ await postPipelineAction(runId, "input", { kind: "proceed" });
4005
+ } catch (error) {
4006
+ addTerminalLine("error", `Your input was not sent. ${error.message}`);
3755
4007
  }
3756
- }, [config.agentsApiUrl, resetStreamState]);
3757
- const handleStreamingChat = React12.useCallback(
4008
+ }, [postPipelineAction, addTerminalLine]);
4009
+ const handleCancelReasoning = React15.useCallback(async () => {
4010
+ const runId = liveRunIdRef.current;
4011
+ if (!runId) return;
4012
+ try {
4013
+ await postPipelineAction(runId, "cancel");
4014
+ setProgressState(null);
4015
+ resetStreamState();
4016
+ addTerminalLine("info", "Stopped the analysis.");
4017
+ } catch (error) {
4018
+ addTerminalLine("error", `The analysis is still running. ${error.message}`);
4019
+ }
4020
+ }, [postPipelineAction, resetStreamState, addTerminalLine]);
4021
+ const settleAgentSteps = React15.useCallback(
4022
+ (lineId) => {
4023
+ setTerminalHistory((prev) => {
4024
+ const idx = prev.findIndex((line) => line.id === lineId);
4025
+ if (idx === -1) return prev;
4026
+ const meta = prev[idx].metadata;
4027
+ if (!meta?.agentStepsLive) return prev;
4028
+ const updated = [...prev];
4029
+ updated[idx] = {
4030
+ ...updated[idx],
4031
+ metadata: { ...updated[idx].metadata || {}, agentStepsLive: false }
4032
+ };
4033
+ return updated;
4034
+ });
4035
+ },
4036
+ [setTerminalHistory]
4037
+ );
4038
+ const handleStreamingChat = React15.useCallback(
3758
4039
  async (cmd) => {
3759
4040
  if (isProcessingRef.current || !onStreamRequest) return;
3760
4041
  if (lastExecutedCommand.current === cmd) return;
@@ -3765,8 +4046,9 @@ function useStreamingChat({
3765
4046
  const startMs = Date.now();
3766
4047
  setStreamTransparency({ startedAtMs: startMs, lastEventAtMs: startMs });
3767
4048
  setActivityEvents([]);
3768
- const userCommandId = Date.now().toString();
3769
- const streamingLineId = (Date.now() + 1).toString();
4049
+ const turnKey = `${Date.now()}-${++turnSequence.current}`;
4050
+ const userCommandId = `${turnKey}:question`;
4051
+ const streamingLineId = `${turnKey}:answer`;
3770
4052
  currentStreamingLineId.current = streamingLineId;
3771
4053
  const userCommandEntry = {
3772
4054
  id: userCommandId,
@@ -3792,14 +4074,14 @@ function useStreamingChat({
3792
4074
  setTerminalHistory((prev) => [
3793
4075
  ...prev,
3794
4076
  {
3795
- id: (Date.now() + 2).toString(),
4077
+ id: `${turnKey}:before-question`,
3796
4078
  type: "info",
3797
4079
  content: "",
3798
4080
  timestamp: /* @__PURE__ */ new Date()
3799
4081
  },
3800
4082
  userCommandEntry,
3801
4083
  {
3802
- id: (Date.now() + 3).toString(),
4084
+ id: `${turnKey}:before-answer`,
3803
4085
  type: "info",
3804
4086
  content: "",
3805
4087
  timestamp: /* @__PURE__ */ new Date()
@@ -3813,10 +4095,37 @@ function useStreamingChat({
3813
4095
  let sources;
3814
4096
  let kgId;
3815
4097
  let runId;
4098
+ const steps = /* @__PURE__ */ new Map();
4099
+ const fail = (error) => {
4100
+ if (currentStreamingLineId.current !== streamingLineId) return;
4101
+ settleAgentSteps(streamingLineId);
4102
+ updateStreamingLine(
4103
+ streamingLineId,
4104
+ fullResponse,
4105
+ pageSuggestions,
4106
+ suggestedActions,
4107
+ progressStateRef.current ? captureReasoningSnapshot(progressStateRef.current, true) : void 0,
4108
+ pipelineDraft,
4109
+ sources,
4110
+ kgId,
4111
+ runId
4112
+ );
4113
+ setTerminalHistory((prev) => prev.map((entry) => entry.id === streamingLineId ? { ...entry, metadata: { ...entry.metadata, completion: { stop_reason: /connection|interrupt/i.test(error) ? "interrupted" : "failed" } } } : entry));
4114
+ addTerminalLine("error", error);
4115
+ setProgressState(null);
4116
+ resetStreamState();
4117
+ };
3816
4118
  try {
3817
4119
  await onStreamRequest(cmd, {
3818
4120
  onChunk: (chunk) => {
4121
+ if (currentStreamingLineId.current !== streamingLineId) return;
4122
+ if (chunk.entryMetadata) {
4123
+ setTerminalHistory((prev) => prev.map((entry) => entry.id === streamingLineId ? { ...entry, metadata: { ...entry.metadata, ...chunk.entryMetadata } } : entry));
4124
+ }
3819
4125
  const eventMs = Date.now();
4126
+ if (chunk.completion) {
4127
+ setTerminalHistory((prev) => prev.map((entry) => entry.id === streamingLineId ? { ...entry, metadata: { ...entry.metadata, completion: chunk.completion } } : entry));
4128
+ }
3820
4129
  if (chunk.sender) {
3821
4130
  setStreamingLineSender(streamingLineId, chunk.sender);
3822
4131
  if (currentUser) {
@@ -3829,6 +4138,28 @@ function useStreamingChat({
3829
4138
  if (chunk.collaboration) {
3830
4139
  setCollaborationState(chunk.collaboration);
3831
4140
  }
4141
+ if (chunk.step) {
4142
+ steps.set(chunk.step.seq, chunk.step);
4143
+ const ordered = Array.from(steps.values()).sort((a, b) => a.seq - b.seq);
4144
+ setTerminalHistory((prev) => {
4145
+ const idx = prev.findIndex((line) => line.id === streamingLineId);
4146
+ if (idx === -1) return prev;
4147
+ const updated = [...prev];
4148
+ updated[idx] = {
4149
+ ...updated[idx],
4150
+ metadata: {
4151
+ ...updated[idx].metadata || {},
4152
+ agentSteps: ordered,
4153
+ // Explicit rather than inferred from the streaming cursor:
4154
+ // a tool loop runs to completion BEFORE the first answer
4155
+ // token, so during the whole loop the entry's content is
4156
+ // empty and carries no cursor to read.
4157
+ agentStepsLive: true
4158
+ }
4159
+ };
4160
+ return updated;
4161
+ });
4162
+ }
3832
4163
  const ckgId = extractKgId(chunk, chunk.progress);
3833
4164
  const cRunId = chunk.run_id || chunk.progress?.run_id;
3834
4165
  const ctId = chunk.thread_id || chunk.progress?.thread_id || chunk.reasoning_thread_id || chunk.progress?.reasoning_thread_id;
@@ -3972,49 +4303,14 @@ function useStreamingChat({
3972
4303
  kgId,
3973
4304
  runId
3974
4305
  );
4306
+ settleAgentSteps(streamingLineId);
3975
4307
  resetStreamState();
3976
4308
  }
3977
4309
  },
3978
- onError: (error) => {
3979
- if (currentStreamingLineId.current === streamingLineId) {
3980
- if (progressStateRef.current) {
3981
- const snap = captureReasoningSnapshot(
3982
- progressStateRef.current,
3983
- true
3984
- );
3985
- updateStreamingLine(
3986
- streamingLineId,
3987
- fullResponse || "",
3988
- void 0,
3989
- void 0,
3990
- snap
3991
- );
3992
- setProgressState(null);
3993
- } else {
3994
- addTerminalLine("error", `STREAMING ERROR: ${error}`);
3995
- setProgressState(null);
3996
- }
3997
- resetStreamState();
3998
- }
3999
- }
4310
+ onError: fail
4000
4311
  }, reasoningModeRef.current ? { reasoningMode: reasoningModeRef.current } : void 0);
4001
4312
  } catch (error) {
4002
- if (progressStateRef.current && currentStreamingLineId.current) {
4003
- const snap = captureReasoningSnapshot(
4004
- progressStateRef.current,
4005
- true
4006
- );
4007
- updateStreamingLine(
4008
- currentStreamingLineId.current,
4009
- fullResponse || "",
4010
- void 0,
4011
- void 0,
4012
- snap
4013
- );
4014
- }
4015
- addTerminalLine("error", `STREAMING EXCEPTION: ${error.message}`);
4016
- setProgressState(null);
4017
- resetStreamState();
4313
+ fail(error?.message || "The answer could not be completed.");
4018
4314
  }
4019
4315
  },
4020
4316
  [
@@ -4023,10 +4319,12 @@ function useStreamingChat({
4023
4319
  updateStreamingLine,
4024
4320
  setStreamingLineSender,
4025
4321
  resetStreamState,
4026
- addTerminalLine
4322
+ addTerminalLine,
4323
+ settleAgentSteps,
4324
+ currentUser
4027
4325
  ]
4028
4326
  );
4029
- const clearReasoningSession = React12.useCallback(() => {
4327
+ const clearReasoningSession = React15.useCallback(() => {
4030
4328
  setLiveKgId(null);
4031
4329
  setLiveRunId(null);
4032
4330
  setLiveThreadId(null);
@@ -4057,9 +4355,9 @@ function useMessagePolling({
4057
4355
  pollIntervalMs = 3e3,
4058
4356
  enabled
4059
4357
  }) {
4060
- const lastMessageIdRef = React12.useRef(void 0);
4061
- const pollingRef = React12.useRef(false);
4062
- const poll = React12.useCallback(async () => {
4358
+ const lastMessageIdRef = React15.useRef(void 0);
4359
+ const pollingRef = React15.useRef(false);
4360
+ const poll = React15.useCallback(async () => {
4063
4361
  if (!onPollMessages || pollingRef.current) return;
4064
4362
  pollingRef.current = true;
4065
4363
  try {
@@ -4098,7 +4396,7 @@ function useMessagePolling({
4098
4396
  pollingRef.current = false;
4099
4397
  }
4100
4398
  }, [onPollMessages, setTerminalHistory]);
4101
- React12.useEffect(() => {
4399
+ React15.useEffect(() => {
4102
4400
  if (!enabled || !onPollMessages) return;
4103
4401
  const timer = setInterval(poll, pollIntervalMs);
4104
4402
  return () => clearInterval(timer);
@@ -4116,6 +4414,7 @@ function useTerminalCore({
4116
4414
  onReasoningModeChangeProp,
4117
4415
  reasoningRef,
4118
4416
  workingGroupContextProp = null,
4417
+ autoFocusInput = true,
4119
4418
  onResolveWorkingGroup,
4120
4419
  onRagFileUpload,
4121
4420
  onListRagFiles,
@@ -4133,14 +4432,15 @@ function useTerminalCore({
4133
4432
  pollIntervalMs,
4134
4433
  authToken
4135
4434
  }) {
4136
- const [internalReasoningMode, setInternalReasoningMode] = React12.useState(null);
4435
+ const agentLabel = config.agentLabel?.trim() || DEFAULT_AGENT_LABEL;
4436
+ const [internalReasoningMode, setInternalReasoningMode] = React15.useState(null);
4137
4437
  const reasoningMode = reasoningModeProp !== void 0 ? reasoningModeProp : internalReasoningMode;
4138
4438
  const onReasoningModeChange = onReasoningModeChangeProp || setInternalReasoningMode;
4139
- const [terminalHistory, setTerminalHistory] = React12.useState(() => {
4439
+ const [terminalHistory, setTerminalHistory] = React15.useState(() => {
4140
4440
  if (initialHistory && initialHistory.length > 0) return initialHistory;
4141
- return [{ type: "system", content: "YieldFabric Agent", timestamp: /* @__PURE__ */ new Date() }];
4441
+ return [{ type: "system", content: agentLabel, timestamp: /* @__PURE__ */ new Date() }];
4142
4442
  });
4143
- React12.useEffect(() => {
4443
+ React15.useEffect(() => {
4144
4444
  if (historyRef) {
4145
4445
  historyRef.current = { setHistory: setTerminalHistory, setIsExecuting };
4146
4446
  }
@@ -4148,10 +4448,10 @@ function useTerminalCore({
4148
4448
  if (historyRef) historyRef.current = null;
4149
4449
  };
4150
4450
  }, [historyRef]);
4151
- const enrichedHistory = React12.useMemo(() => {
4451
+ const enrichedHistory = React15.useMemo(() => {
4152
4452
  if (!sourceKGNodes?.length) return terminalHistory;
4153
4453
  let changed = false;
4154
- const result = terminalHistory.map((entry) => {
4454
+ const result2 = terminalHistory.map((entry) => {
4155
4455
  if ((entry.type === "response" || entry.type === "success") && entry.content && entry.content.length > 20 && !entry.sources?.length) {
4156
4456
  const sources = extractKGSources(entry.content, sourceKGNodes);
4157
4457
  if (sources.length > 0) {
@@ -4161,9 +4461,9 @@ function useTerminalCore({
4161
4461
  }
4162
4462
  return entry;
4163
4463
  });
4164
- return changed ? result : terminalHistory;
4464
+ return changed ? result2 : terminalHistory;
4165
4465
  }, [terminalHistory, sourceKGNodes]);
4166
- React12.useEffect(() => {
4466
+ React15.useEffect(() => {
4167
4467
  if (initialHistory && initialHistory.length > 0) {
4168
4468
  setTerminalHistory((prev) => {
4169
4469
  const isDefault = prev.length <= 1 && prev[0]?.type === "system";
@@ -4171,35 +4471,39 @@ function useTerminalCore({
4171
4471
  });
4172
4472
  }
4173
4473
  }, [initialHistory]);
4174
- React12.useEffect(() => {
4474
+ React15.useEffect(() => {
4175
4475
  onHistoryChange?.(enrichedHistory);
4176
4476
  }, [enrichedHistory, onHistoryChange]);
4177
- const addTerminalLine = React12.useCallback((type, content, pageSuggestions) => {
4477
+ const addTerminalLine = React15.useCallback((type, content, pageSuggestions) => {
4178
4478
  setTerminalHistory((prev) => [...prev, { id: Date.now().toString(), type, content, timestamp: /* @__PURE__ */ new Date(), suggestions: pageSuggestions }]);
4179
4479
  }, []);
4180
- const addTerminalLineWithActions = React12.useCallback((content, actions) => {
4480
+ const addTerminalLineWithActions = React15.useCallback((content, actions) => {
4181
4481
  setTerminalHistory((prev) => [...prev, { id: Date.now().toString(), type: "response", content, timestamp: /* @__PURE__ */ new Date(), suggested_actions: actions }]);
4182
4482
  }, []);
4183
- const [currentCommand, setCurrentCommand] = React12.useState("");
4184
- const [workingGroupContext, setWorkingGroupContext] = React12.useState(workingGroupContextProp);
4185
- const [hasShownWelcome, setHasShownWelcome] = React12.useState(false);
4186
- const [isInputFocused, setIsInputFocused] = React12.useState(true);
4187
- const [commandPaletteItems, setCommandPaletteItems] = React12.useState([]);
4188
- const [selectedPaletteItem, setSelectedPaletteItem] = React12.useState(0);
4189
- const terminalBodyRef = React12.useRef(null);
4190
- const fileInputRef = React12.useRef(null);
4191
- const uploadAbortsRef = React12.useRef([]);
4192
- React12.useEffect(() => () => {
4483
+ const [currentCommand, setCurrentCommand] = React15.useState("");
4484
+ const [pendingSubmit, setPendingSubmit] = React15.useState(null);
4485
+ const [workingGroupContext, setWorkingGroupContext] = React15.useState(workingGroupContextProp);
4486
+ const [hasShownWelcome, setHasShownWelcome] = React15.useState(false);
4487
+ const [isInputFocused, setIsInputFocused] = React15.useState(true);
4488
+ const [commandPaletteItems, setCommandPaletteItems] = React15.useState([]);
4489
+ const [selectedPaletteItem, setSelectedPaletteItem] = React15.useState(0);
4490
+ const terminalBodyRef = React15.useRef(null);
4491
+ const fileInputRef = React15.useRef(null);
4492
+ const uploadAbortsRef = React15.useRef([]);
4493
+ React15.useEffect(() => () => {
4193
4494
  for (const ctrl of uploadAbortsRef.current) ctrl.abort();
4194
4495
  uploadAbortsRef.current = [];
4195
4496
  }, []);
4196
- const { inputRef, focusInput } = useFocusManagement();
4197
- React12.useEffect(() => {
4497
+ const { inputRef, focusInput } = useFocusManagement(autoFocusInput);
4498
+ React15.useEffect(() => {
4198
4499
  function onPrefill(e) {
4199
4500
  const detail = e.detail;
4200
4501
  if (!detail || typeof detail.value !== "string") return;
4201
4502
  const value = detail.value;
4202
4503
  setCurrentCommand(value);
4504
+ if (e.detail?.submit) {
4505
+ setPendingSubmit(value);
4506
+ }
4203
4507
  requestAnimationFrame(() => {
4204
4508
  focusInput();
4205
4509
  const el = inputRef.current;
@@ -4213,6 +4517,9 @@ function useTerminalCore({
4213
4517
  window.removeEventListener("yieldfabric:terminal:prefill", onPrefill);
4214
4518
  };
4215
4519
  }, [focusInput, inputRef]);
4520
+ const restoreInputFocus = React15.useCallback(() => {
4521
+ if (autoFocusInput) focusInput();
4522
+ }, [autoFocusInput, focusInput]);
4216
4523
  const {
4217
4524
  isExecuting,
4218
4525
  setIsExecuting,
@@ -4232,15 +4539,16 @@ function useTerminalCore({
4232
4539
  activityEvents
4233
4540
  } = useStreamingChat({
4234
4541
  config,
4542
+ authToken,
4235
4543
  onStreamRequest,
4236
4544
  reasoningMode,
4237
4545
  setTerminalHistory,
4238
4546
  addTerminalLine,
4239
- focusInput,
4547
+ focusInput: restoreInputFocus,
4240
4548
  currentUser,
4241
4549
  sourceKGNodes
4242
4550
  });
4243
- React12.useEffect(() => {
4551
+ React15.useEffect(() => {
4244
4552
  const handler = () => {
4245
4553
  setCurrentCommand("");
4246
4554
  onReasoningModeChange(null);
@@ -4256,7 +4564,7 @@ function useTerminalCore({
4256
4564
  pollIntervalMs: pollIntervalMs ?? 3e3,
4257
4565
  enabled: !!onPollMessages
4258
4566
  });
4259
- React12.useEffect(() => {
4567
+ React15.useEffect(() => {
4260
4568
  if (reasoningRef) {
4261
4569
  reasoningRef.current = { progressState, submitInput: handleHilSubmit, cancelReasoning: handleCancelReasoning };
4262
4570
  }
@@ -4264,25 +4572,25 @@ function useTerminalCore({
4264
4572
  if (reasoningRef) reasoningRef.current = null;
4265
4573
  };
4266
4574
  });
4267
- React12.useEffect(() => {
4575
+ React15.useEffect(() => {
4268
4576
  if (liveKgId) {
4269
4577
  onKGScopeChange?.({ kgId: liveKgId, label: "Live Analysis" });
4270
4578
  onKgIdChange?.(liveKgId);
4271
4579
  }
4272
4580
  }, [liveKgId]);
4273
- React12.useEffect(() => {
4581
+ React15.useEffect(() => {
4274
4582
  if (liveRunId) onRunIdChange?.(liveRunId);
4275
4583
  }, [liveRunId]);
4276
- React12.useEffect(() => {
4584
+ React15.useEffect(() => {
4277
4585
  if (liveThreadId) onThreadIdChange?.(liveThreadId);
4278
4586
  }, [liveThreadId]);
4279
- React12.useEffect(() => {
4587
+ React15.useEffect(() => {
4280
4588
  onReasoningPhaseChange?.(progressState?.phase ?? null);
4281
4589
  }, [progressState?.phase]);
4282
- React12.useEffect(() => {
4590
+ React15.useEffect(() => {
4283
4591
  setWorkingGroupContext(workingGroupContextProp || null);
4284
4592
  }, [workingGroupContextProp]);
4285
- React12.useEffect(() => {
4593
+ React15.useEffect(() => {
4286
4594
  let cancelled = false;
4287
4595
  if (!onResolveWorkingGroup) return;
4288
4596
  (async () => {
@@ -4297,26 +4605,26 @@ function useTerminalCore({
4297
4605
  cancelled = true;
4298
4606
  };
4299
4607
  }, [onResolveWorkingGroup]);
4300
- React12.useEffect(() => {
4608
+ React15.useEffect(() => {
4301
4609
  const handleActionResult = (event) => {
4302
- const result = event.detail;
4303
- if (result.success) {
4610
+ const result2 = event.detail;
4611
+ if (result2.success) {
4304
4612
  addTerminalLine("success", "Action executed successfully!");
4305
- if (result.data) addTerminalLine("response", JSON.stringify(result.data, null, 2));
4613
+ if (result2.data) addTerminalLine("response", JSON.stringify(result2.data, null, 2));
4306
4614
  } else {
4307
- addTerminalLine("error", `Action failed: ${result.error || "Unknown error"}`);
4615
+ addTerminalLine("error", `Action failed: ${result2.error || "Unknown error"}`);
4308
4616
  }
4309
4617
  };
4310
4618
  window.addEventListener("terminal-action-result", handleActionResult);
4311
4619
  return () => window.removeEventListener("terminal-action-result", handleActionResult);
4312
4620
  }, [addTerminalLine]);
4313
- React12.useEffect(() => {
4621
+ React15.useEffect(() => {
4314
4622
  if (showWelcomeMessage && initialHistory.length === 0 && !hasShownWelcome && config.welcomeMessage) {
4315
4623
  setHasShownWelcome(true);
4316
4624
  const fullMessage = config.welcomeMessage;
4317
4625
  const typingLineId = Date.now().toString();
4318
4626
  setTerminalHistory([
4319
- { type: "system", content: "YieldFabric Agent", timestamp: /* @__PURE__ */ new Date() },
4627
+ { type: "system", content: agentLabel, timestamp: /* @__PURE__ */ new Date() },
4320
4628
  { id: typingLineId, type: "info", content: "", timestamp: /* @__PURE__ */ new Date() }
4321
4629
  ]);
4322
4630
  let i = 0;
@@ -4329,10 +4637,10 @@ function useTerminalCore({
4329
4637
  requestAnimationFrame(step);
4330
4638
  }
4331
4639
  }, [showWelcomeMessage, hasShownWelcome, initialHistory.length, config.welcomeMessage]);
4332
- React12.useEffect(() => {
4640
+ React15.useEffect(() => {
4333
4641
  if (terminalBodyRef.current) terminalBodyRef.current.scrollTop = terminalBodyRef.current.scrollHeight;
4334
4642
  }, [terminalHistory, progressState]);
4335
- const updateCommandPalette = React12.useCallback((value) => {
4643
+ const updateCommandPalette = React15.useCallback((value) => {
4336
4644
  if (value.startsWith("/")) {
4337
4645
  const query = value.slice(1);
4338
4646
  setCommandPaletteItems(filterCommands(query, getBuiltInCommands(), config.customCommands || []));
@@ -4342,7 +4650,7 @@ function useTerminalCore({
4342
4650
  setCommandPaletteItems([]);
4343
4651
  return false;
4344
4652
  }, [config.customCommands]);
4345
- const handleCommandPaletteKeyDown = React12.useCallback((e) => {
4653
+ const handleCommandPaletteKeyDown = React15.useCallback((e) => {
4346
4654
  if (commandPaletteItems.length === 0) return false;
4347
4655
  if (e.key === "ArrowUp") {
4348
4656
  e.preventDefault();
@@ -4370,15 +4678,15 @@ function useTerminalCore({
4370
4678
  }
4371
4679
  return false;
4372
4680
  }, [commandPaletteItems, selectedPaletteItem]);
4373
- const handleClearCommand = React12.useCallback(() => {
4681
+ const handleClearCommand = React15.useCallback(() => {
4374
4682
  setTerminalHistory([
4375
- { type: "system", content: "YieldFabric Agent", timestamp: /* @__PURE__ */ new Date() },
4683
+ { type: "system", content: agentLabel, timestamp: /* @__PURE__ */ new Date() },
4376
4684
  { type: "system", content: "Terminal cleared.", timestamp: /* @__PURE__ */ new Date() }
4377
4685
  ]);
4378
4686
  setCurrentCommand("");
4379
4687
  setTimeout(() => focusInput(), 50);
4380
4688
  }, [focusInput]);
4381
- const handleUploadCommand = React12.useCallback(() => {
4689
+ const handleUploadCommand = React15.useCallback(() => {
4382
4690
  if (!onRagFileUpload) {
4383
4691
  addTerminalLine("error", "Upload not enabled in this terminal.");
4384
4692
  } else {
@@ -4387,7 +4695,7 @@ function useTerminalCore({
4387
4695
  setCurrentCommand("");
4388
4696
  setTimeout(() => focusInput(), 50);
4389
4697
  }, [onRagFileUpload, addTerminalLine, focusInput]);
4390
- const handleUploadFiles = React12.useCallback(async (files) => {
4698
+ const handleUploadFiles = React15.useCallback(async (files) => {
4391
4699
  if (!files?.length || !onRagFileUpload) return;
4392
4700
  const names = files.map((f) => f.name).join(", ");
4393
4701
  addTerminalLine("info", "");
@@ -4395,11 +4703,11 @@ function useTerminalCore({
4395
4703
  addTerminalLine("info", `Uploading ${files.length} file(s)...`);
4396
4704
  setIsExecuting(true);
4397
4705
  try {
4398
- const result = await onRagFileUpload(files, workingGroupContext);
4399
- if (result.success) {
4400
- addTerminalLine("success", `Started ${result.pipelineRuns?.length ?? result.documentsIngested ?? files.length} ingestion pipeline(s)`);
4401
- if (result.message) addTerminalLine("response", result.message);
4402
- const runs = result.pipelineRuns ?? [];
4706
+ const result2 = await onRagFileUpload(files, workingGroupContext);
4707
+ if (result2.success) {
4708
+ addTerminalLine("success", `Started ${result2.pipelineRuns?.length ?? result2.documentsIngested ?? files.length} ingestion pipeline(s)`);
4709
+ if (result2.message) addTerminalLine("response", result2.message);
4710
+ const runs = result2.pipelineRuns ?? [];
4403
4711
  if (runs.length > 0) {
4404
4712
  const apiUrl = config.agentsApiUrl || "http://localhost:3001";
4405
4713
  const remaining = new Set(runs.map((r) => r.run_id));
@@ -4486,7 +4794,7 @@ function useTerminalCore({
4486
4794
  await handleListFilesCommand();
4487
4795
  }
4488
4796
  } else {
4489
- addTerminalLine("error", `Upload failed${result.message ? `: ${result.message}` : ""}`);
4797
+ addTerminalLine("error", `Upload failed${result2.message ? `: ${result2.message}` : ""}`);
4490
4798
  }
4491
4799
  } catch (error) {
4492
4800
  addTerminalLine("error", `Upload exception: ${error?.message || "Unknown error"}`);
@@ -4495,8 +4803,8 @@ function useTerminalCore({
4495
4803
  if (fileInputRef.current) fileInputRef.current.value = "";
4496
4804
  setTimeout(() => focusInput(), 50);
4497
4805
  }
4498
- }, [onRagFileUpload, onListRagFiles, workingGroupContext, addTerminalLine, setIsExecuting, focusInput, config.agentsApiUrl]);
4499
- const handleListFilesCommand = React12.useCallback(async () => {
4806
+ }, [onRagFileUpload, onListRagFiles, workingGroupContext, addTerminalLine, setIsExecuting, focusInput, config.agentsApiUrl, authToken]);
4807
+ const handleListFilesCommand = React15.useCallback(async () => {
4500
4808
  addTerminalLine("info", "");
4501
4809
  addTerminalLine("command", "files");
4502
4810
  if (!onListRagFiles) {
@@ -4505,12 +4813,12 @@ function useTerminalCore({
4505
4813
  }
4506
4814
  setIsExecuting(true);
4507
4815
  try {
4508
- const result = await onListRagFiles(workingGroupContext);
4509
- if (!result.success) {
4510
- addTerminalLine("error", `Could not load files${result.message ? `: ${result.message}` : ""}`);
4816
+ const result2 = await onListRagFiles(workingGroupContext);
4817
+ if (!result2.success) {
4818
+ addTerminalLine("error", `Could not load files${result2.message ? `: ${result2.message}` : ""}`);
4511
4819
  return;
4512
4820
  }
4513
- const files = result.files || [];
4821
+ const files = result2.files || [];
4514
4822
  if (files.length === 0) {
4515
4823
  addTerminalLine("info", "No files uploaded yet for this page working group.");
4516
4824
  return;
@@ -4530,7 +4838,7 @@ function useTerminalCore({
4530
4838
  setIsExecuting(false);
4531
4839
  }
4532
4840
  }, [onListRagFiles, workingGroupContext, addTerminalLine, addTerminalLineWithActions, setIsExecuting]);
4533
- const handleTerminalActionExecute = React12.useCallback(async (updatedAction) => {
4841
+ const handleTerminalActionExecute = React15.useCallback(async (updatedAction) => {
4534
4842
  const actionType = updatedAction?.action_type;
4535
4843
  const payload = updatedAction?.payload || {};
4536
4844
  if (actionType === "delete_file") {
@@ -4539,12 +4847,12 @@ function useTerminalCore({
4539
4847
  return;
4540
4848
  }
4541
4849
  const title = payload.title || payload.document_id;
4542
- const result = await onDeleteRagFile(String(payload.document_id), workingGroupContext);
4543
- if (result.success) {
4850
+ const result2 = await onDeleteRagFile(String(payload.document_id), workingGroupContext);
4851
+ if (result2.success) {
4544
4852
  addTerminalLine("success", `Removed ${title}`);
4545
4853
  await handleListFilesCommand();
4546
4854
  } else {
4547
- addTerminalLine("error", `Failed to remove ${title}${result.message ? `: ${result.message}` : ""}`);
4855
+ addTerminalLine("error", `Failed to remove ${title}${result2.message ? `: ${result2.message}` : ""}`);
4548
4856
  }
4549
4857
  return;
4550
4858
  }
@@ -4554,9 +4862,9 @@ function useTerminalCore({
4554
4862
  return;
4555
4863
  }
4556
4864
  const title = payload.title || payload.document_id;
4557
- const result = await onDownloadRagFile(String(payload.document_id), title, workingGroupContext);
4558
- if (result.success) addTerminalLine("success", `Download started: ${title}`);
4559
- else addTerminalLine("error", `Download failed for ${title}${result.message ? `: ${result.message}` : ""}`);
4865
+ const result2 = await onDownloadRagFile(String(payload.document_id), title, workingGroupContext);
4866
+ if (result2.success) addTerminalLine("success", `Download started: ${title}`);
4867
+ else addTerminalLine("error", `Download failed for ${title}${result2.message ? `: ${result2.message}` : ""}`);
4560
4868
  return;
4561
4869
  }
4562
4870
  if (actionType === "resume_pipeline_run") {
@@ -4595,6 +4903,8 @@ function useTerminalCore({
4595
4903
  window.dispatchEvent(new CustomEvent("terminal-action-execute", { detail: updatedAction, bubbles: true }));
4596
4904
  }, [onDeleteRagFile, onDownloadRagFile, workingGroupContext, addTerminalLine, handleListFilesCommand, config.agentsApiUrl]);
4597
4905
  return {
4906
+ // Identity
4907
+ agentLabel,
4598
4908
  // History
4599
4909
  terminalHistory,
4600
4910
  setTerminalHistory,
@@ -4623,6 +4933,8 @@ function useTerminalCore({
4623
4933
  // Command input
4624
4934
  currentCommand,
4625
4935
  setCurrentCommand,
4936
+ pendingSubmit,
4937
+ setPendingSubmit,
4626
4938
  commandPaletteItems,
4627
4939
  setCommandPaletteItems,
4628
4940
  selectedPaletteItem,
@@ -4653,10 +4965,10 @@ function useSlashMentionPicker({
4653
4965
  enabledCommands = ["note", "personal"],
4654
4966
  requireSlashCommand = true
4655
4967
  }) {
4656
- const [candidates, setCandidates] = React12.useState([]);
4657
- const [selectedIndex, setSelectedIndex] = React12.useState(0);
4658
- const debounceRef = React12.useRef(null);
4659
- const reqIdRef = React12.useRef(0);
4968
+ const [candidates, setCandidates] = React15.useState([]);
4969
+ const [selectedIndex, setSelectedIndex] = React15.useState(0);
4970
+ const debounceRef = React15.useRef(null);
4971
+ const reqIdRef = React15.useRef(0);
4660
4972
  const extracted = extractQuery(
4661
4973
  currentCommand,
4662
4974
  caretIndex,
@@ -4666,7 +4978,7 @@ function useSlashMentionPicker({
4666
4978
  const query = extracted?.query ?? null;
4667
4979
  const command = extracted?.command;
4668
4980
  const queryActive = query !== null && !!onMentionResolve;
4669
- React12.useEffect(() => {
4981
+ React15.useEffect(() => {
4670
4982
  if (!queryActive) {
4671
4983
  setCandidates([]);
4672
4984
  setSelectedIndex(0);
@@ -4689,17 +5001,17 @@ function useSlashMentionPicker({
4689
5001
  if (debounceRef.current) clearTimeout(debounceRef.current);
4690
5002
  };
4691
5003
  }, [queryActive, query, command, onMentionResolve]);
4692
- const navigateUp = React12.useCallback(() => {
5004
+ const navigateUp = React15.useCallback(() => {
4693
5005
  setSelectedIndex((i) => Math.max(0, i - 1));
4694
5006
  }, []);
4695
- const navigateDown = React12.useCallback(() => {
5007
+ const navigateDown = React15.useCallback(() => {
4696
5008
  setSelectedIndex((i) => Math.min((candidates.length || 1) - 1, i + 1));
4697
5009
  }, [candidates.length]);
4698
- const cancel = React12.useCallback(() => {
5010
+ const cancel = React15.useCallback(() => {
4699
5011
  setCandidates([]);
4700
5012
  setSelectedIndex(0);
4701
5013
  }, []);
4702
- const complete = React12.useCallback(
5014
+ const complete = React15.useCallback(
4703
5015
  (candidate) => {
4704
5016
  if (query === null) return null;
4705
5017
  const head = currentCommand.slice(0, caretIndex);
@@ -4745,6 +5057,7 @@ function extractQuery(input, caret, enabledCommands, requireSlashCommand) {
4745
5057
  return { query: tail, command: cmd };
4746
5058
  }
4747
5059
  function StandardTerminal({
5060
+ showBusyIndicator,
4748
5061
  theme: themeOverrides,
4749
5062
  config,
4750
5063
  onCommandExecute,
@@ -4764,9 +5077,15 @@ function StandardTerminal({
4764
5077
  onDeleteRagFile,
4765
5078
  onDownloadRagFile,
4766
5079
  workingGroupContext: workingGroupContextProp = null,
5080
+ showWorkingGroupBanner = true,
5081
+ autoFocusInput = true,
5082
+ inputPlaceholder,
5083
+ submitRequest,
5084
+ onSubmitRequest,
4767
5085
  onPipelineDraftEdit,
4768
5086
  onPipelineDraftReject,
4769
5087
  onSubmitNote,
5088
+ onSubmitLog,
4770
5089
  onMentionResolve,
4771
5090
  onMentionPicked,
4772
5091
  availableKGs,
@@ -4787,6 +5106,7 @@ function StandardTerminal({
4787
5106
  widgets,
4788
5107
  slots,
4789
5108
  onSourcesActivate,
5109
+ onSourceActivate,
4790
5110
  onPollMessages,
4791
5111
  pollIntervalMs,
4792
5112
  historyRef
@@ -4802,6 +5122,7 @@ function StandardTerminal({
4802
5122
  reasoningRef,
4803
5123
  workingGroupContextProp,
4804
5124
  onResolveWorkingGroup,
5125
+ autoFocusInput,
4805
5126
  onRagFileUpload,
4806
5127
  onListRagFiles,
4807
5128
  onDeleteRagFile,
@@ -4817,17 +5138,32 @@ function StandardTerminal({
4817
5138
  showWelcomeMessage
4818
5139
  });
4819
5140
  const { pushCommand, navigateUp, navigateDown, resetIndex } = useCommandHistory();
4820
- const [suggestions, setSuggestions] = React12.useState([]);
4821
- const [selectedSuggestion, setSelectedSuggestion] = React12.useState(0);
4822
- const [internalAuthToken, setInternalAuthToken] = React12.useState(authToken);
4823
- const authTokenRef = React12.useRef(internalAuthToken);
5141
+ const consumedRequest = React15.useRef(null);
5142
+ React15__default.default.useEffect(() => {
5143
+ if (!submitRequest || consumedRequest.current === submitRequest.id || !submitRequest.value.trim() || !onStreamRequest || core.isExecuting || core.isStreaming || core.currentStreamingLineId.current) return;
5144
+ consumedRequest.current = submitRequest.id;
5145
+ onSubmitRequest?.(submitRequest.id);
5146
+ void core.handleStreamingChat(submitRequest.value.trim());
5147
+ }, [
5148
+ submitRequest,
5149
+ onSubmitRequest,
5150
+ onStreamRequest,
5151
+ core.isExecuting,
5152
+ core.isStreaming,
5153
+ core.currentStreamingLineId,
5154
+ core.handleStreamingChat
5155
+ ]);
5156
+ const [suggestions, setSuggestions] = React15.useState([]);
5157
+ const [selectedSuggestion, setSelectedSuggestion] = React15.useState(0);
5158
+ const [internalAuthToken, setInternalAuthToken] = React15.useState(authToken);
5159
+ const authTokenRef = React15.useRef(internalAuthToken);
4824
5160
  authTokenRef.current = internalAuthToken;
4825
- React12__default.default.useEffect(() => {
5161
+ React15__default.default.useEffect(() => {
4826
5162
  if (authToken !== internalAuthToken) setInternalAuthToken(authToken);
4827
5163
  }, [authToken]);
4828
- const [caretIndex, setCaretIndex] = React12.useState(0);
4829
- const [slashPickedNames, setSlashPickedNames] = React12.useState([]);
4830
- const liveSlashPickedNames = React12__default.default.useMemo(
5164
+ const [caretIndex, setCaretIndex] = React15.useState(0);
5165
+ const [slashPickedNames, setSlashPickedNames] = React15.useState([]);
5166
+ const liveSlashPickedNames = React15__default.default.useMemo(
4831
5167
  () => slashPickedNames.filter(
4832
5168
  (n) => core.currentCommand.toLowerCase().includes(`@${n.toLowerCase()}`)
4833
5169
  ),
@@ -4914,6 +5250,11 @@ function StandardTerminal({
4914
5250
  setSuggestions([]);
4915
5251
  }
4916
5252
  };
5253
+ React15__default.default.useEffect(() => {
5254
+ if (!core.pendingSubmit) return;
5255
+ core.setPendingSubmit(null);
5256
+ void handleSubmit();
5257
+ }, [core.pendingSubmit]);
4917
5258
  const handleSubmit = async () => {
4918
5259
  if (!core.currentCommand.trim() || core.isExecuting || core.isStreaming || core.currentStreamingLineId.current) return;
4919
5260
  const rawCmd = core.currentCommand.trim();
@@ -4961,6 +5302,21 @@ function StandardTerminal({
4961
5302
  setTimeout(() => core.focusInput(), 50);
4962
5303
  return;
4963
5304
  }
5305
+ if (command === "log") {
5306
+ const prose = args.join(" ");
5307
+ core.addTerminalLine("command", prose.trim() ? `log ${prose}` : "log");
5308
+ if (!onSubmitLog) {
5309
+ core.addTerminalLine("error", "Work capture is not available in this context.");
5310
+ } else if (!prose.trim()) {
5311
+ core.addTerminalLine("info", "Usage: /log <what you did or decided>");
5312
+ } else {
5313
+ const result2 = await onSubmitLog(prose);
5314
+ core.addTerminalLine(result2.ok ? "success" : "error", result2.message);
5315
+ }
5316
+ core.setCurrentCommand("");
5317
+ setTimeout(() => core.focusInput(), 50);
5318
+ return;
5319
+ }
4964
5320
  if (isNaturalLanguage(cmd, config.endpoints) && onStreamRequest) {
4965
5321
  await core.handleStreamingChat(cmd);
4966
5322
  core.setCurrentCommand("");
@@ -5016,8 +5372,8 @@ function StandardTerminal({
5016
5372
  );
5017
5373
  return;
5018
5374
  }
5019
- const result = await onSubmitNote(prose, scope);
5020
- core.addTerminalLine(result.ok ? "success" : "error", result.message);
5375
+ const result2 = await onSubmitNote(prose, scope);
5376
+ core.addTerminalLine(result2.ok ? "success" : "error", result2.message);
5021
5377
  };
5022
5378
  const handleTokenCommand = (args) => {
5023
5379
  core.addTerminalLine("command", `token ${args.join(" ")}`);
@@ -5045,18 +5401,18 @@ Method: ${parsed.endpoint.method}
5045
5401
  Path: ${parsed.endpoint.path}`);
5046
5402
  core.addTerminalLine("info", "");
5047
5403
  try {
5048
- const result = await onCommandExecute(cmd, parsed.endpoint, parsed.args);
5049
- if (result.success) {
5050
- core.addTerminalLine("success", result.message || "RESPONSE: SUCCESS");
5051
- if (result.data) core.addTerminalLine("response", JSON.stringify(result.data, null, 2));
5052
- if (parsed.endpoint.id.includes("login") && result.data?.token) {
5053
- setInternalAuthToken(result.data.token);
5054
- onAuthTokenChange?.(result.data.token);
5404
+ const result2 = await onCommandExecute(cmd, parsed.endpoint, parsed.args);
5405
+ if (result2.success) {
5406
+ core.addTerminalLine("success", result2.message || "RESPONSE: SUCCESS");
5407
+ if (result2.data) core.addTerminalLine("response", JSON.stringify(result2.data, null, 2));
5408
+ if (parsed.endpoint.id.includes("login") && result2.data?.token) {
5409
+ setInternalAuthToken(result2.data.token);
5410
+ onAuthTokenChange?.(result2.data.token);
5055
5411
  core.addTerminalLine("success", "AUTH TOKEN AUTO-SAVED");
5056
5412
  }
5057
5413
  } else {
5058
- core.addTerminalLine("error", `ERROR: ${result.error || "Request failed"}`);
5059
- if (result.data) core.addTerminalLine("response", JSON.stringify(result.data, null, 2));
5414
+ core.addTerminalLine("error", `ERROR: ${result2.error || "Request failed"}`);
5415
+ if (result2.data) core.addTerminalLine("response", JSON.stringify(result2.data, null, 2));
5060
5416
  }
5061
5417
  } catch (error) {
5062
5418
  core.addTerminalLine("error", `SYSTEM ERROR: ${error.message}`);
@@ -5079,14 +5435,17 @@ Path: ${parsed.endpoint.path}`);
5079
5435
  className,
5080
5436
  style,
5081
5437
  showHeader,
5438
+ agentLabel: core.agentLabel,
5082
5439
  focusInput: core.focusInput,
5083
5440
  setTerminalHistory: core.setTerminalHistory,
5084
5441
  terminalBodyRef: core.terminalBodyRef,
5085
5442
  workingGroupContext: core.workingGroupContext,
5443
+ showWorkingGroupBanner,
5086
5444
  progressState: core.progressState,
5087
5445
  streamTransparency: core.streamTransparency,
5088
5446
  streamNowMs: core.streamNowMs,
5089
5447
  isExecuting: core.isExecuting,
5448
+ showBusyIndicator,
5090
5449
  handleCancelReasoning: core.handleCancelReasoning,
5091
5450
  onViewKnowledgeGraph,
5092
5451
  onLiveKGUpdate,
@@ -5161,11 +5520,12 @@ Path: ${parsed.endpoint.path}`);
5161
5520
  inputBar: /* @__PURE__ */ jsxRuntime.jsx(
5162
5521
  TerminalInputBar,
5163
5522
  {
5523
+ autoFocus: autoFocusInput,
5164
5524
  inputRef: core.inputRef,
5165
5525
  fileInputRef: core.fileInputRef,
5166
5526
  currentCommand: core.currentCommand,
5167
5527
  isExecuting: core.isExecuting,
5168
- placeholder: activeKGScope ? `Ask about ${activeKGScope.label}...` : "Ask anything...",
5528
+ placeholder: activeKGScope ? `Ask about ${activeKGScope.label}...` : inputPlaceholder ?? "Ask anything...",
5169
5529
  onInputChange: handleInputChange,
5170
5530
  onKeyDown: handleKeyDown,
5171
5531
  onSubmit: handleSubmit,
@@ -5202,6 +5562,7 @@ Path: ${parsed.endpoint.path}`);
5202
5562
  authToken: authTokenRef.current,
5203
5563
  onPageNavigation,
5204
5564
  onSourcesActivate,
5565
+ onSourceActivate,
5205
5566
  renderEntryExtra,
5206
5567
  renderEntry,
5207
5568
  widgets,
@@ -5315,8 +5676,8 @@ function MentionDropdown({
5315
5676
  const name = (p.display_name || p.entity_id).toLowerCase();
5316
5677
  return name.includes(query.toLowerCase());
5317
5678
  });
5318
- const selectedRef = React12.useRef(null);
5319
- React12.useEffect(() => {
5679
+ const selectedRef = React15.useRef(null);
5680
+ React15.useEffect(() => {
5320
5681
  selectedRef.current?.scrollIntoView({ block: "nearest" });
5321
5682
  }, [selectedIndex]);
5322
5683
  if (filtered.length === 0) return null;
@@ -5377,8 +5738,8 @@ var ALL_TARGET = {
5377
5738
  type: "special"
5378
5739
  };
5379
5740
  function useMentions(currentCommand, participants, mentionTargets) {
5380
- const [selectedMentionIndex, setSelectedMentionIndex] = React12.useState(0);
5381
- const allCandidates = React12.useMemo(() => {
5741
+ const [selectedMentionIndex, setSelectedMentionIndex] = React15.useState(0);
5742
+ const allCandidates = React15.useMemo(() => {
5382
5743
  const map = /* @__PURE__ */ new Map();
5383
5744
  if (participants) {
5384
5745
  for (const p of participants) {
@@ -5409,7 +5770,7 @@ function useMentions(currentCommand, participants, mentionTargets) {
5409
5770
  return list;
5410
5771
  }, [participants, mentionTargets]);
5411
5772
  const hasCandidates = allCandidates.length > 0;
5412
- const mentionQuery = React12.useMemo(() => {
5773
+ const mentionQuery = React15.useMemo(() => {
5413
5774
  if (!hasCandidates) return null;
5414
5775
  const atIdx = currentCommand.lastIndexOf("@");
5415
5776
  if (atIdx === -1) return null;
@@ -5418,7 +5779,7 @@ function useMentions(currentCommand, participants, mentionTargets) {
5418
5779
  if (query.includes(" ") && query.trim().length > 0) return null;
5419
5780
  return query;
5420
5781
  }, [currentCommand, hasCandidates]);
5421
- const mentionCandidates = React12.useMemo(() => {
5782
+ const mentionCandidates = React15.useMemo(() => {
5422
5783
  if (mentionQuery === null) return [];
5423
5784
  const q = mentionQuery.toLowerCase();
5424
5785
  return allCandidates.filter(
@@ -5426,18 +5787,18 @@ function useMentions(currentCommand, participants, mentionTargets) {
5426
5787
  );
5427
5788
  }, [mentionQuery, allCandidates]);
5428
5789
  const safeIndex = mentionCandidates.length > 0 ? Math.min(selectedMentionIndex, mentionCandidates.length - 1) : 0;
5429
- const navigateMentionUp = React12.useCallback(() => {
5790
+ const navigateMentionUp = React15.useCallback(() => {
5430
5791
  setSelectedMentionIndex((prev) => Math.max(0, prev - 1));
5431
5792
  }, []);
5432
- const navigateMentionDown = React12.useCallback(() => {
5793
+ const navigateMentionDown = React15.useCallback(() => {
5433
5794
  setSelectedMentionIndex(
5434
5795
  (prev) => Math.min((mentionCandidates.length || 1) - 1, prev + 1)
5435
5796
  );
5436
5797
  }, [mentionCandidates.length]);
5437
- const resetMentionIndex = React12.useCallback(() => {
5798
+ const resetMentionIndex = React15.useCallback(() => {
5438
5799
  setSelectedMentionIndex(0);
5439
5800
  }, []);
5440
- const completeMention = React12.useCallback(
5801
+ const completeMention = React15.useCallback(
5441
5802
  (candidate) => {
5442
5803
  const atIdx = currentCommand.lastIndexOf("@");
5443
5804
  if (atIdx === -1) return currentCommand;
@@ -5446,7 +5807,7 @@ function useMentions(currentCommand, participants, mentionTargets) {
5446
5807
  },
5447
5808
  [currentCommand]
5448
5809
  );
5449
- const parseMentions = React12.useCallback(
5810
+ const parseMentions = React15.useCallback(
5450
5811
  (cmd) => {
5451
5812
  if (allCandidates.length === 0) return [];
5452
5813
  const sortedCandidates = [...allCandidates].sort(
@@ -5492,6 +5853,7 @@ function useMentions(currentCommand, participants, mentionTargets) {
5492
5853
  };
5493
5854
  }
5494
5855
  function ChatTerminal({
5856
+ showBusyIndicator,
5495
5857
  theme: themeOverrides,
5496
5858
  config,
5497
5859
  className = "",
@@ -5507,6 +5869,8 @@ function ChatTerminal({
5507
5869
  onDeleteRagFile,
5508
5870
  onDownloadRagFile,
5509
5871
  workingGroupContext: workingGroupContextProp = null,
5872
+ showWorkingGroupBanner = true,
5873
+ autoFocusInput = true,
5510
5874
  onPipelineDraftEdit,
5511
5875
  onPipelineDraftReject,
5512
5876
  onPageNavigation,
@@ -5529,6 +5893,7 @@ function ChatTerminal({
5529
5893
  widgets,
5530
5894
  slots,
5531
5895
  onSourcesActivate,
5896
+ onSourceActivate,
5532
5897
  historyRef,
5533
5898
  currentUser,
5534
5899
  onSendMessage,
@@ -5538,8 +5903,10 @@ function ChatTerminal({
5538
5903
  typingUsers,
5539
5904
  onTyping,
5540
5905
  onSubmitNote,
5906
+ onSubmitLog,
5541
5907
  onMentionResolve,
5542
- onMentionPicked
5908
+ onMentionPicked,
5909
+ authToken
5543
5910
  }) {
5544
5911
  const core = useTerminalCore({
5545
5912
  config,
@@ -5552,6 +5919,7 @@ function ChatTerminal({
5552
5919
  reasoningRef,
5553
5920
  workingGroupContextProp,
5554
5921
  onResolveWorkingGroup,
5922
+ autoFocusInput,
5555
5923
  onRagFileUpload,
5556
5924
  onListRagFiles,
5557
5925
  onDeleteRagFile,
@@ -5565,9 +5933,10 @@ function ChatTerminal({
5565
5933
  showWelcomeMessage,
5566
5934
  currentUser,
5567
5935
  onPollMessages,
5568
- pollIntervalMs
5936
+ pollIntervalMs,
5937
+ authToken
5569
5938
  });
5570
- React12.useEffect(() => {
5939
+ React15.useEffect(() => {
5571
5940
  onActivityEventsChange?.(core.activityEvents);
5572
5941
  }, [core.activityEvents]);
5573
5942
  const isCollaborative = !!core.collaborationState?.session_id || !!onSendMessage || !!currentUser;
@@ -5582,8 +5951,8 @@ function ChatTerminal({
5582
5951
  completeMention,
5583
5952
  parseMentions
5584
5953
  } = useMentions(mentionsInput, core.collaborationState?.participants, mentionTargets);
5585
- const [caretIndex, setCaretIndex] = React12.useState(0);
5586
- const [slashPickedNames, setSlashPickedNames] = React12.useState([]);
5954
+ const [caretIndex, setCaretIndex] = React15.useState(0);
5955
+ const [slashPickedNames, setSlashPickedNames] = React15.useState([]);
5587
5956
  const slashMentions = useSlashMentionPicker({
5588
5957
  currentCommand: core.currentCommand,
5589
5958
  caretIndex,
@@ -5605,13 +5974,13 @@ function ChatTerminal({
5605
5974
  setCaretIndex(replaced.caret);
5606
5975
  });
5607
5976
  };
5608
- const liveSlashPickedNames = React12.useMemo(
5977
+ const liveSlashPickedNames = React15.useMemo(
5609
5978
  () => slashPickedNames.filter(
5610
5979
  (n) => core.currentCommand.toLowerCase().includes(`@${n.toLowerCase()}`)
5611
5980
  ),
5612
5981
  [slashPickedNames, core.currentCommand]
5613
5982
  );
5614
- const knownMentionNames = React12.useMemo(() => {
5983
+ const knownMentionNames = React15.useMemo(() => {
5615
5984
  const names = [...liveSlashPickedNames];
5616
5985
  if (mentionTargets) for (const t of mentionTargets) names.push(t.display_name);
5617
5986
  if (core.collaborationState?.participants) {
@@ -5709,11 +6078,26 @@ function ChatTerminal({
5709
6078
  `Usage: /${command} <prose>. Use @name to link an entity.`
5710
6079
  );
5711
6080
  } else {
5712
- const result = await onSubmitNote(
6081
+ const result2 = await onSubmitNote(
5713
6082
  prose,
5714
6083
  command === "personal" ? "personal" : "workspace"
5715
6084
  );
5716
- core.addTerminalLine(result.ok ? "success" : "error", result.message);
6085
+ core.addTerminalLine(result2.ok ? "success" : "error", result2.message);
6086
+ }
6087
+ core.setCurrentCommand("");
6088
+ setTimeout(() => core.focusInput(), 50);
6089
+ return;
6090
+ }
6091
+ if (command === "log") {
6092
+ const prose = args.join(" ");
6093
+ core.addTerminalLine("command", prose.trim() ? `log ${prose}` : "log");
6094
+ if (!onSubmitLog) {
6095
+ core.addTerminalLine("error", "Work capture is not available in this context.");
6096
+ } else if (!prose.trim()) {
6097
+ core.addTerminalLine("info", "Usage: /log <what you did or decided>");
6098
+ } else {
6099
+ const result2 = await onSubmitLog(prose);
6100
+ core.addTerminalLine(result2.ok ? "success" : "error", result2.message);
5717
6101
  }
5718
6102
  core.setCurrentCommand("");
5719
6103
  setTimeout(() => core.focusInput(), 50);
@@ -5760,14 +6144,17 @@ function ChatTerminal({
5760
6144
  className,
5761
6145
  style,
5762
6146
  showHeader,
6147
+ agentLabel: core.agentLabel,
5763
6148
  focusInput: core.focusInput,
5764
6149
  setTerminalHistory: core.setTerminalHistory,
5765
6150
  terminalBodyRef: core.terminalBodyRef,
5766
6151
  workingGroupContext: core.workingGroupContext,
6152
+ showWorkingGroupBanner,
5767
6153
  progressState: core.progressState,
5768
6154
  streamTransparency: core.streamTransparency,
5769
6155
  streamNowMs: core.streamNowMs,
5770
6156
  isExecuting: core.isExecuting,
6157
+ showBusyIndicator,
5771
6158
  handleCancelReasoning: core.handleCancelReasoning,
5772
6159
  onViewKnowledgeGraph,
5773
6160
  onLiveKGUpdate,
@@ -5804,6 +6191,7 @@ function ChatTerminal({
5804
6191
  inputBar: /* @__PURE__ */ jsxRuntime.jsx(
5805
6192
  TerminalInputBar,
5806
6193
  {
6194
+ autoFocus: autoFocusInput,
5807
6195
  inputRef: core.inputRef,
5808
6196
  fileInputRef: core.fileInputRef,
5809
6197
  currentCommand: core.currentCommand,
@@ -5856,6 +6244,7 @@ function ChatTerminal({
5856
6244
  config,
5857
6245
  onPageNavigation,
5858
6246
  onSourcesActivate,
6247
+ onSourceActivate,
5859
6248
  renderEntryExtra,
5860
6249
  renderEntry,
5861
6250
  widgets,
@@ -5877,17 +6266,17 @@ function CoreTerminal(props) {
5877
6266
  return /* @__PURE__ */ jsxRuntime.jsx(StandardTerminal, { ...props });
5878
6267
  }
5879
6268
  function TypingAnimation({ text, className = "", shouldStart = false }) {
5880
- const [displayedText, setDisplayedText] = React12.useState("");
5881
- const [currentIndex, setCurrentIndex] = React12.useState(0);
5882
- const [isTyping, setIsTyping] = React12.useState(false);
5883
- React12.useEffect(() => {
6269
+ const [displayedText, setDisplayedText] = React15.useState("");
6270
+ const [currentIndex, setCurrentIndex] = React15.useState(0);
6271
+ const [isTyping, setIsTyping] = React15.useState(false);
6272
+ React15.useEffect(() => {
5884
6273
  if (shouldStart && !isTyping) {
5885
6274
  setIsTyping(true);
5886
6275
  setDisplayedText("");
5887
6276
  setCurrentIndex(0);
5888
6277
  }
5889
6278
  }, [shouldStart, isTyping]);
5890
- React12.useEffect(() => {
6279
+ React15.useEffect(() => {
5891
6280
  if (isTyping && currentIndex < text.length) {
5892
6281
  const timeout = setTimeout(() => {
5893
6282
  setDisplayedText((prev) => prev + text[currentIndex]);
@@ -5908,19 +6297,19 @@ function ExpandableTerminal({
5908
6297
  ...terminalProps
5909
6298
  }) {
5910
6299
  const t = mergeTheme(themeOverrides);
5911
- const [isExpanded, setIsExpanded] = React12.useState(false);
5912
- const [isFullscreen, setIsFullscreen] = React12.useState(false);
5913
- const initialHistoryRef = React12.useRef(initialHistory);
5914
- React12.useEffect(() => {
6300
+ const [isExpanded, setIsExpanded] = React15.useState(false);
6301
+ const [isFullscreen, setIsFullscreen] = React15.useState(false);
6302
+ const initialHistoryRef = React15.useRef(initialHistory);
6303
+ React15.useEffect(() => {
5915
6304
  initialHistoryRef.current = initialHistory;
5916
6305
  }, [initialHistory]);
5917
- const [currentGuidance, setCurrentGuidance] = React12.useState(guidanceMessage || "");
5918
- const [isLoadingGuidance, setIsLoadingGuidance] = React12.useState(false);
5919
- const [hasTriggeredTyping, setHasTriggeredTyping] = React12.useState(false);
5920
- const [internalWindowWidth, setInternalWindowWidth] = React12.useState(windowWidth);
5921
- const terminalRef = React12.useRef(null);
5922
- const justOpenedRef = React12.useRef(false);
5923
- React12.useEffect(() => {
6306
+ const [currentGuidance, setCurrentGuidance] = React15.useState(guidanceMessage || "");
6307
+ const [isLoadingGuidance, setIsLoadingGuidance] = React15.useState(false);
6308
+ const [hasTriggeredTyping, setHasTriggeredTyping] = React15.useState(false);
6309
+ const [internalWindowWidth, setInternalWindowWidth] = React15.useState(windowWidth);
6310
+ const terminalRef = React15.useRef(null);
6311
+ const justOpenedRef = React15.useRef(false);
6312
+ React15.useEffect(() => {
5924
6313
  if (typeof window !== "undefined") {
5925
6314
  const updateWindowWidth = () => setInternalWindowWidth(window.innerWidth);
5926
6315
  updateWindowWidth();
@@ -5928,7 +6317,7 @@ function ExpandableTerminal({
5928
6317
  return () => window.removeEventListener("resize", updateWindowWidth);
5929
6318
  }
5930
6319
  }, []);
5931
- React12.useEffect(() => {
6320
+ React15.useEffect(() => {
5932
6321
  const handleClickOutside = (event) => {
5933
6322
  if (justOpenedRef.current) return;
5934
6323
  if ((isExpanded || isFullscreen) && terminalRef.current && !terminalRef.current.contains(event.target)) {
@@ -5947,13 +6336,13 @@ function ExpandableTerminal({
5947
6336
  };
5948
6337
  }
5949
6338
  }, [isExpanded, isFullscreen]);
5950
- React12.useEffect(() => {
6339
+ React15.useEffect(() => {
5951
6340
  if (onGuidanceRequest && !currentGuidance && !isLoadingGuidance) {
5952
6341
  setIsLoadingGuidance(true);
5953
6342
  onGuidanceRequest().then((message) => setCurrentGuidance(message)).catch(() => setCurrentGuidance("\u{1F4AC} Intelligence Online - Ask anything!")).finally(() => setIsLoadingGuidance(false));
5954
6343
  }
5955
6344
  }, [onGuidanceRequest, currentGuidance, isLoadingGuidance]);
5956
- React12.useEffect(() => {
6345
+ React15.useEffect(() => {
5957
6346
  const timer = setTimeout(() => setHasTriggeredTyping(true), 1e3);
5958
6347
  return () => clearTimeout(timer);
5959
6348
  }, []);
@@ -6139,12 +6528,12 @@ function InlineTerminal({
6139
6528
  autoFocus = false
6140
6529
  }) {
6141
6530
  const t = useTheme();
6142
- const [command, setCommand] = React12.useState("");
6143
- const [isProcessing, setIsProcessing] = React12.useState(false);
6144
- const [response, setResponse] = React12.useState("");
6145
- const [showResponse, setShowResponse] = React12.useState(false);
6146
- const inputRef = React12.useRef(null);
6147
- React12.useEffect(() => {
6531
+ const [command, setCommand] = React15.useState("");
6532
+ const [isProcessing, setIsProcessing] = React15.useState(false);
6533
+ const [response, setResponse] = React15.useState("");
6534
+ const [showResponse, setShowResponse] = React15.useState(false);
6535
+ const inputRef = React15.useRef(null);
6536
+ React15.useEffect(() => {
6148
6537
  if (autoFocus && inputRef.current) inputRef.current.focus();
6149
6538
  }, [autoFocus]);
6150
6539
  const handleSubmit = async (e) => {
@@ -6298,18 +6687,18 @@ function buildNarrativeSummary(snapshot, columnConfig) {
6298
6687
  }
6299
6688
  function KnowledgeGraphPanel({ snapshot, genericKG, onClose }) {
6300
6689
  const t = useTheme();
6301
- const [selected, setSelected] = React12.useState(null);
6302
- const [fullscreen, setFullscreen] = React12.useState(false);
6303
- const [searchTerm, setSearchTerm] = React12.useState("");
6304
- const COLUMN_CONFIG = React12.useMemo(() => getColumnConfig(t), [t]);
6305
- const SEVERITY_COLORS = React12.useMemo(() => getSeverityColors(t), [t]);
6306
- const FALLBACK_COLORS = React12.useMemo(() => getFallbackColors(t), [t]);
6307
- const genericNodeMap = React12.useMemo(() => {
6690
+ const [selected, setSelected] = React15.useState(null);
6691
+ const [fullscreen, setFullscreen] = React15.useState(false);
6692
+ const [searchTerm, setSearchTerm] = React15.useState("");
6693
+ const COLUMN_CONFIG = React15.useMemo(() => getColumnConfig(t), [t]);
6694
+ const SEVERITY_COLORS = React15.useMemo(() => getSeverityColors(t), [t]);
6695
+ const FALLBACK_COLORS = React15.useMemo(() => getFallbackColors(t), [t]);
6696
+ const genericNodeMap = React15.useMemo(() => {
6308
6697
  if (!genericKG) return /* @__PURE__ */ new Map();
6309
6698
  return new Map(genericKG.nodes.map((n) => [n.id, n]));
6310
6699
  }, [genericKG]);
6311
- const narrativeSummary = React12.useMemo(() => buildNarrativeSummary(snapshot, COLUMN_CONFIG), [snapshot, COLUMN_CONFIG]);
6312
- React12.useEffect(() => {
6700
+ const narrativeSummary = React15.useMemo(() => buildNarrativeSummary(snapshot, COLUMN_CONFIG), [snapshot, COLUMN_CONFIG]);
6701
+ React15.useEffect(() => {
6313
6702
  if (!fullscreen) return;
6314
6703
  const handleEsc = (e) => {
6315
6704
  if (e.key === "Escape") setFullscreen(false);
@@ -6317,11 +6706,11 @@ function KnowledgeGraphPanel({ snapshot, genericKG, onClose }) {
6317
6706
  window.addEventListener("keydown", handleEsc);
6318
6707
  return () => window.removeEventListener("keydown", handleEsc);
6319
6708
  }, [fullscreen]);
6320
- const isStructured = React12.useMemo(() => {
6709
+ const isStructured = React15.useMemo(() => {
6321
6710
  const types = new Set(snapshot.nodes.map((n) => n.node_type));
6322
6711
  return types.has("document_element") || types.has("finding") || types.has("recommendation");
6323
6712
  }, [snapshot]);
6324
- const { columns, otherNodes } = React12.useMemo(() => {
6713
+ const { columns, otherNodes } = React15.useMemo(() => {
6325
6714
  const cols = {
6326
6715
  document_element: [],
6327
6716
  finding: [],
@@ -6343,7 +6732,7 @@ function KnowledgeGraphPanel({ snapshot, genericKG, onClose }) {
6343
6732
  });
6344
6733
  return { columns: cols, otherNodes: other };
6345
6734
  }, [snapshot, searchTerm]);
6346
- const edgeMap = React12.useMemo(() => {
6735
+ const edgeMap = React15.useMemo(() => {
6347
6736
  const map = {};
6348
6737
  snapshot.edges.forEach((e) => {
6349
6738
  if (!map[e.from]) map[e.from] = [];
@@ -6709,7 +7098,7 @@ function HistoryAgentCard({
6709
7098
  thinking
6710
7099
  }) {
6711
7100
  const t = useTheme();
6712
- const [agentExpanded, setAgentExpanded] = React12.useState(false);
7101
+ const [agentExpanded, setAgentExpanded] = React15.useState(false);
6713
7102
  const name = agent.display_name || agent.id.replace(/_/g, " ");
6714
7103
  const statusColor = agent.status === "complete" ? t.success : agent.status === "failed" ? t.error : t.warning;
6715
7104
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -6772,8 +7161,8 @@ function ReasoningHistoryCard({
6772
7161
  defaultExpanded = false
6773
7162
  }) {
6774
7163
  const t = useTheme();
6775
- const [expanded, setExpanded] = React12.useState(defaultExpanded);
6776
- const [showKG, setShowKG] = React12.useState(false);
7164
+ const [expanded, setExpanded] = React15.useState(defaultExpanded);
7165
+ const [showKG, setShowKG] = React15.useState(false);
6777
7166
  const agentCount = snapshot.agents?.length || 0;
6778
7167
  const completedCount = snapshot.agents?.filter((a) => a.status === "complete").length || 0;
6779
7168
  const elapsedSec = snapshot.elapsedMs ? Math.round(snapshot.elapsedMs / 1e3) : null;
@@ -7012,6 +7401,227 @@ function ReasoningHistoryCard({
7012
7401
  }
7013
7402
  );
7014
7403
  }
7404
+ function subject(step) {
7405
+ const idx = step.detail.indexOf(": ");
7406
+ const s = idx > -1 ? step.detail.slice(idx + 2).trim() : "";
7407
+ return s.length ? s : null;
7408
+ }
7409
+ function bare(tool) {
7410
+ return tool.replace(/^yf_kg_/, "").replace(/^yf_/, "");
7411
+ }
7412
+ function action(step) {
7413
+ const subj = subject(step);
7414
+ const quoted = subj ? `\u201C${subj}\u201D` : null;
7415
+ switch (bare(step.tool)) {
7416
+ case "graphs":
7417
+ return "Listed knowledge collections";
7418
+ case "search":
7419
+ return quoted ? `Searched for ${quoted}` : "Searched the documents";
7420
+ case "count":
7421
+ return quoted ? `Counted mentions of ${quoted}` : "Counted mentions";
7422
+ case "enumerate":
7423
+ return quoted ? `Listed every match for ${quoted}` : "Listed every match";
7424
+ case "fetch":
7425
+ return "Read a document";
7426
+ case "entities":
7427
+ return "Listed the people and things found";
7428
+ case "explore":
7429
+ return quoted ? `Followed connections from ${quoted}` : "Followed connections";
7430
+ case "sets":
7431
+ return "Listed frozen document sets";
7432
+ case "get_set":
7433
+ return "Read a frozen document set";
7434
+ case "count_in_set":
7435
+ return quoted ? `Counted ${quoted} inside a set` : "Counted inside a set";
7436
+ case "think":
7437
+ return "Thought it through";
7438
+ default:
7439
+ return subj ? `${bare(step.tool).replace(/_/g, " ")} ${subj}` : bare(step.tool).replace(/_/g, " ");
7440
+ }
7441
+ }
7442
+ function took(step) {
7443
+ if (step.status === "running") return null;
7444
+ const ms = Number(step.ms);
7445
+ if (!Number.isFinite(ms) || ms < 1e3) return null;
7446
+ return ms < 1e4 ? `${(ms / 1e3).toFixed(1)}s` : `${Math.round(ms / 1e3)}s`;
7447
+ }
7448
+ function groupTook(g) {
7449
+ const slowest = g.steps.reduce(
7450
+ (worst, s) => Number(s.ms) > Number(worst.ms) ? s : worst,
7451
+ g.steps[0]
7452
+ );
7453
+ return took(slowest);
7454
+ }
7455
+ function result(step) {
7456
+ if (step.status === "running") return null;
7457
+ if (step.status === "error") return "unavailable";
7458
+ const n = Number(step.outcome);
7459
+ if (!Number.isFinite(n)) return null;
7460
+ const [one, many] = {
7461
+ graphs: ["collection", "collections"],
7462
+ search: ["result", "results"],
7463
+ count: ["document", "documents"],
7464
+ enumerate: ["match", "matches"],
7465
+ entities: ["entity", "entities"],
7466
+ explore: ["connection", "connections"],
7467
+ sets: ["set", "sets"]
7468
+ }[bare(step.tool)] ?? ["result", "results"];
7469
+ if (n === 0) return "nothing found";
7470
+ return `${n} ${n === 1 ? one : many}`;
7471
+ }
7472
+ function group(steps) {
7473
+ const out = [];
7474
+ const byKey = /* @__PURE__ */ new Map();
7475
+ for (const step of steps) {
7476
+ const label = action(step);
7477
+ const key = `${step.round ?? ""}\0${label}`;
7478
+ const existing = byKey.get(key);
7479
+ if (existing) {
7480
+ existing.steps.push(step);
7481
+ continue;
7482
+ }
7483
+ const g = { key: step.seq, label, round: step.round, steps: [step] };
7484
+ byKey.set(key, g);
7485
+ out.push(g);
7486
+ }
7487
+ return out;
7488
+ }
7489
+ function groupResult(g) {
7490
+ if (g.steps.length === 1) return result(g.steps[0]);
7491
+ const done = g.steps.filter((s) => s.status !== "running");
7492
+ if (!done.length) return null;
7493
+ const hits = done.filter((s) => Number(s.outcome) > 0).length;
7494
+ if (hits === 0) return "nothing found";
7495
+ return `found in ${hits} of ${done.length}`;
7496
+ }
7497
+ function roundCount(steps) {
7498
+ const seen = /* @__PURE__ */ new Set();
7499
+ for (const s of steps) if (typeof s.round === "number") seen.add(s.round);
7500
+ return seen.size ? seen.size : null;
7501
+ }
7502
+ function AgentStepTrace({ steps, working }) {
7503
+ const t = useTheme();
7504
+ const failed = steps.some((s) => s.status === "error");
7505
+ const prominent = working || failed;
7506
+ const [open, setOpen] = React15.useState(prominent);
7507
+ const [touched, setTouched] = React15.useState(false);
7508
+ const [hover, setHover] = React15.useState(false);
7509
+ React15.useEffect(() => {
7510
+ if (!touched) setOpen(prominent);
7511
+ }, [prominent, touched]);
7512
+ if (!steps.length) return null;
7513
+ const groups = group(steps);
7514
+ const rounds = roundCount(steps);
7515
+ const n = rounds ?? groups.length;
7516
+ const count = `${n} ${rounds ? "round" : "step"}${n === 1 ? "" : "s"}`;
7517
+ const only = groups.length === 1 ? groups[0] : null;
7518
+ const summary = working ? `${action(steps[steps.length - 1])}\u2026` : failed ? `${count}, some unavailable` : only ? [
7519
+ only.label + (only.steps.length > 1 ? ` \xD7${only.steps.length}` : ""),
7520
+ groupResult(only)
7521
+ ].filter(Boolean).join(" \u2014 ") : count;
7522
+ const toggle = /* @__PURE__ */ jsxRuntime.jsxs(
7523
+ "button",
7524
+ {
7525
+ type: "button",
7526
+ onClick: () => {
7527
+ setTouched(true);
7528
+ setOpen((o) => !o);
7529
+ },
7530
+ onMouseEnter: () => setHover(true),
7531
+ onMouseLeave: () => setHover(false),
7532
+ "aria-expanded": open,
7533
+ className: "flex w-full items-center gap-2 text-left text-xs",
7534
+ style: { color: failed ? t.error : hover ? t.text : t.textMuted },
7535
+ children: [
7536
+ working && /* @__PURE__ */ jsxRuntime.jsx(
7537
+ "span",
7538
+ {
7539
+ "aria-hidden": true,
7540
+ className: "inline-block h-1.5 w-1.5 shrink-0 rounded-full motion-safe:animate-pulse",
7541
+ style: { backgroundColor: t.primary }
7542
+ }
7543
+ ),
7544
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: summary }),
7545
+ !(only && !working && !failed) && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "shrink-0", children: open ? "\u2212" : "+" })
7546
+ ]
7547
+ }
7548
+ );
7549
+ const rows = /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "mt-2 space-y-1", children: groups.map((g, i) => {
7550
+ const res = groupResult(g);
7551
+ const slow = groupTook(g);
7552
+ const anyError = g.steps.some((s) => s.status === "error");
7553
+ const running = g.steps.some((s) => s.status === "running");
7554
+ const startsRound = g.round !== void 0 && g.round !== groups[i - 1]?.round;
7555
+ return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-baseline gap-2 text-xs", children: [
7556
+ rounds !== null && /* @__PURE__ */ jsxRuntime.jsx(
7557
+ "span",
7558
+ {
7559
+ className: "w-3 shrink-0 text-right tabular-nums",
7560
+ style: { color: t.textMuted },
7561
+ "aria-hidden": !startsRound,
7562
+ children: startsRound ? g.round : ""
7563
+ }
7564
+ ),
7565
+ /* @__PURE__ */ jsxRuntime.jsx(
7566
+ "span",
7567
+ {
7568
+ "aria-hidden": true,
7569
+ className: "w-3 shrink-0 text-[10px]",
7570
+ style: { color: anyError ? t.error : t.textMuted },
7571
+ children: running ? "\xB7" : anyError ? "!" : "\u2713"
7572
+ }
7573
+ ),
7574
+ /* @__PURE__ */ jsxRuntime.jsxs(
7575
+ "span",
7576
+ {
7577
+ className: "min-w-0 flex-1 truncate",
7578
+ style: { color: t.textSecondary },
7579
+ title: g.label,
7580
+ children: [
7581
+ g.label,
7582
+ g.steps.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: t.textMuted }, children: [
7583
+ " \xD7",
7584
+ g.steps.length
7585
+ ] })
7586
+ ]
7587
+ }
7588
+ ),
7589
+ slow && /* @__PURE__ */ jsxRuntime.jsx(
7590
+ "span",
7591
+ {
7592
+ className: "shrink-0 tabular-nums",
7593
+ style: { color: t.textMuted },
7594
+ children: slow
7595
+ }
7596
+ ),
7597
+ res && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", style: { color: anyError ? t.error : t.textMuted }, children: res })
7598
+ ] }, g.key);
7599
+ }) });
7600
+ if (!prominent) {
7601
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2", children: [
7602
+ toggle,
7603
+ open && !only && rows
7604
+ ] });
7605
+ }
7606
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7607
+ "div",
7608
+ {
7609
+ className: "mt-2 rounded-lg p-3",
7610
+ style: { backgroundColor: t.bgRaisedAlt, border: `1px solid ${t.border}` },
7611
+ children: [
7612
+ toggle,
7613
+ open && rows
7614
+ ]
7615
+ }
7616
+ );
7617
+ }
7618
+ function agentStepTraceExtra(entry) {
7619
+ const meta = entry.metadata;
7620
+ const steps = meta?.agentSteps;
7621
+ if (!steps?.length) return null;
7622
+ const working = meta?.agentStepsLive ?? entry.content.endsWith("\u258B");
7623
+ return /* @__PURE__ */ jsxRuntime.jsx(AgentStepTrace, { steps, working });
7624
+ }
7015
7625
 
7016
7626
  // src/knowledge/graphTheme.ts
7017
7627
  var NODE_TYPE_COLORS = {
@@ -7277,7 +7887,7 @@ function GraphNodeComponent({ data, selected }) {
7277
7887
  ` })
7278
7888
  ] });
7279
7889
  }
7280
- var GraphNode = React12.memo(GraphNodeComponent);
7890
+ var GraphNode = React15.memo(GraphNodeComponent);
7281
7891
  function GraphEdgeComponent({
7282
7892
  id,
7283
7893
  sourceX,
@@ -7346,7 +7956,7 @@ function GraphEdgeComponent({
7346
7956
  ) })
7347
7957
  ] });
7348
7958
  }
7349
- var GraphEdge = React12.memo(GraphEdgeComponent);
7959
+ var GraphEdge = React15.memo(GraphEdgeComponent);
7350
7960
  function EdgeMarkerDefs() {
7351
7961
  const types = [
7352
7962
  "supports",
@@ -7476,18 +8086,18 @@ function AnnotationCard({ annotation: a }) {
7476
8086
  }
7477
8087
  );
7478
8088
  }
7479
- var MarkdownContent = React12.memo(function MarkdownContent2({
8089
+ var MarkdownContent = React15.memo(function MarkdownContent2({
7480
8090
  children,
7481
8091
  className = "",
7482
8092
  entities,
7483
8093
  onEntityClick
7484
8094
  }) {
7485
8095
  if (!children) return null;
7486
- const components = React12.useMemo(() => {
8096
+ const components = React15.useMemo(() => {
7487
8097
  if (!entities || entities.length === 0) return MARKDOWN_COMPONENTS;
7488
8098
  return { ...MARKDOWN_COMPONENTS, ...buildHighlightOverrides(entities, onEntityClick) };
7489
8099
  }, [entities, onEntityClick]);
7490
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `text-xs leading-relaxed text-gray-300 break-words ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx(ReactMarkdown__default.default, { components, children }) });
8100
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `text-xs leading-relaxed text-gray-300 break-words ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx(ReactMarkdown__default.default, { remarkPlugins: [remarkGfm__default.default], components, children }) });
7491
8101
  });
7492
8102
  function escapeRegex(s) {
7493
8103
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -7553,13 +8163,13 @@ function highlightText(text, regex, entityMap, onEntityClick) {
7553
8163
  return parts;
7554
8164
  }
7555
8165
  function highlightChildren(children, regex, entityMap, onEntityClick) {
7556
- return React12__default.default.Children.map(children, (child) => {
8166
+ return React15__default.default.Children.map(children, (child) => {
7557
8167
  if (typeof child === "string") {
7558
8168
  const highlighted = highlightText(child, regex, entityMap, onEntityClick);
7559
8169
  return highlighted.length === 1 && typeof highlighted[0] === "string" ? child : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: highlighted });
7560
8170
  }
7561
- if (React12__default.default.isValidElement(child) && child.props.children) {
7562
- return React12__default.default.cloneElement(child, {
8171
+ if (React15__default.default.isValidElement(child) && child.props.children) {
8172
+ return React15__default.default.cloneElement(child, {
7563
8173
  ...child.props,
7564
8174
  children: highlightChildren(child.props.children, regex, entityMap, onEntityClick)
7565
8175
  });
@@ -7727,7 +8337,7 @@ var MARKDOWN_COMPONENTS = {
7727
8337
  }
7728
8338
  )
7729
8339
  };
7730
- var MarkdownEditor = React12.memo(function MarkdownEditor2({
8340
+ var MarkdownEditor = React15.memo(function MarkdownEditor2({
7731
8341
  value,
7732
8342
  onChange,
7733
8343
  onSave,
@@ -7736,14 +8346,14 @@ var MarkdownEditor = React12.memo(function MarkdownEditor2({
7736
8346
  autoFocus = true,
7737
8347
  disabled = false
7738
8348
  }) {
7739
- const editorRef = React12.useRef(null);
7740
- React12.useEffect(() => {
8349
+ const editorRef = React15.useRef(null);
8350
+ React15.useEffect(() => {
7741
8351
  if (autoFocus && editorRef.current) {
7742
8352
  const id = requestAnimationFrame(() => editorRef.current?.focus());
7743
8353
  return () => cancelAnimationFrame(id);
7744
8354
  }
7745
8355
  }, [autoFocus]);
7746
- const handleKeyDown = React12.useCallback(
8356
+ const handleKeyDown = React15.useCallback(
7747
8357
  (e) => {
7748
8358
  if (disabled) return;
7749
8359
  if (e.key === "Escape") {
@@ -7760,7 +8370,7 @@ var MarkdownEditor = React12.memo(function MarkdownEditor2({
7760
8370
  },
7761
8371
  [disabled, onCancel, onSave, onChange]
7762
8372
  );
7763
- const handleChange = React12.useCallback(
8373
+ const handleChange = React15.useCallback(
7764
8374
  (markdown, initialNormalize) => {
7765
8375
  if (initialNormalize) return;
7766
8376
  onChange(markdown);
@@ -8014,7 +8624,7 @@ var MarkdownEditor = React12.memo(function MarkdownEditor2({
8014
8624
  }
8015
8625
  );
8016
8626
  });
8017
- var KbdKey = React12.memo(function KbdKey2({ children }) {
8627
+ var KbdKey = React15.memo(function KbdKey2({ children }) {
8018
8628
  return /* @__PURE__ */ jsxRuntime.jsx(
8019
8629
  "kbd",
8020
8630
  {
@@ -8030,10 +8640,10 @@ var SAVE_STAGE_MESSAGES = {
8030
8640
  extracting: "re-analyzing entities with AI\u2026",
8031
8641
  finishing: "almost done \xB7 finalizing graph\u2026"
8032
8642
  };
8033
- function summarizeSaveResult(result) {
8034
- if (!result?.diff) return "Saved";
8035
- const added = result.diff.added_node_keys?.length ?? 0;
8036
- const removed = result.diff.removed_node_keys?.length ?? 0;
8643
+ function summarizeSaveResult(result2) {
8644
+ if (!result2?.diff) return "Saved";
8645
+ const added = result2.diff.added_node_keys?.length ?? 0;
8646
+ const removed = result2.diff.removed_node_keys?.length ?? 0;
8037
8647
  if (added === 0 && removed === 0) return "Saved \xB7 graph unchanged";
8038
8648
  const parts = [];
8039
8649
  if (added > 0) parts.push(`+${added}`);
@@ -8044,21 +8654,21 @@ function NodeDetailDrawer({ node, connectedNodes, chunks = [], annotations, onCl
8044
8654
  const vocabType = node.properties?.vocabulary_type;
8045
8655
  const colors = vocabType ? getVocabTypeColors(vocabType) : getNodeColors(node.nodeType);
8046
8656
  const typeLabel = vocabType ? getVocabTypeLabel(vocabType) : getNodeTypeLabel(node.nodeType);
8047
- const [showProperties, setShowProperties] = React12.useState(false);
8048
- const [expandedChunks, setExpandedChunks] = React12.useState(/* @__PURE__ */ new Set());
8049
- const [isEditing, setIsEditing] = React12.useState(false);
8050
- const [draftText, setDraftText] = React12.useState("");
8051
- const [localDescription, setLocalDescription] = React12.useState(null);
8052
- const [isSaving, setIsSaving] = React12.useState(false);
8053
- const [saveError, setSaveError] = React12.useState(null);
8054
- const [lastSaveResult, setLastSaveResult] = React12.useState(null);
8055
- const [saveProgressStage, setSaveProgressStage] = React12.useState("starting");
8056
- const currentNodeIdRef = React12.useRef(node.id);
8057
- const savedPillTimerRef = React12.useRef(null);
8657
+ const [showProperties, setShowProperties] = React15.useState(false);
8658
+ const [expandedChunks, setExpandedChunks] = React15.useState(/* @__PURE__ */ new Set());
8659
+ const [isEditing, setIsEditing] = React15.useState(false);
8660
+ const [draftText, setDraftText] = React15.useState("");
8661
+ const [localDescription, setLocalDescription] = React15.useState(null);
8662
+ const [isSaving, setIsSaving] = React15.useState(false);
8663
+ const [saveError, setSaveError] = React15.useState(null);
8664
+ const [lastSaveResult, setLastSaveResult] = React15.useState(null);
8665
+ const [saveProgressStage, setSaveProgressStage] = React15.useState("starting");
8666
+ const currentNodeIdRef = React15.useRef(node.id);
8667
+ const savedPillTimerRef = React15.useRef(null);
8058
8668
  const displayedDescription = localDescription ?? node.description ?? "";
8059
8669
  const isLocallyEdited = localDescription !== null && localDescription !== (node.description ?? "");
8060
8670
  const isDirty = isEditing && draftText !== displayedDescription;
8061
- React12.useEffect(() => {
8671
+ React15.useEffect(() => {
8062
8672
  currentNodeIdRef.current = node.id;
8063
8673
  setIsEditing(false);
8064
8674
  setLocalDescription(null);
@@ -8071,7 +8681,7 @@ function NodeDetailDrawer({ node, connectedNodes, chunks = [], annotations, onCl
8071
8681
  savedPillTimerRef.current = null;
8072
8682
  }
8073
8683
  }, [node.id]);
8074
- React12.useEffect(() => {
8684
+ React15.useEffect(() => {
8075
8685
  if (!isSaving) return;
8076
8686
  if (saveMode !== "reextract") {
8077
8687
  setSaveProgressStage("embedding");
@@ -8087,7 +8697,7 @@ function NodeDetailDrawer({ node, connectedNodes, chunks = [], annotations, onCl
8087
8697
  clearTimeout(t3);
8088
8698
  };
8089
8699
  }, [isSaving, saveMode]);
8090
- React12.useEffect(() => () => {
8700
+ React15.useEffect(() => () => {
8091
8701
  if (savedPillTimerRef.current) clearTimeout(savedPillTimerRef.current);
8092
8702
  }, []);
8093
8703
  const handleStartEdit = () => {
@@ -8112,11 +8722,11 @@ function NodeDetailDrawer({ node, connectedNodes, chunks = [], annotations, onCl
8112
8722
  setIsSaving(true);
8113
8723
  try {
8114
8724
  const rawResult = await onSaveDescription(draftAtSaveTime);
8115
- const result = rawResult ?? null;
8725
+ const result2 = rawResult ?? null;
8116
8726
  if (currentNodeIdRef.current === savingForNodeId) {
8117
8727
  setLocalDescription(draftAtSaveTime);
8118
8728
  setIsEditing(false);
8119
- setLastSaveResult(result);
8729
+ setLastSaveResult(result2);
8120
8730
  if (savedPillTimerRef.current) clearTimeout(savedPillTimerRef.current);
8121
8731
  savedPillTimerRef.current = setTimeout(() => {
8122
8732
  setLastSaveResult(null);
@@ -8148,7 +8758,7 @@ function NodeDetailDrawer({ node, connectedNodes, chunks = [], annotations, onCl
8148
8758
  onClose();
8149
8759
  };
8150
8760
  const PLATFORM_SLOT_RE = /<[^>]*(chunk|timestamp|source|when|date|where|location)[^>]*>/i;
8151
- const renderedClaims = React12.useMemo(() => {
8761
+ const renderedClaims = React15.useMemo(() => {
8152
8762
  const seen = /* @__PURE__ */ new Set();
8153
8763
  const out = [];
8154
8764
  for (const cn of connectedNodes) {
@@ -8223,7 +8833,7 @@ function NodeDetailDrawer({ node, connectedNodes, chunks = [], annotations, onCl
8223
8833
  }
8224
8834
  return out;
8225
8835
  }, [connectedNodes, node.label]);
8226
- const claimGroups = React12.useMemo(() => {
8836
+ const claimGroups = React15.useMemo(() => {
8227
8837
  const byPredicate = /* @__PURE__ */ new Map();
8228
8838
  for (const c of renderedClaims) {
8229
8839
  const key = c.predicateClean || "(related)";
@@ -8238,11 +8848,11 @@ function NodeDetailDrawer({ node, connectedNodes, chunks = [], annotations, onCl
8238
8848
  }).map(([predicate, items]) => ({ predicate, items }));
8239
8849
  }, [renderedClaims]);
8240
8850
  const sourceDocs = node.properties?.source_documents ?? [];
8241
- const aliases = React12.useMemo(() => {
8851
+ const aliases = React15.useMemo(() => {
8242
8852
  const a = node.aliases ?? [];
8243
8853
  return a.filter((v) => v && v.toLowerCase() !== node.label.toLowerCase());
8244
8854
  }, [node.aliases, node.label]);
8245
- const speakerMeta = React12.useMemo(() => {
8855
+ const speakerMeta = React15.useMemo(() => {
8246
8856
  const raw = node.source?.trim();
8247
8857
  if (!raw) return null;
8248
8858
  if (raw === "system_extractor") return { label: "System extractor", klass: "extractor" };
@@ -8253,7 +8863,7 @@ function NodeDetailDrawer({ node, connectedNodes, chunks = [], annotations, onCl
8253
8863
  return { label: raw.replace(/_/g, " "), klass: "other" };
8254
8864
  }, [node.source]);
8255
8865
  const graphLayer = node.graphLayer || node.properties?.graph_layer;
8256
- const HIDDEN_PROPERTY_KEYS = React12.useMemo(() => /* @__PURE__ */ new Set([
8866
+ const HIDDEN_PROPERTY_KEYS = React15.useMemo(() => /* @__PURE__ */ new Set([
8257
8867
  "vocabulary_type",
8258
8868
  "claim_status",
8259
8869
  "settled",
@@ -8269,7 +8879,7 @@ function NodeDetailDrawer({ node, connectedNodes, chunks = [], annotations, onCl
8269
8879
  "sample_labels",
8270
8880
  "view"
8271
8881
  ]), []);
8272
- const visibleProperties = React12.useMemo(() => {
8882
+ const visibleProperties = React15.useMemo(() => {
8273
8883
  const src = node.properties ?? {};
8274
8884
  const out = {};
8275
8885
  for (const [k, v] of Object.entries(src)) {
@@ -8278,23 +8888,23 @@ function NodeDetailDrawer({ node, connectedNodes, chunks = [], annotations, onCl
8278
8888
  }
8279
8889
  return out;
8280
8890
  }, [node.properties, HIDDEN_PROPERTY_KEYS]);
8281
- const reviewIndex = React12.useMemo(() => {
8891
+ const reviewIndex = React15.useMemo(() => {
8282
8892
  if (!reviewNodeIds || reviewNodeIds.length === 0) return -1;
8283
8893
  return reviewNodeIds.indexOf(node.id);
8284
8894
  }, [reviewNodeIds, node.id]);
8285
8895
  const hasPrev = reviewIndex > 0;
8286
8896
  const hasNext = reviewNodeIds ? reviewIndex < reviewNodeIds.length - 1 : false;
8287
8897
  const isChunk = node.nodeType === "chunk";
8288
- const noteTitle = React12.useMemo(() => {
8898
+ const noteTitle = React15.useMemo(() => {
8289
8899
  if (!isChunk || !displayedDescription) return null;
8290
8900
  const match = displayedDescription.match(/^#{1,4}\s+(.+)/m);
8291
8901
  return match ? match[1].trim() : null;
8292
8902
  }, [isChunk, displayedDescription]);
8293
- const chunkEntities = React12.useMemo(() => {
8903
+ const chunkEntities = React15.useMemo(() => {
8294
8904
  if (!isChunk) return [];
8295
8905
  return connectedNodes.map((cn) => ({ id: cn.id, label: cn.label, nodeType: cn.nodeType }));
8296
8906
  }, [isChunk, connectedNodes]);
8297
- const [showMeta, setShowMeta] = React12.useState(false);
8907
+ const [showMeta, setShowMeta] = React15.useState(false);
8298
8908
  const entityCount = node.properties?.entity_count;
8299
8909
  const relationshipCount = node.properties?.relationship_count;
8300
8910
  const reviewNav = reviewNodeIds && reviewNodeIds.length > 1 && reviewIndex >= 0 && onReviewNavigate ? /* @__PURE__ */ jsxRuntime.jsxs(
@@ -8652,11 +9262,11 @@ function NodeDetailDrawer({ node, connectedNodes, chunks = [], annotations, onCl
8652
9262
  renderedClaims.length,
8653
9263
  ")"
8654
9264
  ] }),
8655
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: claimGroups.map((group) => {
8656
- const isRelated = group.predicate === "(related)";
9265
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: claimGroups.map((group2) => {
9266
+ const isRelated = group2.predicate === "(related)";
8657
9267
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8658
- group.items.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] text-gray-500 italic mb-0.5 px-2", children: group.predicate }),
8659
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-0.5", children: group.items.map((claim) => {
9268
+ group2.items.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] text-gray-500 italic mb-0.5 px-2", children: group2.predicate }),
9269
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-0.5", children: group2.items.map((claim) => {
8660
9270
  const cnColors = getNodeColors(claim.targetType);
8661
9271
  return /* @__PURE__ */ jsxRuntime.jsxs(
8662
9272
  "button",
@@ -8694,7 +9304,7 @@ function NodeDetailDrawer({ node, connectedNodes, chunks = [], annotations, onCl
8694
9304
  claim.key
8695
9305
  );
8696
9306
  }) })
8697
- ] }, group.predicate);
9307
+ ] }, group2.predicate);
8698
9308
  }) })
8699
9309
  ] }),
8700
9310
  Object.keys(visibleProperties).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
@@ -8839,8 +9449,8 @@ function EdgeDetailDrawer({ edge, annotations, onClose, onNavigate }) {
8839
9449
  ] });
8840
9450
  }
8841
9451
  function EditableField({ label, value, placeholder, onSave, color }) {
8842
- const [editing, setEditing] = React12.useState(false);
8843
- const [editVal, setEditVal] = React12.useState(value);
9452
+ const [editing, setEditing] = React15.useState(false);
9453
+ const [editVal, setEditVal] = React15.useState(value);
8844
9454
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: 20 }, children: [
8845
9455
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#888", fontSize: 10, textTransform: "uppercase", letterSpacing: 1, marginBottom: 6 }, children: label }),
8846
9456
  editing ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -8884,15 +9494,15 @@ function EditableField({ label, value, placeholder, onSave, color }) {
8884
9494
  ] });
8885
9495
  }
8886
9496
  function TeamStage({ agents, onSendAction, onUpdateAgent, onRemoveAgent, onAddAgent }) {
8887
- const [editingId, setEditingId] = React12.useState(null);
8888
- const [editField, setEditField] = React12.useState(null);
8889
- const [editValue, setEditValue] = React12.useState("");
8890
- const [addingAgent, setAddingAgent] = React12.useState(false);
8891
- const [newName, setNewName] = React12.useState("");
8892
- const [newRole, setNewRole] = React12.useState("");
8893
- const [confirmDeleteId, setConfirmDeleteId] = React12.useState(null);
8894
- const [selectedAgent, setSelectedAgent] = React12.useState(null);
8895
- const [hoveredId, setHoveredId] = React12.useState(null);
9497
+ const [editingId, setEditingId] = React15.useState(null);
9498
+ const [editField, setEditField] = React15.useState(null);
9499
+ const [editValue, setEditValue] = React15.useState("");
9500
+ const [addingAgent, setAddingAgent] = React15.useState(false);
9501
+ const [newName, setNewName] = React15.useState("");
9502
+ const [newRole, setNewRole] = React15.useState("");
9503
+ const [confirmDeleteId, setConfirmDeleteId] = React15.useState(null);
9504
+ const [selectedAgent, setSelectedAgent] = React15.useState(null);
9505
+ const [hoveredId, setHoveredId] = React15.useState(null);
8896
9506
  const startEdit = (agent, field) => {
8897
9507
  setEditingId(agent.id);
8898
9508
  setEditField(field);
@@ -9308,8 +9918,8 @@ var RECRUITING_LINES = [
9308
9918
  "Briefing the team on the working group context\u2026"
9309
9919
  ];
9310
9920
  function RecruitingHint() {
9311
- const [idx, setIdx] = React12.useState(0);
9312
- React12__default.default.useEffect(() => {
9921
+ const [idx, setIdx] = React15.useState(0);
9922
+ React15__default.default.useEffect(() => {
9313
9923
  const t = setInterval(() => setIdx((i) => (i + 1) % RECRUITING_LINES.length), 2500);
9314
9924
  return () => clearInterval(t);
9315
9925
  }, []);
@@ -9412,7 +10022,7 @@ function RelationshipSentence({ rel }) {
9412
10022
  const hasRange = rel.range.length > 0;
9413
10023
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { lineHeight: 2, color: "#888", fontSize: 13, wordBreak: "break-word" }, children: [
9414
10024
  hasDomain && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9415
- rel.domain.map((d, i) => /* @__PURE__ */ jsxRuntime.jsxs(React12__default.default.Fragment, { children: [
10025
+ rel.domain.map((d, i) => /* @__PURE__ */ jsxRuntime.jsxs(React15__default.default.Fragment, { children: [
9416
10026
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#666" }, children: " or " }),
9417
10027
  /* @__PURE__ */ jsxRuntime.jsx(TypeChip, { name: d })
9418
10028
  ] }, d)),
@@ -9421,7 +10031,7 @@ function RelationshipSentence({ rel }) {
9421
10031
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#ddd", fontStyle: "italic", fontWeight: 500 }, children: verb }),
9422
10032
  hasRange && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9423
10033
  " ",
9424
- rel.range.map((r, i) => /* @__PURE__ */ jsxRuntime.jsxs(React12__default.default.Fragment, { children: [
10034
+ rel.range.map((r, i) => /* @__PURE__ */ jsxRuntime.jsxs(React15__default.default.Fragment, { children: [
9425
10035
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#666" }, children: " and " }),
9426
10036
  /* @__PURE__ */ jsxRuntime.jsx(TypeChip, { name: r })
9427
10037
  ] }, r))
@@ -9437,14 +10047,14 @@ function SchemaStage({
9437
10047
  edgeTypeCount,
9438
10048
  onSendAction
9439
10049
  }) {
9440
- const [renamingType, setRenamingType] = React12.useState(null);
9441
- const [renameValue, setRenameValue] = React12.useState("");
9442
- const [addingType, setAddingType] = React12.useState(false);
9443
- const [newTypeName, setNewTypeName] = React12.useState("");
9444
- const [addingRel, setAddingRel] = React12.useState(false);
9445
- const [newRelName, setNewRelName] = React12.useState("");
9446
- const [newRelDomain, setNewRelDomain] = React12.useState("");
9447
- const [newRelRange, setNewRelRange] = React12.useState("");
10050
+ const [renamingType, setRenamingType] = React15.useState(null);
10051
+ const [renameValue, setRenameValue] = React15.useState("");
10052
+ const [addingType, setAddingType] = React15.useState(false);
10053
+ const [newTypeName, setNewTypeName] = React15.useState("");
10054
+ const [addingRel, setAddingRel] = React15.useState(false);
10055
+ const [newRelName, setNewRelName] = React15.useState("");
10056
+ const [newRelDomain, setNewRelDomain] = React15.useState("");
10057
+ const [newRelRange, setNewRelRange] = React15.useState("");
9448
10058
  const removeType = (name) => {
9449
10059
  onSendAction(`remove the "${name}" type from the schema`);
9450
10060
  };
@@ -9900,8 +10510,8 @@ var DOCUMENT_PIPELINE_STEPS = [
9900
10510
  { key: "complete", label: "Done" }
9901
10511
  ];
9902
10512
  function DocumentProcessingProgress() {
9903
- const [state, setState] = React12.useState(null);
9904
- React12.useEffect(() => {
10513
+ const [state, setState] = React15.useState(null);
10514
+ React15.useEffect(() => {
9905
10515
  const handler = (e) => {
9906
10516
  const event = e.detail;
9907
10517
  if (!event?.step) return;
@@ -9941,7 +10551,7 @@ function DocumentProcessingProgress() {
9941
10551
  if (!state) return null;
9942
10552
  const currentIdx = DOCUMENT_PIPELINE_STEPS.findIndex((s) => s.key === state.step);
9943
10553
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-1.5 flex flex-col gap-1", style: { borderBottom: "1px solid #282828", backgroundColor: "#1a1a1a" }, children: [
9944
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0", children: DOCUMENT_PIPELINE_STEPS.map((step, i) => /* @__PURE__ */ jsxRuntime.jsxs(React12__default.default.Fragment, { children: [
10554
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0", children: DOCUMENT_PIPELINE_STEPS.map((step, i) => /* @__PURE__ */ jsxRuntime.jsxs(React15__default.default.Fragment, { children: [
9945
10555
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-px mx-0.5", style: { backgroundColor: i <= currentIdx ? "#10b981" : "#333" } }),
9946
10556
  /* @__PURE__ */ jsxRuntime.jsx(
9947
10557
  "span",
@@ -10139,7 +10749,7 @@ function useStageActionBridge({
10139
10749
  kgId,
10140
10750
  agentsApiUrl
10141
10751
  }) {
10142
- React12.useEffect(() => {
10752
+ React15.useEffect(() => {
10143
10753
  const threadMode = !!threadId && !!onPostMessage;
10144
10754
  const pipelineMode = !!runId && !!agentsApiUrl;
10145
10755
  if (!threadMode && !pipelineMode) return;
@@ -10225,10 +10835,10 @@ function hydrateAgentIds(ids) {
10225
10835
  };
10226
10836
  });
10227
10837
  }
10228
- function stageReducer(state, action) {
10229
- switch (action.type) {
10838
+ function stageReducer(state, action2) {
10839
+ switch (action2.type) {
10230
10840
  case "TEAM_SETUP": {
10231
- const incomingIds = new Set(action.agents.map((a) => a.id));
10841
+ const incomingIds = new Set(action2.agents.map((a) => a.id));
10232
10842
  let isWholesaleReplace = state.lastBackendTeamIds.size > 0;
10233
10843
  if (isWholesaleReplace) {
10234
10844
  state.lastBackendTeamIds.forEach((id) => {
@@ -10246,48 +10856,48 @@ function stageReducer(state, action) {
10246
10856
  return {
10247
10857
  ...state,
10248
10858
  stage: "team_formation",
10249
- team: [...action.agents, ...surviving],
10859
+ team: [...action2.agents, ...surviving],
10250
10860
  localOnlyAgentIds: nextLocalOnly,
10251
10861
  lastBackendTeamIds: incomingIds
10252
10862
  };
10253
10863
  }
10254
10864
  case "PHASE_ADVANCED": {
10255
- const to = action.to;
10865
+ const to = action2.to;
10256
10866
  if (to === "team_formation") return { ...state, stage: "team_formation" };
10257
10867
  if (to === "schema_seeding") return { ...state, stage: "schema_seeding" };
10258
10868
  if (to === "construction" || to === "synthesis" || to === "done") return { ...state, stage: "graph" };
10259
10869
  return state;
10260
10870
  }
10261
10871
  case "UPDATE_AGENT":
10262
- return { ...state, team: state.team.map((a) => a.id === action.id ? { ...a, ...action.updates } : a) };
10872
+ return { ...state, team: state.team.map((a) => a.id === action2.id ? { ...a, ...action2.updates } : a) };
10263
10873
  case "REMOVE_AGENT": {
10264
10874
  const nextLocalOnly = new Set(state.localOnlyAgentIds);
10265
- nextLocalOnly.delete(action.id);
10875
+ nextLocalOnly.delete(action2.id);
10266
10876
  return {
10267
10877
  ...state,
10268
- team: state.team.filter((a) => a.id !== action.id),
10878
+ team: state.team.filter((a) => a.id !== action2.id),
10269
10879
  localOnlyAgentIds: nextLocalOnly
10270
10880
  };
10271
10881
  }
10272
10882
  case "ADD_AGENT": {
10273
10883
  const nextLocalOnly = new Set(state.localOnlyAgentIds);
10274
- nextLocalOnly.add(action.agent.id);
10884
+ nextLocalOnly.add(action2.agent.id);
10275
10885
  return {
10276
10886
  ...state,
10277
- team: [...state.team, action.agent],
10887
+ team: [...state.team, action2.agent],
10278
10888
  localOnlyAgentIds: nextLocalOnly
10279
10889
  };
10280
10890
  }
10281
10891
  case "SCHEMA_SEEDED":
10282
- return { ...state, schemaNodeTypeCount: action.nodeTypeCount, schemaEdgeTypeCount: action.edgeTypeCount };
10892
+ return { ...state, schemaNodeTypeCount: action2.nodeTypeCount, schemaEdgeTypeCount: action2.edgeTypeCount };
10283
10893
  case "SCHEMA_TYPE_ADDED":
10284
- return { ...state, schemaNodeTypes: state.schemaNodeTypes.includes(action.typeName) ? state.schemaNodeTypes : [...state.schemaNodeTypes, action.typeName] };
10894
+ return { ...state, schemaNodeTypes: state.schemaNodeTypes.includes(action2.typeName) ? state.schemaNodeTypes : [...state.schemaNodeTypes, action2.typeName] };
10285
10895
  case "SCHEMA_TEXT": {
10286
10896
  const rels = [];
10287
10897
  const nodeTypes2 = new Set(state.schemaNodeTypes);
10288
10898
  const relPattern = /(\w+)\s*:\s*\[([^\]]*)\]\s*→\s*\[([^\]]*)\]/g;
10289
10899
  let m;
10290
- while ((m = relPattern.exec(action.text)) !== null) {
10900
+ while ((m = relPattern.exec(action2.text)) !== null) {
10291
10901
  const name = m[1];
10292
10902
  const domain = m[2].split(",").map((s) => s.replace(/"/g, "").trim()).filter(Boolean);
10293
10903
  const range = m[3].split(",").map((s) => s.replace(/"/g, "").trim()).filter(Boolean);
@@ -10302,7 +10912,7 @@ function stageReducer(state, action) {
10302
10912
  };
10303
10913
  }
10304
10914
  case "DOC_STEP": {
10305
- const step = action.step;
10915
+ const step = action2.step;
10306
10916
  if (step === "complete") return { ...state, stage: "graph" };
10307
10917
  if (step === "processing" || step === "vocabulary") return { ...state, stage: "doc_preparing" };
10308
10918
  if (step === "extracting") return { ...state, stage: "doc_extracting" };
@@ -10311,7 +10921,7 @@ function stageReducer(state, action) {
10311
10921
  return state;
10312
10922
  }
10313
10923
  case "DOC_ACTIVITY":
10314
- return { ...state, docActivity: [...state.docActivity, action.item] };
10924
+ return { ...state, docActivity: [...state.docActivity, action2.item] };
10315
10925
  case "FORCE_GRAPH":
10316
10926
  return { ...state, stage: "graph" };
10317
10927
  default:
@@ -10332,7 +10942,7 @@ var initialState = {
10332
10942
  docActivity: []
10333
10943
  };
10334
10944
  function StageCanvas({ nodeCount, onForceGraph, initialPhase, initialTeam, kgId }) {
10335
- const [state, dispatch] = React12.useReducer(stageReducer, initialState, (base) => {
10945
+ const [state, dispatch] = React15.useReducer(stageReducer, initialState, (base) => {
10336
10946
  if (!initialPhase) return base;
10337
10947
  let stage = "idle";
10338
10948
  if (initialPhase === "team_formation") stage = "team_formation";
@@ -10341,13 +10951,13 @@ function StageCanvas({ nodeCount, onForceGraph, initialPhase, initialTeam, kgId
10341
10951
  const team = initialTeam && initialTeam.length > 0 ? initialTeam : stage === "team_formation" ? hydrateAgentIds(["proposer", "critic", "synthesizer"]) : base.team;
10342
10952
  return { ...base, stage, team };
10343
10953
  });
10344
- React12.useEffect(() => {
10954
+ React15.useEffect(() => {
10345
10955
  if (initialPhase) dispatch({ type: "PHASE_ADVANCED", to: initialPhase });
10346
10956
  }, [initialPhase]);
10347
- React12.useEffect(() => {
10957
+ React15.useEffect(() => {
10348
10958
  if (initialTeam && initialTeam.length > 0) dispatch({ type: "TEAM_SETUP", agents: initialTeam });
10349
10959
  }, [initialTeam]);
10350
- const handleProgressEvent = React12.useCallback((event) => {
10960
+ const handleProgressEvent = React15.useCallback((event) => {
10351
10961
  if (!event?.type) return;
10352
10962
  switch (event.type) {
10353
10963
  case "TeamSetup":
@@ -10436,7 +11046,7 @@ function StageCanvas({ nodeCount, onForceGraph, initialPhase, initialTeam, kgId
10436
11046
  }
10437
11047
  }, []);
10438
11048
  useScopedProgressEvent(kgId, handleProgressEvent);
10439
- React12.useEffect(() => {
11049
+ React15.useEffect(() => {
10440
11050
  const handler = (e) => {
10441
11051
  const event = e.detail;
10442
11052
  if (!event?.step) return;
@@ -10542,8 +11152,8 @@ var STATUS_COLORS = {
10542
11152
  idle: "#6b7280"
10543
11153
  };
10544
11154
  function AgentPresenceBar({ listenForEvents = true, agents: agentsProp, kgId }) {
10545
- const [agents, setAgents] = React12.useState(/* @__PURE__ */ new Map());
10546
- const handleAgentEvent = React12.useCallback((event) => {
11155
+ const [agents, setAgents] = React15.useState(/* @__PURE__ */ new Map());
11156
+ const handleAgentEvent = React15.useCallback((event) => {
10547
11157
  if (!event?.type) return;
10548
11158
  switch (event.type) {
10549
11159
  case "TeamSetup": {
@@ -10958,7 +11568,7 @@ function ClaimNodeComponent({ data, selected }) {
10958
11568
  /* @__PURE__ */ jsxRuntime.jsx(react.Handle, { type: "source", position: react.Position.Bottom, style: { background: borderColor, border: "none", width: 6, height: 6 } })
10959
11569
  ] });
10960
11570
  }
10961
- var ClaimNode = React12.memo(ClaimNodeComponent);
11571
+ var ClaimNode = React15.memo(ClaimNodeComponent);
10962
11572
  function extractTitle(text) {
10963
11573
  const headingMatch = text.match(/^#{1,4}\s+(.+)/m);
10964
11574
  if (headingMatch) {
@@ -11057,7 +11667,7 @@ function NoteCardComponent({ data, selected }) {
11057
11667
  /* @__PURE__ */ jsxRuntime.jsx(react.Handle, { type: "source", position: react.Position.Bottom, style: { opacity: 0, width: 1, height: 1 } })
11058
11668
  ] });
11059
11669
  }
11060
- var NoteCard = React12.memo(NoteCardComponent);
11670
+ var NoteCard = React15.memo(NoteCardComponent);
11061
11671
 
11062
11672
  // src/knowledge/claimsProjection.ts
11063
11673
  function buildClaimsGraph(nodes, edges) {
@@ -11128,13 +11738,13 @@ var PIPELINE_STEPS = [
11128
11738
  { key: "construction", label: "Building", short: "B" }
11129
11739
  ];
11130
11740
  function PipelineProgressBar({ listenForEvents = true, currentPhase: currentPhaseProp, completedPhases: completedProp, kgId }) {
11131
- const [currentPhase, setCurrentPhase] = React12.useState(currentPhaseProp || "");
11132
- const [completed, setCompleted] = React12.useState(new Set(completedProp || []));
11133
- const [backtracking, setBacktracking] = React12.useState(false);
11134
- React12.useEffect(() => {
11741
+ const [currentPhase, setCurrentPhase] = React15.useState(currentPhaseProp || "");
11742
+ const [completed, setCompleted] = React15.useState(new Set(completedProp || []));
11743
+ const [backtracking, setBacktracking] = React15.useState(false);
11744
+ React15.useEffect(() => {
11135
11745
  if (currentPhaseProp) setCurrentPhase(currentPhaseProp);
11136
11746
  }, [currentPhaseProp]);
11137
- const handlePipelineEvent = React12.useCallback((event) => {
11747
+ const handlePipelineEvent = React15.useCallback((event) => {
11138
11748
  if (!event?.type) return;
11139
11749
  const isAdvance = event.type === "PhaseAdvanced" || event.type === "transform_extension" && event.kind === "phase_advanced";
11140
11750
  const isBacktrack = event.type === "PhaseBacktracked" || event.type === "transform_extension" && event.kind === "phase_backtracked";
@@ -11177,7 +11787,7 @@ function PipelineProgressBar({ listenForEvents = true, currentPhase: currentPhas
11177
11787
  PIPELINE_STEPS.map((step, i) => {
11178
11788
  const isCompleted = completed.has(step.key) || i < currentIdx;
11179
11789
  const isCurrent = step.key === currentPhase;
11180
- return /* @__PURE__ */ jsxRuntime.jsxs(React12__default.default.Fragment, { children: [
11790
+ return /* @__PURE__ */ jsxRuntime.jsxs(React15__default.default.Fragment, { children: [
11181
11791
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(
11182
11792
  "div",
11183
11793
  {
@@ -11250,9 +11860,9 @@ var EMPTY_STATE = {
11250
11860
  edgeCount: 0
11251
11861
  };
11252
11862
  function ConstructionProgress({ kgId } = {}) {
11253
- const [state, setState] = React12.useState(null);
11254
- const [isBuilding, setIsBuilding] = React12.useState(false);
11255
- const handleConstructionEvent = React12.useCallback((event) => {
11863
+ const [state, setState] = React15.useState(null);
11864
+ const [isBuilding, setIsBuilding] = React15.useState(false);
11865
+ const handleConstructionEvent = React15.useCallback((event) => {
11256
11866
  if (!event?.type) return;
11257
11867
  const isAdvance = event.type === "PhaseAdvanced" || event.type === "transform_extension" && event.kind === "phase_advanced";
11258
11868
  if (isAdvance && event.to === "construction") {
@@ -11361,12 +11971,12 @@ function ConstructionProgress({ kgId } = {}) {
11361
11971
  }
11362
11972
  var MAX_ADOPTED_KG_IDS = 16;
11363
11973
  function useAdoptedKgIds(kgId) {
11364
- const adoptedKgIdsRef = React12.useRef(/* @__PURE__ */ new Set());
11365
- const kgIdRef = React12.useRef(kgId);
11366
- React12.useEffect(() => {
11974
+ const adoptedKgIdsRef = React15.useRef(/* @__PURE__ */ new Set());
11975
+ const kgIdRef = React15.useRef(kgId);
11976
+ React15.useEffect(() => {
11367
11977
  kgIdRef.current = kgId;
11368
11978
  }, [kgId]);
11369
- const adoptKgIdFromChunk = React12.useCallback(
11979
+ const adoptKgIdFromChunk = React15.useCallback(
11370
11980
  (chunk, progress) => {
11371
11981
  if (isFixedKgId(kgIdRef.current)) return;
11372
11982
  const fromChunk = extractKgId(chunk, progress);
@@ -11379,7 +11989,7 @@ function useAdoptedKgIds(kgId) {
11379
11989
  },
11380
11990
  []
11381
11991
  );
11382
- const hasOwnedKgId = React12.useCallback((id) => {
11992
+ const hasOwnedKgId = React15.useCallback((id) => {
11383
11993
  if (id === kgIdRef.current) return true;
11384
11994
  return adoptedKgIdsRef.current.has(id);
11385
11995
  }, []);
@@ -11394,7 +12004,7 @@ function useReasoningKeepalive({
11394
12004
  authToken
11395
12005
  }) {
11396
12006
  const isRealKg = isFixedKgId(kgId);
11397
- React12.useEffect(() => {
12007
+ React15.useEffect(() => {
11398
12008
  if (!isRealKg || !runId || isLiveReasoning || !agentsApiUrl) return;
11399
12009
  const abort = new AbortController();
11400
12010
  const broadcastProgress = (event) => {
@@ -11425,12 +12035,12 @@ function useCheckpointCard({
11425
12035
  isLoadedSession,
11426
12036
  initialPhase
11427
12037
  }) {
11428
- const [checkpoint, setCheckpoint] = React12.useState(null);
11429
- const currentPhaseRef = React12.useRef(initialPhase || "");
11430
- React12.useEffect(() => {
12038
+ const [checkpoint, setCheckpoint] = React15.useState(null);
12039
+ const currentPhaseRef = React15.useRef(initialPhase || "");
12040
+ React15.useEffect(() => {
11431
12041
  if (initialPhase) currentPhaseRef.current = initialPhase;
11432
12042
  }, [initialPhase]);
11433
- const handler = React12.useCallback(
12043
+ const handler = React15.useCallback(
11434
12044
  (event) => {
11435
12045
  if (!event?.type) return;
11436
12046
  if (event.type === "PhaseAdvanced" || event.type === "PhaseBacktracked" || event.type === "transform_extension") {
@@ -11475,7 +12085,7 @@ function useCheckpointCard({
11475
12085
  handler,
11476
12086
  (!!threadId || !!runId) && !isLoadedSession
11477
12087
  );
11478
- const setCheckpointResponded = React12.useCallback(() => {
12088
+ const setCheckpointResponded = React15.useCallback(() => {
11479
12089
  setCheckpoint((prev) => prev ? { ...prev, responded: true } : null);
11480
12090
  }, []);
11481
12091
  return { checkpoint, setCheckpointResponded };
@@ -11511,10 +12121,10 @@ function GraphChatPanel({
11511
12121
  reasoningPhase,
11512
12122
  authToken
11513
12123
  }) {
11514
- const accumulatedTextRef = React12.useRef("");
11515
- const conversationRef = React12.useRef([]);
11516
- const historyRef = React12.useRef(null);
11517
- const [loadedHistory, setLoadedHistory] = React12.useState(null);
12124
+ const accumulatedTextRef = React15.useRef("");
12125
+ const conversationRef = React15.useRef([]);
12126
+ const historyRef = React15.useRef(null);
12127
+ const [loadedHistory, setLoadedHistory] = React15.useState(null);
11518
12128
  const { adoptKgIdFromChunk, hasOwnedKgId } = useAdoptedKgIds(kgId);
11519
12129
  useReasoningKeepalive({
11520
12130
  kgId,
@@ -11523,7 +12133,7 @@ function GraphChatPanel({
11523
12133
  agentsApiUrl: config.agentsApiUrl,
11524
12134
  authToken
11525
12135
  });
11526
- const narrativeHandler = React12.useCallback((event) => {
12136
+ const narrativeHandler = React15.useCallback((event) => {
11527
12137
  if (event?.type !== "transform_extension" || event?.kind !== "narrative_text") return;
11528
12138
  const text = event?.payload?.text;
11529
12139
  if (typeof text !== "string" || !text.trim()) return;
@@ -11559,7 +12169,7 @@ function GraphChatPanel({
11559
12169
  kgId,
11560
12170
  agentsApiUrl: config.agentsApiUrl
11561
12171
  });
11562
- const deduplicateMessages = React12.useCallback((sorted) => {
12172
+ const deduplicateMessages = React15.useCallback((sorted) => {
11563
12173
  return sorted.filter((msg, i) => {
11564
12174
  if (i === 0) return true;
11565
12175
  const prev = sorted[i - 1];
@@ -11567,7 +12177,7 @@ function GraphChatPanel({
11567
12177
  return true;
11568
12178
  });
11569
12179
  }, []);
11570
- const mapMessages = React12.useCallback((msgs) => {
12180
+ const mapMessages = React15.useCallback((msgs) => {
11571
12181
  const nonEmpty = msgs.filter((m) => typeof m.content === "string" && m.content.trim().length > 0);
11572
12182
  const sorted = nonEmpty.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
11573
12183
  const deduped = deduplicateMessages(sorted);
@@ -11590,7 +12200,7 @@ function GraphChatPanel({
11590
12200
  };
11591
12201
  });
11592
12202
  }, [deduplicateMessages, currentUser]);
11593
- React12.useEffect(() => {
12203
+ React15.useEffect(() => {
11594
12204
  if (!threadId) {
11595
12205
  console.warn("[GraphChatPanel] no threadId \u2014 skipping history load", { groupId, kgId });
11596
12206
  return;
@@ -11629,7 +12239,7 @@ function GraphChatPanel({
11629
12239
  cancelled = true;
11630
12240
  };
11631
12241
  }, [groupId, threadId, mapMessages]);
11632
- const onPollMessages = React12.useCallback(async () => {
12242
+ const onPollMessages = React15.useCallback(async () => {
11633
12243
  if (!threadId) return [];
11634
12244
  try {
11635
12245
  const msgs = await onLoadMessages(groupId, threadId);
@@ -11642,14 +12252,14 @@ function GraphChatPanel({
11642
12252
  return [];
11643
12253
  }
11644
12254
  }, [groupId, threadId, mapMessages]);
11645
- const defaultHistory = React12.useMemo(() => [
12255
+ const defaultHistory = React15.useMemo(() => [
11646
12256
  {
11647
12257
  type: "system",
11648
12258
  content: threadId ? "Reasoning session \u2014 agent progress and your questions appear here." : "Ask questions about this document. Answers are grounded in the knowledge graph.",
11649
12259
  timestamp: /* @__PURE__ */ new Date()
11650
12260
  }
11651
12261
  ], [threadId]);
11652
- const resumeOrInputPipeline = React12.useCallback(async (message) => {
12262
+ const resumeOrInputPipeline = React15.useCallback(async (message) => {
11653
12263
  if (!runId || !config.agentsApiUrl) return;
11654
12264
  if (checkpoint) setCheckpointResponded();
11655
12265
  const trimmed = message.trim();
@@ -11662,7 +12272,7 @@ function GraphChatPanel({
11662
12272
  });
11663
12273
  historyRef.current?.setIsExecuting?.(false);
11664
12274
  }, [runId, checkpoint, config.agentsApiUrl, setCheckpointResponded]);
11665
- const onSendMessage = React12.useCallback(async (content) => {
12275
+ const onSendMessage = React15.useCallback(async (content) => {
11666
12276
  if (runId && !threadId && checkpoint) {
11667
12277
  historyRef.current?.setIsExecuting?.(true);
11668
12278
  resumeOrInputPipeline(content).catch(() => {
@@ -11695,7 +12305,7 @@ function GraphChatPanel({
11695
12305
  sender: currentUser
11696
12306
  };
11697
12307
  }, [groupId, threadId, runId, currentUser, resumeOrInputPipeline]);
11698
- const extractSources = React12.useCallback((text) => {
12308
+ const extractSources = React15.useCallback((text) => {
11699
12309
  const lower = text.toLowerCase();
11700
12310
  const matched = [];
11701
12311
  const seen = /* @__PURE__ */ new Set();
@@ -11740,7 +12350,7 @@ function GraphChatPanel({
11740
12350
  }
11741
12351
  return matched;
11742
12352
  }, [rawNodes]);
11743
- const onStreamRequest = React12.useCallback(async (command, handlers) => {
12353
+ const onStreamRequest = React15.useCallback(async (command, handlers) => {
11744
12354
  accumulatedTextRef.current = "";
11745
12355
  let senderOverridden = false;
11746
12356
  let mentionedAgent;
@@ -11852,7 +12462,7 @@ ${kgContext}` : ""}`,
11852
12462
  handlers.onError
11853
12463
  );
11854
12464
  }, [groupId, kgId, threadId, onHighlightNodes, extractSources, config.agentsApiUrl, onStreamChat, adoptKgIdFromChunk]);
11855
- const sourceKGNodes = React12.useMemo(
12465
+ const sourceKGNodes = React15.useMemo(
11856
12466
  () => rawNodes.map((n) => ({
11857
12467
  id: n.node_key,
11858
12468
  label: n.label,
@@ -11868,7 +12478,7 @@ ${kgContext}` : ""}`,
11868
12478
  })),
11869
12479
  [rawNodes]
11870
12480
  );
11871
- const mentionTargets = React12.useMemo(() => {
12481
+ const mentionTargets = React15.useMemo(() => {
11872
12482
  const agentKeys = /* @__PURE__ */ new Set();
11873
12483
  for (const n of rawNodes) {
11874
12484
  const key = n.source_agent_key || n.created_by || n.properties?.created_by || n.properties?.source_agent_key;
@@ -11978,8 +12588,8 @@ function extractTitle2(text) {
11978
12588
  function stripMarkdown2(text) {
11979
12589
  return text.replace(/#{1,6}\s+/g, "").replace(/\*\*(.+?)\*\*/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/`(.+?)`/g, "$1").replace(/\[(.+?)\]\(.+?\)/g, "$1").replace(/^[-*+]\s+/gm, "").replace(/^\d+\.\s+/gm, "").replace(/\n{2,}/g, " ").trim();
11980
12590
  }
11981
- var NotesList = React12.memo(function NotesList2({ chunks, selectedId, onSelect, onCreateNote, filter }) {
11982
- const allNotes = React12.useMemo(() => {
12591
+ var NotesList = React15.memo(function NotesList2({ chunks, selectedId, onSelect, onCreateNote, filter }) {
12592
+ const allNotes = React15.useMemo(() => {
11983
12593
  const byChunk = /* @__PURE__ */ new Map();
11984
12594
  for (const link of chunks) {
11985
12595
  const list = byChunk.get(link.chunk_id) ?? [];
@@ -12000,7 +12610,7 @@ var NotesList = React12.memo(function NotesList2({ chunks, selectedId, onSelect,
12000
12610
  groups.sort((a, b) => (a.chunkIndex ?? Infinity) - (b.chunkIndex ?? Infinity));
12001
12611
  return groups;
12002
12612
  }, [chunks]);
12003
- const notes = React12.useMemo(() => {
12613
+ const notes = React15.useMemo(() => {
12004
12614
  if (!filter || !filter.trim()) return allNotes;
12005
12615
  const q = filter.toLowerCase().trim();
12006
12616
  return allNotes.filter((n) => n.excerpt.toLowerCase().includes(q));
@@ -12200,19 +12810,19 @@ function NoteExtractionToast({
12200
12810
  onRunFailed,
12201
12811
  authToken
12202
12812
  }) {
12203
- const [phase, setPhase] = React12.useState("Saving note\u2026");
12204
- const [successFlash, setSuccessFlash] = React12.useState(false);
12205
- const [error, setError] = React12.useState(null);
12206
- const abortsRef = React12.useRef(/* @__PURE__ */ new Map());
12207
- const onRunCompleteRef = React12.useRef(onRunComplete);
12208
- const onRunFailedRef = React12.useRef(onRunFailed);
12209
- React12.useEffect(() => {
12813
+ const [phase, setPhase] = React15.useState("Saving note\u2026");
12814
+ const [successFlash, setSuccessFlash] = React15.useState(false);
12815
+ const [error, setError] = React15.useState(null);
12816
+ const abortsRef = React15.useRef(/* @__PURE__ */ new Map());
12817
+ const onRunCompleteRef = React15.useRef(onRunComplete);
12818
+ const onRunFailedRef = React15.useRef(onRunFailed);
12819
+ React15.useEffect(() => {
12210
12820
  onRunCompleteRef.current = onRunComplete;
12211
12821
  }, [onRunComplete]);
12212
- React12.useEffect(() => {
12822
+ React15.useEffect(() => {
12213
12823
  onRunFailedRef.current = onRunFailed;
12214
12824
  }, [onRunFailed]);
12215
- React12.useEffect(() => {
12825
+ React15.useEffect(() => {
12216
12826
  const controllers = abortsRef.current;
12217
12827
  for (const run of runs) {
12218
12828
  if (controllers.has(run.run_id)) continue;
@@ -12263,7 +12873,7 @@ function NoteExtractionToast({
12263
12873
  }
12264
12874
  }
12265
12875
  }, [runs, agentsApiUrl, authToken]);
12266
- React12.useEffect(() => {
12876
+ React15.useEffect(() => {
12267
12877
  if (runs.length === 0 && !error) {
12268
12878
  setSuccessFlash(true);
12269
12879
  const t = setTimeout(() => setSuccessFlash(false), 1800);
@@ -12271,7 +12881,7 @@ function NoteExtractionToast({
12271
12881
  }
12272
12882
  if (runs.length > 0) setSuccessFlash(false);
12273
12883
  }, [runs.length, error]);
12274
- React12.useEffect(() => {
12884
+ React15.useEffect(() => {
12275
12885
  return () => {
12276
12886
  abortsRef.current.forEach((abort) => abort.abort());
12277
12887
  abortsRef.current.clear();
@@ -12383,10 +12993,10 @@ function KnowledgeGraphView({
12383
12993
  }) {
12384
12994
  const [nodes, setNodes, onNodesChangeBase] = react.useNodesState([]);
12385
12995
  const [edges, setEdges, onEdgesChange] = react.useEdgesState([]);
12386
- const liveNodePositionsRef = React12.useRef(/* @__PURE__ */ new Map());
12387
- const [activityItems, setActivityItems] = React12.useState([]);
12388
- const prevActivityLenRef = React12.useRef(0);
12389
- React12.useEffect(() => {
12996
+ const liveNodePositionsRef = React15.useRef(/* @__PURE__ */ new Map());
12997
+ const [activityItems, setActivityItems] = React15.useState([]);
12998
+ const prevActivityLenRef = React15.useRef(0);
12999
+ React15.useEffect(() => {
12390
13000
  if (!activityEvents || activityEvents.length <= prevActivityLenRef.current) {
12391
13001
  prevActivityLenRef.current = activityEvents?.length || 0;
12392
13002
  return;
@@ -12399,23 +13009,23 @@ function KnowledgeGraphView({
12399
13009
  }
12400
13010
  }, [activityEvents?.length]);
12401
13011
  const useWindowEvents = !activityEvents;
12402
- const [liveRefreshTrigger, setLiveRefreshTrigger] = React12.useState(0);
12403
- const lastPersistRef = React12.useRef(0);
12404
- const pipelineDoneRef = React12.useRef(false);
12405
- const pendingActivityRef = React12.useRef([]);
12406
- const activityFlushRef = React12.useRef(null);
12407
- const flushActivity = React12.useCallback(() => {
13012
+ const [liveRefreshTrigger, setLiveRefreshTrigger] = React15.useState(0);
13013
+ const lastPersistRef = React15.useRef(0);
13014
+ const pipelineDoneRef = React15.useRef(false);
13015
+ const pendingActivityRef = React15.useRef([]);
13016
+ const activityFlushRef = React15.useRef(null);
13017
+ const flushActivity = React15.useCallback(() => {
12408
13018
  activityFlushRef.current = null;
12409
13019
  if (pendingActivityRef.current.length === 0) return;
12410
13020
  const batch = pendingActivityRef.current;
12411
13021
  pendingActivityRef.current = [];
12412
13022
  setActivityItems((prev) => [...prev, ...batch]);
12413
13023
  }, []);
12414
- React12.useEffect(() => () => {
13024
+ React15.useEffect(() => () => {
12415
13025
  if (activityFlushRef.current) clearTimeout(activityFlushRef.current);
12416
13026
  flushActivity();
12417
13027
  }, [flushActivity]);
12418
- const handleActivityEvent = React12.useCallback((event) => {
13028
+ const handleActivityEvent = React15.useCallback((event) => {
12419
13029
  if (pipelineDoneRef.current) return;
12420
13030
  const item = eventToActivity(event);
12421
13031
  if (item) {
@@ -12438,8 +13048,8 @@ function KnowledgeGraphView({
12438
13048
  }
12439
13049
  }, [flushActivity]);
12440
13050
  useScopedProgressEvent(kgId, handleActivityEvent, useWindowEvents);
12441
- const [forceGraph, setForceGraph] = React12.useState(false);
12442
- const onNodesChange = React12.useCallback((changes) => {
13051
+ const [forceGraph, setForceGraph] = React15.useState(false);
13052
+ const onNodesChange = React15.useCallback((changes) => {
12443
13053
  onNodesChangeBase(changes);
12444
13054
  for (const change of changes) {
12445
13055
  if (change.type === "position" && "position" in change && change.position) {
@@ -12447,29 +13057,29 @@ function KnowledgeGraphView({
12447
13057
  }
12448
13058
  }
12449
13059
  }, [onNodesChangeBase]);
12450
- const [loading, setLoading] = React12.useState(true);
12451
- const [error, setError] = React12.useState(null);
12452
- const [searchTerm, setSearchTerm] = React12.useState("");
12453
- const [phaseFilter, setPhaseFilter] = React12.useState("all");
12454
- const [isFullscreen, setIsFullscreen] = React12.useState(false);
12455
- const [selectedNodeId, setSelectedNodeId] = React12.useState(null);
12456
- const [selectedEdgeId, setSelectedEdgeId] = React12.useState(null);
12457
- const [hoveredNodeId, setHoveredNodeId] = React12.useState(null);
13060
+ const [loading, setLoading] = React15.useState(true);
13061
+ const [error, setError] = React15.useState(null);
13062
+ const [searchTerm, setSearchTerm] = React15.useState("");
13063
+ const [phaseFilter, setPhaseFilter] = React15.useState("all");
13064
+ const [isFullscreen, setIsFullscreen] = React15.useState(false);
13065
+ const [selectedNodeId, setSelectedNodeId] = React15.useState(null);
13066
+ const [selectedEdgeId, setSelectedEdgeId] = React15.useState(null);
13067
+ const [hoveredNodeId, setHoveredNodeId] = React15.useState(null);
12458
13068
  const hasChat = !!(renderChat || config);
12459
- const [chatOpen, setChatOpen] = React12.useState(hasChat);
12460
- const [chatMounted, setChatMounted] = React12.useState(hasChat);
12461
- React12.useEffect(() => {
13069
+ const [chatOpen, setChatOpen] = React15.useState(hasChat);
13070
+ const [chatMounted, setChatMounted] = React15.useState(hasChat);
13071
+ React15.useEffect(() => {
12462
13072
  if (chatOpen && !chatMounted) setChatMounted(true);
12463
13073
  }, [chatOpen]);
12464
- React12.useEffect(() => {
13074
+ React15.useEffect(() => {
12465
13075
  if ((runId || genericKGProp) && hasChat && !chatOpen) {
12466
13076
  setChatOpen(true);
12467
13077
  setChatMounted(true);
12468
13078
  }
12469
13079
  }, [runId, genericKGProp, hasChat]);
12470
- const [chatQuery, setChatQuery] = React12.useState(void 0);
12471
- const [ontologyOpen, setOntologyOpen] = React12.useState(false);
12472
- React12.useEffect(() => {
13080
+ const [chatQuery, setChatQuery] = React15.useState(void 0);
13081
+ const [ontologyOpen, setOntologyOpen] = React15.useState(false);
13082
+ React15.useEffect(() => {
12473
13083
  if (chatToggleRef) {
12474
13084
  chatToggleRef.current = () => {
12475
13085
  setChatOpen((v) => !v);
@@ -12480,43 +13090,43 @@ function KnowledgeGraphView({
12480
13090
  };
12481
13091
  }
12482
13092
  }, [chatToggleRef]);
12483
- const [searching, setSearching] = React12.useState(false);
12484
- const [searchResult, setSearchResult] = React12.useState({ hits: [], traversal: [] });
12485
- const [searchActive, setSearchActive] = React12.useState(false);
12486
- const searchTimerRef = React12.useRef(null);
12487
- const fitViewTimerRef = React12.useRef(null);
12488
- const rfInstanceRef = React12.useRef(null);
12489
- const didInitialFitRef = React12.useRef(false);
12490
- const [rfReady, setRfReady] = React12.useState(false);
12491
- React12.useEffect(() => {
13093
+ const [searching, setSearching] = React15.useState(false);
13094
+ const [searchResult, setSearchResult] = React15.useState({ hits: [], traversal: [] });
13095
+ const [searchActive, setSearchActive] = React15.useState(false);
13096
+ const searchTimerRef = React15.useRef(null);
13097
+ const fitViewTimerRef = React15.useRef(null);
13098
+ const rfInstanceRef = React15.useRef(null);
13099
+ const didInitialFitRef = React15.useRef(false);
13100
+ const [rfReady, setRfReady] = React15.useState(false);
13101
+ React15.useEffect(() => {
12492
13102
  didInitialFitRef.current = false;
12493
13103
  setRfReady(false);
12494
13104
  }, [kgId]);
12495
- const gkgNodeMap = React12.useMemo(() => {
13105
+ const gkgNodeMap = React15.useMemo(() => {
12496
13106
  if (!genericKGProp) return /* @__PURE__ */ new Map();
12497
13107
  return new Map(genericKGProp.nodes.map((n) => [n.id, n]));
12498
13108
  }, [genericKGProp]);
12499
- const gkgEdgeMap = React12.useMemo(() => {
13109
+ const gkgEdgeMap = React15.useMemo(() => {
12500
13110
  if (!genericKGProp) return /* @__PURE__ */ new Map();
12501
13111
  return new Map(genericKGProp.edges.map((e) => [e.id, e]));
12502
13112
  }, [genericKGProp]);
12503
- const fullNodesRef = React12.useRef([]);
12504
- const fullEdgesRef = React12.useRef([]);
12505
- const [rawNodes, setRawNodes] = React12.useState([]);
12506
- const [rawEdges, setRawEdges] = React12.useState([]);
12507
- const [nodeChunks, setNodeChunks] = React12.useState([]);
13113
+ const fullNodesRef = React15.useRef([]);
13114
+ const fullEdgesRef = React15.useRef([]);
13115
+ const [rawNodes, setRawNodes] = React15.useState([]);
13116
+ const [rawEdges, setRawEdges] = React15.useState([]);
13117
+ const [nodeChunks, setNodeChunks] = React15.useState([]);
12508
13118
  const hasLiveReasoning = !!runId || !!genericKGProp;
12509
- const [viewMode, setViewMode] = React12.useState(
13119
+ const [viewMode, setViewMode] = React15.useState(
12510
13120
  hasLiveReasoning ? "entity" : data.onLoadAllChunks ? "chunk" : "entity"
12511
13121
  );
12512
- const viewModeRef = React12.useRef(viewMode);
13122
+ const viewModeRef = React15.useRef(viewMode);
12513
13123
  viewModeRef.current = viewMode;
12514
- const [allChunks, setAllChunks] = React12.useState(null);
12515
- const [chunksLoading, setChunksLoading] = React12.useState(false);
12516
- const [draftNote, setDraftNote] = React12.useState(null);
12517
- const [savingDraft, setSavingDraft] = React12.useState(false);
12518
- const [noteRuns, setNoteRuns] = React12.useState([]);
12519
- const handleNoteRunFinished = React12.useCallback((runId2) => {
13124
+ const [allChunks, setAllChunks] = React15.useState(null);
13125
+ const [chunksLoading, setChunksLoading] = React15.useState(false);
13126
+ const [draftNote, setDraftNote] = React15.useState(null);
13127
+ const [savingDraft, setSavingDraft] = React15.useState(false);
13128
+ const [noteRuns, setNoteRuns] = React15.useState([]);
13129
+ const handleNoteRunFinished = React15.useCallback((runId2) => {
12520
13130
  setNoteRuns((prev) => {
12521
13131
  const next = prev.filter((r) => r.run_id !== runId2);
12522
13132
  if (next.length === 0 && data.onLoadAllChunks) {
@@ -12525,9 +13135,9 @@ function KnowledgeGraphView({
12525
13135
  return next;
12526
13136
  });
12527
13137
  }, [data, groupId, kgId]);
12528
- React12.useRef(null);
12529
- React12.useRef(null);
12530
- React12.useEffect(() => {
13138
+ React15.useRef(null);
13139
+ React15.useRef(null);
13140
+ React15.useEffect(() => {
12531
13141
  if (!selectedNodeId) {
12532
13142
  setNodeChunks([]);
12533
13143
  return;
@@ -12553,7 +13163,7 @@ function KnowledgeGraphView({
12553
13163
  cancelled = true;
12554
13164
  };
12555
13165
  }, [selectedNodeId, groupId, kgId, allChunks]);
12556
- React12.useEffect(() => {
13166
+ React15.useEffect(() => {
12557
13167
  if (allChunks !== null || !data.onLoadAllChunks) return;
12558
13168
  let cancelled = false;
12559
13169
  setChunksLoading(true);
@@ -12569,8 +13179,8 @@ function KnowledgeGraphView({
12569
13179
  cancelled = true;
12570
13180
  };
12571
13181
  }, [viewMode, allChunks, groupId, kgId, data.onLoadAllChunks]);
12572
- const prevViewModeRef = React12.useRef(viewMode);
12573
- React12.useEffect(() => {
13182
+ const prevViewModeRef = React15.useRef(viewMode);
13183
+ React15.useEffect(() => {
12574
13184
  const modeChanged = prevViewModeRef.current !== viewMode;
12575
13185
  prevViewModeRef.current = viewMode;
12576
13186
  if (viewMode === "entity") {
@@ -12632,7 +13242,7 @@ function KnowledgeGraphView({
12632
13242
  fitViewTimerRef.current = setTimeout(() => rfInstanceRef.current?.fitView({ padding: 0.2, duration: 300 }), 60);
12633
13243
  }
12634
13244
  }, [viewMode, allChunks, rawNodes, rawEdges]);
12635
- const buildRfGraph = React12.useCallback((subgraph, existingPositions) => {
13245
+ const buildRfGraph = React15.useCallback((subgraph, existingPositions) => {
12636
13246
  const rfNodes = subgraph.nodes.map((n) => {
12637
13247
  const gkg = gkgNodeMap.get(n.node_key);
12638
13248
  const filterValue = gkg?.claim_status ?? n.properties?.claim_status ?? gkg?.phase ?? n.properties?.phase;
@@ -12683,8 +13293,8 @@ function KnowledgeGraphView({
12683
13293
  }));
12684
13294
  return { rfNodes, rfEdges };
12685
13295
  }, [phaseFilter, gkgNodeMap]);
12686
- const prevNodeIdsRef = React12.useRef("");
12687
- const applyRfGraph = React12.useCallback((rfNodes, rfEdges, existingPositions) => {
13296
+ const prevNodeIdsRef = React15.useRef("");
13297
+ const applyRfGraph = React15.useCallback((rfNodes, rfEdges, existingPositions) => {
12688
13298
  const nodeIds = rfNodes.map((n) => n.id).join(",");
12689
13299
  const structureChanged = nodeIds !== prevNodeIdsRef.current || existingPositions.size === 0;
12690
13300
  prevNodeIdsRef.current = nodeIds;
@@ -12721,7 +13331,7 @@ function KnowledgeGraphView({
12721
13331
  setNodes(finalNodes);
12722
13332
  setEdges(rfEdges);
12723
13333
  }, [setNodes, setEdges]);
12724
- React12.useEffect(() => {
13334
+ React15.useEffect(() => {
12725
13335
  let cancelled = false;
12726
13336
  const isLiveUpdate = !!genericKGProp;
12727
13337
  (async () => {
@@ -12792,7 +13402,7 @@ function KnowledgeGraphView({
12792
13402
  cancelled = true;
12793
13403
  };
12794
13404
  }, [groupId, kgId, genericKGProp, data.onLoadKg, liveRefreshTrigger]);
12795
- React12.useEffect(() => {
13405
+ React15.useEffect(() => {
12796
13406
  if (!rfReady) return;
12797
13407
  if (nodes.length === 0) return;
12798
13408
  if (didInitialFitRef.current) return;
@@ -12802,8 +13412,8 @@ function KnowledgeGraphView({
12802
13412
  });
12803
13413
  return () => cancelAnimationFrame(raf);
12804
13414
  }, [rfReady, nodes.length, kgId]);
12805
- const prevSnapshotFingerprintRef = React12.useRef("");
12806
- React12.useEffect(() => {
13415
+ const prevSnapshotFingerprintRef = React15.useRef("");
13416
+ React15.useEffect(() => {
12807
13417
  if (!processingDetail && !runId) return;
12808
13418
  if (!isFixedKgId(kgId)) return;
12809
13419
  const interval = setInterval(async () => {
@@ -12829,7 +13439,7 @@ function KnowledgeGraphView({
12829
13439
  }, 5e3);
12830
13440
  return () => clearInterval(interval);
12831
13441
  }, [!!processingDetail, !!runId, groupId, kgId, buildRfGraph, applyRfGraph]);
12832
- const applyFocusedSubgraph = React12.useCallback((matchIds, scoreMap, neighborIds, traversalIds) => {
13442
+ const applyFocusedSubgraph = React15.useCallback((matchIds, scoreMap, neighborIds, traversalIds) => {
12833
13443
  const visibleIds = new Set(matchIds);
12834
13444
  neighborIds?.forEach((id) => visibleIds.add(id));
12835
13445
  traversalIds?.forEach((id) => visibleIds.add(id));
@@ -12868,7 +13478,7 @@ function KnowledgeGraphView({
12868
13478
  if (fitViewTimerRef.current) clearTimeout(fitViewTimerRef.current);
12869
13479
  fitViewTimerRef.current = setTimeout(() => rfInstanceRef.current?.fitView({ padding: 0.3, duration: 300 }), 60);
12870
13480
  }, [rawEdges, setNodes, setEdges]);
12871
- const restoreFullGraph = React12.useCallback(() => {
13481
+ const restoreFullGraph = React15.useCallback(() => {
12872
13482
  setNodes(fullNodesRef.current.map((n) => ({
12873
13483
  ...n,
12874
13484
  data: { ...n.data, isHighlighted: false, isDimmed: false, searchScore: null }
@@ -12881,17 +13491,17 @@ function KnowledgeGraphView({
12881
13491
  if (fitViewTimerRef.current) clearTimeout(fitViewTimerRef.current);
12882
13492
  fitViewTimerRef.current = setTimeout(() => rfInstanceRef.current?.fitView({ padding: 0.2, duration: 300 }), 60);
12883
13493
  }, [setNodes, setEdges]);
12884
- const hasClaimStatuses = React12.useMemo(() => {
13494
+ const hasClaimStatuses = React15.useMemo(() => {
12885
13495
  if (genericKGProp) return genericKGProp.nodes.some((n) => n.claim_status);
12886
13496
  return rawNodes.some((n) => n.properties?.claim_status);
12887
13497
  }, [genericKGProp, rawNodes]);
12888
- const hasPhases = React12.useMemo(() => {
13498
+ const hasPhases = React15.useMemo(() => {
12889
13499
  if (hasClaimStatuses) return false;
12890
13500
  if (genericKGProp) return genericKGProp.nodes.some((n) => n.phase && n.phase !== "simple");
12891
13501
  return rawNodes.some((n) => n.properties?.phase && n.properties.phase !== "simple");
12892
13502
  }, [genericKGProp, hasClaimStatuses, rawNodes]);
12893
13503
  const hasFilters = hasClaimStatuses || hasPhases;
12894
- React12.useEffect(() => {
13504
+ React15.useEffect(() => {
12895
13505
  if (!hasFilters || searchActive) return;
12896
13506
  if (phaseFilter === "all") {
12897
13507
  setNodes((nds) => nds.map((n) => ({ ...n, data: { ...n.data, isDimmed: false } })));
@@ -12915,7 +13525,7 @@ function KnowledgeGraphView({
12915
13525
  return { ...n, data: { ...n.data, isDimmed: !matches } };
12916
13526
  }));
12917
13527
  }, [phaseFilter, hasFilters, searchActive, setNodes, setEdges]);
12918
- React12.useEffect(() => {
13528
+ React15.useEffect(() => {
12919
13529
  if (searchActive) return;
12920
13530
  if (!hoveredNodeId) {
12921
13531
  setNodes((nds) => nds.map((n) => ({ ...n, data: { ...n.data, isHighlighted: false, isDimmed: false } })));
@@ -12944,7 +13554,7 @@ function KnowledgeGraphView({
12944
13554
  }
12945
13555
  })));
12946
13556
  }, [hoveredNodeId, searchActive, setNodes, setEdges]);
12947
- React12.useEffect(() => {
13557
+ React15.useEffect(() => {
12948
13558
  if (searchTimerRef.current) clearTimeout(searchTimerRef.current);
12949
13559
  if (!searchTerm.trim()) {
12950
13560
  setSearchResult({ hits: [], traversal: [] });
@@ -12965,19 +13575,19 @@ function KnowledgeGraphView({
12965
13575
  setSearching(true);
12966
13576
  searchTimerRef.current = setTimeout(async () => {
12967
13577
  try {
12968
- const result = data.onSearchNodes ? await data.onSearchNodes(groupId, kgId, q, 10, 2) : { hits: [], traversal: [] };
12969
- setSearchResult(result);
12970
- if (result.hits.length === 0 && localMatchIds.size === 0) {
13578
+ const result2 = data.onSearchNodes ? await data.onSearchNodes(groupId, kgId, q, 10, 2) : { hits: [], traversal: [] };
13579
+ setSearchResult(result2);
13580
+ if (result2.hits.length === 0 && localMatchIds.size === 0) {
12971
13581
  restoreFullGraph();
12972
13582
  setSearching(false);
12973
13583
  return;
12974
13584
  }
12975
- if (result.hits.length === 0) {
13585
+ if (result2.hits.length === 0) {
12976
13586
  setSearching(false);
12977
13587
  return;
12978
13588
  }
12979
13589
  const scoreMap = /* @__PURE__ */ new Map();
12980
- result.hits.forEach((h) => {
13590
+ result2.hits.forEach((h) => {
12981
13591
  const existing = scoreMap.get(h.node_key) ?? 0;
12982
13592
  if ((h.score ?? 0) > existing) scoreMap.set(h.node_key, h.score ?? 0);
12983
13593
  });
@@ -12985,9 +13595,9 @@ function KnowledgeGraphView({
12985
13595
  if (!scoreMap.has(id)) scoreMap.set(id, 0.5);
12986
13596
  });
12987
13597
  const traversalIds = /* @__PURE__ */ new Set();
12988
- result.traversal.forEach((t) => traversalIds.add(t.node_key));
13598
+ result2.traversal.forEach((t) => traversalIds.add(t.node_key));
12989
13599
  const neighborIds = /* @__PURE__ */ new Set();
12990
- result.hits.forEach((h) => {
13600
+ result2.hits.forEach((h) => {
12991
13601
  h.neighbors?.forEach((nk) => {
12992
13602
  if (!scoreMap.has(nk)) neighborIds.add(nk);
12993
13603
  });
@@ -13002,7 +13612,7 @@ function KnowledgeGraphView({
13002
13612
  if (searchTimerRef.current) clearTimeout(searchTimerRef.current);
13003
13613
  };
13004
13614
  }, [searchTerm, rawNodes, rawEdges, groupId, kgId, applyFocusedSubgraph, restoreFullGraph]);
13005
- const onNodeClick = React12.useCallback((_, node) => {
13615
+ const onNodeClick = React15.useCallback((_, node) => {
13006
13616
  if (node.id === "__add_note__" && data.onCreateNote) {
13007
13617
  setSelectedNodeId(null);
13008
13618
  setSelectedEdgeId(null);
@@ -13012,21 +13622,21 @@ function KnowledgeGraphView({
13012
13622
  setSelectedNodeId(node.id);
13013
13623
  setSelectedEdgeId(null);
13014
13624
  }, [data.onCreateNote]);
13015
- const onEdgeClick = React12.useCallback((_, edge) => {
13625
+ const onEdgeClick = React15.useCallback((_, edge) => {
13016
13626
  setSelectedEdgeId(edge.id);
13017
13627
  setSelectedNodeId(null);
13018
13628
  }, []);
13019
- const onNodeMouseEnter = React12.useCallback((_, node) => {
13629
+ const onNodeMouseEnter = React15.useCallback((_, node) => {
13020
13630
  setHoveredNodeId(node.id);
13021
13631
  }, []);
13022
- const onNodeMouseLeave = React12.useCallback(() => {
13632
+ const onNodeMouseLeave = React15.useCallback(() => {
13023
13633
  setHoveredNodeId(null);
13024
13634
  }, []);
13025
- const onPaneClick = React12.useCallback(() => {
13635
+ const onPaneClick = React15.useCallback(() => {
13026
13636
  setSelectedNodeId(null);
13027
13637
  setSelectedEdgeId(null);
13028
13638
  }, []);
13029
- const selectedNodeConnections = React12.useMemo(() => {
13639
+ const selectedNodeConnections = React15.useMemo(() => {
13030
13640
  if (!selectedNodeId) return [];
13031
13641
  if (viewMode === "chunk" && selectedNodeId.startsWith("chunk:") && allChunks) {
13032
13642
  const chunkId = selectedNodeId.slice("chunk:".length);
@@ -13076,7 +13686,7 @@ function KnowledgeGraphView({
13076
13686
  };
13077
13687
  });
13078
13688
  }, [selectedNodeId, rawNodes, rawEdges, viewMode, allChunks]);
13079
- const selectedEdgeData = React12.useMemo(() => {
13689
+ const selectedEdgeData = React15.useMemo(() => {
13080
13690
  if (!selectedEdgeId) return null;
13081
13691
  const raw = rawEdges.find((e) => e.edge_key === selectedEdgeId);
13082
13692
  if (!raw) return null;
@@ -13096,7 +13706,7 @@ function KnowledgeGraphView({
13096
13706
  targetNode: { id: raw.to_node_key, label: targetNode?.label || raw.to_node_key, nodeType: targetNode?.node_type || "unknown" }
13097
13707
  };
13098
13708
  }, [selectedEdgeId, rawNodes, rawEdges, gkgEdgeMap]);
13099
- const selectedNodeData = React12.useMemo(() => {
13709
+ const selectedNodeData = React15.useMemo(() => {
13100
13710
  if (!selectedNodeId) return null;
13101
13711
  if (viewMode === "chunk" && selectedNodeId.startsWith("chunk:") && allChunks) {
13102
13712
  const chunkId = selectedNodeId.slice("chunk:".length);
@@ -13142,12 +13752,12 @@ function KnowledgeGraphView({
13142
13752
  hasRagChunks: !!(raw.properties?.rag_chunks?.length || raw.properties?.source_chunks?.length || raw.properties?.references?.length)
13143
13753
  };
13144
13754
  }, [selectedNodeId, rawNodes, viewMode, allChunks]);
13145
- const navigateToNode = React12.useCallback((nodeId) => {
13755
+ const navigateToNode = React15.useCallback((nodeId) => {
13146
13756
  setSelectedNodeId(nodeId);
13147
13757
  setSelectedEdgeId(null);
13148
13758
  }, []);
13149
- const reviewNodeIds = React12.useMemo(() => rawNodes.map((n) => n.node_key), [rawNodes]);
13150
- const onReviewNavigate = React12.useCallback((nodeId) => {
13759
+ const reviewNodeIds = React15.useMemo(() => rawNodes.map((n) => n.node_key), [rawNodes]);
13760
+ const onReviewNavigate = React15.useCallback((nodeId) => {
13151
13761
  setSelectedNodeId(nodeId);
13152
13762
  setSelectedEdgeId(null);
13153
13763
  const rfNode = nodes.find((n) => n.id === nodeId);
@@ -13160,8 +13770,8 @@ function KnowledgeGraphView({
13160
13770
  );
13161
13771
  }
13162
13772
  }, [nodes]);
13163
- const lastChatHighlightRef = React12.useRef("");
13164
- const handleChatHighlight = React12.useCallback((nodeIds) => {
13773
+ const lastChatHighlightRef = React15.useRef("");
13774
+ const handleChatHighlight = React15.useCallback((nodeIds) => {
13165
13775
  if (nodeIds.length === 0) return;
13166
13776
  const key = nodeIds.sort().join(",");
13167
13777
  if (key === lastChatHighlightRef.current) return;
@@ -13177,7 +13787,7 @@ function KnowledgeGraphView({
13177
13787
  })));
13178
13788
  setSearchActive(true);
13179
13789
  }, [setNodes, setEdges]);
13180
- const minimapNodeColor = React12.useCallback((node) => {
13790
+ const minimapNodeColor = React15.useCallback((node) => {
13181
13791
  return getNodeColors(node.data?.nodeType || "").badge;
13182
13792
  }, []);
13183
13793
  const hasLiveRun = !!runId;
@@ -13476,9 +14086,9 @@ function KnowledgeGraphView({
13476
14086
  if (!data.onCreateNote || !draftNote || !draftNote.trim()) return;
13477
14087
  setSavingDraft(true);
13478
14088
  try {
13479
- const result = await data.onCreateNote(groupId, kgId, draftNote);
14089
+ const result2 = await data.onCreateNote(groupId, kgId, draftNote);
13480
14090
  setDraftNote(null);
13481
- setSelectedNodeId(`chunk:${result.chunk_id}`);
14091
+ setSelectedNodeId(`chunk:${result2.chunk_id}`);
13482
14092
  if (data.onLoadAllChunks) {
13483
14093
  try {
13484
14094
  const fresh = await data.onLoadAllChunks(groupId, kgId);
@@ -13487,10 +14097,10 @@ function KnowledgeGraphView({
13487
14097
  console.warn("[KGV] post-create chunk refetch failed", err);
13488
14098
  }
13489
14099
  }
13490
- if (result.run_id && config?.agentsApiUrl) {
14100
+ if (result2.run_id && config?.agentsApiUrl) {
13491
14101
  setNoteRuns((prev) => [
13492
14102
  ...prev,
13493
- { run_id: result.run_id, kg_id: kgId }
14103
+ { run_id: result2.run_id, kg_id: kgId }
13494
14104
  ]);
13495
14105
  }
13496
14106
  } catch (err) {
@@ -13586,9 +14196,9 @@ function ReasoningView({
13586
14196
  activityEvents,
13587
14197
  className = ""
13588
14198
  }) {
13589
- const [chainOpen, setChainOpen] = React12.useState(false);
13590
- const [chainGoal, setChainGoal] = React12.useState("");
13591
- const chainInputRef = React12.useRef(null);
14199
+ const [chainOpen, setChainOpen] = React15.useState(false);
14200
+ const [chainGoal, setChainGoal] = React15.useState("");
14201
+ const chainInputRef = React15.useRef(null);
13592
14202
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col h-full overflow-hidden ${className}`, style: { backgroundColor: "#181818" }, children: [
13593
14203
  (title || onClose) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 px-4 py-2 flex-shrink-0", style: { borderBottom: "1px solid #282828" }, children: [
13594
14204
  onClose && /* @__PURE__ */ jsxRuntime.jsx(
@@ -13740,15 +14350,15 @@ function SettlementBar({ settledCount, totalCount }) {
13740
14350
  ] });
13741
14351
  }
13742
14352
  function ReasoningOverlay({ config, currentUser, data, onLookupKg, authToken }) {
13743
- const [open, setOpen] = React12.useState(false);
13744
- const [kgId, setKgId] = React12.useState(null);
13745
- const [runId, setRunId] = React12.useState();
13746
- const [workingGroupId, setWorkingGroupId] = React12.useState(null);
13747
- const [threadId, setThreadId] = React12.useState();
13748
- const [reasoningPhase, setReasoningPhase] = React12.useState(null);
13749
- const [reasoningAgents, setReasoningAgents] = React12.useState();
13750
- const [genericKG, setGenericKG] = React12.useState(null);
13751
- const loadKg = React12.useCallback(async (id) => {
14353
+ const [open, setOpen] = React15.useState(false);
14354
+ const [kgId, setKgId] = React15.useState(null);
14355
+ const [runId, setRunId] = React15.useState();
14356
+ const [workingGroupId, setWorkingGroupId] = React15.useState(null);
14357
+ const [threadId, setThreadId] = React15.useState();
14358
+ const [reasoningPhase, setReasoningPhase] = React15.useState(null);
14359
+ const [reasoningAgents, setReasoningAgents] = React15.useState();
14360
+ const [genericKG, setGenericKG] = React15.useState(null);
14361
+ const loadKg = React15.useCallback(async (id) => {
13752
14362
  try {
13753
14363
  let wgId = null;
13754
14364
  let resolvedThread;
@@ -13824,7 +14434,7 @@ function ReasoningOverlay({ config, currentUser, data, onLookupKg, authToken })
13824
14434
  console.error("[ReasoningOverlay] Failed to load:", e);
13825
14435
  }
13826
14436
  }, [data, onLookupKg]);
13827
- const close = React12.useCallback(() => {
14437
+ const close = React15.useCallback(() => {
13828
14438
  setOpen(false);
13829
14439
  setGenericKG(null);
13830
14440
  setKgId(null);
@@ -13833,7 +14443,7 @@ function ReasoningOverlay({ config, currentUser, data, onLookupKg, authToken })
13833
14443
  setRunId(void 0);
13834
14444
  window.dispatchEvent(new CustomEvent("reasoning-overlay-closed", { bubbles: true }));
13835
14445
  }, []);
13836
- React12.useEffect(() => {
14446
+ React15.useEffect(() => {
13837
14447
  const handler = (e) => {
13838
14448
  const detail = e.detail || {};
13839
14449
  const id = detail.kgId || detail.reasoningSetId;
@@ -13846,7 +14456,7 @@ function ReasoningOverlay({ config, currentUser, data, onLookupKg, authToken })
13846
14456
  window.removeEventListener("view-reasoning-set", handler);
13847
14457
  };
13848
14458
  }, [loadKg]);
13849
- React12.useEffect(() => {
14459
+ React15.useEffect(() => {
13850
14460
  if (!open) return;
13851
14461
  const handler = (e) => {
13852
14462
  if (e.key === "Escape") close();
@@ -13907,9 +14517,9 @@ function CheckpointCard({
13907
14517
  onAction,
13908
14518
  responded = false
13909
14519
  }) {
13910
- const [inputValue, setInputValue] = React12.useState("");
13911
- const [showInput, setShowInput] = React12.useState(false);
13912
- const inputRef = React12.useRef(null);
14520
+ const [inputValue, setInputValue] = React15.useState("");
14521
+ const [showInput, setShowInput] = React15.useState(false);
14522
+ const inputRef = React15.useRef(null);
13913
14523
  const config = TYPE_CONFIG2[type] || TYPE_CONFIG2.generic;
13914
14524
  const handleSend = () => {
13915
14525
  if (!inputValue.trim()) return;
@@ -13917,7 +14527,7 @@ function CheckpointCard({
13917
14527
  setInputValue("");
13918
14528
  setShowInput(false);
13919
14529
  };
13920
- React12.useEffect(() => {
14530
+ React15.useEffect(() => {
13921
14531
  if (showInput) inputRef.current?.focus();
13922
14532
  }, [showInput]);
13923
14533
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -14049,6 +14659,7 @@ exports.ADVANCE_PHASE_SIGNAL = ADVANCE_PHASE_SIGNAL;
14049
14659
  exports.AGENT_PALETTE = AGENT_PALETTE;
14050
14660
  exports.AgentAvatar = AgentAvatar;
14051
14661
  exports.AgentPresenceBar = AgentPresenceBar;
14662
+ exports.AgentStepTrace = AgentStepTrace;
14052
14663
  exports.AnnotationThread = AnnotationThread;
14053
14664
  exports.CLAIM_STATUS_COLORS = CLAIM_STATUS_COLORS;
14054
14665
  exports.ChatTerminal = ChatTerminal;
@@ -14056,6 +14667,7 @@ exports.CheckpointCard = CheckpointCard;
14056
14667
  exports.ClaimNode = ClaimNode;
14057
14668
  exports.ConstructionProgress = ConstructionProgress;
14058
14669
  exports.CoreTerminal = CoreTerminal;
14670
+ exports.DEFAULT_AGENT_LABEL = DEFAULT_AGENT_LABEL;
14059
14671
  exports.DOCUMENT_PIPELINE_STEPS = DOCUMENT_PIPELINE_STEPS;
14060
14672
  exports.DocumentProcessingProgress = DocumentProcessingProgress;
14061
14673
  exports.EDGE_TYPE_COLORS = EDGE_TYPE_COLORS;
@@ -14080,6 +14692,8 @@ exports.PipelineProgressBar = PipelineProgressBar;
14080
14692
  exports.ReasoningHistoryCard = ReasoningHistoryCard;
14081
14693
  exports.ReasoningOverlay = ReasoningOverlay;
14082
14694
  exports.ReasoningView = ReasoningView;
14695
+ exports.SSE_KEEPALIVE_MS = SSE_KEEPALIVE_MS;
14696
+ exports.SSE_STALL_MS = SSE_STALL_MS;
14083
14697
  exports.SYNTHESIS_DONE_SIGNAL = SYNTHESIS_DONE_SIGNAL;
14084
14698
  exports.ScopedReasoningProvider = ScopedReasoningProvider;
14085
14699
  exports.SettlementBar = SettlementBar;
@@ -14089,6 +14703,7 @@ exports.StandardTerminal = StandardTerminal;
14089
14703
  exports.TerminalInputBar = TerminalInputBar;
14090
14704
  exports.TerminalThemeProvider = TerminalThemeProvider;
14091
14705
  exports.agentSeed = agentSeed;
14706
+ exports.agentStepTraceExtra = agentStepTraceExtra;
14092
14707
  exports.avatarColor = avatarColor;
14093
14708
  exports.blueScope = blueScope;
14094
14709
  exports.buildClaimsGraph = buildClaimsGraph;
@@ -14141,3 +14756,4 @@ exports.useScopedProgressEvent = useScopedProgressEvent;
14141
14756
  exports.useSlashMentionPicker = useSlashMentionPicker;
14142
14757
  exports.useTheme = useTheme;
14143
14758
  exports.warmBg = warmBg;
14759
+ exports.withStallTimeout = withStallTimeout;