1(globalThis["TURBOPACK"] || (globalThis["TURBOPACK"] = [])).push([typeof document === "object" ? document.currentScript : undefined, 2503477, ((__turbopack_context__) => { 3"use strict"; 4 5var __TURBOPACK__imported__module__271645__ = __turbopack_context__.i(271645); 6var __TURBOPACK__imported__module__490746__ = __turbopack_context__.i(490746); 7"use client"; 8; 9; 10function useCurrentUserId() { 11 const [userId, setUserId] = __TURBOPACK__imported__module__271645__["useState"](""); 12 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 13 let cancelled = false; 14 void (async ()=>{ 15 try { 16 const res = await (0, __TURBOPACK__imported__module__490746__["apiCall"])("/api/auth/feature-check", { 17 method: "POST", 18 headers: { 19 "content-type": "application/json" 20 }, 21 body: JSON.stringify({ 22 features: [] 23 }) 24 }); 25 if (!cancelled && res.ok && typeof res.result?.userId === "string") { 26 setUserId(res.result.userId); 27 } 28 } catch { 29 if (!cancelled) setUserId(""); 30 } 31 })(); 32 return ()=>{ 33 cancelled = true; 34 }; 35 }, []); 36 return userId; 37} 38; 39__turbopack_context__.s([ 40 "useCurrentUserId", 41 0, 42 useCurrentUserId 43]); 44}), 45756217, ((__turbopack_context__) => { 46"use strict"; 47 48/** 49 * @license lucide-react v0.556.0 - ISC 50 * 51 * This source code is licensed under the ISC license. 52 * See the LICENSE file in the root directory of this source tree. 53 */ var __TURBOPACK__imported__module__475254__ = __turbopack_context__.i(475254); 54; 55const __iconNode = [ 56 [ 57 "path", 58 { 59 d: "m14 10 7-7", 60 key: "oa77jy" 61 } 62 ], 63 [ 64 "path", 65 { 66 d: "M20 10h-6V4", 67 key: "mjg0md" 68 } 69 ], 70 [ 71 "path", 72 { 73 d: "m3 21 7-7", 74 key: "tjx5ai" 75 } 76 ], 77 [ 78 "path", 79 { 80 d: "M4 14h6v6", 81 key: "rmj7iw" 82 } 83 ] 84]; 85const Minimize2 = (0, __TURBOPACK__imported__module__475254__["default"])("minimize-2", __iconNode); 86; 87__turbopack_context__.s([ 88 "default", 89 0, 90 Minimize2 91]); 92}), 93726336, ((__turbopack_context__) => { 94"use strict"; 95 96var __TURBOPACK__imported__module__756217__ = __turbopack_context__.i(756217); 97__turbopack_context__.s([ 98 "Minimize2", 99 ()=>__TURBOPACK__imported__module__756217__["default"] 100]); 101}), 102309789, ((__turbopack_context__) => { 103"use strict"; 104 105/** 106 * @license lucide-react v0.556.0 - ISC 107 * 108 * This source code is licensed under the ISC license. 109 * See the LICENSE file in the root directory of this source tree. 110 */ var __TURBOPACK__imported__module__475254__ = __turbopack_context__.i(475254); 111; 112const __iconNode = [ 113 [ 114 "rect", 115 { 116 width: "18", 117 height: "18", 118 x: "3", 119 y: "3", 120 rx: "2", 121 key: "afitv7" 122 } 123 ], 124 [ 125 "path", 126 { 127 d: "M15 3v18", 128 key: "14nvp0" 129 } 130 ], 131 [ 132 "path", 133 { 134 d: "m10 15-3-3 3-3", 135 key: "1pgupc" 136 } 137 ] 138]; 139const PanelRightOpen = (0, __TURBOPACK__imported__module__475254__["default"])("panel-right-open", __iconNode); 140; 141__turbopack_context__.s([ 142 "default", 143 0, 144 PanelRightOpen 145]); 146}), 147430172, ((__turbopack_context__) => { 148"use strict"; 149 150var __TURBOPACK__imported__module__309789__ = __turbopack_context__.i(309789); 151__turbopack_context__.s([ 152 "PanelRightOpen", 153 ()=>__TURBOPACK__imported__module__309789__["default"] 154]); 155}), 156570596, ((__turbopack_context__) => { 157"use strict"; 158 159var __TURBOPACK__imported__module__843476__ = __turbopack_context__.i(843476); 160var __TURBOPACK__imported__module__271645__ = __turbopack_context__.i(271645); 161var __TURBOPACK__imported__module__681160__ = __turbopack_context__.i(681160); 162var __TURBOPACK__imported__module__662136__ = __turbopack_context__.i(662136); 163var __TURBOPACK__imported__module__583480__ = __turbopack_context__.i(583480); 164"use client"; 165; 166; 167; 168; 169; 170const LEGACY_STORAGE_KEY = "om-ai-chat-sessions-v1"; 171const STORAGE_KEY_PREFIX = "om-ai-chat-sessions-v1"; 172const HISTORY_LIMIT = 50; 173function getScopedStorageKey(tenantId, organizationId) { 174 return `${STORAGE_KEY_PREFIX}:${tenantId ?? "no-tenant"}:${organizationId ?? "no-org"}`; 175} 176const AiChatSessionsContext = /*#__PURE__*/ __TURBOPACK__imported__module__271645__["createContext"](null); 177function makeId() { 178 const g = globalThis; 179 if (g.crypto && typeof g.crypto.randomUUID === "function") { 180 try { 181 return g.crypto.randomUUID(); 182 } catch {} 183 } 184 const rand = ()=>Math.random().toString(16).slice(2, 10); 185 return `${Date.now().toString(16)}-${rand()}-${rand()}`; 186} 187const AI_CHAT_SESSIONS_VERSION = 1; 188function isPersistedSessionsShape(value) { 189 return !!value && typeof value === "object" && !Array.isArray(value); 190} 191function readPersisted(storageKey) { 192 const parsed = (0, __TURBOPACK__imported__module__662136__["readVersionedPreference"])(storageKey, AI_CHAT_SESSIONS_VERSION, (value)=>isPersistedSessionsShape(value), null, { 193 legacyIsValid: (value)=>isPersistedSessionsShape(value) 194 }); 195 if (!parsed) return { 196 sessions: [], 197 activeByAgent: {} 198 }; 199 const sessions = Array.isArray(parsed.sessions) ? parsed.sessions.filter((entry)=>{ 200 if (!entry || typeof entry !== "object") return false;
201 const value = entry; 202 return typeof value.id === "string" && typeof value.agentId === "string" && typeof value.conversationId === "string" && typeof value.createdAt === "number" && typeof value.lastUsedAt === "number" && (value.status === "open" || value.status === "closed"); 203 }).map((entry)=>{ 204 const value = entry; 205 const candidate = value.name; 206 return { 207 ...entry, 208 name: typeof candidate === "string" ? candidate : void 0 209 }; 210 }) : []; 211 const activeByAgent = parsed.activeByAgent && typeof parsed.activeByAgent === "object" ? Object.fromEntries(Object.entries(parsed.activeByAgent).filter((entry)=>typeof entry[0] === "string" && typeof entry[1] === "string")) : {}; 212 return { 213 sessions, 214 activeByAgent 215 }; 216} 217function writePersisted(storageKey, state) { 218 (0, __TURBOPACK__imported__module__662136__["writeVersionedPreference"])(storageKey, AI_CHAT_SESSIONS_VERSION, state); 219} 220function serverConversationToSession(conversation, existing) { 221 const createdAt = Date.parse(conversation.createdAt); 222 const updatedAt = Date.parse(conversation.lastMessageAt ?? conversation.updatedAt); 223 return { 224 id: existing?.id ?? conversation.conversationId, 225 agentId: conversation.agentId, 226 conversationId: conversation.conversationId, 227 name: conversation.title ?? existing?.name, 228 createdAt: Number.isFinite(createdAt) ? createdAt : existing?.createdAt ?? Date.now(), 229 lastUsedAt: Number.isFinite(updatedAt) ? updatedAt : existing?.lastUsedAt ?? Date.now(), 230 status: conversation.status 231 }; 232} 233function mergeServerConversations(prev, conversations) { 234 const byConversationId = new Map(prev.sessions.map((session)=>[ 235 session.conversationId, 236 session 237 ])); 238 const serverSessions = conversations.map((conversation)=>serverConversationToSession(conversation, byConversationId.get(conversation.conversationId))); 239 const serverIds = new Set(serverSessions.map((session)=>session.conversationId)); 240 const localOnly = prev.sessions.filter((session)=>!serverIds.has(session.conversationId)); 241 const sessions = [ 242 ...serverSessions, 243 ...localOnly 244 ]; 245 const activeByAgent = { 246 ...prev.activeByAgent 247 }; 248 const agentIds = new Set(sessions.map((session)=>session.agentId)); 249 for (const agentId of agentIds){ 250 const activeId = activeByAgent[agentId]; 251 const active = sessions.find((session)=>session.id === activeId); 252 if (active && active.status === "open") continue; 253 const nextOpen = sessions.filter((session)=>session.agentId === agentId && session.status === "open").sort((a, b)=>b.lastUsedAt - a.lastUsedAt)[0]; 254 if (nextOpen) activeByAgent[agentId] = nextOpen.id; 255 else delete activeByAgent[agentId]; 256 } 257 return { 258 sessions, 259 activeByAgent 260 }; 261} 262function AiChatSessionsProvider({ children }) { 263 const [storageKey, setStorageKey] = __TURBOPACK__imported__module__271645__["useState"](()=>{ 264 const scope = (0, __TURBOPACK__imported__module__681160__["getCurrentOrganizationScope"])(); 265 return getScopedStorageKey(scope.tenantId, scope.organizationId); 266 }); 267 const [state, setState] = __TURBOPACK__imported__module__271645__["useState"](()=>readPersisted(storageKey)); 268 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 269 return (0, __TURBOPACK__imported__module__681160__["subscribeOrganizationScopeChanged"])((detail)=>{ 270 const nextKey = getScopedStorageKey(detail.tenantId, detail.organizationId); 271 if (nextKey === storageKey) return; 272 setStorageKey(nextKey); 273 setState(readPersisted(nextKey)); 274 }); 275 }, [ 276 storageKey 277 ]); 278 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 279 writePersisted(storageKey, state); 280 }, [ 281 storageKey, 282 state 283 ]); 284 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 285 let cancelled = false; 286 void (0, __TURBOPACK__imported__module__583480__["listAiServerConversations"])({ 287 limit: 100 288 }).then((conversations)=>{ 289 if (cancelled || !conversations) return; 290 setState((prev)=>mergeServerConversations(prev, conversations)); 291 }); 292 return ()=>{ 293 cancelled = true; 294 }; 295 }, [ 296 storageKey 297 ]); 298 const update = __TURBOPACK__imported__module__271645__["useCallback"]((mutator)=>{ 299 setState((prev)=>mutator(prev)); 300 }, []); 301 const getOpenSessions = __TURBOPACK__imported__module__271645__["useCallback"]((agentId)=>state.sessions.filter((s)=>s.agentId === agentId && s.status === "open").sort((a, b)=>a.createdAt - b.createdAt), [ 302 state.sessions 303 ]); 304 const getClosedSessions = __TURBOPACK__imported__module__271645__["useCallback"]((agentId, limit = HISTORY_LIMIT)=>state.sessions.filter((s)=>s.agentId === agentId && s.status === "closed").sort((a, b)=>b.lastUsedAt - a.lastUsedAt).slice(0, limit), [ 305 state.sessions 306 ]); 307 const getActiveSession = __TURBOPACK__imported__module__271645__["useCallback"]((agentId)=>{ 308 const id = state.activeByAgent[agentId]; 309 if (!id) return null; 310 const session = state.sessions.find((s)=>s.id === id); 311 if (!session || session.status !== "open") return null; 312 return session; 313 }, [ 314 state.activeByAgent, 315 state.sessions 316 ]); 317 const createSession = __TURBOPACK__imported__module__271645__["useCallback"]((agentId)=>{ 318 const session = { 319 id: makeId(), 320 agentId, 321 conversationId: makeId(), 322 createdAt: Date.now(), 323 lastUsedAt: Date.now(), 324 status: "open" 325 }; 326 void (0, __TURBOPACK__imported__module__583480__["createAiServerConversation"])({ 327 agentId: session.agentId, 328 conversationId: session.conversationId 329 }); 330 update((prev)=>({ 331 sessions: [ 332 ...prev.sessions, 333 session 334 ], 335 activeByAgent: { 336 ...prev.activeByAgent, 337 [agentId]: session.id 338 } 339 })); 340 return session; 341 }, [ 342 update 343 ]); 344 const closeSession = __TURBOPACK__imported__module__271645__["useCallback"]((sessionId)=>{ 345 const serverTarget = state.sessions.find((s)=>s.id === sessionId); 346 if (serverTarget) { 347 void (0, __TURBOPACK__imported__module__583480__["updateAiServerConversation"])(serverTarget.conversationId, { 348 status: "closed" 349 }); 350 } 351 update((prev)=>{ 352 const target = prev.sessions.find((s)=>s.id === sessionId); 353 if (!target) return prev; 354 const sessions = prev.sessions.map((s)=>s.id === sessionId ? { 355 ...s, 356 status: "closed", 357 lastUsedAt: Date.now() 358 } : s); 359 const activeByAgent = { 360 ...prev.activeByAgent 361 }; 362 if (activeByAgent[target.agentId] === sessionId) { 363 const fallback = sessions.filter((s)=>s.agentId === target.agentId && s.status === "open").sort((a, b)=>b.lastUsedAt - a.lastUsedAt)[0]; 364 if (fallback) { 365 activeByAgent[target.agentId] = fallback.id; 366 } else { 367 delete activeByAgent[target.agentId]; 368 } 369 } 370 return { 371 sessions, 372 activeByAgent 373 }; 374 }); 375 }, [ 376 state.sessions, 377 update 378 ]); 379 const reopenSession = __TURBOPACK__imported__module__271645__["useCallback"]((sessionId)=>{ 380 const serverTarget = state.sessions.find((s)=>s.id === sessionId); 381 if (serverTarget) { 382 void (0, __TURBOPACK__imported__module__583480__["updateAiServerConversation"])(serverTarget.conversationId, { 383 status: "open" 384 }); 385 } 386 update((prev)=>{ 387 const target = prev.sessions.find((s)=>s.id === sessionId); 388 if (!target) return prev; 389 const sessions = prev.sessions.map((s)=>s.id === sessionId ? { 390 ...s, 391 status: "open", 392 lastUsedAt: Date.now() 393 } : s); 394 return { 395 sessions, 396 activeByAgent: { 397 ...prev.activeByAgent, 398 [target.agentId]: sessionId 399 } 400 }; 401 }); 402 }, [ 403 state.sessions, 404 update 405 ]); 406 const setActiveSession = __TURBOPACK__imported__module__271645__["useCallback"]((sessionId)=>{ 407 update((prev)=>{ 408 const target = prev.sessions.find((s)=>s.id === sessionId); 409 if (!target || target.status !== "open") return prev; 410 if (prev.activeByAgent[target.agentId] === sessionId) return prev; 411 const sessions = prev.sessions.map((s)=>s.id === sessionId ? { 412 ...s, 413 lastUsedAt: Date.now() 414 } : s); 415 return { 416 sessions, 417 activeByAgent: { 418 ...prev.activeByAgent, 419 [target.agentId]: sessionId 420 } 421 }; 422 }); 423 }, [ 424 update 425 ]); 426 const renameSession = __TURBOPACK__imported__module__271645__["useCallback"]((sessionId, name)=>{ 427 const trimmed = name.trim(); 428 const serverTarget = state.sessions.find((s)=>s.id === sessionId); 429 if (serverTarget) { 430 void (0, __TURBOPACK__imported__module__583480__["updateAiServerConversation"])(serverTarget.conversationId, { 431 title: trimmed.length > 0 ? trimmed : null 432 }); 433 } 434 update((prev)=>({ 435 ...prev, 436 sessions: prev.sessions.map((s)=>s.id === sessionId ? { 437 ...s, 438 name: trimmed.length > 0 ? trimmed : void 0 439 } : s) 440 })); 441 }, [ 442 state.sessions, 443 update 444 ]); 445 const touchSession = __TURBOPACK__imported__module__271645__["useCallback"]((sessionId)=>{ 446 update((prev)=>({ 447 ...prev, 448 sessions: prev.sessions.map((s)=>s.id === sessionId ? { 449 ...s, 450 lastUsedAt: Date.now() 451 } : s) 452 })); 453 }, [ 454 update 455 ]); 456 const ensureSession = __TURBOPACK__imported__module__271645__["useCallback"]((agentId)=>{ 457 let resolved = null;
458 let mintedSession = null; 459 setState((prev)=>{ 460 const activeId = prev.activeByAgent[agentId]; 461 if (activeId) { 462 const active = prev.sessions.find((s)=>s.id === activeId); 463 if (active && active.status === "open") { 464 resolved = active; 465 return prev; 466 } 467 } 468 const anyOpen = prev.sessions.filter((s)=>s.agentId === agentId && s.status === "open").sort((a, b)=>b.lastUsedAt - a.lastUsedAt)[0]; 469 if (anyOpen) { 470 resolved = anyOpen; 471 return { 472 ...prev, 473 activeByAgent: { 474 ...prev.activeByAgent, 475 [agentId]: anyOpen.id 476 } 477 }; 478 } 479 if (!mintedSession) { 480 mintedSession = { 481 id: makeId(), 482 agentId, 483 conversationId: makeId(), 484 createdAt: Date.now(), 485 lastUsedAt: Date.now(), 486 status: "open" 487 }; 488 void (0, __TURBOPACK__imported__module__583480__["createAiServerConversation"])({ 489 agentId: mintedSession.agentId, 490 conversationId: mintedSession.conversationId 491 }); 492 } 493 resolved = mintedSession; 494 return { 495 sessions: [ 496 ...prev.sessions, 497 mintedSession 498 ], 499 activeByAgent: { 500 ...prev.activeByAgent, 501 [agentId]: mintedSession.id 502 } 503 }; 504 }); 505 return resolved; 506 }, []); 507 const api = __TURBOPACK__imported__module__271645__["useMemo"](()=>({ 508 state, 509 getOpenSessions, 510 getClosedSessions, 511 getActiveSession, 512 createSession, 513 closeSession, 514 reopenSession,
515 setActiveSession, 516 renameSession, 517 touchSession, 518 ensureSession 519 }), [ 520 state, 521 getOpenSessions, 522 getClosedSessions, 523 getActiveSession, 524 createSession, 525 closeSession, 526 reopenSession, 527 setActiveSession, 528 renameSession, 529 touchSession, 530 ensureSession 531 ]); 532 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(AiChatSessionsContext.Provider, { 533 value: api, 534 children 535 }); 536} 537function useAiChatSessions() { 538 const ctx = __TURBOPACK__imported__module__271645__["useContext"](AiChatSessionsContext); 539 if (ctx) return ctx; 540 return { 541 state: { 542 sessions: [], 543 activeByAgent: {} 544 }, 545 getOpenSessions: ()=>[], 546 getClosedSessions: ()=>[], 547 getActiveSession: ()=>null, 548 createSession: (agentId)=>({ 549 id: "noop", 550 agentId, 551 conversationId: "noop", 552 createdAt: Date.now(), 553 lastUsedAt: Date.now(), 554 status: "open" 555 }), 556 closeSession: ()=>{}, 557 reopenSession: ()=>{}, 558 setActiveSession: ()=>{}, 559 renameSession: ()=>{}, 560 touchSession: ()=>{}, 561 ensureSession: (agentId)=>({ 562 id: "noop", 563 agentId, 564 conversationId: "noop", 565 createdAt: Date.now(), 566 lastUsedAt: Date.now(), 567 status: "open" 568 }) 569 }; 570} 571function defaultSessionLabel(session) { 572 if (session.name && session.name.trim().length > 0) return session.name.trim(); 573 const date = new Date(session.createdAt); 574 if (Number.isNaN(date.getTime())) return "Session"; 575 return date.toLocaleString(void 0, { 576 month: "short", 577 day: "numeric", 578 hour: "2-digit", 579 minute: "2-digit" 580 }); 581} 582; 583__turbopack_context__.s([ 584 "AiChatSessionsProvider", 585 0, 586 AiChatSessionsProvider, 587 "LEGACY_STORAGE_KEY", 588 0, 589 LEGACY_STORAGE_KEY, 590 "defaultSessionLabel", 591 0, 592 defaultSessionLabel, 593 "readPersisted", 594 0, 595 readPersisted, 596 "useAiChatSessions", 597 0, 598 useAiChatSessions, 599 "writePersisted", 600 0, 601 writePersisted 602]); 603}), 604811020, ((__turbopack_context__) => { 605"use strict"; 606 607var __TURBOPACK__imported__module__843476__ = __turbopack_context__.i(843476); 608var __TURBOPACK__imported__module__271645__ = __turbopack_context__.i(271645); 609var __TURBOPACK__imported__module__503116__ = __turbopack_context__.i(503116); 610var __TURBOPACK__imported__module__788699__ = __turbopack_context__.i(788699); 611var __TURBOPACK__imported__module__107233__ = __turbopack_context__.i(107233); 612var __TURBOPACK__imported__module__37727__ = __turbopack_context__.i(37727); 613var __TURBOPACK__imported__module__741870__ = __turbopack_context__.i(741870); 614var __TURBOPACK__imported__module__406911__ = __turbopack_context__.i(406911); 615var __TURBOPACK__imported__module__928441__ = __turbopack_context__.i(928441); 616var __TURBOPACK__imported__module__570596__ = __turbopack_context__.i(570596); 617"use client"; 618; 619; 620; 621; 622; 623; 624; 625function ChatPaneTabs({ agentId, className }) { 626 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 627 const sessions = (0, __TURBOPACK__imported__module__570596__["useAiChatSessions"])(); 628 const open = sessions.getOpenSessions(agentId); 629 const closed = sessions.getClosedSessions(agentId); 630 const active = sessions.getActiveSession(agentId); 631 const [historyOpen, setHistoryOpen] = __TURBOPACK__imported__module__271645__["useState"](false); 632 const [renamingId, setRenamingId] = __TURBOPACK__imported__module__271645__["useState"](null); 633 const [draftName, setDraftName] = __TURBOPACK__imported__module__271645__["useState"](""); 634 const startRename = (session)=>{ 635 setRenamingId(session.id); 636 setDraftName(session.name ?? ""); 637 }; 638 const commitRename = ()=>{ 639 if (!renamingId) return; 640 sessions.renameSession(renamingId, draftName); 641 setRenamingId(null); 642 }; 643 const cancelRename = ()=>{ 644 setRenamingId(null); 645 setDraftName(""); 646 }; 647 return(// Outer wrapper does NOT scroll; only the inner tabs row does. The 648 // `+` button and the history dropdown live OUTSIDE that scroll area 649 // so the dropdown's absolute positioning isn't clipped by the 650 // strip's `overflow-x-auto` (which CSS resolves to `overflow-y:auto` 651 // too once one axis is non-`visible`, making any absolutely- 652 // positioned child get cut off at the strip's bottom edge).
653 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 654 className: (0, __TURBOPACK__imported__module__406911__["cn"])("flex items-center gap-1 px-2 pt-2 text-sm", className), 655 "data-ai-chat-tabs": "", 656 role: "tablist", 657 "aria-label": "Chat sessions", 658 children: [ 659 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 660 className: "flex min-w-0 flex-1 items-center gap-1 overflow-x-auto", 661 "data-ai-chat-tabs-scroll": "", 662 children: open.length === 0 ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 663 className: "px-2 py-1 text-xs text-muted-foreground", 664 "data-ai-chat-tabs-empty": "", 665 children: t("ai_assistant.chat.tabs.noSessions", "No sessions") 666 }) : open.map((session)=>{ 667 const isActive = active?.id === session.id; 668 const isRenaming = renamingId === session.id; 669 const label = (0, __TURBOPACK__imported__module__570596__["defaultSessionLabel"])(session); 670 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 671 role: "tab", 672 "aria-selected": isActive, 673 "data-ai-chat-tab-id": session.id, 674 "data-active": isActive ? "true" : "false", 675 className: (0, __TURBOPACK__imported__module__406911__["cn"])("group flex max-w-[12rem] shrink-0 items-center gap-1 rounded-t-md border-b-2 px-2 py-1", isActive ? "border-accent-indigo bg-background text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"), 676 children: [
677 isRenaming ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("input", { 678 autoFocus: true, 679 type: "text", 680 value: draftName, 681 onChange: (event)=>setDraftName(event.target.value), 682 onBlur: commitRename, 683 onKeyDown: (event)=>{ 684 if (event.key === "Enter") { 685 event.preventDefault(); 686 commitRename(); 687 } else if (event.key === "Escape") { 688 event.preventDefault(); 689 cancelRename(); 690 } 691 }, 692 className: "h-6 max-w-[10rem] rounded border border-input bg-background px-1 text-xs outline-none focus:ring-2 focus:ring-ring/40", 693 "data-ai-chat-tab-rename-input": "" 694 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("button", { 695 type: "button", 696 onClick: ()=>sessions.setActiveSession(session.id), 697 onDoubleClick: ()=>startRename(session), 698 title: label, 699 className: "truncate rounded-sm text-xs font-medium outline-none focus-visible:shadow-focus", 700 children: label 701 }), 702 !isRenaming && isActive ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__741870__["IconButton"], { 703 type: "button", 704 variant: "ghost", 705 size: "xs", 706 "aria-label": t("ai_assistant.chat.tabs.rename", "Rename"), 707 title: t("ai_assistant.chat.tabs.rename", "Rename"), 708 className: "opacity-60 hover:opacity-100", 709 onClick: ()=>startRename(session), 710 "data-ai-chat-tab-rename": "", 711 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__788699__["Pencil"], { 712 className: "size-3" 713 }) 714 }) : null,
715 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__741870__["IconButton"], { 716 type: "button", 717 variant: "ghost", 718 size: "xs", 719 "aria-label": t("ai_assistant.chat.tabs.close", "Close"), 720 title: t("ai_assistant.chat.tabs.close", "Close"), 721 className: (0, __TURBOPACK__imported__module__406911__["cn"])("transition-opacity", isActive ? "opacity-60 hover:opacity-100" : "opacity-50 hover:opacity-100"), 722 "data-active": isActive ? "true" : "false", 723 onMouseDown: (event)=>{ 724 event.stopPropagation(); 725 }, 726 onClick: (event)=>{ 727 event.preventDefault(); 728 event.stopPropagation(); 729 sessions.closeSession(session.id); 730 }, 731 "data-ai-chat-tab-close": "", 732 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__37727__["X"], { 733 className: "size-3" 734 }) 735 }) 736 ] 737 }, session.id); 738 }) 739 }),
740 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__741870__["IconButton"], { 741 type: "button", 742 variant: "ghost", 743 size: "sm", 744 "aria-label": t("ai_assistant.chat.tabs.newSession", "New session"), 745 title: t("ai_assistant.chat.tabs.newSession", "New session"), 746 onClick: ()=>sessions.createSession(agentId), 747 "data-ai-chat-new-session": "", 748 className: "shrink-0", 749 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__107233__["Plus"], { 750 className: "size-4" 751 }) 752 }), 753 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(HistoryDropdown, { 754 open: historyOpen, 755 onOpenChange: setHistoryOpen, 756 closed, 757 onPick: (sessionId)=>{ 758 sessions.reopenSession(sessionId); 759 setHistoryOpen(false); 760 } 761 }) 762 ] 763 })); 764} 765function HistoryDropdown({ open, onOpenChange, closed, onPick }) { 766 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 767 const containerRef = __TURBOPACK__imported__module__271645__["useRef"](null); 768 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 769 if (!open) return; 770 const onDown = (event)=>{ 771 const root = containerRef.current; 772 if (!root) return; 773 if (event.target instanceof Node && root.contains(event.target)) return; 774 onOpenChange(false); 775 }; 776 const onKey = (event)=>{ 777 if (event.key === "Escape") onOpenChange(false); 778 }; 779 window.addEventListener("mousedown", onDown); 780 window.addEventListener("touchstart", onDown, { 781 passive: true 782 }); 783 window.addEventListener("keydown", onKey); 784 return ()=>{ 785 window.removeEventListener("mousedown", onDown); 786 window.removeEventListener("touchstart", onDown); 787 window.removeEventListener("keydown", onKey); 788 }; 789 }, [ 790 open, 791 onOpenChange 792 ]); 793 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 794 ref: containerRef, 795 className: "relative shrink-0", 796 children: [
797 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__741870__["IconButton"], { 798 type: "button", 799 variant: "ghost", 800 size: "sm", 801 "aria-label": t("ai_assistant.chat.tabs.recentSessions", "Recent sessions"), 802 title: t("ai_assistant.chat.tabs.recentSessions", "Recent sessions"), 803 "data-ai-chat-history-trigger": "", 804 "aria-expanded": open, 805 onClick: ()=>onOpenChange(!open), 806 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__503116__["Clock"], { 807 className: "size-4" 808 }) 809 }), 810 open ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 811 className: "absolute right-0 top-full mt-2 w-72 max-h-[60vh] overflow-y-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md", 812 style: { 813 zIndex: 2147483e3 814 }, 815 "data-ai-chat-history-panel": "", 816 role: "menu", 817 children: [
818 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 819 className: "px-3 pt-2 pb-1 text-xs font-medium uppercase tracking-wide text-muted-foreground", 820 children: t("ai_assistant.chat.tabs.recentSessions", "Recent sessions") 821 }), 822 closed.length === 0 ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 823 className: "px-3 py-3 text-xs text-muted-foreground", 824 "data-ai-chat-history-empty": "", 825 children: t("ai_assistant.chat.tabs.noPreviousSessions", "No previous sessions yet.") 826 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 827 className: "flex flex-col gap-0.5", 828 children: closed.map((session)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("button", { 829 type: "button", 830 role: "menuitem", 831 onClick: ()=>onPick(session.id), 832 className: "flex w-full items-center justify-between gap-2 rounded-sm px-2 py-2 text-left text-sm hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground focus-visible:outline-none", 833 "data-ai-chat-history-item": session.id, 834 children: [
835 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 836 className: "min-w-0 flex-1 truncate", 837 children: (0, __TURBOPACK__imported__module__570596__["defaultSessionLabel"])(session) 838 }), 839 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 840 className: "shrink-0 text-[10px] text-muted-foreground", 841 children: new Date(session.lastUsedAt).toLocaleDateString(void 0, { 842 month: "short", 843 day: "numeric" 844 }) 845 }) 846 ] 847 }, session.id)) 848 }) 849 ] 850 }) : null 851 ] 852 }); 853} 854; 855__turbopack_context__.s([ 856 "ChatPaneTabs", 857 0, 858 ChatPaneTabs 859]); 860}), 861520327, ((__turbopack_context__) => { 862"use strict"; 863 864var __TURBOPACK__imported__module__843476__ = __turbopack_context__.i(843476); 865var __TURBOPACK__imported__module__271645__ = __turbopack_context__.i(271645); 866var __TURBOPACK__imported__module__879002__ = __turbopack_context__.i(879002); 867var __TURBOPACK__imported__module__37727__ = __turbopack_context__.i(37727); 868var __TURBOPACK__imported__module__531278__ = __turbopack_context__.i(531278); 869var __TURBOPACK__imported__module__644149__ = __turbopack_context__.i(644149); 870var __TURBOPACK__imported__module__110035__ = __turbopack_context__.i(110035); 871var __TURBOPACK__imported__module__987030__ = __turbopack_context__.i(987030); 872var __TURBOPACK__imported__module__262524__ = __turbopack_context__.i(262524); 873var __TURBOPACK__imported__module__490746__ = __turbopack_context__.i(490746); 874var __TURBOPACK__imported__module__503477__ = __turbopack_context__.i(503477); 875var __TURBOPACK__imported__module__928441__ = __turbopack_context__.i(928441); 876"use client"; 877; 878; 879; 880; 881; 882; 883; 884; 885; 886; 887function ConversationShareDialog({ open, onOpenChange, conversationId }) { 888 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 889 const currentUserId = (0, __TURBOPACK__imported__module__503477__["useCurrentUserId"])(); 890 const [participants, setParticipants] = __TURBOPACK__imported__module__271645__["useState"]([]); 891 const [ownerUserId, setOwnerUserId] = __TURBOPACK__imported__module__271645__["useState"](null); 892 const [users, setUsers] = __TURBOPACK__imported__module__271645__["useState"]([]); 893 const [canListUsers, setCanListUsers] = __TURBOPACK__imported__module__271645__["useState"](true); 894 const [loading, setLoading] = __TURBOPACK__imported__module__271645__["useState"](false); 895 const [loadingUsers, setLoadingUsers] = __TURBOPACK__imported__module__271645__["useState"](false); 896 const [selectedUserId, setSelectedUserId] = __TURBOPACK__imported__module__271645__["useState"](""); 897 const [textUserId, setTextUserId] = __TURBOPACK__imported__module__271645__["useState"](""); 898 const [adding, setAdding] = __TURBOPACK__imported__module__271645__["useState"](false); 899 const [removingId, setRemovingId] = __TURBOPACK__imported__module__271645__["useState"](null); 900 const [error, setError] = __TURBOPACK__imported__module__271645__["useState"](null); 901 const baseUrl = `/api/ai_assistant/ai/conversations/${conversationId}/participants`; 902 const fetchParticipants = __TURBOPACK__imported__module__271645__["useCallback"](async ()=>{ 903 setLoading(true); 904 setError(null); 905 try { 906 const res = await (0, __TURBOPACK__imported__module__490746__["apiCall"])(baseUrl); 907 if (!res.ok || !res.result) throw new Error("fetch failed"); 908 setParticipants(res.result.participants.filter((p)=>p.role !== "owner")); 909 setOwnerUserId(res.result.ownerUserId ?? null); 910 } catch { 911 setError(t("common.error", "Something went wrong.")); 912 } finally{
913 setLoading(false); 914 } 915 }, [ 916 conversationId, 917 t 918 ]); 919 const fetchUsers = __TURBOPACK__imported__module__271645__["useCallback"](async ()=>{ 920 setLoadingUsers(true); 921 try { 922 const res = await (0, __TURBOPACK__imported__module__490746__["apiCall"])("/api/auth/users?limit=200"); 923 if (res.ok && res.result) { 924 setUsers(res.result.items); 925 setCanListUsers(true); 926 } else { 927 setCanListUsers(false); 928 } 929 } catch { 930 setCanListUsers(false); 931 } finally{ 932 setLoadingUsers(false); 933 } 934 }, []); 935 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 936 if (open) { 937 setSelectedUserId(""); 938 setTextUserId(""); 939 setError(null); 940 void Promise.all([ 941 fetchParticipants(), 942 fetchUsers() 943 ]); 944 } 945 }, [ 946 open, 947 fetchParticipants, 948 fetchUsers 949 ]); 950 const participantIds = __TURBOPACK__imported__module__271645__["useMemo"](()=>new Set(participants.map((p)=>p.userId)), [ 951 participants 952 ]); 953 const availableUsers = __TURBOPACK__imported__module__271645__["useMemo"](()=>users.filter((u)=>!participantIds.has(u.id) && u.id !== currentUserId && u.id !== ownerUserId), [ 954 users, 955 participantIds, 956 currentUserId, 957 ownerUserId 958 ]); 959 const activeUserId = canListUsers ? selectedUserId : textUserId.trim(); 960 const handleAdd = __TURBOPACK__imported__module__271645__["useCallback"](async ()=>{ 961 if (!activeUserId) return; 962 setAdding(true); 963 setError(null); 964 try { 965 const res = await (0, __TURBOPACK__imported__module__490746__["apiCall"])(baseUrl, { 966 method: "POST", 967 headers: { 968 "content-type": "application/json" 969 }, 970 body: JSON.stringify({ 971 userId: activeUserId, 972 role: "viewer" 973 }) 974 }); 975 if (!res.ok || !res.result) throw new Error("fetch failed"); 976 setParticipants((prev)=>{ 977 const next = res.result.participant; 978 const exists = prev.find((p)=>p.userId === next.userId); 979 if (exists) return prev.map((p)=>p.userId === next.userId ? next : p); 980 return [ 981 ...prev, 982 next 983 ]; 984 }); 985 setSelectedUserId(""); 986 setTextUserId(""); 987 } catch { 988 setError(t("common.error", "Something went wrong.")); 989 } finally{ 990 setAdding(false); 991 } 992 }, [ 993 activeUserId, 994 baseUrl, 995 t 996 ]); 997 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 998 const handler = (e)=>{ 999 if ((e.metaKey || e.ctrlKey) && e.key === "Enter") { 1000 e.preventDefault(); 1001 if (activeUserId && !adding) void handleAdd(); 1002 } 1003 }; 1004 if (open) document.addEventListener("keydown", handler); 1005 return ()=>document.removeEventListener("keydown", handler); 1006 }, [ 1007 open, 1008 activeUserId, 1009 adding, 1010 handleAdd 1011 ]); 1012 const handleRemove = async (userId)=>{ 1013 setRemovingId(userId); 1014 setError(null); 1015 try { 1016 await (0, __TURBOPACK__imported__module__490746__["apiCall"])(`${baseUrl}/${userId}`, { 1017 method: "DELETE", 1018 headers: { 1019 "content-type": "application/json" 1020 } 1021 }); 1022 setParticipants((prev)=>prev.filter((p)=>p.userId !== userId)); 1023 } catch { 1024 setError(t("common.error", "Something went wrong.")); 1025 } finally{ 1026 setRemovingId(null); 1027 } 1028 }; 1029 const formatUserLabel = (u)=>u.name ? `${u.name} \u2014 ${u.email}` : u.email; 1030 const getUserLabel = (userId)=>{ 1031 const u = users.find((u2)=>u2.id === userId); 1032 return u ? formatUserLabel(u) : userId; 1033 }; 1034 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__644149__["Dialog"], { 1035 open, 1036 onOpenChange, 1037 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__644149__["DialogContent"], { 1038 className: "sm:max-w-md", 1039 children: [
1040 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__644149__["DialogHeader"], { 1041 children: [ 1042 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__644149__["DialogTitle"], { 1043 children: t("ai_assistant.share.dialogTitle", "Share Conversation") 1044 }), 1045 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__644149__["DialogDescription"], { 1046 children: t("ai_assistant.share.dialogDescription", "Share this conversation with other users. They will get read-only access.") 1047 }) 1048 ] 1049 }), 1050 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 1051 className: "space-y-4", 1052 children: [ 1053 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 1054 className: "flex gap-2", 1055 children: [ 1056 canListUsers === false ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__987030__["Input"], { 1057 placeholder: t("ai_assistant.share.participantPlaceholder", "User ID..."), 1058 value: textUserId, 1059 onChange: (e)=>setTextUserId(e.target.value), 1060 onKeyDown: (e)=>{ 1061 if (e.key === "Enter") { 1062 e.preventDefault(); 1063 void handleAdd(); 1064 } 1065 }, 1066 className: "flex-1" 1067 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__262524__["Select"], { 1068 value: selectedUserId, 1069 onValueChange: setSelectedUserId, 1070 disabled: loadingUsers || availableUsers.length === 0, 1071 children: [
1072 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__262524__["SelectTrigger"], { 1073 className: "flex-1", 1074 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__262524__["SelectValue"], { 1075 placeholder: loadingUsers ? t("common.loading", "Loading...") : availableUsers.length === 0 ? t("ai_assistant.share.allUsersAdded", "All users already added") : t("ai_assistant.share.selectUser", "Select a user...") 1076 }) 1077 }), 1078 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__262524__["SelectContent"], { 1079 children: availableUsers.map((u)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__262524__["SelectItem"], { 1080 value: u.id, 1081 children: formatUserLabel(u) 1082 }, u.id)) 1083 }) 1084 ] 1085 }),
1086 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__110035__["Button"], { 1087 type: "button", 1088 onClick: ()=>void handleAdd(), 1089 disabled: !activeUserId || adding, 1090 size: "default", 1091 children: [ 1092 adding ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__531278__["Loader2"], { 1093 className: "size-4 animate-spin" 1094 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__879002__["UserPlus"], { 1095 className: "size-4" 1096 }), 1097 t("ai_assistant.share.addParticipant", "Add") 1098 ] 1099 }) 1100 ] 1101 }), 1102 error ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("p", { 1103 className: "text-sm text-status-danger-text", 1104 children: error 1105 }) : null,
1106 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 1107 className: "space-y-2 min-h-[60px]", 1108 children: loading ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 1109 className: "flex items-center justify-center py-4", 1110 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__531278__["Loader2"], { 1111 className: "size-5 animate-spin text-muted-foreground" 1112 }) 1113 }) : participants.length === 0 ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("p", { 1114 className: "text-sm text-muted-foreground py-2", 1115 children: t("ai_assistant.share.noParticipants", "No participants yet. Add someone to share this conversation.") 1116 }) : participants.map((p)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 1117 className: "flex items-center justify-between rounded-lg border border-border px-3 py-2", 1118 children: [
1119 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 1120 className: "min-w-0 flex-1", 1121 children: [ 1122 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("p", { 1123 className: "truncate text-sm text-foreground", 1124 children: getUserLabel(p.userId) 1125 }), 1126 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("p", { 1127 className: "text-xs text-muted-foreground capitalize", 1128 children: p.role 1129 }) 1130 ] 1131 }),
1132 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__110035__["Button"], { 1133 type: "button", 1134 variant: "ghost", 1135 size: "icon", 1136 onClick: ()=>void handleRemove(p.userId), 1137 disabled: removingId === p.userId, 1138 "aria-label": t("ai_assistant.share.removeParticipant", "Remove"), 1139 children: removingId === p.userId ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__531278__["Loader2"], { 1140 className: "size-3 animate-spin" 1141 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__37727__["X"], { 1142 className: "size-4" 1143 }) 1144 }) 1145 ] 1146 }, p.userId)) 1147 }) 1148 ] 1149 }),
1150 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__644149__["DialogFooter"], { 1151 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__110035__["Button"], { 1152 type: "button", 1153 variant: "outline", 1154 onClick: ()=>onOpenChange(false), 1155 children: t("common.close", "Close") 1156 }) 1157 }) 1158 ] 1159 }) 1160 }); 1161} 1162var ConversationShareDialog_default = ConversationShareDialog; 1163; 1164__turbopack_context__.s([ 1165 "ConversationShareDialog", 1166 0, 1167 ConversationShareDialog, 1168 "default", 1169 0, 1170 ConversationShareDialog_default 1171]); 1172}), 1173899497, ((__turbopack_context__) => { 1174"use strict"; 1175 1176var __TURBOPACK__imported__module__843476__ = __turbopack_context__.i(843476); 1177var __TURBOPACK__imported__module__271645__ = __turbopack_context__.i(271645); 1178var __TURBOPACK__imported__module__662031__ = __turbopack_context__.i(662031); 1179var __TURBOPACK__imported__module__741870__ = __turbopack_context__.i(741870); 1180var __TURBOPACK__imported__module__928441__ = __turbopack_context__.i(928441); 1181var __TURBOPACK__imported__module__520327__ = __turbopack_context__.i(520327); 1182"use client"; 1183; 1184; 1185; 1186; 1187; 1188; 1189function ConversationShareButton({ conversationId }) { 1190 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 1191 const [dialogOpen, setDialogOpen] = __TURBOPACK__imported__module__271645__["useState"](false); 1192 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__843476__["Fragment"], { 1193 children: [
1194 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__741870__["IconButton"], { 1195 type: "button", 1196 variant: "ghost", 1197 size: "sm", 1198 onClick: ()=>setDialogOpen(true), 1199 "aria-label": t("ai_assistant.share.shareButton", "Share"), 1200 title: t("ai_assistant.share.shareButton", "Share"), 1201 "data-ai-chat-share-conversation": "", 1202 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__662031__["Share2"], { 1203 className: "size-4", 1204 "aria-hidden": true 1205 }) 1206 }), 1207 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__520327__["ConversationShareDialog"], { 1208 open: dialogOpen, 1209 onOpenChange: setDialogOpen, 1210 conversationId 1211 }) 1212 ] 1213 }); 1214} 1215var ConversationShareButton_default = ConversationShareButton; 1216; 1217__turbopack_context__.s([ 1218 "ConversationShareButton", 1219 0, 1220 ConversationShareButton, 1221 "default", 1222 0, 1223 ConversationShareButton_default 1224]); 1225}), 1226569016, ((__turbopack_context__) => { 1227"use strict"; 1228 1229var __TURBOPACK__imported__module__843476__ = __turbopack_context__.i(843476); 1230var __TURBOPACK__imported__module__271645__ = __turbopack_context__.i(271645); 1231var __TURBOPACK__imported__module__398361__ = __turbopack_context__.i(398361); 1232var __TURBOPACK__imported__module__726336__ = __turbopack_context__.i(726336); 1233var __TURBOPACK__imported__module__37727__ = __turbopack_context__.i(37727); 1234var __TURBOPACK__imported__module__811020__ = __turbopack_context__.i(811020); 1235var __TURBOPACK__imported__module__570596__ = __turbopack_context__.i(570596); 1236var __TURBOPACK__imported__module__899497__ = __turbopack_context__.i(899497); 1237var __TURBOPACK__imported__module__741870__ = __turbopack_context__.i(741870); 1238var __TURBOPACK__imported__module__928441__ = __turbopack_context__.i(928441); 1239var __TURBOPACK__imported__module__406911__ = __turbopack_context__.i(406911); 1240"use client"; 1241; 1242; 1243; 1244; 1245; 1246; 1247; 1248; 1249; 1250const LazyAiChat = /*#__PURE__*/ __TURBOPACK__imported__module__271645__["lazy"](async ()=>{ 1251 const mod = await __turbopack_context__.A(10642); 1252 return { 1253 default: mod.AiChat 1254 }; 1255}); 1256const STORAGE_KEY = "om-ai-dock-v1"; 1257const MIN_WIDTH = 320; 1258const MAX_WIDTH = 960; 1259const DEFAULT_WIDTH = 420; 1260const COLLAPSED_WIDTH = 48; 1261const AiDockContext = /*#__PURE__*/ __TURBOPACK__imported__module__271645__["createContext"](null); 1262function isRecord(value) { 1263 return Boolean(value) && typeof value === "object" && !Array.isArray(value); 1264} 1265function readOptionalString(value) { 1266 return typeof value === "string" && value.length > 0 ? value : void 0; 1267} 1268function readWidth(value) { 1269 return Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, typeof value === "number" ? value : DEFAULT_WIDTH)); 1270} 1271function readPersistedSuggestions(value) { 1272 if (!Array.isArray(value)) return void 0; 1273 const suggestions = value.filter((entry)=>isRecord(entry)).map((entry)=>{ 1274 const label = readOptionalString(entry.label); 1275 const prompt = readOptionalString(entry.prompt); 1276 if (!label || !prompt) return null; 1277 return { 1278 label, 1279 prompt 1280 }; 1281 }).filter((entry)=>entry !== null); 1282 return suggestions.length > 0 ? suggestions : void 0; 1283} 1284function readPersistedContextItems(value) { 1285 if (!Array.isArray(value)) return void 0; 1286 const contextItems = value.filter((entry)=>isRecord(entry)).map((entry)=>{ 1287 const label = readOptionalString(entry.label); 1288 if (!label) return null; 1289 const detail = readOptionalString(entry.detail); 1290 return detail ? { 1291 label, 1292 detail 1293 } : { 1294 label 1295 }; 1296 }).filter((entry)=>entry !== null); 1297 return contextItems.length > 0 ? contextItems : void 0; 1298} 1299function readPersistedAssistant(value) { 1300 if (!isRecord(value)) return null; 1301 const agent = readOptionalString(value.agent); 1302 const label = readOptionalString(value.label); 1303 if (!agent || !label) return null; 1304 return { 1305 agent, 1306 label, 1307 description: readOptionalString(value.description), 1308 pageContext: isRecord(value.pageContext) ? value.pageContext : void 0, 1309 placeholder: readOptionalString(value.placeholder), 1310 welcomeTitle: readOptionalString(value.welcomeTitle), 1311 welcomeDescription: readOptionalString(value.welcomeDescription), 1312 suggestions: readPersistedSuggestions(value.suggestions), 1313 contextItems: readPersistedContextItems(value.contextItems) 1314 }; 1315} 1316function serializeAssistant(assistant) { 1317 if (!assistant) return null; 1318 return { 1319 agent: assistant.agent, 1320 label: assistant.label, 1321 description: assistant.description, 1322 pageContext: assistant.pageContext, 1323 placeholder: assistant.placeholder, 1324 welcomeTitle: assistant.welcomeTitle, 1325 welcomeDescription: assistant.welcomeDescription, 1326 suggestions: assistant.suggestions?.map((suggestion)=>({ 1327 label: suggestion.label, 1328 prompt: suggestion.prompt 1329 })), 1330 contextItems: assistant.contextItems?.map((item)=>({ 1331 label: item.label, 1332 detail: item.detail 1333 })) 1334 }; 1335} 1336function readPersisted() { 1337 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 1338 ; 1339 try { 1340 const raw = window.localStorage.getItem(STORAGE_KEY); 1341 if (!raw) return { 1342 assistant: null, 1343 width: DEFAULT_WIDTH,
1344 collapsed: false 1345 }; 1346 const parsed = JSON.parse(raw); 1347 return { 1348 assistant: readPersistedAssistant(parsed?.assistant), 1349 width: readWidth(parsed?.width), 1350 collapsed: parsed?.collapsed === true 1351 }; 1352 } catch { 1353 return { 1354 assistant: null, 1355 width: DEFAULT_WIDTH, 1356 collapsed: false 1357 }; 1358 } 1359} 1360function writePersisted(state) { 1361 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 1362 ; 1363 try { 1364 window.localStorage.setItem(STORAGE_KEY, JSON.stringify({ 1365 assistant: serializeAssistant(state.assistant), 1366 width: state.width, 1367 collapsed: state.collapsed 1368 })); 1369 } catch {} 1370} 1371function AiDockProvider({ children }) { 1372 const [state, setState] = __TURBOPACK__imported__module__271645__["useState"](()=>({ 1373 assistant: null, 1374 width: DEFAULT_WIDTH, 1375 collapsed: false 1376 })); 1377 const [hydrated, setHydrated] = __TURBOPACK__imported__module__271645__["useState"](false); 1378 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 1379 const persisted = readPersisted(); 1380 setState(persisted); 1381 setHydrated(true); 1382 }, []); 1383 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 1384 if (!hydrated) return; 1385 writePersisted(state); 1386 }, [ 1387 hydrated, 1388 state 1389 ]); 1390 const dock = __TURBOPACK__imported__module__271645__["useCallback"]((assistant)=>{ 1391 setState((prev)=>({ 1392 ...prev, 1393 assistant, 1394 collapsed: false 1395 })); 1396 }, []); 1397 const undock = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 1398 setState((prev)=>({ 1399 ...prev, 1400 assistant: null, 1401 collapsed: false 1402 })); 1403 }, []); 1404 const isDocked = __TURBOPACK__imported__module__271645__["useCallback"]((agentId)=>state.assistant?.agent === agentId, [ 1405 state.assistant?.agent 1406 ]); 1407 const setWidth = __TURBOPACK__imported__module__271645__["useCallback"]((width)=>{ 1408 setState((prev)=>({ 1409 ...prev, 1410 width 1411 })); 1412 }, []); 1413 const setCollapsed = __TURBOPACK__imported__module__271645__["useCallback"]((collapsed)=>{ 1414 setState((prev)=>({ 1415 ...prev, 1416 collapsed 1417 })); 1418 }, []); 1419 const api = __TURBOPACK__imported__module__271645__["useMemo"](()=>({ 1420 state, 1421 dock, 1422 undock, 1423 isDocked 1424 }), [ 1425 state, 1426 dock, 1427 undock, 1428 isDocked 1429 ]); 1430 const reservedWidth = state.assistant ? state.collapsed ? COLLAPSED_WIDTH : state.width : null; 1431 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(AiDockContext.Provider, { 1432 value: api, 1433 children: [
1434 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 1435 className: reservedWidth != null ? "lg:pr-[var(--om-ai-dock-width)]" : void 0, 1436 style: reservedWidth != null ? { 1437 ["--om-ai-dock-width"]: `${reservedWidth}px` 1438 } : void 0, 1439 children 1440 }), 1441 state.assistant ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(AiDockPanel, { 1442 assistant: state.assistant, 1443 width: state.width, 1444 collapsed: state.collapsed, 1445 onCollapsedChange: setCollapsed, 1446 onWidthChange: setWidth, 1447 onClose: undock 1448 }) : null 1449 ] 1450 }); 1451} 1452function useAiDock() { 1453 const ctx = __TURBOPACK__imported__module__271645__["useContext"](AiDockContext); 1454 if (ctx) return ctx; 1455 return { 1456 state: { 1457 assistant: null, 1458 width: DEFAULT_WIDTH, 1459 collapsed: false 1460 }, 1461 dock: ()=>{}, 1462 undock: ()=>{}, 1463 isDocked: ()=>false 1464 }; 1465} 1466function AiDockPanel({ assistant, width, collapsed, onCollapsedChange, onWidthChange, onClose }) { 1467 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 1468 const dragStateRef = __TURBOPACK__imported__module__271645__["useRef"](null); 1469 const handlePointerDown = __TURBOPACK__imported__module__271645__["useCallback"]((event)=>{ 1470 event.preventDefault(); 1471 const target = event.currentTarget; 1472 target.setPointerCapture(event.pointerId); 1473 dragStateRef.current = { 1474 startX: event.clientX, 1475 startWidth: width 1476 }; 1477 }, [ 1478 width 1479 ]); 1480 const handlePointerMove = __TURBOPACK__imported__module__271645__["useCallback"]((event)=>{ 1481 if (!dragStateRef.current) return; 1482 const delta = dragStateRef.current.startX - event.clientX; 1483 const next = Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, dragStateRef.current.startWidth + delta)); 1484 onWidthChange(next); 1485 }, [ 1486 onWidthChange 1487 ]); 1488 const handlePointerUp = __TURBOPACK__imported__module__271645__["useCallback"]((event)=>{ 1489 const target = event.currentTarget; 1490 try { 1491 target.releasePointerCapture(event.pointerId); 1492 } catch {} 1493 dragStateRef.current = null; 1494 }, []); 1495 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("aside", { 1496 "data-ai-dock-panel": "", 1497 "data-ai-dock-agent": assistant.agent, 1498 className: (0, __TURBOPACK__imported__module__406911__["cn"])(// Dock is desktop-only â on small screens the AiChat dialog is the 1499 // primary surface (full-screen sheet) and a fixed side panel would 1500 // crowd the viewport. 1501 "hidden lg:flex", "fixed top-0 right-0 z-overlay h-svh min-w-0 flex-col overflow-hidden border-l bg-background shadow-lg", collapsed ? "w-12" : ""), 1502 style: collapsed ? void 0 : { 1503 width 1504 }, 1505 "aria-label": assistant.label, 1506 children: [ 1507 !collapsed ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 1508 role: "separator", 1509 "aria-orientation": "vertical", 1510 tabIndex: -1, 1511 onPointerDown: handlePointerDown, 1512 onPointerMove: handlePointerMove, 1513 onPointerUp: handlePointerUp, 1514 onPointerCancel: handlePointerUp, 1515 className: "absolute left-0 top-0 h-full w-1 cursor-col-resize bg-transparent hover:bg-primary/20", 1516 "data-ai-dock-resize-handle": "" 1517 }) : null,
1518 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("header", { 1519 className: "flex items-center gap-2 px-3 py-2", 1520 children: collapsed ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__741870__["IconButton"], { 1521 type: "button", 1522 variant: "ghost", 1523 size: "sm", 1524 "aria-label": t("ai_assistant.chat.dock.expand", "Expand AI dock"), 1525 title: t("ai_assistant.chat.dock.expand", "Expand AI dock"), 1526 onClick: ()=>onCollapsedChange(false), 1527 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__398361__["Maximize2"], { 1528 className: "size-4" 1529 }) 1530 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__843476__["Fragment"], { 1531 children: [
1532 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 1533 className: "min-w-0 flex-1", 1534 children: [ 1535 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 1536 className: "flex items-center gap-2 text-sm font-medium", 1537 "data-ai-dock-label": "", 1538 children: [ 1539 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 1540 className: "truncate", 1541 children: assistant.label 1542 }), 1543 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 1544 className: "inline-flex shrink-0 items-center rounded-full border border-border bg-secondary px-1.5 py-0 text-[10px] font-medium uppercase tracking-wide text-secondary-foreground", 1545 "data-ai-beta-chip": "", 1546 children: t("ai_assistant.chat.betaChip", "beta") 1547 }) 1548 ] 1549 }), 1550 assistant.description ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 1551 className: "truncate text-xs text-muted-foreground", 1552 children: assistant.description 1553 }) : null 1554 ] 1555 }),
1556 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__741870__["IconButton"], { 1557 type: "button", 1558 variant: "ghost", 1559 size: "sm", 1560 "aria-label": t("ai_assistant.chat.dock.collapse", "Collapse AI dock"), 1561 title: t("ai_assistant.chat.dock.collapse", "Collapse AI dock"), 1562 onClick: ()=>onCollapsedChange(true), 1563 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__726336__["Minimize2"], { 1564 className: "size-4" 1565 }) 1566 }), 1567 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__741870__["IconButton"], { 1568 type: "button", 1569 variant: "ghost", 1570 size: "sm", 1571 "aria-label": t("ai_assistant.chat.dock.close", "Close AI dock"), 1572 title: t("ai_assistant.chat.dock.close", "Close AI dock"), 1573 onClick: onClose, 1574 "data-ai-dock-close": "", 1575 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__37727__["X"], { 1576 className: "size-4" 1577 }) 1578 }) 1579 ] 1580 }) 1581 }), 1582 !collapsed ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(DockedChatBody, { 1583 assistant 1584 }) : null 1585 ] 1586 }); 1587} 1588function DockedChatBody({ assistant }) { 1589 const sessions = (0, __TURBOPACK__imported__module__570596__["useAiChatSessions"])(); 1590 const session = sessions.getActiveSession(assistant.agent); 1591 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 1592 if (!session) sessions.ensureSession(assistant.agent); 1593 }, [ 1594 assistant.agent, 1595 session, 1596 sessions 1597 ]); 1598 const activeSessionId = session?.id ?? null; 1599 const handleConversationNotFound = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 1600 if (activeSessionId) sessions.closeSession(activeSessionId); 1601 }, [ 1602 activeSessionId, 1603 sessions 1604 ]); 1605 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__843476__["Fragment"], { 1606 children: [
1607 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__811020__["ChatPaneTabs"], { 1608 agentId: assistant.agent, 1609 className: "border-b" 1610 }), 1611 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 1612 className: "min-h-0 min-w-0 flex-1 overflow-hidden", 1613 "data-ai-dock-chat-container": "", 1614 children: session ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__271645__["Suspense"], { 1615 fallback: null, 1616 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(LazyAiChat, { 1617 agent: assistant.agent, 1618 conversationId: session.conversationId, 1619 pageContext: assistant.pageContext, 1620 className: "h-full", 1621 defaultCompactFooter: true, 1622 placeholder: assistant.placeholder, 1623 suggestions: assistant.suggestions, 1624 contextItems: assistant.contextItems, 1625 welcomeTitle: assistant.welcomeTitle, 1626 welcomeDescription: assistant.welcomeDescription, 1627 headerActions: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__899497__["ConversationShareButton"], { 1628 conversationId: session.conversationId 1629 }), 1630 onConversationNotFound: handleConversationNotFound 1631 }, session.id) 1632 }) : null 1633 }) 1634 ] 1635 }); 1636} 1637; 1638__turbopack_context__.s([ 1639 "AiDockProvider", 1640 0, 1641 AiDockProvider, 1642 "useAiDock", 1643 0, 1644 useAiDock 1645]); 1646}), 1647]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.