@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
|
@@ -255,7 +255,7 @@ h1 {
|
|
|
255
255
|
|
|
256
256
|
.web-safe-notice {
|
|
257
257
|
width: 100%;
|
|
258
|
-
max-width:
|
|
258
|
+
max-width: 1000px;
|
|
259
259
|
margin: 0 auto 18px;
|
|
260
260
|
padding: 12px 14px;
|
|
261
261
|
border: 1px solid color-mix(in srgb, var(--accent) 34%, var(--border));
|
|
@@ -297,7 +297,7 @@ h1 {
|
|
|
297
297
|
flex-direction: column;
|
|
298
298
|
gap: 18px;
|
|
299
299
|
width: 100%;
|
|
300
|
-
max-width:
|
|
300
|
+
max-width: 1000px;
|
|
301
301
|
margin: 0 auto;
|
|
302
302
|
animation: fadeTab 0.18s ease;
|
|
303
303
|
}
|
|
@@ -369,7 +369,7 @@ h1 {
|
|
|
369
369
|
|
|
370
370
|
.form-grid.single {
|
|
371
371
|
grid-template-columns: minmax(0, 1fr);
|
|
372
|
-
max-width:
|
|
372
|
+
max-width: 100%;
|
|
373
373
|
}
|
|
374
374
|
|
|
375
375
|
.setting-row {
|
|
@@ -623,7 +623,7 @@ input:checked + .toggle-slider::before {
|
|
|
623
623
|
.slider-stack {
|
|
624
624
|
display: grid;
|
|
625
625
|
gap: 16px;
|
|
626
|
-
max-width:
|
|
626
|
+
max-width: 100%;
|
|
627
627
|
}
|
|
628
628
|
|
|
629
629
|
.slider-group {
|
|
@@ -1098,3 +1098,13 @@ kbd {
|
|
|
1098
1098
|
grid-template-columns: minmax(0, 1fr);
|
|
1099
1099
|
}
|
|
1100
1100
|
}
|
|
1101
|
+
|
|
1102
|
+
.memory-field-container {
|
|
1103
|
+
display: flex;
|
|
1104
|
+
flex-direction: column;
|
|
1105
|
+
gap: 8px;
|
|
1106
|
+
width: 100%;
|
|
1107
|
+
align-items: flex-start;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
|
|
@@ -18,6 +18,16 @@
|
|
|
18
18
|
--border-light: rgba(255, 255, 255, 0.11);
|
|
19
19
|
--shadow: none;
|
|
20
20
|
--glass-blur: none;
|
|
21
|
+
--status-listening: #7dd3fc;
|
|
22
|
+
--status-thinking: var(--accent);
|
|
23
|
+
--status-speaking: #22c55e;
|
|
24
|
+
--status-error: #ef4444;
|
|
25
|
+
--hover-delete: #fca5a5;
|
|
26
|
+
--hover-delete-bg: rgba(248, 113, 113, 0.12);
|
|
27
|
+
--hover-edit: #c7d2fe;
|
|
28
|
+
--hover-edit-bg: rgba(99, 102, 241, 0.12);
|
|
29
|
+
--close-btn-hover-bg: #3a2020;
|
|
30
|
+
--close-btn-hover-color: #ff8a8a;
|
|
21
31
|
}
|
|
22
32
|
|
|
23
33
|
[data-theme="light"] {
|
|
@@ -37,6 +47,16 @@
|
|
|
37
47
|
--border: rgba(0, 0, 0, 0.06);
|
|
38
48
|
--border-light: rgba(255, 255, 255, 0.6);
|
|
39
49
|
--shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
|
|
50
|
+
--status-listening: #0284c7;
|
|
51
|
+
--status-thinking: var(--accent);
|
|
52
|
+
--status-speaking: #16a34a;
|
|
53
|
+
--status-error: #dc2626;
|
|
54
|
+
--hover-delete: #dc2626;
|
|
55
|
+
--hover-delete-bg: rgba(220, 38, 38, 0.08);
|
|
56
|
+
--hover-edit: #4f46e5;
|
|
57
|
+
--hover-edit-bg: rgba(79, 70, 229, 0.08);
|
|
58
|
+
--close-btn-hover-bg: #fee2e2;
|
|
59
|
+
--close-btn-hover-color: #dc2626;
|
|
40
60
|
}
|
|
41
61
|
|
|
42
62
|
[data-theme="midnight"] {
|
|
@@ -56,6 +76,16 @@
|
|
|
56
76
|
--border: rgba(99, 102, 241, 0.16);
|
|
57
77
|
--border-light: rgba(99, 102, 241, 0.26);
|
|
58
78
|
--shadow: none;
|
|
79
|
+
--status-listening: #7dd3fc;
|
|
80
|
+
--status-thinking: var(--accent);
|
|
81
|
+
--status-speaking: #22c55e;
|
|
82
|
+
--status-error: #fca5a5;
|
|
83
|
+
--hover-delete: #fca5a5;
|
|
84
|
+
--hover-delete-bg: rgba(248, 113, 113, 0.12);
|
|
85
|
+
--hover-edit: #c7d2fe;
|
|
86
|
+
--hover-edit-bg: rgba(99, 102, 241, 0.12);
|
|
87
|
+
--close-btn-hover-bg: #3a2020;
|
|
88
|
+
--close-btn-hover-color: #ff8a8a;
|
|
59
89
|
}
|
|
60
90
|
|
|
61
91
|
* {
|
|
@@ -107,7 +137,6 @@ body {
|
|
|
107
137
|
|
|
108
138
|
/* Header - Drag Region */
|
|
109
139
|
.drag-region {
|
|
110
|
-
app-region: no-drag;
|
|
111
140
|
-webkit-app-region: no-drag;
|
|
112
141
|
min-height: 34px;
|
|
113
142
|
padding: 0 8px;
|
|
@@ -124,7 +153,6 @@ body {
|
|
|
124
153
|
}
|
|
125
154
|
|
|
126
155
|
.header-content {
|
|
127
|
-
app-region: drag;
|
|
128
156
|
-webkit-app-region: drag;
|
|
129
157
|
display: flex;
|
|
130
158
|
align-items: center;
|
|
@@ -134,7 +162,6 @@ body {
|
|
|
134
162
|
}
|
|
135
163
|
|
|
136
164
|
.titlebar-drag-space {
|
|
137
|
-
app-region: drag;
|
|
138
165
|
-webkit-app-region: drag;
|
|
139
166
|
align-self: stretch;
|
|
140
167
|
min-width: 0;
|
|
@@ -165,7 +192,6 @@ h1 {
|
|
|
165
192
|
.header-actions,
|
|
166
193
|
.header-utility,
|
|
167
194
|
.window-controls {
|
|
168
|
-
app-region: no-drag;
|
|
169
195
|
-webkit-app-region: no-drag;
|
|
170
196
|
display: flex;
|
|
171
197
|
align-items: center;
|
|
@@ -197,7 +223,6 @@ h1 {
|
|
|
197
223
|
.clear-btn,
|
|
198
224
|
.settings-btn {
|
|
199
225
|
-webkit-app-region: no-drag;
|
|
200
|
-
app-region: no-drag;
|
|
201
226
|
min-width: 0;
|
|
202
227
|
height: 28px;
|
|
203
228
|
border: 1px solid transparent;
|
|
@@ -231,7 +256,6 @@ h1 {
|
|
|
231
256
|
.maximize-btn,
|
|
232
257
|
.minimize-btn {
|
|
233
258
|
-webkit-app-region: no-drag;
|
|
234
|
-
app-region: no-drag;
|
|
235
259
|
background: transparent;
|
|
236
260
|
border: none;
|
|
237
261
|
color: var(--text-muted);
|
|
@@ -1282,8 +1306,8 @@ h1 {
|
|
|
1282
1306
|
.approval-card {
|
|
1283
1307
|
align-items: stretch;
|
|
1284
1308
|
flex-direction: column;
|
|
1285
|
-
background:
|
|
1286
|
-
border-color:
|
|
1309
|
+
background: transparent;
|
|
1310
|
+
border-color: transparent;
|
|
1287
1311
|
}
|
|
1288
1312
|
|
|
1289
1313
|
.approval-card[data-tier="dangerous"] {
|
|
@@ -2190,13 +2214,13 @@ input:checked + .slider:before {
|
|
|
2190
2214
|
}
|
|
2191
2215
|
|
|
2192
2216
|
.sidebar-chat-delete:hover {
|
|
2193
|
-
color:
|
|
2194
|
-
background:
|
|
2217
|
+
color: var(--hover-delete);
|
|
2218
|
+
background: var(--hover-delete-bg);
|
|
2195
2219
|
}
|
|
2196
2220
|
|
|
2197
2221
|
.sidebar-chat-edit:hover {
|
|
2198
|
-
color:
|
|
2199
|
-
background:
|
|
2222
|
+
color: var(--hover-edit);
|
|
2223
|
+
background: var(--hover-edit-bg);
|
|
2200
2224
|
}
|
|
2201
2225
|
|
|
2202
2226
|
.sidebar-chat-rename-input {
|
|
@@ -2288,49 +2312,49 @@ input:checked + .slider:before {
|
|
|
2288
2312
|
|
|
2289
2313
|
.mint-status-pill[data-state="listening"],
|
|
2290
2314
|
.model-activity-badge[data-state="listening"] {
|
|
2291
|
-
color:
|
|
2315
|
+
color: var(--status-listening);
|
|
2292
2316
|
}
|
|
2293
2317
|
|
|
2294
2318
|
.mint-status-pill[data-state="listening"] .mint-status-dot,
|
|
2295
2319
|
.model-activity-badge[data-state="listening"] .mint-status-dot {
|
|
2296
|
-
background:
|
|
2297
|
-
box-shadow: 0 0 0 3px
|
|
2320
|
+
background: var(--status-listening);
|
|
2321
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--status-listening) 16%, transparent);
|
|
2298
2322
|
animation: mintStatusPulse 1.2s ease-in-out infinite;
|
|
2299
2323
|
}
|
|
2300
2324
|
|
|
2301
2325
|
.mint-status-pill[data-state="thinking"],
|
|
2302
2326
|
.model-activity-badge[data-state="thinking"] {
|
|
2303
|
-
color:
|
|
2327
|
+
color: var(--status-thinking);
|
|
2304
2328
|
}
|
|
2305
2329
|
|
|
2306
2330
|
.mint-status-pill[data-state="thinking"] .mint-status-dot,
|
|
2307
2331
|
.model-activity-badge[data-state="thinking"] .mint-status-dot {
|
|
2308
|
-
background: var(--
|
|
2309
|
-
box-shadow: 0 0 0 3px color-mix(in srgb, var(--
|
|
2332
|
+
background: var(--status-thinking);
|
|
2333
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--status-thinking) 20%, transparent);
|
|
2310
2334
|
animation: mintStatusPulse 1s ease-in-out infinite;
|
|
2311
2335
|
}
|
|
2312
2336
|
|
|
2313
2337
|
.mint-status-pill[data-state="speaking"],
|
|
2314
2338
|
.model-activity-badge[data-state="speaking"] {
|
|
2315
|
-
color:
|
|
2339
|
+
color: var(--status-speaking);
|
|
2316
2340
|
}
|
|
2317
2341
|
|
|
2318
2342
|
.mint-status-pill[data-state="speaking"] .mint-status-dot,
|
|
2319
2343
|
.model-activity-badge[data-state="speaking"] .mint-status-dot {
|
|
2320
|
-
background:
|
|
2321
|
-
box-shadow: 0 0 0 3px
|
|
2344
|
+
background: var(--status-speaking);
|
|
2345
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--status-speaking) 16%, transparent);
|
|
2322
2346
|
animation: mintStatusPulse 0.9s ease-in-out infinite;
|
|
2323
2347
|
}
|
|
2324
2348
|
|
|
2325
2349
|
.mint-status-pill[data-state="error"],
|
|
2326
2350
|
.model-activity-badge[data-state="error"] {
|
|
2327
|
-
color:
|
|
2351
|
+
color: var(--status-error);
|
|
2328
2352
|
}
|
|
2329
2353
|
|
|
2330
2354
|
.mint-status-pill[data-state="error"] .mint-status-dot,
|
|
2331
2355
|
.model-activity-badge[data-state="error"] .mint-status-dot {
|
|
2332
|
-
background:
|
|
2333
|
-
box-shadow: 0 0 0 3px
|
|
2356
|
+
background: var(--status-error);
|
|
2357
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--status-error) 16%, transparent);
|
|
2334
2358
|
}
|
|
2335
2359
|
|
|
2336
2360
|
@keyframes mintStatusPulse {
|
|
@@ -3319,8 +3343,8 @@ input:checked + .slider:before {
|
|
|
3319
3343
|
}
|
|
3320
3344
|
|
|
3321
3345
|
.close-btn:hover {
|
|
3322
|
-
background:
|
|
3323
|
-
color:
|
|
3346
|
+
background: var(--close-btn-hover-bg);
|
|
3347
|
+
color: var(--close-btn-hover-color);
|
|
3324
3348
|
}
|
|
3325
3349
|
|
|
3326
3350
|
.assistant-workspace.layout-horizontal {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
@import './css/settings.css';
|
|
3
3
|
@import './css/spotlight.css';
|
|
4
4
|
@import './css/widget.css';
|
|
5
|
+
@import './css/image-studio.css';
|
|
5
6
|
|
|
6
7
|
* {
|
|
7
8
|
box-sizing: border-box;
|
|
@@ -377,3 +378,108 @@ button {
|
|
|
377
378
|
text-align: center;
|
|
378
379
|
}
|
|
379
380
|
}
|
|
381
|
+
|
|
382
|
+
/* Premium Markdown Styles for Chat Messages */
|
|
383
|
+
.chat-inline-code {
|
|
384
|
+
background: rgba(16, 185, 129, 0.15);
|
|
385
|
+
border: 1px solid rgba(16, 185, 129, 0.25);
|
|
386
|
+
color: #34d399;
|
|
387
|
+
padding: 2px 6px;
|
|
388
|
+
border-radius: 6px;
|
|
389
|
+
font-family: 'Fira Code', 'Courier New', Courier, monospace;
|
|
390
|
+
font-size: 0.88em;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.chat-code-block-container {
|
|
394
|
+
display: flex;
|
|
395
|
+
flex-direction: column;
|
|
396
|
+
background: var(--input-bg, #0f172a);
|
|
397
|
+
border: 1px solid var(--border);
|
|
398
|
+
border-radius: 8px;
|
|
399
|
+
margin: 12px 0;
|
|
400
|
+
overflow: hidden;
|
|
401
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.chat-code-block-header {
|
|
405
|
+
display: flex;
|
|
406
|
+
align-items: center;
|
|
407
|
+
justify-content: space-between;
|
|
408
|
+
background: var(--surface-bg, #1e293b);
|
|
409
|
+
padding: 8px 14px;
|
|
410
|
+
border-bottom: 1px solid var(--border);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.chat-code-block-lang {
|
|
414
|
+
color: var(--accent);
|
|
415
|
+
font-size: 0.78rem;
|
|
416
|
+
font-weight: 650;
|
|
417
|
+
text-transform: capitalize;
|
|
418
|
+
font-family: ui-sans-serif, system-ui, sans-serif;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.chat-code-block-actions {
|
|
422
|
+
display: flex;
|
|
423
|
+
gap: 10px;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
.chat-code-action-btn {
|
|
427
|
+
background: transparent;
|
|
428
|
+
border: none;
|
|
429
|
+
color: var(--text-soft, #94a3b8);
|
|
430
|
+
cursor: pointer;
|
|
431
|
+
padding: 4px;
|
|
432
|
+
border-radius: 4px;
|
|
433
|
+
display: flex;
|
|
434
|
+
align-items: center;
|
|
435
|
+
justify-content: center;
|
|
436
|
+
transition: all 0.2s ease;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.chat-code-action-btn:hover {
|
|
440
|
+
background: rgba(255, 255, 255, 0.05);
|
|
441
|
+
color: var(--accent-hover, #34d399);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
.chat-code-block-body {
|
|
445
|
+
margin: 0;
|
|
446
|
+
padding: 14px;
|
|
447
|
+
overflow-x: auto;
|
|
448
|
+
background: var(--input-bg, #0f172a);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
.chat-code-block-body code {
|
|
452
|
+
font-family: 'Fira Code', 'Courier New', Courier, monospace;
|
|
453
|
+
font-size: 0.88rem;
|
|
454
|
+
color: var(--text-main, #e2e8f0);
|
|
455
|
+
line-height: 1.5;
|
|
456
|
+
white-space: pre;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.chat-ordered-list,
|
|
460
|
+
.chat-unordered-list {
|
|
461
|
+
margin: 8px 0;
|
|
462
|
+
padding-left: 24px;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
.chat-ordered-list {
|
|
466
|
+
list-style-type: decimal;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.chat-unordered-list {
|
|
470
|
+
list-style-type: disc;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.chat-bold-highlight {
|
|
474
|
+
color: var(--accent) !important;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
.chat-inline-code {
|
|
478
|
+
background: color-mix(in srgb, var(--accent) 12%, transparent);
|
|
479
|
+
border: 1px solid color-mix(in srgb, var(--accent) 24%, transparent);
|
|
480
|
+
color: var(--accent);
|
|
481
|
+
padding: 2px 6px;
|
|
482
|
+
border-radius: 4px;
|
|
483
|
+
font-family: 'Fira Code', 'Courier New', Courier, monospace;
|
|
484
|
+
font-size: 0.9em;
|
|
485
|
+
}
|
|
@@ -66,6 +66,30 @@ export interface PictureEntry {
|
|
|
66
66
|
thumbnailUrl?: string
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
export interface ImageGenRequest {
|
|
70
|
+
prompt: string
|
|
71
|
+
negativePrompt?: string
|
|
72
|
+
aspectRatio?: '1:1' | '16:9' | '9:16' | '4:3'
|
|
73
|
+
numImages?: number
|
|
74
|
+
model?: string
|
|
75
|
+
/** Which image generation provider to use. Falls back to config default when omitted. */
|
|
76
|
+
provider?: string
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface ImageGenProviders {
|
|
80
|
+
active: string
|
|
81
|
+
available: string[]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface ImageGenResponse {
|
|
85
|
+
images: PictureEntry[]
|
|
86
|
+
model: string
|
|
87
|
+
provider: string
|
|
88
|
+
prompt: string
|
|
89
|
+
description?: string | null
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
69
93
|
export interface CodeEdit {
|
|
70
94
|
path: string
|
|
71
95
|
content: string
|
|
@@ -404,6 +428,106 @@ export async function listSavedPictures(): Promise<PictureEntry[]> {
|
|
|
404
428
|
return invoke<PictureEntry[]>('list_pictures')
|
|
405
429
|
}
|
|
406
430
|
|
|
431
|
+
export async function generateImages(
|
|
432
|
+
request: ImageGenRequest
|
|
433
|
+
): Promise<ImageGenResponse> {
|
|
434
|
+
if (typeof window === 'undefined' || !isTauriRuntime()) {
|
|
435
|
+
const API_BASE = getApiBase()
|
|
436
|
+
const res = await fetch(`${API_BASE}/image-generate`, {
|
|
437
|
+
method: 'POST',
|
|
438
|
+
headers: { 'Content-Type': 'application/json' },
|
|
439
|
+
body: JSON.stringify({
|
|
440
|
+
prompt: request.prompt,
|
|
441
|
+
negativePrompt: request.negativePrompt,
|
|
442
|
+
aspectRatio: request.aspectRatio ?? '1:1',
|
|
443
|
+
numImages: request.numImages ?? 1,
|
|
444
|
+
model: request.model,
|
|
445
|
+
provider: request.provider,
|
|
446
|
+
}),
|
|
447
|
+
})
|
|
448
|
+
if (!res.ok) {
|
|
449
|
+
const err = await res.json().catch(() => null)
|
|
450
|
+
throw new Error(err?.error || `Image generation failed: HTTP ${res.status}`)
|
|
451
|
+
}
|
|
452
|
+
const data = await res.json()
|
|
453
|
+
// Normalize image URLs for web mode
|
|
454
|
+
const images: PictureEntry[] = Array.isArray(data.images)
|
|
455
|
+
? data.images.map((pic: PictureEntry) => {
|
|
456
|
+
const pictureUrl = pic.url ? `${API_BASE.replace('/api', '')}${pic.url}` : pic.url
|
|
457
|
+
return { ...pic, url: pictureUrl, thumbnailUrl: pictureUrl }
|
|
458
|
+
})
|
|
459
|
+
: []
|
|
460
|
+
return { ...data, images }
|
|
461
|
+
}
|
|
462
|
+
// Desktop / Tauri mode
|
|
463
|
+
const { invoke } = await import('@tauri-apps/api/core')
|
|
464
|
+
return invoke<ImageGenResponse>('generate_images', { request })
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/** Fetch which image-generation providers are currently configured on the backend. */
|
|
468
|
+
export async function getImageGenProviders(): Promise<ImageGenProviders> {
|
|
469
|
+
if (typeof window === 'undefined' || !isTauriRuntime()) {
|
|
470
|
+
const API_BASE = getApiBase()
|
|
471
|
+
try {
|
|
472
|
+
const res = await fetch(`${API_BASE}/image-gen/providers`)
|
|
473
|
+
if (res.ok) return await res.json()
|
|
474
|
+
} catch (_) { /* ignore */ }
|
|
475
|
+
return { active: 'nanobanana', available: ['nanobanana'] }
|
|
476
|
+
}
|
|
477
|
+
// Desktop / Tauri: read config to know which keys are set
|
|
478
|
+
try {
|
|
479
|
+
const { invoke } = await import('@tauri-apps/api/core')
|
|
480
|
+
const config = await invoke<Record<string, string>>('get_config')
|
|
481
|
+
const available: string[] = []
|
|
482
|
+
if (config.api_key) available.push('nanobanana')
|
|
483
|
+
if (config.openai_api_key) available.push('dalle')
|
|
484
|
+
if (config.stability_api_key) available.push('stability')
|
|
485
|
+
if (config.ideogram_api_key) available.push('ideogram')
|
|
486
|
+
if (config.replicate_api_key) available.push('replicate')
|
|
487
|
+
if (available.length === 0) available.push('nanobanana')
|
|
488
|
+
const active = available.includes(config.image_gen_provider)
|
|
489
|
+
? config.image_gen_provider
|
|
490
|
+
: available[0]
|
|
491
|
+
return { active, available }
|
|
492
|
+
} catch (_) {
|
|
493
|
+
return { active: 'nanobanana', available: ['nanobanana'] }
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/** Updates the default image generation provider in the configuration. */
|
|
498
|
+
export async function setDefaultImageProvider(provider: string): Promise<boolean> {
|
|
499
|
+
if (typeof window === 'undefined' || !isTauriRuntime()) {
|
|
500
|
+
const API_BASE = getApiBase()
|
|
501
|
+
try {
|
|
502
|
+
const getRes = await fetch(`${API_BASE}/config`)
|
|
503
|
+
if (!getRes.ok) return false
|
|
504
|
+
const config = await getRes.json()
|
|
505
|
+
config.image_gen_provider = provider
|
|
506
|
+
const saveRes = await fetch(`${API_BASE}/config`, {
|
|
507
|
+
method: 'POST',
|
|
508
|
+
headers: { 'Content-Type': 'application/json' },
|
|
509
|
+
body: JSON.stringify(config)
|
|
510
|
+
})
|
|
511
|
+
return saveRes.ok
|
|
512
|
+
} catch (_) {
|
|
513
|
+
return false
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Desktop / Tauri
|
|
518
|
+
try {
|
|
519
|
+
const { invoke } = await import('@tauri-apps/api/core')
|
|
520
|
+
const config = await invoke<any>('get_config')
|
|
521
|
+
config.image_gen_provider = provider
|
|
522
|
+
await invoke('update_config', { config })
|
|
523
|
+
return true
|
|
524
|
+
} catch (_) {
|
|
525
|
+
return false
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
|
|
407
531
|
export async function submitToolApproval(token: string, approved: boolean): Promise<void> {
|
|
408
532
|
if (typeof window === 'undefined' || !isTauriRuntime()) {
|
|
409
533
|
return;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "mint-desktop"
|
|
3
|
+
version.workspace = true
|
|
4
|
+
edition.workspace = true
|
|
5
|
+
license.workspace = true
|
|
6
|
+
|
|
7
|
+
[lib]
|
|
8
|
+
name = "mint_desktop_lib"
|
|
9
|
+
crate-type = ["staticlib", "cdylib", "rlib"]
|
|
10
|
+
|
|
11
|
+
[build-dependencies]
|
|
12
|
+
tauri-build = { version = "2", features = [] }
|
|
13
|
+
|
|
14
|
+
[dependencies]
|
|
15
|
+
base64.workspace = true
|
|
16
|
+
dirs.workspace = true
|
|
17
|
+
futures-util.workspace = true
|
|
18
|
+
hmac.workspace = true
|
|
19
|
+
image.workspace = true
|
|
20
|
+
mint-core = { path = "../crates/mint-core" }
|
|
21
|
+
reqwest.workspace = true
|
|
22
|
+
serde.workspace = true
|
|
23
|
+
serde_json.workspace = true
|
|
24
|
+
sha2.workspace = true
|
|
25
|
+
tauri = { version = "2", features = ["protocol-asset", "tray-icon"] }
|
|
26
|
+
tauri-plugin-global-shortcut = "2"
|
|
27
|
+
tauri-plugin-updater = "2"
|
|
28
|
+
tokio.workspace = true
|
|
29
|
+
tokio-tungstenite.workspace = true
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../gen/schemas/desktop-schema.json",
|
|
3
|
+
"identifier": "main",
|
|
4
|
+
"description": "Capabilities for Mint desktop windows managed by the Rust backend.",
|
|
5
|
+
"windows": ["main", "settings", "spotlight", "widget", "screen-picker"],
|
|
6
|
+
"permissions": ["core:default"]
|
|
7
|
+
}
|