data fixes; indicator=>workspace sync

This commit is contained in:
2026-03-31 20:29:12 -04:00
parent 998f69fa1a
commit cd28e18e52
45 changed files with 1324 additions and 1239 deletions

View File

@@ -36,10 +36,35 @@ const rooms = computed(() => [{
// Streaming state
let currentStreamingMessageId: string | null = null
let toolCallMessageId: string | null = null
let lastSentMessageId: string | null = null
let streamingBuffer = ''
const isAgentProcessing = ref(false)
const toolCallStatus = ref<string | null>(null)
const addToolCallBubble = (label: string) => {
removeToolCallBubble()
toolCallMessageId = `tool-call-${Date.now()}`
const timestamp = new Date().toTimeString().split(' ')[0].slice(0, 5)
messages.value = [...messages.value, {
_id: toolCallMessageId,
content: `${label}`,
senderId: AGENT_ID,
timestamp,
date: new Date().toLocaleDateString(),
saved: false,
distributed: false,
seen: false,
files: [],
toolCall: true
}]
}
const removeToolCallBubble = () => {
if (toolCallMessageId) {
messages.value = messages.value.filter(m => m._id !== toolCallMessageId)
toolCallMessageId = null
}
}
// Generate message ID
const generateMessageId = () => `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
@@ -52,7 +77,7 @@ const handleMessage = (data: WebSocketMessage) => {
console.log('[ChatPanel] Received message:', data)
if (data.type === 'agent_tool_call') {
toolCallStatus.value = data.label ?? data.toolName ?? null
addToolCallBubble(data.label ?? data.toolName ?? 'Tool call...')
return
}
@@ -99,12 +124,13 @@ const handleMessage = (data: WebSocketMessage) => {
if (!currentStreamingMessageId) {
console.log('[ChatPanel] Starting new streaming message')
// Remove any ephemeral tool-call bubble before starting the real response
removeToolCallBubble()
// Set up streaming state and mark user message as seen
isAgentProcessing.value = true
currentStreamingMessageId = generateMessageId()
streamingBuffer = data.content
streamingImages.value = []
toolCallStatus.value = null
// Mark the last sent user message as seen (double-checkmark)
if (lastSentMessageId) {
@@ -205,7 +231,7 @@ const handleMessage = (data: WebSocketMessage) => {
streamingBuffer = ''
streamingImages.value = []
isAgentProcessing.value = false
toolCallStatus.value = null
removeToolCallBubble()
}
}
}
@@ -221,7 +247,7 @@ const stopAgent = () => {
}
wsManager.send(wsMessage)
isAgentProcessing.value = false
toolCallStatus.value = null
removeToolCallBubble()
lastSentMessageId = null
}
@@ -336,34 +362,137 @@ const chatTheme = 'dark'
// Styles to match TradingView dark theme
const chatStyles = computed(() => JSON.stringify({
general: {
color: '#d1d4dc',
colorSpinner: '#2962ff',
borderStyle: '1px solid #2a2e39'
color: '#D3D4DC',
colorButtonClear: '#D3D4DC',
colorButton: '#131722',
backgroundColorButton: '#26A69A',
backgroundInput: '#131722',
colorPlaceholder: '#787B86',
colorCaret: '#D3D4DC',
colorSpinner: '#26A69A',
borderStyle: '1px solid #2A2E39',
backgroundScrollIcon: '#2A2E39'
},
container: {
background: '#131722'
border: 'none',
borderRadius: '0',
boxShadow: 'none'
},
header: {
background: '#1e222d',
colorRoomName: '#d1d4dc',
colorRoomInfo: '#787b86'
background: '#2A2E39',
colorRoomName: '#D3D4DC',
colorRoomInfo: '#787B86',
position: 'absolute',
width: '100%'
},
footer: {
background: '#1e222d',
borderStyleInput: '1px solid #2a2e39',
backgroundInput: '#1e222d',
colorInput: '#d1d4dc',
colorPlaceholder: '#787b86',
colorIcons: '#787b86'
background: '#2A2E39',
borderStyleInput: '1px solid #2A2E39',
borderInputSelected: '#26A69A',
backgroundReply: '#2A2E39',
backgroundTagActive: '#2A2E39',
backgroundTag: '#1E222D'
},
content: {
background: '#131722'
},
sidemenu: {
background: '#131722',
backgroundHover: '#1E222D',
backgroundActive: '#2A2E39',
colorActive: '#D3D4DC',
borderColorSearch: '#2A2E39'
},
dropdown: {
background: '#2A2E39',
backgroundHover: '#363B4A'
},
message: {
background: '#1e222d',
backgroundMe: '#2962ff',
color: '#d1d4dc',
colorMe: '#ffffff'
background: '#1E222D',
backgroundMe: '#26A69A',
color: '#D3D4DC',
colorStarted: '#787B86',
backgroundDeleted: '#131722',
backgroundSelected: '#2A2E39',
colorDeleted: '#787B86',
colorUsername: '#787B86',
colorTimestamp: '#787B86',
backgroundDate: 'rgba(0, 0, 0, 0.3)',
colorDate: '#787B86',
backgroundSystem: 'rgba(0, 0, 0, 0.3)',
colorSystem: '#787B86',
backgroundMedia: 'rgba(0, 0, 0, 0.18)',
backgroundReply: 'rgba(0, 0, 0, 0.18)',
colorReplyUsername: '#D3D4DC',
colorReply: '#B2B5BE',
colorTag: '#26A69A',
backgroundImage: '#2A2E39',
colorNewMessages: '#26A69A',
backgroundScrollCounter: '#26A69A',
colorScrollCounter: '#131722',
backgroundReaction: 'none',
borderStyleReaction: 'none',
backgroundReactionHover: '#2A2E39',
borderStyleReactionHover: 'none',
colorReactionCounter: '#D3D4DC',
backgroundReactionMe: '#26A69A',
borderStyleReactionMe: 'none',
backgroundReactionHoverMe: '#26A69A',
borderStyleReactionHoverMe: 'none',
colorReactionCounterMe: '#131722',
backgroundAudioRecord: '#EF5350',
backgroundAudioLine: 'rgba(255, 255, 255, 0.15)',
backgroundAudioProgress: '#26A69A',
backgroundAudioProgressSelector: '#26A69A',
colorFileExtension: '#787B86'
},
markdown: {
background: 'rgba(42, 46, 57, 0.8)',
border: 'rgba(55, 60, 74, 0.9)',
color: '#26A69A',
colorMulti: '#D3D4DC'
},
room: {
colorUsername: '#D3D4DC',
colorMessage: '#787B86',
colorTimestamp: '#787B86',
colorStateOnline: '#26A69A',
colorStateOffline: '#787B86',
backgroundCounterBadge: '#26A69A',
colorCounterBadge: '#131722'
},
emoji: {
background: '#2A2E39'
},
icons: {
search: '#787B86',
add: '#D3D4DC',
toggle: '#D3D4DC',
menu: '#D3D4DC',
close: '#787B86',
closeImage: '#D3D4DC',
file: '#26A69A',
paperclip: '#787B86',
closeOutline: '#D3D4DC',
closePreview: '#D3D4DC',
send: '#26A69A',
sendDisabled: '#787B86',
emoji: '#787B86',
emojiReaction: '#787B86',
document: '#26A69A',
pencil: '#787B86',
checkmark: '#787B86',
checkmarkSeen: '#26A69A',
eye: '#D3D4DC',
dropdownMessage: '#D3D4DC',
dropdownMessageBackground: 'rgba(0, 0, 0, 0.3)',
dropdownRoom: '#D3D4DC',
dropdownScroll: '#2A2E39',
microphone: '#787B86',
audioPlay: '#26A69A',
audioPause: '#26A69A',
audioCancel: '#EF5350',
audioConfirm: '#26A69A'
}
}))
@@ -429,7 +558,6 @@ onUnmounted(() => {
<!-- Stop button overlay -->
<div v-if="isAgentProcessing" class="stop-button-container">
<div v-if="toolCallStatus" class="tool-call-status">{{ toolCallStatus }}</div>
<Button
icon="pi pi-stop-circle"
label="Stop"
@@ -459,12 +587,12 @@ onUnmounted(() => {
justify-content: center;
gap: 1rem;
background: #131722;
color: #787b86;
color: #787B86;
}
.workspace-loading-spinner {
font-size: 2rem;
color: #787b86;
color: #787B86;
}
.workspace-loading-message {
@@ -485,6 +613,7 @@ onUnmounted(() => {
max-width: 80% !important;
}
.chat-header-custom {
display: flex;
justify-content: space-between;
@@ -504,21 +633,10 @@ onUnmounted(() => {
.stop-button-container {
position: absolute;
bottom: 80px;
right: 20px;
left: 20px;
z-index: 1000;
}
.tool-call-status {
background: rgba(30, 34, 45, 0.92);
color: #787b86;
font-size: 0.75rem;
padding: 4px 10px;
border-radius: 4px;
margin-bottom: 6px;
text-align: center;
border: 1px solid #2a2e39;
}
.stop-button {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
animation: pulse 2s infinite;