quidproquo-web-admin 0.1.24 → 0.1.25

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.
@@ -10,7 +10,7 @@ const material_1 = require("@mui/material");
10
10
  // Renders one message's segments — text (markdown), reasoning (dimmed), tool
11
11
  // calls (a chip per tool, showing input and, once it arrives, output), and
12
12
  // file attachments. Used for both finalized messages and the live stream
13
- // preview (mergeStreamParts produces the same segment shape for both).
13
+ // preview (the live stream is folded into the same segment shape).
14
14
  const EventDocAiSegments = ({ segments }) => ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: segments.map((segment, index) => {
15
15
  if (segment.type === 'text') {
16
16
  return (0, jsx_runtime_1.jsx)(react_markdown_1.default, { children: segment.text }, index);
@@ -1 +1 @@
1
- {"version":3,"file":"EventDocAiSegments.js","sourceRoot":"","sources":["../../../../src/LogViewer/LogChat/EventDocAiSegments.tsx"],"names":[],"mappings":";;;;;;;AAGA,oEAAsC;AACtC,4CAAsD;AAMtD,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AACzE,uEAAuE;AAChE,MAAM,kBAAkB,GAAsC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CACrF,2DACG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;QAC/B,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,uBAAC,wBAAQ,cAAc,OAAO,CAAC,IAAI,IAApB,KAAK,CAA2B,CAAC;QACzD,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACjC,OAAO,CACL,uBAAC,qBAAU,IAAa,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,OAAO,EAAC,OAAO,YACtF,OAAO,CAAC,IAAI,IADE,KAAK,CAET,CACd,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,uBAAC,eAAI,IAAa,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAC,OAAO,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAArE,KAAK,CAAoE,CAAC;QAC9F,CAAC;QAED,OAAO,CACL,uBAAC,cAAG,IAAa,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,YAC/E,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,CACtC,wBAAC,cAAG,IAEF,EAAE,EAAE;oBACF,CAAC,EAAE,CAAC;oBACJ,YAAY,EAAE,CAAC;oBACf,eAAe,EAAE,qBAAqB;oBACtC,UAAU,EAAE,WAAW;oBACvB,QAAQ,EAAE,SAAS;iBACpB,aAED,uBAAC,qBAAU,IAAC,SAAS,EAAC,KAAK,EAAC,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,OAAO,EAAC,SAAS,YACtE,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAC7D,EACb,uBAAC,cAAG,IAAC,SAAS,EAAC,KAAK,EAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAC9E,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GACvB,EACL,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,CAC5B,uBAAC,cAAG,IAAC,SAAS,EAAC,KAAK,EAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,YACrG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,GACxB,CACP,KAnBI,SAAS,CAoBV,CACP,CAAC,IAxBM,KAAK,CAyBT,CACP,CAAC;IACJ,CAAC,CAAC,GACD,CACJ,CAAC;AAjDW,QAAA,kBAAkB,sBAiD7B","sourcesContent":["import { EventDocAiMessageSegment } from 'quidproquo-features';\n\nimport React from 'react';\nimport Markdown from 'react-markdown';\nimport { Box, Chip, Typography } from '@mui/material';\n\ninterface EventDocAiSegmentsProps {\n segments: EventDocAiMessageSegment[];\n}\n\n// Renders one message's segments — text (markdown), reasoning (dimmed), tool\n// calls (a chip per tool, showing input and, once it arrives, output), and\n// file attachments. Used for both finalized messages and the live stream\n// preview (mergeStreamParts produces the same segment shape for both).\nexport const EventDocAiSegments: React.FC<EventDocAiSegmentsProps> = ({ segments }) => (\n <>\n {segments.map((segment, index) => {\n if (segment.type === 'text') {\n return <Markdown key={index}>{segment.text}</Markdown>;\n }\n\n if (segment.type === 'reasoning') {\n return (\n <Typography key={index} sx={{ fontStyle: 'italic', opacity: 0.7, mb: 1 }} variant=\"body2\">\n {segment.text}\n </Typography>\n );\n }\n\n if (segment.type === 'file') {\n return <Chip key={index} label={segment.attachment.filename} size=\"small\" sx={{ mb: 1 }} />;\n }\n\n return (\n <Box key={index} sx={{ display: 'flex', flexDirection: 'column', gap: 0.5, mb: 1 }}>\n {segment.tools.map((tool, toolIndex) => (\n <Box\n key={toolIndex}\n sx={{\n p: 1,\n borderRadius: 1,\n backgroundColor: 'rgba(0, 0, 0, 0.06)',\n fontFamily: 'monospace',\n fontSize: '0.75rem',\n }}\n >\n <Typography component=\"div\" sx={{ fontWeight: 'bold' }} variant=\"caption\">\n {tool.output === undefined ? `Calling ${tool.toolName}…` : tool.toolName}\n </Typography>\n <Box component=\"pre\" sx={{ m: 0, whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>\n {JSON.stringify(tool.input)}\n </Box>\n {tool.output !== undefined && (\n <Box component=\"pre\" sx={{ m: 0, mt: 0.5, whiteSpace: 'pre-wrap', wordBreak: 'break-all', opacity: 0.8 }}>\n {JSON.stringify(tool.output)}\n </Box>\n )}\n </Box>\n ))}\n </Box>\n );\n })}\n </>\n);\n"]}
1
+ {"version":3,"file":"EventDocAiSegments.js","sourceRoot":"","sources":["../../../../src/LogViewer/LogChat/EventDocAiSegments.tsx"],"names":[],"mappings":";;;;;;;AAGA,oEAAsC;AACtC,4CAAsD;AAMtD,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AACzE,mEAAmE;AAC5D,MAAM,kBAAkB,GAAsC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CACrF,2DACG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;QAC/B,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,uBAAC,wBAAQ,cAAc,OAAO,CAAC,IAAI,IAApB,KAAK,CAA2B,CAAC;QACzD,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACjC,OAAO,CACL,uBAAC,qBAAU,IAAa,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,OAAO,EAAC,OAAO,YACtF,OAAO,CAAC,IAAI,IADE,KAAK,CAET,CACd,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,uBAAC,eAAI,IAAa,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAC,OAAO,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAArE,KAAK,CAAoE,CAAC;QAC9F,CAAC;QAED,OAAO,CACL,uBAAC,cAAG,IAAa,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,YAC/E,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,CACtC,wBAAC,cAAG,IAEF,EAAE,EAAE;oBACF,CAAC,EAAE,CAAC;oBACJ,YAAY,EAAE,CAAC;oBACf,eAAe,EAAE,qBAAqB;oBACtC,UAAU,EAAE,WAAW;oBACvB,QAAQ,EAAE,SAAS;iBACpB,aAED,uBAAC,qBAAU,IAAC,SAAS,EAAC,KAAK,EAAC,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,OAAO,EAAC,SAAS,YACtE,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAC7D,EACb,uBAAC,cAAG,IAAC,SAAS,EAAC,KAAK,EAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAC9E,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GACvB,EACL,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,CAC5B,uBAAC,cAAG,IAAC,SAAS,EAAC,KAAK,EAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,YACrG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,GACxB,CACP,KAnBI,SAAS,CAoBV,CACP,CAAC,IAxBM,KAAK,CAyBT,CACP,CAAC;IACJ,CAAC,CAAC,GACD,CACJ,CAAC;AAjDW,QAAA,kBAAkB,sBAiD7B","sourcesContent":["import { EventDocAiMessageSegment } from 'quidproquo-features';\n\nimport React from 'react';\nimport Markdown from 'react-markdown';\nimport { Box, Chip, Typography } from '@mui/material';\n\ninterface EventDocAiSegmentsProps {\n segments: EventDocAiMessageSegment[];\n}\n\n// Renders one message's segments — text (markdown), reasoning (dimmed), tool\n// calls (a chip per tool, showing input and, once it arrives, output), and\n// file attachments. Used for both finalized messages and the live stream\n// preview (the live stream is folded into the same segment shape).\nexport const EventDocAiSegments: React.FC<EventDocAiSegmentsProps> = ({ segments }) => (\n <>\n {segments.map((segment, index) => {\n if (segment.type === 'text') {\n return <Markdown key={index}>{segment.text}</Markdown>;\n }\n\n if (segment.type === 'reasoning') {\n return (\n <Typography key={index} sx={{ fontStyle: 'italic', opacity: 0.7, mb: 1 }} variant=\"body2\">\n {segment.text}\n </Typography>\n );\n }\n\n if (segment.type === 'file') {\n return <Chip key={index} label={segment.attachment.filename} size=\"small\" sx={{ mb: 1 }} />;\n }\n\n return (\n <Box key={index} sx={{ display: 'flex', flexDirection: 'column', gap: 0.5, mb: 1 }}>\n {segment.tools.map((tool, toolIndex) => (\n <Box\n key={toolIndex}\n sx={{\n p: 1,\n borderRadius: 1,\n backgroundColor: 'rgba(0, 0, 0, 0.06)',\n fontFamily: 'monospace',\n fontSize: '0.75rem',\n }}\n >\n <Typography component=\"div\" sx={{ fontWeight: 'bold' }} variant=\"caption\">\n {tool.output === undefined ? `Calling ${tool.toolName}…` : tool.toolName}\n </Typography>\n <Box component=\"pre\" sx={{ m: 0, whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>\n {JSON.stringify(tool.input)}\n </Box>\n {tool.output !== undefined && (\n <Box component=\"pre\" sx={{ m: 0, mt: 0.5, whiteSpace: 'pre-wrap', wordBreak: 'break-all', opacity: 0.8 }}>\n {JSON.stringify(tool.output)}\n </Box>\n )}\n </Box>\n ))}\n </Box>\n );\n })}\n </>\n);\n"]}
@@ -16,7 +16,7 @@ const LogChatConversation = ({ logCorrelation }) => {
16
16
  const chatContainerRef = (0, react_1.useRef)(null);
17
17
  const [api, state] = (0, quidproquo_web_react_2.useQpqWebsocketQueueRuntime)(eventDocAiLogChatRuntime_1.eventDocAiLogChatRuntime, logCorrelation);
18
18
  const [adminApi] = (0, adminApp_1.useAdminApp)();
19
- const streamSegments = (0, quidproquo_features_1.mergeStreamParts)(state.streamParts);
19
+ const streamSegments = state.streamSegments;
20
20
  const isThinking = state.isSending && streamSegments.length === 0;
21
21
  const handleSendMessage = (0, quidproquo_web_react_1.useEffectCallback)(() => {
22
22
  if (inputMessage.trim() !== '') {
@@ -1 +1 @@
1
- {"version":3,"file":"LogChat.js","sourceRoot":"","sources":["../../../../src/LogViewer/LogChat/LogChat.tsx"],"names":[],"mappings":"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","sourcesContent":["import { eventDocAiContext, mergeStreamParts } from 'quidproquo-features';\nimport { useEffectCallback } from 'quidproquo-web-react';\nimport { QpqContextProvider, useQpqWebsocketQueueRuntime } from 'quidproquo-web-react';\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Android as AndroidIcon, Person as PersonIcon } from '@mui/icons-material';\nimport { Avatar, Box, Button, CircularProgress, Paper, TextField, Typography } from '@mui/material';\n\nimport { useAdminApp } from '../../adminApp';\nimport { eventDocAiLogChatRuntime } from './eventDocAiLogChatRuntime';\nimport { EventDocAiSegments } from './EventDocAiSegments';\n\ninterface LogChatProps {\n logServiceName: string;\n logCorrelation: string;\n}\n\nconst LogChatConversation: React.FC<{ logCorrelation: string }> = ({ logCorrelation }) => {\n const [inputMessage, setInputMessage] = useState('');\n const chatContainerRef = useRef<HTMLDivElement>(null);\n\n const [api, state] = useQpqWebsocketQueueRuntime(eventDocAiLogChatRuntime, logCorrelation);\n const [adminApi] = useAdminApp();\n\n const streamSegments = mergeStreamParts(state.streamParts);\n const isThinking = state.isSending && streamSegments.length === 0;\n\n const handleSendMessage = useEffectCallback(() => {\n if (inputMessage.trim() !== '') {\n // Audit trail (session event) and actual chat transport are separate concerns.\n adminApi.sendChatMessage(logCorrelation, inputMessage);\n api.eventDocAiSendMessage(inputMessage);\n setInputMessage('');\n }\n });\n\n const handleKeyPress = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n handleSendMessage();\n }\n };\n\n useEffect(() => {\n if (chatContainerRef.current) {\n chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;\n }\n }, [state.chatMessages, streamSegments]);\n\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%' }}>\n <Box ref={chatContainerRef} sx={{ flexGrow: 1, overflowY: 'auto', p: 2 }}>\n {state.isLoadingHistory && (\n <Box sx={{ display: 'flex', justifyContent: 'center', p: 2 }}>\n <CircularProgress size={20} />\n </Box>\n )}\n {state.chatMessages.map((message, index) => (\n <Box\n key={index}\n sx={{\n display: 'flex',\n alignItems: 'flex-start',\n mb: 2,\n justifyContent: message.role === 'assistant' ? 'flex-start' : 'flex-end',\n }}\n >\n <Paper\n sx={{\n p: 2,\n borderRadius: message.role === 'assistant' ? '20px 20px 20px 0' : '20px 20px 0 20px',\n backgroundColor: message.role === 'assistant' ? 'grey.300' : 'primary.main',\n color: message.role === 'assistant' ? 'black' : 'white',\n maxWidth: '70%',\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>\n <Avatar sx={{ mr: 1, bgcolor: message.role === 'assistant' ? 'grey.500' : 'primary.dark' }}>\n {message.role === 'assistant' ? <AndroidIcon /> : <PersonIcon />}\n </Avatar>\n <Typography variant=\"subtitle2\">{message.role === 'assistant' ? 'AI Assistant' : 'You'}</Typography>\n </Box>\n <EventDocAiSegments segments={message.segments} />\n </Paper>\n </Box>\n ))}\n {streamSegments.length > 0 && (\n <Box sx={{ display: 'flex', alignItems: 'flex-start', mb: 2, justifyContent: 'flex-start' }}>\n <Paper sx={{ p: 2, borderRadius: '20px 20px 20px 0', backgroundColor: 'grey.300', color: 'black', maxWidth: '70%' }}>\n <Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>\n <Avatar sx={{ mr: 1, bgcolor: 'grey.500' }}>\n <AndroidIcon />\n </Avatar>\n <Typography variant=\"subtitle2\">AI Assistant</Typography>\n </Box>\n <EventDocAiSegments segments={streamSegments} />\n </Paper>\n </Box>\n )}\n {isThinking && (\n <Box sx={{ display: 'flex', alignItems: 'flex-start', mb: 2, justifyContent: 'flex-start' }}>\n <Paper sx={{ p: 2, borderRadius: '20px 20px 20px 0', backgroundColor: 'grey.300', color: 'black', maxWidth: '70%' }}>\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <CircularProgress size={20} sx={{ mr: 1 }} />\n <Typography variant=\"body1\">Thinking...</Typography>\n </Box>\n </Paper>\n </Box>\n )}\n {state.error && (\n <Typography color=\"error\" sx={{ mt: 1 }} variant=\"body2\">\n {state.error}\n </Typography>\n )}\n </Box>\n <Box sx={{ p: 2, borderTop: '1px solid #ccc' }}>\n <Box sx={{ display: 'flex' }}>\n <TextField\n fullWidth\n onChange={(e) => setInputMessage(e.target.value)}\n onKeyDown={handleKeyPress}\n placeholder=\"Ask about this log...\"\n sx={{ mr: 2 }}\n value={inputMessage}\n variant=\"outlined\"\n />\n <Button onClick={handleSendMessage} variant=\"contained\">\n Send\n </Button>\n </Box>\n </Box>\n </Box>\n );\n};\n\n// The generic EventDocAi chat, scoped to this one log (docId = correlation id).\n// See eventdoc-chat-plan.md — replaces the old one-off Claude chat.\nexport const LogChat: React.FC<LogChatProps> = ({ logServiceName, logCorrelation }) => {\n if (!logServiceName) {\n return (\n <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>\n <CircularProgress size={20} />\n </Box>\n );\n }\n\n return (\n <QpqContextProvider contextIdentifier={eventDocAiContext} value={{ serviceName: logServiceName, type: 'log', docId: logCorrelation }}>\n <LogChatConversation logCorrelation={logCorrelation} />\n </QpqContextProvider>\n );\n};\n"]}
1
+ {"version":3,"file":"LogChat.js","sourceRoot":"","sources":["../../../../src/LogViewer/LogChat/LogChat.tsx"],"names":[],"mappings":"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","sourcesContent":["import { eventDocAiContext } from 'quidproquo-features';\nimport { useEffectCallback } from 'quidproquo-web-react';\nimport { QpqContextProvider, useQpqWebsocketQueueRuntime } from 'quidproquo-web-react';\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Android as AndroidIcon, Person as PersonIcon } from '@mui/icons-material';\nimport { Avatar, Box, Button, CircularProgress, Paper, TextField, Typography } from '@mui/material';\n\nimport { useAdminApp } from '../../adminApp';\nimport { eventDocAiLogChatRuntime } from './eventDocAiLogChatRuntime';\nimport { EventDocAiSegments } from './EventDocAiSegments';\n\ninterface LogChatProps {\n logServiceName: string;\n logCorrelation: string;\n}\n\nconst LogChatConversation: React.FC<{ logCorrelation: string }> = ({ logCorrelation }) => {\n const [inputMessage, setInputMessage] = useState('');\n const chatContainerRef = useRef<HTMLDivElement>(null);\n\n const [api, state] = useQpqWebsocketQueueRuntime(eventDocAiLogChatRuntime, logCorrelation);\n const [adminApi] = useAdminApp();\n\n const streamSegments = state.streamSegments;\n const isThinking = state.isSending && streamSegments.length === 0;\n\n const handleSendMessage = useEffectCallback(() => {\n if (inputMessage.trim() !== '') {\n // Audit trail (session event) and actual chat transport are separate concerns.\n adminApi.sendChatMessage(logCorrelation, inputMessage);\n api.eventDocAiSendMessage(inputMessage);\n setInputMessage('');\n }\n });\n\n const handleKeyPress = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n handleSendMessage();\n }\n };\n\n useEffect(() => {\n if (chatContainerRef.current) {\n chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;\n }\n }, [state.chatMessages, streamSegments]);\n\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%' }}>\n <Box ref={chatContainerRef} sx={{ flexGrow: 1, overflowY: 'auto', p: 2 }}>\n {state.isLoadingHistory && (\n <Box sx={{ display: 'flex', justifyContent: 'center', p: 2 }}>\n <CircularProgress size={20} />\n </Box>\n )}\n {state.chatMessages.map((message, index) => (\n <Box\n key={index}\n sx={{\n display: 'flex',\n alignItems: 'flex-start',\n mb: 2,\n justifyContent: message.role === 'assistant' ? 'flex-start' : 'flex-end',\n }}\n >\n <Paper\n sx={{\n p: 2,\n borderRadius: message.role === 'assistant' ? '20px 20px 20px 0' : '20px 20px 0 20px',\n backgroundColor: message.role === 'assistant' ? 'grey.300' : 'primary.main',\n color: message.role === 'assistant' ? 'black' : 'white',\n maxWidth: '70%',\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>\n <Avatar sx={{ mr: 1, bgcolor: message.role === 'assistant' ? 'grey.500' : 'primary.dark' }}>\n {message.role === 'assistant' ? <AndroidIcon /> : <PersonIcon />}\n </Avatar>\n <Typography variant=\"subtitle2\">{message.role === 'assistant' ? 'AI Assistant' : 'You'}</Typography>\n </Box>\n <EventDocAiSegments segments={message.segments} />\n </Paper>\n </Box>\n ))}\n {streamSegments.length > 0 && (\n <Box sx={{ display: 'flex', alignItems: 'flex-start', mb: 2, justifyContent: 'flex-start' }}>\n <Paper sx={{ p: 2, borderRadius: '20px 20px 20px 0', backgroundColor: 'grey.300', color: 'black', maxWidth: '70%' }}>\n <Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>\n <Avatar sx={{ mr: 1, bgcolor: 'grey.500' }}>\n <AndroidIcon />\n </Avatar>\n <Typography variant=\"subtitle2\">AI Assistant</Typography>\n </Box>\n <EventDocAiSegments segments={streamSegments} />\n </Paper>\n </Box>\n )}\n {isThinking && (\n <Box sx={{ display: 'flex', alignItems: 'flex-start', mb: 2, justifyContent: 'flex-start' }}>\n <Paper sx={{ p: 2, borderRadius: '20px 20px 20px 0', backgroundColor: 'grey.300', color: 'black', maxWidth: '70%' }}>\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <CircularProgress size={20} sx={{ mr: 1 }} />\n <Typography variant=\"body1\">Thinking...</Typography>\n </Box>\n </Paper>\n </Box>\n )}\n {state.error && (\n <Typography color=\"error\" sx={{ mt: 1 }} variant=\"body2\">\n {state.error}\n </Typography>\n )}\n </Box>\n <Box sx={{ p: 2, borderTop: '1px solid #ccc' }}>\n <Box sx={{ display: 'flex' }}>\n <TextField\n fullWidth\n onChange={(e) => setInputMessage(e.target.value)}\n onKeyDown={handleKeyPress}\n placeholder=\"Ask about this log...\"\n sx={{ mr: 2 }}\n value={inputMessage}\n variant=\"outlined\"\n />\n <Button onClick={handleSendMessage} variant=\"contained\">\n Send\n </Button>\n </Box>\n </Box>\n </Box>\n );\n};\n\n// The generic EventDocAi chat, scoped to this one log (docId = correlation id).\n// See eventdoc-chat-plan.md — replaces the old one-off Claude chat.\nexport const LogChat: React.FC<LogChatProps> = ({ logServiceName, logCorrelation }) => {\n if (!logServiceName) {\n return (\n <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>\n <CircularProgress size={20} />\n </Box>\n );\n }\n\n return (\n <QpqContextProvider contextIdentifier={eventDocAiContext} value={{ serviceName: logServiceName, type: 'log', docId: logCorrelation }}>\n <LogChatConversation logCorrelation={logCorrelation} />\n </QpqContextProvider>\n );\n};\n"]}
@@ -4,7 +4,7 @@ import { Box, Chip, Typography } from '@mui/material';
4
4
  // Renders one message's segments — text (markdown), reasoning (dimmed), tool
5
5
  // calls (a chip per tool, showing input and, once it arrives, output), and
6
6
  // file attachments. Used for both finalized messages and the live stream
7
- // preview (mergeStreamParts produces the same segment shape for both).
7
+ // preview (the live stream is folded into the same segment shape).
8
8
  export const EventDocAiSegments = ({ segments }) => (_jsx(_Fragment, { children: segments.map((segment, index) => {
9
9
  if (segment.type === 'text') {
10
10
  return _jsx(Markdown, { children: segment.text }, index);
@@ -1 +1 @@
1
- {"version":3,"file":"EventDocAiSegments.js","sourceRoot":"","sources":["../../../../src/LogViewer/LogChat/EventDocAiSegments.tsx"],"names":[],"mappings":";AAGA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAMtD,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AACzE,uEAAuE;AACvE,MAAM,CAAC,MAAM,kBAAkB,GAAsC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CACrF,4BACG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;QAC/B,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,KAAC,QAAQ,cAAc,OAAO,CAAC,IAAI,IAApB,KAAK,CAA2B,CAAC;QACzD,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACjC,OAAO,CACL,KAAC,UAAU,IAAa,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,OAAO,EAAC,OAAO,YACtF,OAAO,CAAC,IAAI,IADE,KAAK,CAET,CACd,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,KAAC,IAAI,IAAa,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAC,OAAO,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAArE,KAAK,CAAoE,CAAC;QAC9F,CAAC;QAED,OAAO,CACL,KAAC,GAAG,IAAa,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,YAC/E,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,CACtC,MAAC,GAAG,IAEF,EAAE,EAAE;oBACF,CAAC,EAAE,CAAC;oBACJ,YAAY,EAAE,CAAC;oBACf,eAAe,EAAE,qBAAqB;oBACtC,UAAU,EAAE,WAAW;oBACvB,QAAQ,EAAE,SAAS;iBACpB,aAED,KAAC,UAAU,IAAC,SAAS,EAAC,KAAK,EAAC,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,OAAO,EAAC,SAAS,YACtE,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAC7D,EACb,KAAC,GAAG,IAAC,SAAS,EAAC,KAAK,EAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAC9E,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GACvB,EACL,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,CAC5B,KAAC,GAAG,IAAC,SAAS,EAAC,KAAK,EAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,YACrG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,GACxB,CACP,KAnBI,SAAS,CAoBV,CACP,CAAC,IAxBM,KAAK,CAyBT,CACP,CAAC;IACJ,CAAC,CAAC,GACD,CACJ,CAAC","sourcesContent":["import { EventDocAiMessageSegment } from 'quidproquo-features';\n\nimport React from 'react';\nimport Markdown from 'react-markdown';\nimport { Box, Chip, Typography } from '@mui/material';\n\ninterface EventDocAiSegmentsProps {\n segments: EventDocAiMessageSegment[];\n}\n\n// Renders one message's segments — text (markdown), reasoning (dimmed), tool\n// calls (a chip per tool, showing input and, once it arrives, output), and\n// file attachments. Used for both finalized messages and the live stream\n// preview (mergeStreamParts produces the same segment shape for both).\nexport const EventDocAiSegments: React.FC<EventDocAiSegmentsProps> = ({ segments }) => (\n <>\n {segments.map((segment, index) => {\n if (segment.type === 'text') {\n return <Markdown key={index}>{segment.text}</Markdown>;\n }\n\n if (segment.type === 'reasoning') {\n return (\n <Typography key={index} sx={{ fontStyle: 'italic', opacity: 0.7, mb: 1 }} variant=\"body2\">\n {segment.text}\n </Typography>\n );\n }\n\n if (segment.type === 'file') {\n return <Chip key={index} label={segment.attachment.filename} size=\"small\" sx={{ mb: 1 }} />;\n }\n\n return (\n <Box key={index} sx={{ display: 'flex', flexDirection: 'column', gap: 0.5, mb: 1 }}>\n {segment.tools.map((tool, toolIndex) => (\n <Box\n key={toolIndex}\n sx={{\n p: 1,\n borderRadius: 1,\n backgroundColor: 'rgba(0, 0, 0, 0.06)',\n fontFamily: 'monospace',\n fontSize: '0.75rem',\n }}\n >\n <Typography component=\"div\" sx={{ fontWeight: 'bold' }} variant=\"caption\">\n {tool.output === undefined ? `Calling ${tool.toolName}…` : tool.toolName}\n </Typography>\n <Box component=\"pre\" sx={{ m: 0, whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>\n {JSON.stringify(tool.input)}\n </Box>\n {tool.output !== undefined && (\n <Box component=\"pre\" sx={{ m: 0, mt: 0.5, whiteSpace: 'pre-wrap', wordBreak: 'break-all', opacity: 0.8 }}>\n {JSON.stringify(tool.output)}\n </Box>\n )}\n </Box>\n ))}\n </Box>\n );\n })}\n </>\n);\n"]}
1
+ {"version":3,"file":"EventDocAiSegments.js","sourceRoot":"","sources":["../../../../src/LogViewer/LogChat/EventDocAiSegments.tsx"],"names":[],"mappings":";AAGA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAMtD,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AACzE,mEAAmE;AACnE,MAAM,CAAC,MAAM,kBAAkB,GAAsC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CACrF,4BACG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;QAC/B,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,KAAC,QAAQ,cAAc,OAAO,CAAC,IAAI,IAApB,KAAK,CAA2B,CAAC;QACzD,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACjC,OAAO,CACL,KAAC,UAAU,IAAa,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,OAAO,EAAC,OAAO,YACtF,OAAO,CAAC,IAAI,IADE,KAAK,CAET,CACd,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,KAAC,IAAI,IAAa,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAC,OAAO,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAArE,KAAK,CAAoE,CAAC;QAC9F,CAAC;QAED,OAAO,CACL,KAAC,GAAG,IAAa,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,YAC/E,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,CACtC,MAAC,GAAG,IAEF,EAAE,EAAE;oBACF,CAAC,EAAE,CAAC;oBACJ,YAAY,EAAE,CAAC;oBACf,eAAe,EAAE,qBAAqB;oBACtC,UAAU,EAAE,WAAW;oBACvB,QAAQ,EAAE,SAAS;iBACpB,aAED,KAAC,UAAU,IAAC,SAAS,EAAC,KAAK,EAAC,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,OAAO,EAAC,SAAS,YACtE,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAC7D,EACb,KAAC,GAAG,IAAC,SAAS,EAAC,KAAK,EAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAC9E,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GACvB,EACL,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,CAC5B,KAAC,GAAG,IAAC,SAAS,EAAC,KAAK,EAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,YACrG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,GACxB,CACP,KAnBI,SAAS,CAoBV,CACP,CAAC,IAxBM,KAAK,CAyBT,CACP,CAAC;IACJ,CAAC,CAAC,GACD,CACJ,CAAC","sourcesContent":["import { EventDocAiMessageSegment } from 'quidproquo-features';\n\nimport React from 'react';\nimport Markdown from 'react-markdown';\nimport { Box, Chip, Typography } from '@mui/material';\n\ninterface EventDocAiSegmentsProps {\n segments: EventDocAiMessageSegment[];\n}\n\n// Renders one message's segments — text (markdown), reasoning (dimmed), tool\n// calls (a chip per tool, showing input and, once it arrives, output), and\n// file attachments. Used for both finalized messages and the live stream\n// preview (the live stream is folded into the same segment shape).\nexport const EventDocAiSegments: React.FC<EventDocAiSegmentsProps> = ({ segments }) => (\n <>\n {segments.map((segment, index) => {\n if (segment.type === 'text') {\n return <Markdown key={index}>{segment.text}</Markdown>;\n }\n\n if (segment.type === 'reasoning') {\n return (\n <Typography key={index} sx={{ fontStyle: 'italic', opacity: 0.7, mb: 1 }} variant=\"body2\">\n {segment.text}\n </Typography>\n );\n }\n\n if (segment.type === 'file') {\n return <Chip key={index} label={segment.attachment.filename} size=\"small\" sx={{ mb: 1 }} />;\n }\n\n return (\n <Box key={index} sx={{ display: 'flex', flexDirection: 'column', gap: 0.5, mb: 1 }}>\n {segment.tools.map((tool, toolIndex) => (\n <Box\n key={toolIndex}\n sx={{\n p: 1,\n borderRadius: 1,\n backgroundColor: 'rgba(0, 0, 0, 0.06)',\n fontFamily: 'monospace',\n fontSize: '0.75rem',\n }}\n >\n <Typography component=\"div\" sx={{ fontWeight: 'bold' }} variant=\"caption\">\n {tool.output === undefined ? `Calling ${tool.toolName}…` : tool.toolName}\n </Typography>\n <Box component=\"pre\" sx={{ m: 0, whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>\n {JSON.stringify(tool.input)}\n </Box>\n {tool.output !== undefined && (\n <Box component=\"pre\" sx={{ m: 0, mt: 0.5, whiteSpace: 'pre-wrap', wordBreak: 'break-all', opacity: 0.8 }}>\n {JSON.stringify(tool.output)}\n </Box>\n )}\n </Box>\n ))}\n </Box>\n );\n })}\n </>\n);\n"]}
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { eventDocAiContext, mergeStreamParts } from 'quidproquo-features';
2
+ import { eventDocAiContext } from 'quidproquo-features';
3
3
  import { useEffectCallback } from 'quidproquo-web-react';
4
4
  import { QpqContextProvider, useQpqWebsocketQueueRuntime } from 'quidproquo-web-react';
5
5
  import { useEffect, useRef, useState } from 'react';
@@ -13,7 +13,7 @@ const LogChatConversation = ({ logCorrelation }) => {
13
13
  const chatContainerRef = useRef(null);
14
14
  const [api, state] = useQpqWebsocketQueueRuntime(eventDocAiLogChatRuntime, logCorrelation);
15
15
  const [adminApi] = useAdminApp();
16
- const streamSegments = mergeStreamParts(state.streamParts);
16
+ const streamSegments = state.streamSegments;
17
17
  const isThinking = state.isSending && streamSegments.length === 0;
18
18
  const handleSendMessage = useEffectCallback(() => {
19
19
  if (inputMessage.trim() !== '') {
@@ -1 +1 @@
1
- {"version":3,"file":"LogChat.js","sourceRoot":"","sources":["../../../../src/LogViewer/LogChat/LogChat.tsx"],"names":[],"mappings":"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","sourcesContent":["import { eventDocAiContext, mergeStreamParts } from 'quidproquo-features';\nimport { useEffectCallback } from 'quidproquo-web-react';\nimport { QpqContextProvider, useQpqWebsocketQueueRuntime } from 'quidproquo-web-react';\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Android as AndroidIcon, Person as PersonIcon } from '@mui/icons-material';\nimport { Avatar, Box, Button, CircularProgress, Paper, TextField, Typography } from '@mui/material';\n\nimport { useAdminApp } from '../../adminApp';\nimport { eventDocAiLogChatRuntime } from './eventDocAiLogChatRuntime';\nimport { EventDocAiSegments } from './EventDocAiSegments';\n\ninterface LogChatProps {\n logServiceName: string;\n logCorrelation: string;\n}\n\nconst LogChatConversation: React.FC<{ logCorrelation: string }> = ({ logCorrelation }) => {\n const [inputMessage, setInputMessage] = useState('');\n const chatContainerRef = useRef<HTMLDivElement>(null);\n\n const [api, state] = useQpqWebsocketQueueRuntime(eventDocAiLogChatRuntime, logCorrelation);\n const [adminApi] = useAdminApp();\n\n const streamSegments = mergeStreamParts(state.streamParts);\n const isThinking = state.isSending && streamSegments.length === 0;\n\n const handleSendMessage = useEffectCallback(() => {\n if (inputMessage.trim() !== '') {\n // Audit trail (session event) and actual chat transport are separate concerns.\n adminApi.sendChatMessage(logCorrelation, inputMessage);\n api.eventDocAiSendMessage(inputMessage);\n setInputMessage('');\n }\n });\n\n const handleKeyPress = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n handleSendMessage();\n }\n };\n\n useEffect(() => {\n if (chatContainerRef.current) {\n chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;\n }\n }, [state.chatMessages, streamSegments]);\n\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%' }}>\n <Box ref={chatContainerRef} sx={{ flexGrow: 1, overflowY: 'auto', p: 2 }}>\n {state.isLoadingHistory && (\n <Box sx={{ display: 'flex', justifyContent: 'center', p: 2 }}>\n <CircularProgress size={20} />\n </Box>\n )}\n {state.chatMessages.map((message, index) => (\n <Box\n key={index}\n sx={{\n display: 'flex',\n alignItems: 'flex-start',\n mb: 2,\n justifyContent: message.role === 'assistant' ? 'flex-start' : 'flex-end',\n }}\n >\n <Paper\n sx={{\n p: 2,\n borderRadius: message.role === 'assistant' ? '20px 20px 20px 0' : '20px 20px 0 20px',\n backgroundColor: message.role === 'assistant' ? 'grey.300' : 'primary.main',\n color: message.role === 'assistant' ? 'black' : 'white',\n maxWidth: '70%',\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>\n <Avatar sx={{ mr: 1, bgcolor: message.role === 'assistant' ? 'grey.500' : 'primary.dark' }}>\n {message.role === 'assistant' ? <AndroidIcon /> : <PersonIcon />}\n </Avatar>\n <Typography variant=\"subtitle2\">{message.role === 'assistant' ? 'AI Assistant' : 'You'}</Typography>\n </Box>\n <EventDocAiSegments segments={message.segments} />\n </Paper>\n </Box>\n ))}\n {streamSegments.length > 0 && (\n <Box sx={{ display: 'flex', alignItems: 'flex-start', mb: 2, justifyContent: 'flex-start' }}>\n <Paper sx={{ p: 2, borderRadius: '20px 20px 20px 0', backgroundColor: 'grey.300', color: 'black', maxWidth: '70%' }}>\n <Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>\n <Avatar sx={{ mr: 1, bgcolor: 'grey.500' }}>\n <AndroidIcon />\n </Avatar>\n <Typography variant=\"subtitle2\">AI Assistant</Typography>\n </Box>\n <EventDocAiSegments segments={streamSegments} />\n </Paper>\n </Box>\n )}\n {isThinking && (\n <Box sx={{ display: 'flex', alignItems: 'flex-start', mb: 2, justifyContent: 'flex-start' }}>\n <Paper sx={{ p: 2, borderRadius: '20px 20px 20px 0', backgroundColor: 'grey.300', color: 'black', maxWidth: '70%' }}>\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <CircularProgress size={20} sx={{ mr: 1 }} />\n <Typography variant=\"body1\">Thinking...</Typography>\n </Box>\n </Paper>\n </Box>\n )}\n {state.error && (\n <Typography color=\"error\" sx={{ mt: 1 }} variant=\"body2\">\n {state.error}\n </Typography>\n )}\n </Box>\n <Box sx={{ p: 2, borderTop: '1px solid #ccc' }}>\n <Box sx={{ display: 'flex' }}>\n <TextField\n fullWidth\n onChange={(e) => setInputMessage(e.target.value)}\n onKeyDown={handleKeyPress}\n placeholder=\"Ask about this log...\"\n sx={{ mr: 2 }}\n value={inputMessage}\n variant=\"outlined\"\n />\n <Button onClick={handleSendMessage} variant=\"contained\">\n Send\n </Button>\n </Box>\n </Box>\n </Box>\n );\n};\n\n// The generic EventDocAi chat, scoped to this one log (docId = correlation id).\n// See eventdoc-chat-plan.md — replaces the old one-off Claude chat.\nexport const LogChat: React.FC<LogChatProps> = ({ logServiceName, logCorrelation }) => {\n if (!logServiceName) {\n return (\n <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>\n <CircularProgress size={20} />\n </Box>\n );\n }\n\n return (\n <QpqContextProvider contextIdentifier={eventDocAiContext} value={{ serviceName: logServiceName, type: 'log', docId: logCorrelation }}>\n <LogChatConversation logCorrelation={logCorrelation} />\n </QpqContextProvider>\n );\n};\n"]}
1
+ {"version":3,"file":"LogChat.js","sourceRoot":"","sources":["../../../../src/LogViewer/LogChat/LogChat.tsx"],"names":[],"mappings":"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","sourcesContent":["import { eventDocAiContext } from 'quidproquo-features';\nimport { useEffectCallback } from 'quidproquo-web-react';\nimport { QpqContextProvider, useQpqWebsocketQueueRuntime } from 'quidproquo-web-react';\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Android as AndroidIcon, Person as PersonIcon } from '@mui/icons-material';\nimport { Avatar, Box, Button, CircularProgress, Paper, TextField, Typography } from '@mui/material';\n\nimport { useAdminApp } from '../../adminApp';\nimport { eventDocAiLogChatRuntime } from './eventDocAiLogChatRuntime';\nimport { EventDocAiSegments } from './EventDocAiSegments';\n\ninterface LogChatProps {\n logServiceName: string;\n logCorrelation: string;\n}\n\nconst LogChatConversation: React.FC<{ logCorrelation: string }> = ({ logCorrelation }) => {\n const [inputMessage, setInputMessage] = useState('');\n const chatContainerRef = useRef<HTMLDivElement>(null);\n\n const [api, state] = useQpqWebsocketQueueRuntime(eventDocAiLogChatRuntime, logCorrelation);\n const [adminApi] = useAdminApp();\n\n const streamSegments = state.streamSegments;\n const isThinking = state.isSending && streamSegments.length === 0;\n\n const handleSendMessage = useEffectCallback(() => {\n if (inputMessage.trim() !== '') {\n // Audit trail (session event) and actual chat transport are separate concerns.\n adminApi.sendChatMessage(logCorrelation, inputMessage);\n api.eventDocAiSendMessage(inputMessage);\n setInputMessage('');\n }\n });\n\n const handleKeyPress = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n handleSendMessage();\n }\n };\n\n useEffect(() => {\n if (chatContainerRef.current) {\n chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;\n }\n }, [state.chatMessages, streamSegments]);\n\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%' }}>\n <Box ref={chatContainerRef} sx={{ flexGrow: 1, overflowY: 'auto', p: 2 }}>\n {state.isLoadingHistory && (\n <Box sx={{ display: 'flex', justifyContent: 'center', p: 2 }}>\n <CircularProgress size={20} />\n </Box>\n )}\n {state.chatMessages.map((message, index) => (\n <Box\n key={index}\n sx={{\n display: 'flex',\n alignItems: 'flex-start',\n mb: 2,\n justifyContent: message.role === 'assistant' ? 'flex-start' : 'flex-end',\n }}\n >\n <Paper\n sx={{\n p: 2,\n borderRadius: message.role === 'assistant' ? '20px 20px 20px 0' : '20px 20px 0 20px',\n backgroundColor: message.role === 'assistant' ? 'grey.300' : 'primary.main',\n color: message.role === 'assistant' ? 'black' : 'white',\n maxWidth: '70%',\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>\n <Avatar sx={{ mr: 1, bgcolor: message.role === 'assistant' ? 'grey.500' : 'primary.dark' }}>\n {message.role === 'assistant' ? <AndroidIcon /> : <PersonIcon />}\n </Avatar>\n <Typography variant=\"subtitle2\">{message.role === 'assistant' ? 'AI Assistant' : 'You'}</Typography>\n </Box>\n <EventDocAiSegments segments={message.segments} />\n </Paper>\n </Box>\n ))}\n {streamSegments.length > 0 && (\n <Box sx={{ display: 'flex', alignItems: 'flex-start', mb: 2, justifyContent: 'flex-start' }}>\n <Paper sx={{ p: 2, borderRadius: '20px 20px 20px 0', backgroundColor: 'grey.300', color: 'black', maxWidth: '70%' }}>\n <Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>\n <Avatar sx={{ mr: 1, bgcolor: 'grey.500' }}>\n <AndroidIcon />\n </Avatar>\n <Typography variant=\"subtitle2\">AI Assistant</Typography>\n </Box>\n <EventDocAiSegments segments={streamSegments} />\n </Paper>\n </Box>\n )}\n {isThinking && (\n <Box sx={{ display: 'flex', alignItems: 'flex-start', mb: 2, justifyContent: 'flex-start' }}>\n <Paper sx={{ p: 2, borderRadius: '20px 20px 20px 0', backgroundColor: 'grey.300', color: 'black', maxWidth: '70%' }}>\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <CircularProgress size={20} sx={{ mr: 1 }} />\n <Typography variant=\"body1\">Thinking...</Typography>\n </Box>\n </Paper>\n </Box>\n )}\n {state.error && (\n <Typography color=\"error\" sx={{ mt: 1 }} variant=\"body2\">\n {state.error}\n </Typography>\n )}\n </Box>\n <Box sx={{ p: 2, borderTop: '1px solid #ccc' }}>\n <Box sx={{ display: 'flex' }}>\n <TextField\n fullWidth\n onChange={(e) => setInputMessage(e.target.value)}\n onKeyDown={handleKeyPress}\n placeholder=\"Ask about this log...\"\n sx={{ mr: 2 }}\n value={inputMessage}\n variant=\"outlined\"\n />\n <Button onClick={handleSendMessage} variant=\"contained\">\n Send\n </Button>\n </Box>\n </Box>\n </Box>\n );\n};\n\n// The generic EventDocAi chat, scoped to this one log (docId = correlation id).\n// See eventdoc-chat-plan.md — replaces the old one-off Claude chat.\nexport const LogChat: React.FC<LogChatProps> = ({ logServiceName, logCorrelation }) => {\n if (!logServiceName) {\n return (\n <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>\n <CircularProgress size={20} />\n </Box>\n );\n }\n\n return (\n <QpqContextProvider contextIdentifier={eventDocAiContext} value={{ serviceName: logServiceName, type: 'log', docId: logCorrelation }}>\n <LogChatConversation logCorrelation={logCorrelation} />\n </QpqContextProvider>\n );\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo-web-admin",
3
- "version": "0.1.24",
3
+ "version": "0.1.25",
4
4
  "description": "",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -47,12 +47,12 @@
47
47
  "date-fns": "^2.30.0",
48
48
  "dayjs": "^1.11.7",
49
49
  "javascript-time-ago": "^2.5.9",
50
- "quidproquo-core": "0.1.24",
51
- "quidproquo-features": "0.1.24",
52
- "quidproquo-tsconfig": "0.1.24",
53
- "quidproquo-web": "0.1.24",
54
- "quidproquo-web-react": "0.1.24",
55
- "quidproquo-webserver": "0.1.24",
50
+ "quidproquo-core": "0.1.25",
51
+ "quidproquo-features": "0.1.25",
52
+ "quidproquo-tsconfig": "0.1.25",
53
+ "quidproquo-web": "0.1.25",
54
+ "quidproquo-web-react": "0.1.25",
55
+ "quidproquo-webserver": "0.1.25",
56
56
  "react": ">=18.3.1",
57
57
  "react-d3-tree": "^3.6.6",
58
58
  "react-dom": "18.3.1",