@pheem49/mint 1.6.4 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.toml +1 -1
- package/bin/mint +0 -0
- package/crates/mint-cli/src/agent.rs +42 -14
- package/crates/mint-cli/src/main.rs +389 -2
- package/crates/mint-cli/src/setup.rs +173 -32
- package/crates/mint-core/src/api_server.rs +39 -0
- package/crates/mint-core/src/config.rs +2 -2
- package/crates/mint-core/src/memory.rs +27 -1
- package/crates/mint-core/src/orchestration.rs +1 -1
- package/crates/mint-core/src/plugins.rs +32 -0
- package/crates/mint-core/tests/memory_persistence.rs +28 -0
- package/package.json +1 -1
- package/src/renderer/src/agentProgress.ts +39 -0
- package/src/renderer/src/components/ChatPanel.tsx +308 -34
- package/src/renderer/src/components/DashboardSidebar.tsx +3 -3
- package/src/renderer/src/components/MintDashboard.tsx +71 -27
- package/src/renderer/src/components/ModelPanel.tsx +2 -2
- package/src/renderer/src/components/PicturesLibrary.tsx +5 -1
- package/src/renderer/src/components/SpotlightWindow.tsx +8 -8
- package/src/renderer/src/components/WorkspacePanel.tsx +1 -1
- package/src/renderer/src/css/styles.css +195 -17
- package/src/renderer/src/index.css +46 -0
- package/src/renderer/src/tauri.ts +25 -0
- package/src/renderer/src-web/App.tsx +16 -1
- package/src/renderer/src-web/agentProgress.ts +39 -0
- package/src/renderer/src-web/components/ChatPanel.tsx +309 -35
- package/src/renderer/src-web/components/DashboardSidebar.tsx +1 -1
- package/src/renderer/src-web/components/MintDashboard.tsx +53 -16
- package/src/renderer/src-web/components/PicturesLibrary.tsx +5 -1
- package/src/renderer/src-web/css/styles.css +242 -18
- package/src/renderer/src-web/index.css +46 -0
- package/src/renderer/src-web/tauri.ts +25 -0
- package/src-tauri/src/lib.rs +17 -0
- package/src-tauri/tauri.conf.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ChangeEvent, type FormEvent, useEffect, useRef, useState } from 'react'
|
|
2
|
+
import { mergeActivitySnapshots, trimAgentProgress } from '../agentProgress'
|
|
2
3
|
import {
|
|
3
4
|
clearChatHistory,
|
|
4
5
|
deleteChatSession,
|
|
@@ -8,6 +9,7 @@ import {
|
|
|
8
9
|
listChatSessions,
|
|
9
10
|
listSavedPictures,
|
|
10
11
|
selectWorkspaceDirectory,
|
|
12
|
+
saveInteractionAgentActivity,
|
|
11
13
|
streamChatMessage,
|
|
12
14
|
submitToolApproval,
|
|
13
15
|
listen,
|
|
@@ -28,19 +30,19 @@ import PicturesLibrary from './PicturesLibrary'
|
|
|
28
30
|
import WorkspacePanel from './WorkspacePanel'
|
|
29
31
|
|
|
30
32
|
const EXPRESSIONS = [
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
33
|
+
"Default",
|
|
34
|
+
"Dumb Cat",
|
|
35
|
+
"Dumb Cat Eye Roll",
|
|
36
|
+
"Take Photo",
|
|
37
|
+
"Poke",
|
|
38
|
+
"Cat Filter",
|
|
37
39
|
]
|
|
38
40
|
|
|
39
41
|
const ACCESSORIES = [
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
42
|
+
"None",
|
|
43
|
+
"Apron",
|
|
44
|
+
"Glasses",
|
|
45
|
+
"Hold Pen",
|
|
44
46
|
]
|
|
45
47
|
|
|
46
48
|
const DEFAULT_CONFIG = {
|
|
@@ -78,7 +80,7 @@ function activeConversationId() {
|
|
|
78
80
|
const MOCK_WELCOME_INTERACTION = {
|
|
79
81
|
id: -1,
|
|
80
82
|
userText: '',
|
|
81
|
-
aiText:
|
|
83
|
+
aiText: `Hi there! I'm Mint, your AI assistant! 🎯✨ I'm here and ready to help you with whatever you need. I've been organizing some background data to make things smoother for you. 💖\n\nBut the moment you start chatting with me, I'll put everything aside and focus on you! Is there something I can help you with today, or would you like to chat about something special? Let's do this! 🚀💪`,
|
|
82
84
|
provider: 'gemini',
|
|
83
85
|
model: 'gemini-3-flash-preview',
|
|
84
86
|
createdAt: new Date().toISOString(),
|
|
@@ -233,8 +235,11 @@ export default function MintDashboard() {
|
|
|
233
235
|
const [sendingImageCount, setSendingImageCount] = useState(0)
|
|
234
236
|
const [streamedReply, setStreamedReply] = useState('')
|
|
235
237
|
const [streamedResponse, setStreamedResponse] = useState<ChatResponse | null>(null)
|
|
238
|
+
const [streamingConversationId, setStreamingConversationId] = useState<string | null>(null)
|
|
236
239
|
const [agentProgress, setAgentProgress] = useState<AgentProgress[]>([])
|
|
237
240
|
const [agentActivitySnapshots, setAgentActivitySnapshots] = useState<Record<string, AgentProgress[]>>({})
|
|
241
|
+
const [thinkingExpanded, setThinkingExpanded] = useState<Record<string, boolean>>({})
|
|
242
|
+
const liveThinkingOpenRef = useRef(true)
|
|
238
243
|
const [imageAttachments, setImageAttachments] = useState<Array<{ dataUri: string; name: string; previewDataUri?: string }>>([])
|
|
239
244
|
const [documentAttachment, setDocumentAttachment] = useState<DocumentAttachment | null>(null)
|
|
240
245
|
const [pendingApproval, setPendingApproval] = useState<any | null>(null)
|
|
@@ -264,7 +269,9 @@ export default function MintDashboard() {
|
|
|
264
269
|
|
|
265
270
|
async function refreshHistory() {
|
|
266
271
|
const history = await getRecentInteractions(50, conversationId)
|
|
267
|
-
|
|
272
|
+
const reversed = history.reverse()
|
|
273
|
+
setInteractions(reversed)
|
|
274
|
+
setAgentActivitySnapshots((current) => mergeActivitySnapshots(current, reversed))
|
|
268
275
|
}
|
|
269
276
|
|
|
270
277
|
async function refreshChatSessions(nextActiveId = conversationId) {
|
|
@@ -286,8 +293,15 @@ export default function MintDashboard() {
|
|
|
286
293
|
)
|
|
287
294
|
}
|
|
288
295
|
|
|
296
|
+
const [picturesRefreshing, setPicturesRefreshing] = useState(false)
|
|
297
|
+
|
|
289
298
|
async function refreshPictures() {
|
|
290
|
-
|
|
299
|
+
setPicturesRefreshing(true)
|
|
300
|
+
try {
|
|
301
|
+
setPictures(await listSavedPictures())
|
|
302
|
+
} finally {
|
|
303
|
+
setPicturesRefreshing(false)
|
|
304
|
+
}
|
|
291
305
|
}
|
|
292
306
|
|
|
293
307
|
useEffect(() => {
|
|
@@ -445,12 +459,15 @@ export default function MintDashboard() {
|
|
|
445
459
|
const outgoingImage = outgoingImages.map((img) => img.dataUri).join(' ')
|
|
446
460
|
const outgoingImageCount = outgoingImages.length
|
|
447
461
|
setSending(true)
|
|
462
|
+
setStreamingConversationId(conversationId)
|
|
448
463
|
setSendingMessage(promptText)
|
|
449
464
|
setSendingImageCount(outgoingImageCount)
|
|
450
465
|
setError('')
|
|
451
466
|
setStreamedReply('')
|
|
452
467
|
setStreamedResponse(null)
|
|
453
468
|
setAgentProgress([])
|
|
469
|
+
liveThinkingOpenRef.current = true
|
|
470
|
+
setThinkingExpanded((current) => ({ ...current, live: true }))
|
|
454
471
|
const progressSnapshot: AgentProgress[] = []
|
|
455
472
|
if (options.clearComposer) {
|
|
456
473
|
setMessage('')
|
|
@@ -467,7 +484,7 @@ export default function MintDashboard() {
|
|
|
467
484
|
options.systemInstruction ?? '',
|
|
468
485
|
(progress) => {
|
|
469
486
|
progressSnapshot.push(progress)
|
|
470
|
-
setAgentProgress((current) => [...current, progress]
|
|
487
|
+
setAgentProgress((current) => trimAgentProgress([...current, progress]))
|
|
471
488
|
},
|
|
472
489
|
outgoingDocument,
|
|
473
490
|
workspacePath || null,
|
|
@@ -475,18 +492,33 @@ export default function MintDashboard() {
|
|
|
475
492
|
)
|
|
476
493
|
setStreamedResponse(response)
|
|
477
494
|
const history = (await getRecentInteractions(50, conversationId)).reverse()
|
|
495
|
+
let enrichedHistory = history
|
|
478
496
|
if (progressSnapshot.length > 0) {
|
|
479
497
|
const newestInteraction = [...history]
|
|
480
498
|
.reverse()
|
|
481
499
|
.find((interaction) => interaction.aiText === response.text || interaction.userText === promptText) ?? history[history.length - 1]
|
|
482
500
|
if (newestInteraction?.id != null) {
|
|
501
|
+
const interactionKey = String(newestInteraction.id)
|
|
502
|
+
enrichedHistory = history.map((interaction) =>
|
|
503
|
+
interaction.id === newestInteraction.id
|
|
504
|
+
? { ...interaction, agentActivity: progressSnapshot }
|
|
505
|
+
: interaction,
|
|
506
|
+
)
|
|
483
507
|
setAgentActivitySnapshots((current) => ({
|
|
484
508
|
...current,
|
|
485
|
-
[
|
|
509
|
+
[interactionKey]: progressSnapshot.slice(),
|
|
486
510
|
}))
|
|
511
|
+
if (liveThinkingOpenRef.current) {
|
|
512
|
+
setThinkingExpanded((current) => ({
|
|
513
|
+
...current,
|
|
514
|
+
[interactionKey]: true,
|
|
515
|
+
}))
|
|
516
|
+
}
|
|
517
|
+
await saveInteractionAgentActivity(newestInteraction.id, progressSnapshot)
|
|
487
518
|
}
|
|
488
519
|
}
|
|
489
|
-
setInteractions(
|
|
520
|
+
setInteractions(enrichedHistory)
|
|
521
|
+
setAgentActivitySnapshots((current) => mergeActivitySnapshots(current, enrichedHistory))
|
|
490
522
|
await refreshChatSessions()
|
|
491
523
|
await refreshPictures()
|
|
492
524
|
setStreamedReply('')
|
|
@@ -495,6 +527,7 @@ export default function MintDashboard() {
|
|
|
495
527
|
setError(errorMessage(reason))
|
|
496
528
|
} finally {
|
|
497
529
|
setSending(false)
|
|
530
|
+
setStreamingConversationId(null)
|
|
498
531
|
setSendingMessage('')
|
|
499
532
|
setSendingImageCount(0)
|
|
500
533
|
}
|
|
@@ -516,7 +549,7 @@ export default function MintDashboard() {
|
|
|
516
549
|
}
|
|
517
550
|
|
|
518
551
|
async function sendVoiceMessage(transcript: string, audioDataUri?: string | null) {
|
|
519
|
-
const promptText = transcript.trim() || '
|
|
552
|
+
const promptText = transcript.trim() || 'Voice message'
|
|
520
553
|
if (!promptText || sending) return
|
|
521
554
|
await sendPrompt(promptText, {
|
|
522
555
|
audioDataUri,
|
|
@@ -678,6 +711,11 @@ export default function MintDashboard() {
|
|
|
678
711
|
}
|
|
679
712
|
}
|
|
680
713
|
|
|
714
|
+
function handleThinkingExpandedChange(key: string, open: boolean) {
|
|
715
|
+
if (key === 'live') liveThinkingOpenRef.current = open
|
|
716
|
+
setThinkingExpanded((current) => ({ ...current, [key]: open }))
|
|
717
|
+
}
|
|
718
|
+
|
|
681
719
|
async function selectConversation(id: string) {
|
|
682
720
|
if (id === conversationId) {
|
|
683
721
|
setView('chat')
|
|
@@ -693,7 +731,9 @@ export default function MintDashboard() {
|
|
|
693
731
|
setDocumentAttachment(null)
|
|
694
732
|
setAgentProgress([])
|
|
695
733
|
const history = await getRecentInteractions(50, id)
|
|
696
|
-
|
|
734
|
+
const reversed = history.reverse()
|
|
735
|
+
setInteractions(reversed)
|
|
736
|
+
setAgentActivitySnapshots((current) => mergeActivitySnapshots(current, reversed))
|
|
697
737
|
}
|
|
698
738
|
|
|
699
739
|
async function deleteConversation(id: string) {
|
|
@@ -714,7 +754,9 @@ export default function MintDashboard() {
|
|
|
714
754
|
setConversationId(nextActive)
|
|
715
755
|
setAgentProgress([])
|
|
716
756
|
const history = await getRecentInteractions(50, nextActive)
|
|
717
|
-
|
|
757
|
+
const reversed = history.reverse()
|
|
758
|
+
setInteractions(reversed)
|
|
759
|
+
setAgentActivitySnapshots((current) => mergeActivitySnapshots(current, reversed))
|
|
718
760
|
}
|
|
719
761
|
|
|
720
762
|
await refreshChatSessions(nextActive)
|
|
@@ -888,17 +930,19 @@ export default function MintDashboard() {
|
|
|
888
930
|
/>
|
|
889
931
|
<ChatPanel
|
|
890
932
|
interactions={interactions}
|
|
891
|
-
sending={sending}
|
|
892
|
-
sendingMessage={sendingMessage}
|
|
893
|
-
sendingImageCount={sendingImageCount}
|
|
894
|
-
streamedReply={streamedReply}
|
|
895
|
-
streamedResponse={streamedResponse}
|
|
896
|
-
agentProgress={agentProgress}
|
|
933
|
+
sending={sending && streamingConversationId === conversationId}
|
|
934
|
+
sendingMessage={streamingConversationId === conversationId ? sendingMessage : ''}
|
|
935
|
+
sendingImageCount={streamingConversationId === conversationId ? sendingImageCount : 0}
|
|
936
|
+
streamedReply={streamingConversationId === conversationId ? streamedReply : ''}
|
|
937
|
+
streamedResponse={streamingConversationId === conversationId ? streamedResponse : null}
|
|
938
|
+
agentProgress={streamingConversationId === conversationId ? agentProgress : []}
|
|
897
939
|
agentActivitySnapshots={agentActivitySnapshots}
|
|
940
|
+
thinkingExpanded={thinkingExpanded}
|
|
941
|
+
onThinkingExpandedChange={handleThinkingExpandedChange}
|
|
898
942
|
message={message}
|
|
899
943
|
imageAttachments={imageAttachments}
|
|
900
944
|
documentName={documentAttachment?.filename ?? ''}
|
|
901
|
-
pendingApproval={pendingApproval}
|
|
945
|
+
pendingApproval={streamingConversationId === conversationId ? pendingApproval : null}
|
|
902
946
|
smartContext={smartContext}
|
|
903
947
|
agentMode={agentMode}
|
|
904
948
|
status={status}
|
|
@@ -927,7 +971,7 @@ export default function MintDashboard() {
|
|
|
927
971
|
onApproval={handleApproval}
|
|
928
972
|
/>
|
|
929
973
|
</main>
|
|
930
|
-
<PicturesLibrary view={view} pictures={pictures} onSetView={setView} />
|
|
974
|
+
<PicturesLibrary view={view} pictures={pictures} onSetView={setView} onRefreshPictures={refreshPictures} />
|
|
931
975
|
<ImageStudioPanel
|
|
932
976
|
view={view}
|
|
933
977
|
onRefreshPictures={refreshPictures}
|
|
@@ -98,13 +98,13 @@ export default function ModelPanel({
|
|
|
98
98
|
</svg>
|
|
99
99
|
</button>
|
|
100
100
|
<div className="layout-preset-group">
|
|
101
|
-
<button className={`layout-preset-btn ${layoutPreset === 'chat-wide' ? 'is-active' : ''}`} onClick={() => onChangeLayoutPreset('chat-wide')} title="
|
|
101
|
+
<button className={`layout-preset-btn ${layoutPreset === 'chat-wide' ? 'is-active' : ''}`} onClick={() => onChangeLayoutPreset('chat-wide')} title="Expand chat panel (minimize model)">
|
|
102
102
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
|
103
103
|
<rect x="3" y="3" width="18" height="18" rx="2" />
|
|
104
104
|
<path d="M9 3v18" />
|
|
105
105
|
</svg>
|
|
106
106
|
</button>
|
|
107
|
-
<button className={`layout-preset-btn ${layoutPreset === 'model-wide' ? 'is-active' : ''}`} onClick={() => onChangeLayoutPreset('model-wide')} title="
|
|
107
|
+
<button className={`layout-preset-btn ${layoutPreset === 'model-wide' ? 'is-active' : ''}`} onClick={() => onChangeLayoutPreset('model-wide')} title="Expand model panel (minimize chat)">
|
|
108
108
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
|
109
109
|
<rect x="3" y="3" width="18" height="18" rx="2" />
|
|
110
110
|
<path d="M15 3v18" />
|
|
@@ -5,9 +5,10 @@ interface PicturesLibraryProps {
|
|
|
5
5
|
view: DashboardView
|
|
6
6
|
pictures: PictureEntry[]
|
|
7
7
|
onSetView: (view: DashboardView) => void
|
|
8
|
+
onRefreshPictures?: () => Promise<void>
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
export default function PicturesLibrary({ view, pictures, onSetView }: PicturesLibraryProps) {
|
|
11
|
+
export default function PicturesLibrary({ view, pictures, onSetView, onRefreshPictures }: PicturesLibraryProps) {
|
|
11
12
|
if (view !== 'pictures') return null
|
|
12
13
|
|
|
13
14
|
return (
|
|
@@ -16,6 +17,9 @@ export default function PicturesLibrary({ view, pictures, onSetView }: PicturesL
|
|
|
16
17
|
<div><span className="pictures-kicker">Gallery</span><h2>Saved Pictures</h2></div>
|
|
17
18
|
<div className="pictures-header-actions">
|
|
18
19
|
<button className="pictures-close-btn" onClick={() => onSetView('chat')}>Close Gallery</button>
|
|
20
|
+
<button type="button" className="picture-refresh-btn" title="Refresh" onClick={() => onRefreshPictures?.()}>
|
|
21
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.13-3.36L23 10"/><path d="M20.49 15a9 9 0 0 1-14.13 3.36L1 14"/></svg>
|
|
22
|
+
</button>
|
|
19
23
|
<button type="button" className="picture-folder-btn" disabled={pictures.length === 0} onClick={() => window.settingsApi?.openFolder(pictures[0]?.path || '')}>
|
|
20
24
|
Open Folder
|
|
21
25
|
</button>
|
|
@@ -2,14 +2,14 @@ import React, { useState, useEffect, useRef } from 'react'
|
|
|
2
2
|
import { evaluateArithmetic } from '../calculator'
|
|
3
3
|
|
|
4
4
|
const COMMANDS = [
|
|
5
|
-
{ label: 'Open YouTube', desc: '
|
|
6
|
-
{ label: 'Open Facebook', desc: '
|
|
7
|
-
{ label: 'Open Instagram', desc: '
|
|
8
|
-
{ label: 'Open GitHub', desc: '
|
|
9
|
-
{ label: 'System Info', desc: '
|
|
10
|
-
{ label: 'Weather', desc: '
|
|
11
|
-
{ label: 'Open Spotify', desc: '
|
|
12
|
-
{ label: 'Open VS Code', desc: '
|
|
5
|
+
{ label: 'Open YouTube', desc: 'Open YouTube website', icon: '📺', action: { type: 'open_url', target: 'https://youtube.com' } },
|
|
6
|
+
{ label: 'Open Facebook', desc: 'Open Facebook website', icon: '📘', action: { type: 'open_url', target: 'https://facebook.com' } },
|
|
7
|
+
{ label: 'Open Instagram', desc: 'Open Instagram website', icon: '📸', action: { type: 'open_url', target: 'https://instagram.com' } },
|
|
8
|
+
{ label: 'Open GitHub', desc: 'Open GitHub website', icon: '🐙', action: { type: 'open_url', target: 'https://github.com' } },
|
|
9
|
+
{ label: 'System Info', desc: 'Show system information', icon: '💻', action: { type: 'chat', query: 'Show me system information' } },
|
|
10
|
+
{ label: 'Weather', desc: 'Check the weather', icon: '🌤️', action: { type: 'chat', query: 'What is the current weather' } },
|
|
11
|
+
{ label: 'Open Spotify', desc: 'Open Spotify app', icon: '🎵', action: { type: 'open_app', target: 'spotify' } },
|
|
12
|
+
{ label: 'Open VS Code', desc: 'Open VS Code app', icon: '💻', action: { type: 'open_app', target: 'code' } },
|
|
13
13
|
]
|
|
14
14
|
|
|
15
15
|
function getCommandIcon(iconName: string) {
|
|
@@ -221,7 +221,7 @@ export default function WorkspacePanel({ agentMode, sending, workspacePath, onEn
|
|
|
221
221
|
|
|
222
222
|
const startWorkspacePrompt = () => {
|
|
223
223
|
onEnableAgentMode()
|
|
224
|
-
onSetMessage('
|
|
224
|
+
onSetMessage('Review this workspace and help plan next steps')
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
return (
|
|
@@ -397,6 +397,30 @@ h1 {
|
|
|
397
397
|
opacity: 1;
|
|
398
398
|
}
|
|
399
399
|
|
|
400
|
+
/* pictures header actions */
|
|
401
|
+
|
|
402
|
+
.picture-refresh-btn {
|
|
403
|
+
-webkit-app-region: no-drag;
|
|
404
|
+
height: 28px;
|
|
405
|
+
min-width: 0;
|
|
406
|
+
padding: 0 8px;
|
|
407
|
+
display: inline-flex;
|
|
408
|
+
align-items: center;
|
|
409
|
+
justify-content: center;
|
|
410
|
+
gap: 8px;
|
|
411
|
+
border-radius: 6px;
|
|
412
|
+
background: transparent;
|
|
413
|
+
color: var(--text-muted);
|
|
414
|
+
border: 1px solid transparent;
|
|
415
|
+
cursor: pointer;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.picture-refresh-btn:hover {
|
|
419
|
+
background: color-mix(in srgb, var(--accent) 10%, transparent);
|
|
420
|
+
border-color: color-mix(in srgb, var(--accent) 16%, transparent);
|
|
421
|
+
color: var(--accent);
|
|
422
|
+
}
|
|
423
|
+
|
|
400
424
|
.interaction-guide-btn:hover {
|
|
401
425
|
background: rgba(34, 211, 238, 0.14);
|
|
402
426
|
border-color: rgba(34, 211, 238, 0.2);
|
|
@@ -829,8 +853,9 @@ h1 {
|
|
|
829
853
|
}
|
|
830
854
|
|
|
831
855
|
.conversation-panel {
|
|
832
|
-
|
|
833
|
-
|
|
856
|
+
/* Make conversation panel wider by default */
|
|
857
|
+
flex: 0 1 720px;
|
|
858
|
+
min-width: 600px;
|
|
834
859
|
display: flex;
|
|
835
860
|
flex-direction: column;
|
|
836
861
|
min-height: 0;
|
|
@@ -877,7 +902,7 @@ h1 {
|
|
|
877
902
|
|
|
878
903
|
.message {
|
|
879
904
|
display: flex;
|
|
880
|
-
max-width:
|
|
905
|
+
max-width: 95%;
|
|
881
906
|
animation: messagePopIn 0.5s cubic-bezier(0.2, 0.9, 0.3, 1.2) forwards;
|
|
882
907
|
opacity: 0;
|
|
883
908
|
transform: translateY(15px) scale(0.95);
|
|
@@ -1066,24 +1091,26 @@ h1 {
|
|
|
1066
1091
|
}
|
|
1067
1092
|
|
|
1068
1093
|
.ai-message .message-bubble {
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
border
|
|
1074
|
-
border-
|
|
1075
|
-
|
|
1076
|
-
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1);
|
|
1094
|
+
/* Render AI replies without a framed bubble — plain inline text */
|
|
1095
|
+
background: transparent;
|
|
1096
|
+
backdrop-filter: none;
|
|
1097
|
+
-webkit-backdrop-filter: none;
|
|
1098
|
+
border: none;
|
|
1099
|
+
border-radius: 0;
|
|
1100
|
+
box-shadow: none;
|
|
1077
1101
|
color: var(--text-main);
|
|
1102
|
+
padding: 0; /* keep spacing handled by wrapper */
|
|
1078
1103
|
}
|
|
1079
1104
|
|
|
1080
1105
|
.message.ai-message.thinking-message .message-bubble {
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1106
|
+
/* Keep thinking state unframed too */
|
|
1107
|
+
background: transparent !important;
|
|
1108
|
+
border: none !important;
|
|
1109
|
+
box-shadow: none !important;
|
|
1084
1110
|
color: var(--text-muted) !important;
|
|
1085
1111
|
backdrop-filter: none !important;
|
|
1086
1112
|
-webkit-backdrop-filter: none !important;
|
|
1113
|
+
padding: 0 !important;
|
|
1087
1114
|
}
|
|
1088
1115
|
|
|
1089
1116
|
|
|
@@ -1702,6 +1729,146 @@ h1 {
|
|
|
1702
1729
|
line-height: 1;
|
|
1703
1730
|
}
|
|
1704
1731
|
|
|
1732
|
+
/* ── Thinking Block ─────────────────────────────────────── */
|
|
1733
|
+
.thinking-block {
|
|
1734
|
+
margin-bottom: 6px;
|
|
1735
|
+
border-radius: 8px;
|
|
1736
|
+
border: 1px solid rgba(148, 163, 184, 0.18);
|
|
1737
|
+
background: rgba(148, 163, 184, 0.04);
|
|
1738
|
+
overflow: hidden;
|
|
1739
|
+
animation: agent-activity-slide-up-fade 0.25s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
.thinking-block-header {
|
|
1743
|
+
display: flex;
|
|
1744
|
+
align-items: center;
|
|
1745
|
+
gap: 7px;
|
|
1746
|
+
width: 100%;
|
|
1747
|
+
padding: 6px 10px;
|
|
1748
|
+
background: transparent;
|
|
1749
|
+
border: 0;
|
|
1750
|
+
color: #94a3b8;
|
|
1751
|
+
font-size: 0.76rem;
|
|
1752
|
+
font-weight: 500;
|
|
1753
|
+
cursor: pointer;
|
|
1754
|
+
text-align: left;
|
|
1755
|
+
transition: background 0.15s ease, color 0.15s ease;
|
|
1756
|
+
user-select: none;
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
.thinking-block-header:hover {
|
|
1760
|
+
background: rgba(148, 163, 184, 0.08);
|
|
1761
|
+
color: #cbd5e1;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
.thinking-block-label {
|
|
1765
|
+
flex: 1;
|
|
1766
|
+
min-width: 0;
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
.thinking-block-live-dot {
|
|
1770
|
+
width: 6px;
|
|
1771
|
+
height: 6px;
|
|
1772
|
+
border-radius: 50%;
|
|
1773
|
+
background: #94a3b8;
|
|
1774
|
+
flex-shrink: 0;
|
|
1775
|
+
animation: thinkingDotPulse 1.4s ease-in-out infinite;
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
@keyframes thinkingDotPulse {
|
|
1779
|
+
0%, 100% {
|
|
1780
|
+
opacity: 0.4;
|
|
1781
|
+
transform: scale(0.85);
|
|
1782
|
+
}
|
|
1783
|
+
50% {
|
|
1784
|
+
opacity: 1;
|
|
1785
|
+
transform: scale(1.1);
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
.thinking-block-chevron {
|
|
1790
|
+
color: rgba(148, 163, 184, 0.6);
|
|
1791
|
+
flex-shrink: 0;
|
|
1792
|
+
display: inline-flex;
|
|
1793
|
+
align-items: center;
|
|
1794
|
+
transition: transform 0.2s ease;
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
.thinking-block-chevron.is-open {
|
|
1798
|
+
transform: rotate(90deg);
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
.thinking-block-body {
|
|
1802
|
+
border-top: 1px solid rgba(148, 163, 184, 0.12);
|
|
1803
|
+
animation: thinkingBodyIn 0.18s ease;
|
|
1804
|
+
}
|
|
1805
|
+
|
|
1806
|
+
@keyframes thinkingBodyIn {
|
|
1807
|
+
from {
|
|
1808
|
+
opacity: 0;
|
|
1809
|
+
transform: translateY(-4px);
|
|
1810
|
+
}
|
|
1811
|
+
to {
|
|
1812
|
+
opacity: 1;
|
|
1813
|
+
transform: translateY(0);
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
.thinking-block-content {
|
|
1818
|
+
padding: 8px 12px 10px;
|
|
1819
|
+
font-size: 0.76rem;
|
|
1820
|
+
line-height: 1.6;
|
|
1821
|
+
color: #64748b;
|
|
1822
|
+
white-space: pre-wrap;
|
|
1823
|
+
max-height: 260px;
|
|
1824
|
+
overflow-y: auto;
|
|
1825
|
+
user-select: text;
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
.thinking-block-step + .thinking-block-step {
|
|
1829
|
+
margin-top: 10px;
|
|
1830
|
+
padding-top: 10px;
|
|
1831
|
+
border-top: 1px dashed rgba(148, 163, 184, 0.16);
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
.thinking-block-step-label {
|
|
1835
|
+
font-size: 0.68rem;
|
|
1836
|
+
font-weight: 600;
|
|
1837
|
+
letter-spacing: 0.02em;
|
|
1838
|
+
color: #94a3b8;
|
|
1839
|
+
margin-bottom: 4px;
|
|
1840
|
+
font-style: normal;
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
.thinking-block-step-body {
|
|
1844
|
+
font-style: italic;
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
.thinking-block-empty-state {
|
|
1848
|
+
padding: 6px 10px;
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
.thinking-block-empty {
|
|
1852
|
+
display: block;
|
|
1853
|
+
font-size: 0.74rem;
|
|
1854
|
+
line-height: 1.5;
|
|
1855
|
+
color: #64748b;
|
|
1856
|
+
font-style: italic;
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
.thinking-block-content::-webkit-scrollbar {
|
|
1860
|
+
width: 3px;
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
.thinking-block-content::-webkit-scrollbar-track {
|
|
1864
|
+
background: transparent;
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
.thinking-block-content::-webkit-scrollbar-thumb {
|
|
1868
|
+
background: rgba(148, 163, 184, 0.22);
|
|
1869
|
+
border-radius: 2px;
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1705
1872
|
/* Smart Context Toggle */
|
|
1706
1873
|
.smart-context-bar {
|
|
1707
1874
|
display: flex;
|
|
@@ -3155,13 +3322,15 @@ input:checked + .slider:before {
|
|
|
3155
3322
|
|
|
3156
3323
|
.ai-message .message-bubble,
|
|
3157
3324
|
.typing-indicator {
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
border
|
|
3325
|
+
/* Keep AI messages unframed here as well */
|
|
3326
|
+
background: transparent;
|
|
3327
|
+
border: none;
|
|
3328
|
+
border-radius: 0;
|
|
3161
3329
|
color: var(--text-main);
|
|
3162
3330
|
backdrop-filter: none;
|
|
3163
3331
|
-webkit-backdrop-filter: none;
|
|
3164
3332
|
box-shadow: none;
|
|
3333
|
+
padding: 0; /* spacing handled by wrapper */
|
|
3165
3334
|
}
|
|
3166
3335
|
|
|
3167
3336
|
.user-message .message-bubble {
|
|
@@ -3176,6 +3345,15 @@ input:checked + .slider:before {
|
|
|
3176
3345
|
color: var(--accent-hover);
|
|
3177
3346
|
}
|
|
3178
3347
|
|
|
3348
|
+
/* Force AI replies to render as plain inline text (no bubble/frame). */
|
|
3349
|
+
.message.ai-message .message-bubble {
|
|
3350
|
+
background: transparent !important;
|
|
3351
|
+
border: none !important;
|
|
3352
|
+
box-shadow: none !important;
|
|
3353
|
+
border-radius: 0 !important;
|
|
3354
|
+
padding: 0 !important;
|
|
3355
|
+
}
|
|
3356
|
+
|
|
3179
3357
|
.input-area {
|
|
3180
3358
|
flex: 0 0 auto;
|
|
3181
3359
|
padding: 0;
|
|
@@ -483,3 +483,49 @@ button {
|
|
|
483
483
|
font-family: 'Fira Code', 'Courier New', Courier, monospace;
|
|
484
484
|
font-size: 0.9em;
|
|
485
485
|
}
|
|
486
|
+
|
|
487
|
+
/* Premium Table Styles for Chat Panel */
|
|
488
|
+
.chat-table-container {
|
|
489
|
+
overflow-x: auto;
|
|
490
|
+
margin: 14px 0;
|
|
491
|
+
width: 100%;
|
|
492
|
+
border-radius: 8px;
|
|
493
|
+
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
494
|
+
background: rgba(30, 41, 59, 0.35);
|
|
495
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
.chat-table {
|
|
499
|
+
width: 100%;
|
|
500
|
+
border-collapse: collapse;
|
|
501
|
+
font-size: 0.86rem;
|
|
502
|
+
text-align: left;
|
|
503
|
+
line-height: 1.5;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
.chat-table th {
|
|
507
|
+
padding: 12px 16px;
|
|
508
|
+
font-weight: 700;
|
|
509
|
+
color: var(--accent);
|
|
510
|
+
background: rgba(255, 255, 255, 0.04);
|
|
511
|
+
border-bottom: 2px solid rgba(255, 255, 255, 0.15);
|
|
512
|
+
font-family: ui-sans-serif, system-ui, sans-serif;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
.chat-table td {
|
|
516
|
+
padding: 12px 16px;
|
|
517
|
+
color: var(--text-main, #e2e8f0);
|
|
518
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
.chat-table tbody tr {
|
|
522
|
+
transition: background 0.15s ease;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
.chat-table tbody tr:hover {
|
|
526
|
+
background: rgba(255, 255, 255, 0.03);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.chat-table tbody tr:last-child td {
|
|
530
|
+
border-bottom: none;
|
|
531
|
+
}
|
|
@@ -42,6 +42,7 @@ export interface InteractionMemory {
|
|
|
42
42
|
model: string
|
|
43
43
|
fallbackProvider?: string | null
|
|
44
44
|
createdAt: string
|
|
45
|
+
agentActivity?: AgentProgress[] | null
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
export interface ChatSession {
|
|
@@ -281,6 +282,30 @@ export async function getRecentInteractions(limit = 50, chatId?: string | null):
|
|
|
281
282
|
return invoke<InteractionMemory[]>('get_recent_interactions', { limit, chatId })
|
|
282
283
|
}
|
|
283
284
|
|
|
285
|
+
export async function saveInteractionAgentActivity(
|
|
286
|
+
interactionId: number,
|
|
287
|
+
activity: AgentProgress[],
|
|
288
|
+
): Promise<void> {
|
|
289
|
+
if (typeof window === 'undefined' || !(window as any).__TAURI_INTERNALS__) {
|
|
290
|
+
const API_BASE = "http://localhost:3000/api";
|
|
291
|
+
try {
|
|
292
|
+
const res = await fetch(`${API_BASE}/interactions/agent-activity`, {
|
|
293
|
+
method: 'POST',
|
|
294
|
+
headers: { 'Content-Type': 'application/json' },
|
|
295
|
+
body: JSON.stringify({ interactionId, activity }),
|
|
296
|
+
});
|
|
297
|
+
if (!res.ok) {
|
|
298
|
+
throw new Error(`HTTP ${res.status}`);
|
|
299
|
+
}
|
|
300
|
+
} catch (error) {
|
|
301
|
+
console.error('Failed to persist agent activity:', error);
|
|
302
|
+
}
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const { invoke } = await import('@tauri-apps/api/core')
|
|
306
|
+
await invoke('save_interaction_agent_activity', { interactionId, activity })
|
|
307
|
+
}
|
|
308
|
+
|
|
284
309
|
export async function listChatSessions(): Promise<ChatSession[]> {
|
|
285
310
|
if (typeof window === 'undefined' || !(window as any).__TAURI_INTERNALS__) {
|
|
286
311
|
const API_BASE = "http://localhost:3000/api";
|