@pheem49/mint 1.6.2 → 1.6.4
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/.github/workflows/ci.yml +14 -0
- package/Cargo.lock +3 -3
- package/Cargo.toml +1 -1
- package/README.md +82 -21
- package/assets/Mint_CLI.png +0 -0
- package/assets/Mint_Desktop.png +0 -0
- package/assets/Mint_Web.png +0 -0
- package/assets/Mint_WorkSpace.png +0 -0
- package/assets/Setting.png +0 -0
- package/assets/bridges.svg +4 -0
- package/assets/chat.svg +3 -0
- package/assets/code.svg +4 -0
- package/assets/features.svg +3 -0
- package/assets/imagegen.svg +5 -0
- package/assets/live2d.svg +6 -0
- package/assets/memory.svg +5 -0
- package/assets/screencapture.svg +4 -0
- package/assets/setup.svg +3 -0
- package/assets/tools.svg +4 -0
- package/bin/mint +0 -0
- package/crates/mint-cli/src/agent.rs +6 -2
- package/crates/mint-cli/src/main.rs +145 -5
- package/crates/mint-cli/src/onboard.rs +134 -1
- package/crates/mint-core/src/api_server.rs +108 -3
- package/crates/mint-core/src/config.rs +20 -1
- package/crates/mint-core/src/image_gen.rs +895 -0
- package/crates/mint-core/src/lib.rs +4 -0
- package/package.json +3 -3
- package/src/bin/index.js +0 -0
- package/src/renderer/index-web.html +1 -1
- package/src/renderer/index.html +1 -1
- package/src/renderer/src/components/ChatPanel.tsx +252 -26
- package/src/renderer/src/components/DashboardSidebar.tsx +11 -3
- package/src/renderer/src/components/ImageStudioPanel.tsx +638 -0
- package/src/renderer/src/components/MintDashboard.tsx +14 -5
- package/src/renderer/src/components/SettingsWindow.tsx +29 -20
- package/src/renderer/src/css/image-studio.css +722 -0
- package/src/renderer/src/css/settings.css +13 -3
- package/src/renderer/src/css/styles.css +50 -26
- package/src/renderer/src/index.css +106 -0
- package/src/renderer/src/tauri.ts +123 -0
- package/src/renderer/src-web/components/ChatPanel.tsx +273 -25
- package/src/renderer/src-web/components/DashboardSidebar.tsx +11 -3
- package/src/renderer/src-web/components/ImageStudioPanel.tsx +638 -0
- package/src/renderer/src-web/components/MintDashboard.tsx +13 -4
- package/src/renderer/src-web/components/SettingsWindow.tsx +29 -20
- package/src/renderer/src-web/css/image-studio.css +722 -0
- package/src/renderer/src-web/css/settings.css +14 -4
- package/src/renderer/src-web/css/styles.css +50 -26
- package/src/renderer/src-web/index.css +106 -0
- package/src/renderer/src-web/tauri.ts +124 -0
- package/src-tauri/Cargo.toml +29 -0
- package/src-tauri/build.rs +3 -0
- package/src-tauri/capabilities/main.json +7 -0
- package/src-tauri/gen/schemas/acl-manifests.json +1 -0
- package/src-tauri/gen/schemas/capabilities.json +1 -0
- package/src-tauri/gen/schemas/desktop-schema.json +2412 -0
- package/src-tauri/gen/schemas/linux-schema.json +2412 -0
- package/src-tauri/src/browser.rs +141 -0
- package/src-tauri/src/desktop.rs +392 -0
- package/src-tauri/src/discord_rpc.rs +99 -0
- package/src-tauri/src/events.rs +70 -0
- package/src-tauri/src/headless.rs +222 -0
- package/src-tauri/src/integrations.rs +126 -0
- package/src-tauri/src/lib.rs +1076 -0
- package/src-tauri/src/main.rs +3 -0
- package/src-tauri/src/plugins.rs +16 -0
- package/src-tauri/src/proactive.rs +254 -0
- package/src-tauri/src/system.rs +250 -0
- package/src-tauri/src/updater.rs +148 -0
- package/src-tauri/src/webhooks.rs +255 -0
- package/src-tauri/src/workflows.rs +70 -0
- package/src-tauri/tauri.conf.json +48 -0
- package/tsconfig.json +1 -1
|
@@ -260,6 +260,64 @@ function renderApprovalDetails(approval: any): ApprovalDetails {
|
|
|
260
260
|
return { title: 'Unknown Action', body: JSON.stringify(approval, null, 2), reason: 'Requires approval to proceed.', isDangerous: false }
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
+
function renderDiff(diffText: string) {
|
|
264
|
+
if (!diffText) return null
|
|
265
|
+
const lines = diffText.split('\n')
|
|
266
|
+
return (
|
|
267
|
+
<div style={{
|
|
268
|
+
background: '#0b0f19',
|
|
269
|
+
borderRadius: '6px',
|
|
270
|
+
padding: '8px',
|
|
271
|
+
border: '1px solid rgba(255, 255, 255, 0.08)',
|
|
272
|
+
overflowX: 'auto',
|
|
273
|
+
maxHeight: '400px',
|
|
274
|
+
fontFamily: 'monospace',
|
|
275
|
+
fontSize: '0.74rem',
|
|
276
|
+
lineHeight: '1.4',
|
|
277
|
+
}}>
|
|
278
|
+
{lines.map((line, idx) => {
|
|
279
|
+
let style: any = {
|
|
280
|
+
whiteSpace: 'pre-wrap',
|
|
281
|
+
padding: '2px 6px',
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (line.startsWith('@@') || line.startsWith('---') || line.startsWith('+++')) {
|
|
285
|
+
style = {
|
|
286
|
+
...style,
|
|
287
|
+
color: '#64748b',
|
|
288
|
+
fontWeight: 'bold',
|
|
289
|
+
}
|
|
290
|
+
} else if (line.startsWith('+')) {
|
|
291
|
+
style = {
|
|
292
|
+
...style,
|
|
293
|
+
background: 'rgba(16, 185, 129, 0.12)',
|
|
294
|
+
borderLeft: '3px solid #10b981',
|
|
295
|
+
color: '#a7f3d0'
|
|
296
|
+
}
|
|
297
|
+
} else if (line.startsWith('-')) {
|
|
298
|
+
style = {
|
|
299
|
+
...style,
|
|
300
|
+
background: 'rgba(239, 68, 68, 0.12)',
|
|
301
|
+
borderLeft: '3px solid #ef4444',
|
|
302
|
+
color: '#fca5a5'
|
|
303
|
+
}
|
|
304
|
+
} else {
|
|
305
|
+
style = {
|
|
306
|
+
...style,
|
|
307
|
+
color: '#e2e8f0',
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return (
|
|
312
|
+
<div key={idx} style={style}>
|
|
313
|
+
{line}
|
|
314
|
+
</div>
|
|
315
|
+
)
|
|
316
|
+
})}
|
|
317
|
+
</div>
|
|
318
|
+
)
|
|
319
|
+
}
|
|
320
|
+
|
|
263
321
|
interface ChatPanelProps {
|
|
264
322
|
interactions: any[]
|
|
265
323
|
sending: boolean
|
|
@@ -298,55 +356,171 @@ interface ChatPanelProps {
|
|
|
298
356
|
onSetModel: (model: string) => void
|
|
299
357
|
}
|
|
300
358
|
|
|
359
|
+
function ChatCodeBlock({ code, language }: { code: string; language: string; key?: any }) {
|
|
360
|
+
const [copied, setCopied] = useState(false)
|
|
361
|
+
|
|
362
|
+
const handleCopy = async () => {
|
|
363
|
+
try {
|
|
364
|
+
await navigator.clipboard.writeText(code)
|
|
365
|
+
setCopied(true)
|
|
366
|
+
setTimeout(() => setCopied(false), 2000)
|
|
367
|
+
} catch (err) {
|
|
368
|
+
console.error('Failed to copy code: ', err)
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
const handleDownload = () => {
|
|
373
|
+
try {
|
|
374
|
+
const blob = new Blob([code], { type: 'text/plain;charset=utf-8' })
|
|
375
|
+
const url = URL.createObjectURL(blob)
|
|
376
|
+
const link = document.createElement('a')
|
|
377
|
+
link.href = url
|
|
378
|
+
link.download = `code.${language === 'plaintext' ? 'txt' : language}`
|
|
379
|
+
link.click()
|
|
380
|
+
URL.revokeObjectURL(url)
|
|
381
|
+
} catch (err) {
|
|
382
|
+
console.error('Failed to download code: ', err)
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const displayLang = language.charAt(0).toUpperCase() + language.slice(1).toLowerCase()
|
|
387
|
+
|
|
388
|
+
return (
|
|
389
|
+
<div className="chat-code-block-container" style={{ whiteSpace: 'normal' }}>
|
|
390
|
+
<div className="chat-code-block-header">
|
|
391
|
+
<span className="chat-code-block-lang">{displayLang}</span>
|
|
392
|
+
<div className="chat-code-block-actions">
|
|
393
|
+
<button type="button" onClick={handleDownload} title="Download code" className="chat-code-action-btn">
|
|
394
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
395
|
+
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
|
396
|
+
<polyline points="7 10 12 15 17 10" />
|
|
397
|
+
<line x1="12" y1="15" x2="12" y2="3" />
|
|
398
|
+
</svg>
|
|
399
|
+
</button>
|
|
400
|
+
<button type="button" onClick={handleCopy} title="Copy code" className="chat-code-action-btn">
|
|
401
|
+
{copied ? (
|
|
402
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
|
|
403
|
+
<polyline points="20 6 9 17 4 12" />
|
|
404
|
+
</svg>
|
|
405
|
+
) : (
|
|
406
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
407
|
+
<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
|
|
408
|
+
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
|
|
409
|
+
</svg>
|
|
410
|
+
)}
|
|
411
|
+
</button>
|
|
412
|
+
</div>
|
|
413
|
+
</div>
|
|
414
|
+
<pre className="chat-code-block-body">
|
|
415
|
+
<code>{code}</code>
|
|
416
|
+
</pre>
|
|
417
|
+
</div>
|
|
418
|
+
)
|
|
419
|
+
}
|
|
420
|
+
|
|
301
421
|
function renderFormattedMessage(text: string) {
|
|
302
422
|
const displayText = readableAssistantText(text)
|
|
303
423
|
if (!displayText) return null
|
|
304
|
-
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
424
|
+
|
|
425
|
+
const formatInline = (str: string) => {
|
|
426
|
+
const codeParts = str.split(/`([\s\S]*?)`/g)
|
|
427
|
+
return codeParts.map((codePart, codeIndex) => {
|
|
428
|
+
if (codeIndex % 2 === 1) {
|
|
429
|
+
return (
|
|
430
|
+
<code key={`code-${codeIndex}`} className="chat-inline-code">
|
|
431
|
+
{codePart}
|
|
432
|
+
</code>
|
|
433
|
+
)
|
|
434
|
+
}
|
|
435
|
+
const boldParts = codePart.split(/\*\*([\s\S]*?)\*\*/g)
|
|
436
|
+
return boldParts.map((boldPart, boldIndex) => {
|
|
437
|
+
if (boldIndex % 2 === 1) {
|
|
313
438
|
return (
|
|
314
|
-
<strong key={
|
|
315
|
-
{
|
|
439
|
+
<strong key={`bold-${boldIndex}`} className="chat-bold-highlight">
|
|
440
|
+
{boldPart}
|
|
316
441
|
</strong>
|
|
317
442
|
)
|
|
318
443
|
}
|
|
319
|
-
return
|
|
444
|
+
return boldPart
|
|
320
445
|
})
|
|
446
|
+
})
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const lines = displayText.split('\n')
|
|
450
|
+
const items: any[] = []
|
|
451
|
+
|
|
452
|
+
let inCodeBlock = false
|
|
453
|
+
let codeBlockLang = ''
|
|
454
|
+
let codeBlockLines: string[] = []
|
|
455
|
+
|
|
456
|
+
for (let i = 0; i < lines.length; i++) {
|
|
457
|
+
const line = lines[i]
|
|
458
|
+
|
|
459
|
+
if (line.trim().startsWith('```')) {
|
|
460
|
+
if (inCodeBlock) {
|
|
461
|
+
const codeText = codeBlockLines.join('\n')
|
|
462
|
+
items.push(
|
|
463
|
+
<ChatCodeBlock
|
|
464
|
+
key={`code-block-${i}`}
|
|
465
|
+
code={codeText}
|
|
466
|
+
language={codeBlockLang}
|
|
467
|
+
/>
|
|
468
|
+
)
|
|
469
|
+
inCodeBlock = false
|
|
470
|
+
codeBlockLines = []
|
|
471
|
+
} else {
|
|
472
|
+
inCodeBlock = true
|
|
473
|
+
codeBlockLang = line.trim().slice(3).trim() || 'plaintext'
|
|
474
|
+
}
|
|
475
|
+
continue
|
|
321
476
|
}
|
|
322
477
|
|
|
478
|
+
if (inCodeBlock) {
|
|
479
|
+
codeBlockLines.push(line)
|
|
480
|
+
continue
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const headerMatch = line.match(/^(#{1,6})\s+(.*)$/)
|
|
323
484
|
if (headerMatch) {
|
|
324
485
|
const level = headerMatch[1].length
|
|
325
486
|
const content = headerMatch[2]
|
|
326
|
-
|
|
487
|
+
|
|
327
488
|
const style = {
|
|
328
489
|
fontWeight: 'bold',
|
|
329
490
|
display: 'block',
|
|
330
491
|
marginTop: level === 1 ? '16px' : level === 2 ? '14px' : '10px',
|
|
331
492
|
marginBottom: '6px',
|
|
332
493
|
fontSize: level === 1 ? '1.25em' : level === 2 ? '1.15em' : '1.05em',
|
|
333
|
-
color: 'var(--text-main)'
|
|
494
|
+
color: 'var(--text-main)',
|
|
334
495
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
<span key={
|
|
496
|
+
|
|
497
|
+
items.push(
|
|
498
|
+
<span key={`line-${i}`} style={style}>
|
|
338
499
|
{formatInline(content)}
|
|
339
500
|
</span>
|
|
340
501
|
)
|
|
502
|
+
} else {
|
|
503
|
+
items.push(
|
|
504
|
+
<Fragment key={`line-${i}`}>
|
|
505
|
+
{formatInline(line)}
|
|
506
|
+
{i < lines.length - 1 && '\n'}
|
|
507
|
+
</Fragment>
|
|
508
|
+
)
|
|
341
509
|
}
|
|
510
|
+
}
|
|
342
511
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
512
|
+
if (inCodeBlock && codeBlockLines.length > 0) {
|
|
513
|
+
const codeText = codeBlockLines.join('\n')
|
|
514
|
+
items.push(
|
|
515
|
+
<ChatCodeBlock
|
|
516
|
+
key={`code-block-end`}
|
|
517
|
+
code={codeText}
|
|
518
|
+
language={codeBlockLang}
|
|
519
|
+
/>
|
|
348
520
|
)
|
|
349
|
-
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
return items
|
|
350
524
|
}
|
|
351
525
|
|
|
352
526
|
function readableAssistantText(text: string) {
|
|
@@ -607,6 +781,25 @@ export default function ChatPanel({
|
|
|
607
781
|
}
|
|
608
782
|
const activeModel = getActiveModel(activeProvider)
|
|
609
783
|
|
|
784
|
+
const [elapsedSeconds, setElapsedSeconds] = useState(0)
|
|
785
|
+
|
|
786
|
+
useEffect(() => {
|
|
787
|
+
if (!sending) {
|
|
788
|
+
setElapsedSeconds(0)
|
|
789
|
+
return
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
const startTime = Date.now()
|
|
793
|
+
setElapsedSeconds(0)
|
|
794
|
+
|
|
795
|
+
const timer = setInterval(() => {
|
|
796
|
+
const elapsed = Math.round((Date.now() - startTime) / 1000)
|
|
797
|
+
setElapsedSeconds(elapsed)
|
|
798
|
+
}, 1000)
|
|
799
|
+
|
|
800
|
+
return () => clearInterval(timer)
|
|
801
|
+
}, [sending])
|
|
802
|
+
|
|
610
803
|
const [isRecording, setIsRecording] = useState(false)
|
|
611
804
|
const [voiceMode, setVoiceMode] = useState(false)
|
|
612
805
|
const [voiceTranscript, setVoiceTranscript] = useState('')
|
|
@@ -1319,7 +1512,7 @@ export default function ChatPanel({
|
|
|
1319
1512
|
</button>
|
|
1320
1513
|
<div className="chat-header-title">
|
|
1321
1514
|
<img src="./assets/icon.png" alt="Logo" className="chat-header-logo" />
|
|
1322
|
-
<span>Agent
|
|
1515
|
+
<span>Mint Agent</span>
|
|
1323
1516
|
</div>
|
|
1324
1517
|
</div>
|
|
1325
1518
|
|
|
@@ -1425,7 +1618,30 @@ export default function ChatPanel({
|
|
|
1425
1618
|
{renderActiveFileChanges()}
|
|
1426
1619
|
<div className="message ai-message thinking-message">
|
|
1427
1620
|
<div className="bubble-wrapper">
|
|
1428
|
-
<div className="message-bubble"
|
|
1621
|
+
<div className="message-bubble">
|
|
1622
|
+
<span>
|
|
1623
|
+
{streamedReply ? (
|
|
1624
|
+
renderFormattedMessage(streamedReply)
|
|
1625
|
+
) : (
|
|
1626
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', color: 'var(--text-soft, #94a3b8)' }}>
|
|
1627
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" style={{ display: 'inline-block', flexShrink: 0 }}>
|
|
1628
|
+
<circle cx="12" cy="12" r="10" stroke="rgba(255, 255, 255, 0.12)" />
|
|
1629
|
+
<path d="M12 2a10 10 0 0 1 10 10" stroke="var(--accent)" strokeLinecap="round">
|
|
1630
|
+
<animateTransform
|
|
1631
|
+
attributeName="transform"
|
|
1632
|
+
type="rotate"
|
|
1633
|
+
from="0 12 12"
|
|
1634
|
+
to="360 12 12"
|
|
1635
|
+
dur="0.9s"
|
|
1636
|
+
repeatCount="indefinite"
|
|
1637
|
+
/>
|
|
1638
|
+
</path>
|
|
1639
|
+
</svg>
|
|
1640
|
+
<span>Thinking for {elapsedSeconds}s</span>
|
|
1641
|
+
</div>
|
|
1642
|
+
)}
|
|
1643
|
+
</span>
|
|
1644
|
+
</div>
|
|
1429
1645
|
{streamedResponse && (
|
|
1430
1646
|
<div className="message-time" style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
1431
1647
|
<button className="provider-badge">{badge(streamedResponse.provider, streamedResponse.model)}</button>
|
|
@@ -1459,6 +1675,38 @@ export default function ChatPanel({
|
|
|
1459
1675
|
</div>
|
|
1460
1676
|
)}
|
|
1461
1677
|
|
|
1678
|
+
{pendingApproval && (() => {
|
|
1679
|
+
const details = renderApprovalDetails(pendingApproval.approval)
|
|
1680
|
+
const writeFile = pendingApproval.approval?.WriteFile
|
|
1681
|
+
const applyPatch = pendingApproval.approval?.ApplyPatch
|
|
1682
|
+
const diffText = writeFile?.diff || applyPatch?.diff
|
|
1683
|
+
|
|
1684
|
+
return (
|
|
1685
|
+
<div className="message ai-message" style={{ width: '100%' }}>
|
|
1686
|
+
<div className="bubble-wrapper" style={{ width: '100%' }}>
|
|
1687
|
+
<div className="action-card approval-card" data-tier={details.isDangerous ? 'dangerous' : undefined} style={{ width: '100%' }}>
|
|
1688
|
+
<div className="approval-card-content" style={{ width: '100%' }}>
|
|
1689
|
+
<div className="approval-card-title">{details.title}</div>
|
|
1690
|
+
<div className="approval-card-body" style={{ whiteSpace: 'pre-wrap', fontFamily: 'monospace' }}>{details.body}</div>
|
|
1691
|
+
{diffText ? (
|
|
1692
|
+
<div className="approval-card-diff-container" style={{ marginTop: '8px', width: '100%' }}>
|
|
1693
|
+
<div style={{ fontSize: '0.8rem', fontWeight: 600, color: 'var(--text-soft, #94a3b8)', marginBottom: '4px' }}>Diff:</div>
|
|
1694
|
+
{renderDiff(diffText)}
|
|
1695
|
+
</div>
|
|
1696
|
+
) : (
|
|
1697
|
+
details.reason && <div className="approval-card-reason" style={{ whiteSpace: 'pre-wrap', fontFamily: 'monospace' }}>{details.reason}</div>
|
|
1698
|
+
)}
|
|
1699
|
+
</div>
|
|
1700
|
+
<div className="approval-card-actions">
|
|
1701
|
+
<button type="button" className="approval-btn approval-btn-approve" onClick={() => onApproval(true)}>Approve</button>
|
|
1702
|
+
<button type="button" className="approval-btn" style={{ backgroundColor: 'rgba(16, 185, 129, 0.22)', borderColor: 'rgba(16, 185, 129, 0.4)', color: '#a7f3d0' }} onClick={() => onApproval(true, true)}>Approve this session</button>
|
|
1703
|
+
<button type="button" className="approval-btn approval-btn-cancel" onClick={() => onApproval(false)}>Cancel</button>
|
|
1704
|
+
</div>
|
|
1705
|
+
</div>
|
|
1706
|
+
</div>
|
|
1707
|
+
</div>
|
|
1708
|
+
)
|
|
1709
|
+
})()}
|
|
1462
1710
|
<div ref={chatEnd} />
|
|
1463
1711
|
</div>
|
|
1464
1712
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useState } from 'react'
|
|
2
2
|
|
|
3
|
-
export type DashboardView = 'chat' | 'pictures' | 'model'
|
|
3
|
+
export type DashboardView = 'chat' | 'pictures' | 'model' | 'imagine'
|
|
4
4
|
|
|
5
5
|
interface ChatSessionItem {
|
|
6
6
|
id: string
|
|
@@ -63,8 +63,8 @@ export default function DashboardSidebar({
|
|
|
63
63
|
if (event.key === 'Enter' || event.key === ' ') onToggleSidebar()
|
|
64
64
|
}}
|
|
65
65
|
>
|
|
66
|
-
<img src="./assets/icon.png" alt="Agent
|
|
67
|
-
<span className="sidebar-brand-name">Agent
|
|
66
|
+
<img src="./assets/icon.png" alt="Mint Agent Logo" className="sidebar-logo" />
|
|
67
|
+
<span className="sidebar-brand-name">Mint Agent</span>
|
|
68
68
|
</div>
|
|
69
69
|
|
|
70
70
|
<button className="sidebar-new-chat" onClick={() => onClearHistory('New chat')}>
|
|
@@ -95,6 +95,14 @@ export default function DashboardSidebar({
|
|
|
95
95
|
</span>
|
|
96
96
|
<span>Pictures</span>
|
|
97
97
|
</button>
|
|
98
|
+
<button className={`sidebar-top-action ${view === 'imagine' ? 'is-active' : ''}`} onClick={() => onSetView('imagine')}>
|
|
99
|
+
<span aria-hidden="true" style={{ display: 'inline-flex', alignItems: 'center' }}>
|
|
100
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
|
101
|
+
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
|
|
102
|
+
</svg>
|
|
103
|
+
</span>
|
|
104
|
+
<span>Image Studio</span>
|
|
105
|
+
</button>
|
|
98
106
|
|
|
99
107
|
<div className="sidebar-section">
|
|
100
108
|
<div className="sidebar-section-title">Conversation CLI</div>
|