@pheem49/mint 1.8.0 → 1.8.2
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/release.yml +1 -1
- package/Cargo.lock +34 -3
- package/Cargo.toml +2 -2
- package/README.md +20 -6
- package/Release_Note.md +129 -0
- package/assets/Mint_CLI.png +0 -0
- package/bin/mint +0 -0
- package/crates/mint-cli/Cargo.toml +1 -0
- package/crates/mint-cli/src/agent.rs +242 -54
- package/crates/mint-cli/src/main.rs +397 -74
- package/crates/mint-core/src/agent_loop.rs +1 -0
- package/crates/mint-core/src/api_server.rs +64 -2
- package/crates/mint-core/src/browser.rs +456 -0
- package/crates/mint-core/src/channels.rs +1 -0
- package/crates/mint-core/src/chat.rs +3 -0
- package/crates/mint-core/src/config.rs +130 -1
- package/crates/mint-core/src/lib.rs +19 -0
- package/crates/mint-core/src/orchestration.rs +317 -12
- package/crates/mint-core/src/skills.rs +113 -4
- package/crates/mint-core/src/tts.rs +3 -1
- package/crates/mint-core/src/workflows.rs +1 -22
- package/flatpak/com.pheem49.mint.desktop +9 -0
- package/flatpak/com.pheem49.mint.metainfo.xml +35 -0
- package/flatpak/com.pheem49.mint.yaml +52 -0
- package/package.json +1 -1
- package/shared-modules/.github/workflows/ci.yml +120 -0
- package/shared-modules/.github/workflows/update.yaml +28 -0
- package/shared-modules/CODEOWNERS +23 -0
- package/shared-modules/README.md +79 -0
- package/shared-modules/SDL/README.md +3 -0
- package/shared-modules/SDL/SDL-1.2.15.json +51 -0
- package/shared-modules/SDL/SDL_Pango-0.1.2-API-adds.patch +118 -0
- package/shared-modules/SDL/SDL_image-1.2.12.json +25 -0
- package/shared-modules/SDL/SDL_mixer-1.2.12.json +27 -0
- package/shared-modules/SDL/SDL_net-1.2.8.json +19 -0
- package/shared-modules/SDL/SDL_pango-0.1.2.json +26 -0
- package/shared-modules/SDL/SDL_ttf-2.0.11.json +28 -0
- package/shared-modules/SDL/libsdl-1.2.15-strict-prototypes.patch +316 -0
- package/shared-modules/SDL/sdl-check-for-SDL_VIDEO_X11_BACKINGSTORE.patch +24 -0
- package/shared-modules/SDL/sdl-libx11-build.patch +59 -0
- package/shared-modules/SDL/sdl-sysloadso-buffer-length.patch +27 -0
- package/shared-modules/SDL/sdl12-compat.json +22 -0
- package/shared-modules/SDL2/SDL2_image.json +27 -0
- package/shared-modules/SDL2/SDL2_ttf.json +29 -0
- package/shared-modules/cld2/CMakeLists.txt +157 -0
- package/shared-modules/cld2/cld2.json +24 -0
- package/shared-modules/clutter/clutter.json +72 -0
- package/shared-modules/dbus-glib/dbus-glib.json +29 -0
- package/shared-modules/glew/glew.json +36 -0
- package/shared-modules/glu/glu-9.json +12 -0
- package/shared-modules/gtk2/arc-gtk2-theme-Replace-Inkscape-dependency-with-rsvg-convert.patch +180 -0
- package/shared-modules/gtk2/gtk2-common-themes.json +360 -0
- package/shared-modules/gtk2/gtk2-fix-crash-in-show-uri.patch +30 -0
- package/shared-modules/gtk2/gtk2-gcc14.patch +281 -0
- package/shared-modules/gtk2/gtk2-gcc15.patch +250 -0
- package/shared-modules/gtk2/gtk2-murrine-c99.patch +34 -0
- package/shared-modules/gtk2/gtk2-use-adwaita-theme.patch +80 -0
- package/shared-modules/gtk2/gtk2.json +120 -0
- package/shared-modules/gtk2/ibus-gcc15.patch +13 -0
- package/shared-modules/gtk2/murrine-engine-fix-crash.patch +12 -0
- package/shared-modules/gtk2/readme.md +10 -0
- package/shared-modules/intltool/intltool-0.51.json +20 -0
- package/shared-modules/intltool/intltool-perl5.26-regex-fixes.patch +59 -0
- package/shared-modules/lame/0001-Build-xmm_quantize_sub.c-with-msse.patch +34 -0
- package/shared-modules/lame/0002-Include-GTK-1-autoconf-directives-in-build-system.patch +222 -0
- package/shared-modules/lame/0003-Patch-out-remaining-ansi2knr.patch +70 -0
- package/shared-modules/lame/0004-initscr-is-not-used-anywhere-in-lame-sourcetree.patch +41 -0
- package/shared-modules/lame/0005-Update-autoconf.patch +81 -0
- package/shared-modules/lame/lame-3.99.5.json +32 -0
- package/shared-modules/libappindicator/libappindicator-gtk2-12.10.json +140 -0
- package/shared-modules/libappindicator/libappindicator-gtk3-12.10.json +140 -0
- package/shared-modules/libappindicator/libappindicator-gtk3-introspection-12.10.json +140 -0
- package/shared-modules/libappindicator/patches/0001-libappindicator-ftbfs.patch +20 -0
- package/shared-modules/libappindicator/patches/0002-libappindicator-no-python.patch +888 -0
- package/shared-modules/libappindicator/patches/0003-libappindicator-fix-crash-from-incorrect-signal-emission.patch +74 -0
- package/shared-modules/libappindicator/patches/0004-libappindicator-fix-crash-iterating-icon-themes.patch +11 -0
- package/shared-modules/libayatana-appindicator/0001-Fix-HAVE_VALGRIND-AM_CONDITIONAL.patch +51 -0
- package/shared-modules/libayatana-appindicator/0001-Make-introspection-configurable.patch +44 -0
- package/shared-modules/libayatana-appindicator/libayatana-appindicator-gtk3.json +121 -0
- package/shared-modules/libcanberra/0001-gtk-Don-t-assume-all-GdkDisplays-are-GdkX11Displays-.patch +123 -0
- package/shared-modules/libcanberra/libcanberra.json +44 -0
- package/shared-modules/libmad/libmad.json +19 -0
- package/shared-modules/libsecret/libsecret.json +23 -0
- package/shared-modules/libsoup/libsoup-2.4.json +14 -0
- package/shared-modules/libusb/libusb.json +27 -0
- package/shared-modules/linux-audio/dssi.json +31 -0
- package/shared-modules/linux-audio/fftw3f-static.json +44 -0
- package/shared-modules/linux-audio/fftw3f.json +42 -0
- package/shared-modules/linux-audio/fluidsynth2-static.json +30 -0
- package/shared-modules/linux-audio/fluidsynth2.json +19 -0
- package/shared-modules/linux-audio/ladspa.json +26 -0
- package/shared-modules/linux-audio/lash.json +35 -0
- package/shared-modules/linux-audio/libinstpatch.json +16 -0
- package/shared-modules/linux-audio/liblo-static.json +22 -0
- package/shared-modules/linux-audio/liblo.json +17 -0
- package/shared-modules/linux-audio/lilv-static.json +94 -0
- package/shared-modules/linux-audio/lilv.json +82 -0
- package/shared-modules/linux-audio/lrdf.json +57 -0
- package/shared-modules/linux-audio/lv2.json +21 -0
- package/shared-modules/linux-audio/patches/lash/0001-configure-remove-aclocal-m4.patch +29 -0
- package/shared-modules/linux-audio/patches/lash/0002-Fix-build-with-recent-gcc.patch +73 -0
- package/shared-modules/linux-audio/patches/lash/0003-Fix-linking.patch +136 -0
- package/shared-modules/linux-audio/patches/raptor-libxml.patch +31 -0
- package/shared-modules/linux-audio/patches/stk-install.sh +54 -0
- package/shared-modules/linux-audio/stk.json +28 -0
- package/shared-modules/lua5.1/0004-Fix-stack-overflow-in-vararg-functions.patch +21 -0
- package/shared-modules/lua5.1/lua-5.1.5-so.patch +43 -0
- package/shared-modules/lua5.1/lua-5.1.5.json +42 -0
- package/shared-modules/lua5.3/lua-5.3.5.json +41 -0
- package/shared-modules/lua5.3/lua.pc.in +8 -0
- package/shared-modules/lua5.3/luaconf.patch +47 -0
- package/shared-modules/lua5.3/makefile-add-liblua.so-rule.patch +47 -0
- package/shared-modules/lua5.4/lua-5.4.json +41 -0
- package/shared-modules/lua5.4/lua.pc.in +8 -0
- package/shared-modules/lua5.4/luaconf.patch +34 -0
- package/shared-modules/lua5.4/makefile-add-liblua.so-rule.patch +42 -0
- package/shared-modules/luajit/luajit.json +30 -0
- package/shared-modules/lzo/lzo.json +27 -0
- package/shared-modules/mac/mac.json +18 -0
- package/shared-modules/physfs/physfs.json +26 -0
- package/shared-modules/pygame/audiofile-gcc6.patch +21 -0
- package/shared-modules/pygame/cython-fixes.patch +34 -0
- package/shared-modules/pygame/fluidsynth-no-rawmidi.patch +69 -0
- package/shared-modules/pygame/glib.patch +25 -0
- package/shared-modules/pygame/pygame1-python2.json +157 -0
- package/shared-modules/pygtk/pygtk-c99.patch +15 -0
- package/shared-modules/pygtk/pygtk.json +117 -0
- package/shared-modules/pygtk/pygtk.patch +39 -0
- package/shared-modules/python2.7/python-2.7.json +48 -0
- package/shared-modules/smpeg/smpeg-0.4.5.json +50 -0
- package/shared-modules/smpeg/smpeg-am-prog-as.patch +12 -0
- package/shared-modules/smpeg/smpeg-export-mpegaudio-class.patch +17 -0
- package/shared-modules/smpeg/smpeg-gcc6.patch +40 -0
- package/shared-modules/smpeg/smpeg-no-gtk.patch +37 -0
- package/shared-modules/squashfs-tools/squashfs-tools.json +25 -0
- package/shared-modules/update-checker.sh +50 -0
- package/shared-modules/vorbisgain/0001-temp_files.patch +75 -0
- package/shared-modules/vorbisgain/0002-errno.patch +33 -0
- package/shared-modules/vorbisgain/0003-manpage.patch +248 -0
- package/shared-modules/vorbisgain/0004-vorbisgain_mtime.patch +183 -0
- package/shared-modules/vorbisgain/0005-double_fclose.patch +21 -0
- package/shared-modules/vorbisgain/0006-manpage_hyphens.patch +56 -0
- package/shared-modules/vorbisgain/0007-recursively_spelling.patch +14 -0
- package/shared-modules/vorbisgain/0008-manpage_recursion_mistake.patch +23 -0
- package/shared-modules/vorbisgain/0009-hardening.patch +13 -0
- package/shared-modules/vorbisgain/0010-fclose.patch +13 -0
- package/shared-modules/vorbisgain/README.md +23 -0
- package/shared-modules/vorbisgain/vorbisgain_0.37-2.json +29 -0
- package/src/renderer/shared/agentProgress.ts +145 -0
- package/src/renderer/shared/calculator.ts +52 -0
- package/src/renderer/shared/components/AgentActivityDrawer.tsx +72 -0
- package/src/renderer/shared/components/AgentActivityTable.tsx +66 -0
- package/src/renderer/shared/components/ApprovalCard.tsx +93 -0
- package/src/renderer/shared/components/ChatCodeBlock.tsx +75 -0
- package/src/renderer/shared/components/ThinkingBlock.tsx +101 -0
- package/src/renderer/shared/constants/models.ts +91 -0
- package/src/renderer/shared/platform.ts +82 -0
- package/src/renderer/shared/types.ts +140 -0
- package/src/renderer/shared/utils/agentActivity.ts +187 -0
- package/src/renderer/shared/utils/approval.ts +1 -0
- package/src/renderer/shared/utils/approval.tsx +64 -0
- package/src/renderer/shared/utils/markdown.tsx +347 -0
- package/src/renderer/shared/utils/providers.ts +36 -0
- package/src/renderer/shared/utils/speech.ts +216 -0
- package/src/renderer/shared/utils/ui.ts +147 -0
- package/src/renderer/src/agentProgress.ts +11 -39
- package/src/renderer/src/calculator.ts +3 -46
- package/src/renderer/src/components/ChatPanel.tsx +230 -1202
- package/src/renderer/src/components/ImageStudioPanel.tsx +11 -1
- package/src/renderer/src/components/MintDashboard.tsx +63 -171
- package/src/renderer/src/components/PicturesLibrary.tsx +32 -8
- package/src/renderer/src/components/Settings/AgentsTab.tsx +362 -0
- package/src/renderer/src/components/Settings/AutomationTab.tsx +0 -22
- package/src/renderer/src/components/Settings/PluginsTab.tsx +221 -41
- package/src/renderer/src/components/SettingsWindow.tsx +54 -12
- package/src/renderer/src/components/WorkspacePanel.tsx +66 -9
- package/src/renderer/src/css/image-studio.css +6 -0
- package/src/renderer/src/css/styles.css +148 -11
- package/src/renderer/src/index.css +12 -1
- package/src/renderer/src/tauri.ts +169 -143
- package/src/renderer/src-web/agentProgress.ts +11 -39
- package/src/renderer/src-web/calculator.ts +3 -46
- package/src/renderer/src-web/components/ChatPanel.tsx +223 -1199
- package/src/renderer/src-web/components/ImageStudioPanel.tsx +11 -1
- package/src/renderer/src-web/components/MintDashboard.tsx +31 -172
- package/src/renderer/src-web/components/PicturesLibrary.tsx +23 -29
- package/src/renderer/src-web/components/Settings/AgentsTab.tsx +362 -0
- package/src/renderer/src-web/components/Settings/AutomationTab.tsx +0 -22
- package/src/renderer/src-web/components/Settings/PluginsTab.tsx +221 -41
- package/src/renderer/src-web/components/SettingsWindow.tsx +54 -12
- package/src/renderer/src-web/css/image-studio.css +6 -0
- package/src/renderer/src-web/css/styles.css +184 -12
- package/src/renderer/src-web/index.css +12 -1
- package/src/renderer/src-web/tauri.ts +204 -104
- package/src-tauri/src/browser.rs +1 -141
- package/src-tauri/src/headless.rs +3 -2
- package/src-tauri/src/lib.rs +254 -59
- package/src-tauri/src/webhooks.rs +1 -0
- package/src-tauri/src/workflows.rs +57 -4
- package/src-tauri/tauri.conf.json +1 -1
|
@@ -1,115 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
activeProvider: string
|
|
5
|
-
availableProviders: string[]
|
|
6
|
-
integrations: Record<string, unknown>
|
|
7
|
-
}
|
|
1
|
+
/** Returns true when running inside the Tauri webview (desktop app). */
|
|
2
|
+
export const isTauriRuntime = (): boolean =>
|
|
3
|
+
typeof window !== 'undefined' && Boolean((window as any).__TAURI_INTERNALS__)
|
|
8
4
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Returns the local API base URL.
|
|
7
|
+
* Uses the current hostname so LAN access (e.g. from another device) works correctly.
|
|
8
|
+
* Mirrors the same helper in src-web/tauri.ts.
|
|
9
|
+
*/
|
|
10
|
+
export const getLocalApiBase = (): string => {
|
|
11
|
+
const host = typeof window !== 'undefined' ? window.location.hostname : 'localhost'
|
|
12
|
+
return `http://${host}:3000/api`
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
15
|
+
export * from '../shared/types'
|
|
16
|
+
import type { MintPlatformApi } from '../shared/platform'
|
|
17
|
+
import type {
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
RuntimeStatus,
|
|
20
|
+
ChatResponse,
|
|
21
|
+
TtsUrl,
|
|
22
|
+
DocumentAttachment,
|
|
23
|
+
AgentProgress,
|
|
24
|
+
InteractionMemory,
|
|
25
|
+
ChatSession,
|
|
26
|
+
PictureEntry,
|
|
27
|
+
ImageGenRequest,
|
|
28
|
+
ImageGenProviders,
|
|
29
|
+
ImageGenResponse,
|
|
30
|
+
WorkspaceTreeEntry,
|
|
31
|
+
CodeEdit,
|
|
32
|
+
CodeEditProposal,
|
|
33
|
+
} from '../shared/types'
|
|
25
34
|
|
|
26
|
-
export type AgentProgress =
|
|
27
|
-
| { type: 'Thinking'; data: { elapsed_secs: number } }
|
|
28
|
-
| { type: 'Thought'; data: { thought: string } }
|
|
29
|
-
| { type: 'ToolStart'; data: { action: string; input: Record<string, unknown> } }
|
|
30
|
-
| { type: 'ToolEnd'; data: { action: string; input: Record<string, unknown>; result: string } }
|
|
31
35
|
|
|
32
36
|
type DesktopStreamEvent =
|
|
33
37
|
| { type: 'chunk'; chunk: string }
|
|
34
38
|
| { type: 'progress'; progress: AgentProgress }
|
|
35
39
|
|
|
36
|
-
export interface InteractionMemory {
|
|
37
|
-
id: number
|
|
38
|
-
chatId: string
|
|
39
|
-
userText: string
|
|
40
|
-
aiText: string
|
|
41
|
-
provider: string
|
|
42
|
-
model: string
|
|
43
|
-
fallbackProvider?: string | null
|
|
44
|
-
createdAt: string
|
|
45
|
-
agentActivity?: AgentProgress[] | null
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface ChatSession {
|
|
49
|
-
id: string
|
|
50
|
-
title: string
|
|
51
|
-
kind: string
|
|
52
|
-
createdAt: string
|
|
53
|
-
updatedAt: string
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface PictureEntry {
|
|
57
|
-
id: string
|
|
58
|
-
filename: string
|
|
59
|
-
path: string
|
|
60
|
-
mimeType: string
|
|
61
|
-
createdAt: string
|
|
62
|
-
source: string
|
|
63
|
-
message: string
|
|
64
|
-
thumbnailPath?: string
|
|
65
|
-
url?: string
|
|
66
|
-
thumbnailUrl?: string
|
|
67
|
-
}
|
|
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
|
-
export interface WorkspaceTreeEntry {
|
|
93
|
-
name: string
|
|
94
|
-
path: string
|
|
95
|
-
kind: 'file' | 'directory'
|
|
96
|
-
children: WorkspaceTreeEntry[]
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export interface CodeEdit {
|
|
100
|
-
path: string
|
|
101
|
-
content: string
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export interface CodeEditProposal {
|
|
105
|
-
approvalRequired: boolean
|
|
106
|
-
approvalToken: string
|
|
107
|
-
edits: Array<{ path: string; existed: boolean; diff: string }>
|
|
108
|
-
}
|
|
109
40
|
|
|
110
41
|
export async function getRuntimeStatus(): Promise<RuntimeStatus> {
|
|
111
|
-
if (
|
|
112
|
-
const API_BASE =
|
|
42
|
+
if (!isTauriRuntime()) {
|
|
43
|
+
const API_BASE = getLocalApiBase();
|
|
113
44
|
try {
|
|
114
45
|
const res = await fetch(`${API_BASE}/status`);
|
|
115
46
|
return await res.json();
|
|
@@ -128,6 +59,28 @@ export async function getRuntimeStatus(): Promise<RuntimeStatus> {
|
|
|
128
59
|
return invoke<RuntimeStatus>('get_runtime_status')
|
|
129
60
|
}
|
|
130
61
|
|
|
62
|
+
export interface DetectedTools {
|
|
63
|
+
docker: boolean
|
|
64
|
+
git: boolean
|
|
65
|
+
gh: boolean
|
|
66
|
+
node: boolean
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export async function detectSystemTools(): Promise<DetectedTools> {
|
|
70
|
+
if (!isTauriRuntime()) {
|
|
71
|
+
const API_BASE = getLocalApiBase();
|
|
72
|
+
try {
|
|
73
|
+
const res = await fetch(`${API_BASE}/detect-tools`);
|
|
74
|
+
return await res.json();
|
|
75
|
+
} catch (e) {
|
|
76
|
+
console.error("Failed to detect tools from local server:", e);
|
|
77
|
+
return { docker: false, git: false, gh: false, node: false };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const { invoke } = await import('@tauri-apps/api/core')
|
|
81
|
+
return invoke<DetectedTools>('detect_system_tools')
|
|
82
|
+
}
|
|
83
|
+
|
|
131
84
|
export async function sendChatMessage(
|
|
132
85
|
message: string,
|
|
133
86
|
imageDataUri?: string | null,
|
|
@@ -135,15 +88,16 @@ export async function sendChatMessage(
|
|
|
135
88
|
documentAttachment?: DocumentAttachment | null,
|
|
136
89
|
workspacePath?: string | null,
|
|
137
90
|
chatId?: string | null,
|
|
91
|
+
agentId?: string | null,
|
|
138
92
|
): Promise<ChatResponse> {
|
|
139
93
|
const outgoingMessage = withImagePlaceholder(message, imageDataUri)
|
|
140
|
-
if (
|
|
141
|
-
const API_BASE =
|
|
94
|
+
if (!isTauriRuntime()) {
|
|
95
|
+
const API_BASE = getLocalApiBase();
|
|
142
96
|
try {
|
|
143
97
|
const res = await fetch(`${API_BASE}/chat`, {
|
|
144
98
|
method: 'POST',
|
|
145
99
|
headers: { 'Content-Type': 'application/json' },
|
|
146
|
-
body: JSON.stringify({ message: outgoingMessage, systemInstruction: '', chatId, imageDataUri, audioDataUri, documentAttachment })
|
|
100
|
+
body: JSON.stringify({ message: outgoingMessage, systemInstruction: '', chatId, imageDataUri, audioDataUri, documentAttachment, agentId })
|
|
147
101
|
});
|
|
148
102
|
const data = await res.json().catch(() => null);
|
|
149
103
|
if (!res.ok) {
|
|
@@ -164,7 +118,7 @@ export async function sendChatMessage(
|
|
|
164
118
|
}
|
|
165
119
|
const { invoke } = await import('@tauri-apps/api/core')
|
|
166
120
|
const response = await invoke<ChatResponse>('send_chat_message', {
|
|
167
|
-
request: { message: outgoingMessage, systemInstruction: '', chatId, imageDataUri, audioDataUri, documentAttachment, workspacePath },
|
|
121
|
+
request: { message: outgoingMessage, systemInstruction: '', chatId, imageDataUri, audioDataUri, documentAttachment, workspacePath, agentId },
|
|
168
122
|
})
|
|
169
123
|
if (imageDataUri) {
|
|
170
124
|
await invoke('save_pictures', {
|
|
@@ -186,14 +140,15 @@ export async function streamChatMessage(
|
|
|
186
140
|
documentAttachment?: DocumentAttachment | null,
|
|
187
141
|
workspacePath?: string | null,
|
|
188
142
|
chatId?: string | null,
|
|
143
|
+
agentId?: string | null,
|
|
189
144
|
): Promise<ChatResponse> {
|
|
190
|
-
if (
|
|
191
|
-
const API_BASE =
|
|
145
|
+
if (!isTauriRuntime()) {
|
|
146
|
+
const API_BASE = getLocalApiBase();
|
|
192
147
|
const outgoingMessage = withImagePlaceholder(message, imageDataUri);
|
|
193
148
|
const res = await fetch(`${API_BASE}/chat-stream`, {
|
|
194
149
|
method: 'POST',
|
|
195
150
|
headers: { 'Content-Type': 'application/json' },
|
|
196
|
-
body: JSON.stringify({ message: outgoingMessage, systemInstruction, chatId, imageDataUri, audioDataUri, documentAttachment })
|
|
151
|
+
body: JSON.stringify({ message: outgoingMessage, systemInstruction, chatId, imageDataUri, audioDataUri, documentAttachment, agentId })
|
|
197
152
|
});
|
|
198
153
|
if (!res.ok) {
|
|
199
154
|
const data = await res.json().catch(() => null);
|
|
@@ -239,7 +194,7 @@ export async function streamChatMessage(
|
|
|
239
194
|
else onProgress?.(event.progress)
|
|
240
195
|
}
|
|
241
196
|
const response = await invoke<ChatResponse>('stream_chat_message', {
|
|
242
|
-
request: { message: outgoingMessage, systemInstruction, chatId, imageDataUri, audioDataUri, documentAttachment, workspacePath },
|
|
197
|
+
request: { message: outgoingMessage, systemInstruction, chatId, imageDataUri, audioDataUri, documentAttachment, workspacePath, agentId },
|
|
243
198
|
onEvent,
|
|
244
199
|
})
|
|
245
200
|
if (imageDataUri) {
|
|
@@ -265,9 +220,23 @@ export async function getTtsUrls(text: string): Promise<TtsUrl[]> {
|
|
|
265
220
|
return invoke<TtsUrl[]>('get_tts_urls', { text })
|
|
266
221
|
}
|
|
267
222
|
|
|
223
|
+
export async function cancelChatMessage(chatId: string): Promise<void> {
|
|
224
|
+
if (!isTauriRuntime()) {
|
|
225
|
+
const API_BASE = getLocalApiBase();
|
|
226
|
+
await fetch(`${API_BASE}/cancel-chat`, {
|
|
227
|
+
method: 'POST',
|
|
228
|
+
headers: { 'Content-Type': 'application/json' },
|
|
229
|
+
body: JSON.stringify({ chatId })
|
|
230
|
+
});
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const { invoke } = await import('@tauri-apps/api/core')
|
|
234
|
+
await invoke('cancel_chat_message', { chatId })
|
|
235
|
+
}
|
|
236
|
+
|
|
268
237
|
export async function getRecentInteractions(limit = 50, chatId?: string | null): Promise<InteractionMemory[]> {
|
|
269
|
-
if (
|
|
270
|
-
const API_BASE =
|
|
238
|
+
if (!isTauriRuntime()) {
|
|
239
|
+
const API_BASE = getLocalApiBase();
|
|
271
240
|
try {
|
|
272
241
|
const params = new URLSearchParams({ limit: String(limit) });
|
|
273
242
|
if (chatId) params.set('chatId', chatId);
|
|
@@ -288,8 +257,8 @@ export async function saveSystemInteraction(
|
|
|
288
257
|
provider: string,
|
|
289
258
|
model: string,
|
|
290
259
|
): Promise<any> {
|
|
291
|
-
if (
|
|
292
|
-
const API_BASE =
|
|
260
|
+
if (!isTauriRuntime()) {
|
|
261
|
+
const API_BASE = getLocalApiBase();
|
|
293
262
|
try {
|
|
294
263
|
const res = await fetch(`${API_BASE}/interactions`, {
|
|
295
264
|
method: 'POST',
|
|
@@ -310,8 +279,8 @@ export async function saveInteractionAgentActivity(
|
|
|
310
279
|
interactionId: number,
|
|
311
280
|
activity: AgentProgress[],
|
|
312
281
|
): Promise<void> {
|
|
313
|
-
if (
|
|
314
|
-
const API_BASE =
|
|
282
|
+
if (!isTauriRuntime()) {
|
|
283
|
+
const API_BASE = getLocalApiBase();
|
|
315
284
|
try {
|
|
316
285
|
const res = await fetch(`${API_BASE}/interactions/agent-activity`, {
|
|
317
286
|
method: 'POST',
|
|
@@ -331,8 +300,8 @@ export async function saveInteractionAgentActivity(
|
|
|
331
300
|
}
|
|
332
301
|
|
|
333
302
|
export async function listChatSessions(): Promise<ChatSession[]> {
|
|
334
|
-
if (
|
|
335
|
-
const API_BASE =
|
|
303
|
+
if (!isTauriRuntime()) {
|
|
304
|
+
const API_BASE = getLocalApiBase();
|
|
336
305
|
try {
|
|
337
306
|
const res = await fetch(`${API_BASE}/chat-sessions`);
|
|
338
307
|
const data = await res.json();
|
|
@@ -347,8 +316,8 @@ export async function listChatSessions(): Promise<ChatSession[]> {
|
|
|
347
316
|
}
|
|
348
317
|
|
|
349
318
|
export async function deleteChatSession(chatId: string): Promise<number> {
|
|
350
|
-
if (
|
|
351
|
-
const API_BASE =
|
|
319
|
+
if (!isTauriRuntime()) {
|
|
320
|
+
const API_BASE = getLocalApiBase();
|
|
352
321
|
try {
|
|
353
322
|
const params = new URLSearchParams({ chatId });
|
|
354
323
|
const res = await fetch(`${API_BASE}/chat-sessions/delete?${params.toString()}`, { method: 'POST' });
|
|
@@ -364,8 +333,8 @@ export async function deleteChatSession(chatId: string): Promise<number> {
|
|
|
364
333
|
}
|
|
365
334
|
|
|
366
335
|
export async function renameChatSession(chatId: string, newTitle: string): Promise<number> {
|
|
367
|
-
if (
|
|
368
|
-
const API_BASE =
|
|
336
|
+
if (!isTauriRuntime()) {
|
|
337
|
+
const API_BASE = getLocalApiBase();
|
|
369
338
|
try {
|
|
370
339
|
const res = await fetch(`${API_BASE}/chat-sessions/rename`, {
|
|
371
340
|
method: 'POST',
|
|
@@ -384,8 +353,8 @@ export async function renameChatSession(chatId: string, newTitle: string): Promi
|
|
|
384
353
|
}
|
|
385
354
|
|
|
386
355
|
export async function getProfileValue(key: string): Promise<string> {
|
|
387
|
-
if (
|
|
388
|
-
const API_BASE =
|
|
356
|
+
if (!isTauriRuntime()) {
|
|
357
|
+
const API_BASE = getLocalApiBase();
|
|
389
358
|
try {
|
|
390
359
|
const params = new URLSearchParams({ key });
|
|
391
360
|
const res = await fetch(`${API_BASE}/profile?${params.toString()}`);
|
|
@@ -401,8 +370,8 @@ export async function getProfileValue(key: string): Promise<string> {
|
|
|
401
370
|
}
|
|
402
371
|
|
|
403
372
|
export async function setProfileValue(key: string, value: string): Promise<boolean> {
|
|
404
|
-
if (
|
|
405
|
-
const API_BASE =
|
|
373
|
+
if (!isTauriRuntime()) {
|
|
374
|
+
const API_BASE = getLocalApiBase();
|
|
406
375
|
try {
|
|
407
376
|
const res = await fetch(`${API_BASE}/profile`, {
|
|
408
377
|
method: 'POST',
|
|
@@ -426,9 +395,10 @@ export interface LearnedSkill {
|
|
|
426
395
|
sourcePath: string
|
|
427
396
|
content: string
|
|
428
397
|
updatedAt: string
|
|
398
|
+
location?: string
|
|
429
399
|
}
|
|
430
400
|
|
|
431
|
-
export async function listLearnedSkills(): Promise<LearnedSkill[]> {
|
|
401
|
+
export async function listLearnedSkills(workspacePath?: string): Promise<LearnedSkill[]> {
|
|
432
402
|
if (typeof window === 'undefined' || !(window as any).__TAURI_INTERNALS__) {
|
|
433
403
|
try {
|
|
434
404
|
const val = await getProfileValue('learned-skills-web-mock')
|
|
@@ -442,7 +412,7 @@ export async function listLearnedSkills(): Promise<LearnedSkill[]> {
|
|
|
442
412
|
}
|
|
443
413
|
}
|
|
444
414
|
const { invoke } = await import('@tauri-apps/api/core')
|
|
445
|
-
return invoke<LearnedSkill[]>('list_learned_skills')
|
|
415
|
+
return invoke<LearnedSkill[]>('list_learned_skills', { workspacePath })
|
|
446
416
|
}
|
|
447
417
|
|
|
448
418
|
export async function addLearnedSkill(name: string, content: string): Promise<LearnedSkill> {
|
|
@@ -486,8 +456,8 @@ export async function deleteLearnedSkill(name: string): Promise<number> {
|
|
|
486
456
|
}
|
|
487
457
|
|
|
488
458
|
export async function clearChatHistory(chatId?: string | null): Promise<number> {
|
|
489
|
-
if (
|
|
490
|
-
const API_BASE =
|
|
459
|
+
if (!isTauriRuntime()) {
|
|
460
|
+
const API_BASE = getLocalApiBase();
|
|
491
461
|
try {
|
|
492
462
|
const params = new URLSearchParams();
|
|
493
463
|
if (chatId) params.set('chatId', chatId);
|
|
@@ -505,14 +475,15 @@ export async function clearChatHistory(chatId?: string | null): Promise<number>
|
|
|
505
475
|
}
|
|
506
476
|
|
|
507
477
|
export async function listSavedPictures(): Promise<PictureEntry[]> {
|
|
508
|
-
if (
|
|
509
|
-
const API_BASE =
|
|
478
|
+
if (!isTauriRuntime()) {
|
|
479
|
+
const API_BASE = getLocalApiBase();
|
|
510
480
|
try {
|
|
511
|
-
const res = await fetch(`${API_BASE}/pictures`);
|
|
481
|
+
const res = await fetch(`${API_BASE}/pictures?_t=${Date.now()}`);
|
|
512
482
|
const pictures = await res.json();
|
|
483
|
+
const timestamp = Date.now();
|
|
513
484
|
return Array.isArray(pictures)
|
|
514
485
|
? pictures.map((picture) => {
|
|
515
|
-
const pictureUrl = picture.url ? `${API_BASE.replace('/api', '')}${picture.url}` : undefined
|
|
486
|
+
const pictureUrl = picture.url ? `${API_BASE.replace('/api', '')}${picture.url}?_t=${timestamp}` : undefined
|
|
516
487
|
return {
|
|
517
488
|
...picture,
|
|
518
489
|
path: pictureUrl || picture.path,
|
|
@@ -534,8 +505,8 @@ export async function listSavedPictures(): Promise<PictureEntry[]> {
|
|
|
534
505
|
export async function generateImages(
|
|
535
506
|
request: ImageGenRequest
|
|
536
507
|
): Promise<ImageGenResponse> {
|
|
537
|
-
if (
|
|
538
|
-
const API_BASE =
|
|
508
|
+
if (!isTauriRuntime()) {
|
|
509
|
+
const API_BASE = getLocalApiBase()
|
|
539
510
|
const res = await fetch(`${API_BASE}/image-generate`, {
|
|
540
511
|
method: 'POST',
|
|
541
512
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -569,8 +540,8 @@ export async function generateImages(
|
|
|
569
540
|
|
|
570
541
|
/** Fetch which image-generation providers are currently configured on the backend. */
|
|
571
542
|
export async function getImageGenProviders(): Promise<ImageGenProviders> {
|
|
572
|
-
if (
|
|
573
|
-
const API_BASE =
|
|
543
|
+
if (!isTauriRuntime()) {
|
|
544
|
+
const API_BASE = getLocalApiBase()
|
|
574
545
|
try {
|
|
575
546
|
const res = await fetch(`${API_BASE}/image-gen/providers`)
|
|
576
547
|
if (res.ok) return await res.json()
|
|
@@ -599,8 +570,8 @@ export async function getImageGenProviders(): Promise<ImageGenProviders> {
|
|
|
599
570
|
|
|
600
571
|
/** Updates the default image generation provider in the configuration. */
|
|
601
572
|
export async function setDefaultImageProvider(provider: string): Promise<boolean> {
|
|
602
|
-
if (
|
|
603
|
-
const API_BASE =
|
|
573
|
+
if (!isTauriRuntime()) {
|
|
574
|
+
const API_BASE = getLocalApiBase();
|
|
604
575
|
try {
|
|
605
576
|
const getRes = await fetch(`${API_BASE}/config`)
|
|
606
577
|
if (!getRes.ok) return false
|
|
@@ -647,6 +618,24 @@ export async function getWorkspaceTree(path?: string | null): Promise<WorkspaceT
|
|
|
647
618
|
return invoke<WorkspaceTreeEntry>('get_workspace_tree', { path })
|
|
648
619
|
}
|
|
649
620
|
|
|
621
|
+
export async function createWorkspaceFile(path: string): Promise<void> {
|
|
622
|
+
if (typeof window === 'undefined' || !(window as any).__TAURI_INTERNALS__) return
|
|
623
|
+
const { invoke } = await import('@tauri-apps/api/core')
|
|
624
|
+
return invoke('create_workspace_file', { path })
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
export async function createWorkspaceFolder(path: string): Promise<void> {
|
|
628
|
+
if (typeof window === 'undefined' || !(window as any).__TAURI_INTERNALS__) return
|
|
629
|
+
const { invoke } = await import('@tauri-apps/api/core')
|
|
630
|
+
return invoke('create_workspace_folder', { path })
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
export async function deleteWorkspaceItem(path: string): Promise<void> {
|
|
634
|
+
if (typeof window === 'undefined' || !(window as any).__TAURI_INTERNALS__) return
|
|
635
|
+
const { invoke } = await import('@tauri-apps/api/core')
|
|
636
|
+
return invoke('delete_workspace_item', { path })
|
|
637
|
+
}
|
|
638
|
+
|
|
650
639
|
export async function selectWorkspaceDirectory(): Promise<string | null> {
|
|
651
640
|
if (typeof window === 'undefined' || !(window as any).__TAURI_INTERNALS__) {
|
|
652
641
|
return null
|
|
@@ -656,12 +645,12 @@ export async function selectWorkspaceDirectory(): Promise<string | null> {
|
|
|
656
645
|
return selected?.trim() || null
|
|
657
646
|
}
|
|
658
647
|
|
|
659
|
-
export async function submitToolApproval(token: string, approved: boolean): Promise<void> {
|
|
648
|
+
export async function submitToolApproval(token: string, approved: boolean, answer?: string): Promise<void> {
|
|
660
649
|
if (typeof window === 'undefined' || !(window as any).__TAURI_INTERNALS__) {
|
|
661
650
|
return;
|
|
662
651
|
}
|
|
663
652
|
const { invoke } = await import('@tauri-apps/api/core')
|
|
664
|
-
return invoke('submit_tool_approval', { token, approved })
|
|
653
|
+
return invoke('submit_tool_approval', { token, approved, answer })
|
|
665
654
|
}
|
|
666
655
|
|
|
667
656
|
export async function proposeCodeEdits(root: string, edits: CodeEdit[]): Promise<CodeEditProposal> {
|
|
@@ -701,9 +690,9 @@ export function convertFileSrc(filePath: string, protocol = 'asset'): string {
|
|
|
701
690
|
}
|
|
702
691
|
|
|
703
692
|
export function installTauriAdapters() {
|
|
704
|
-
if (
|
|
705
|
-
|
|
706
|
-
|
|
693
|
+
if (!isTauriRuntime()) {
|
|
694
|
+
const API_BASE = getLocalApiBase();
|
|
695
|
+
console.warn(`Not running inside Tauri. Connecting to local API server fallback at ${API_BASE}.`);
|
|
707
696
|
|
|
708
697
|
(window as any).settingsApi = {
|
|
709
698
|
getSettings: async () => {
|
|
@@ -1239,3 +1228,40 @@ export async function readClipboardImage(): Promise<string | null> {
|
|
|
1239
1228
|
return null
|
|
1240
1229
|
}
|
|
1241
1230
|
}
|
|
1231
|
+
|
|
1232
|
+
// Enforce compile-time check against the shared platform interface
|
|
1233
|
+
const _apiCheck: MintPlatformApi = {
|
|
1234
|
+
getRuntimeStatus,
|
|
1235
|
+
detectSystemTools,
|
|
1236
|
+
sendChatMessage,
|
|
1237
|
+
streamChatMessage,
|
|
1238
|
+
getTtsUrls,
|
|
1239
|
+
cancelChatMessage,
|
|
1240
|
+
getRecentInteractions,
|
|
1241
|
+
saveSystemInteraction,
|
|
1242
|
+
saveInteractionAgentActivity,
|
|
1243
|
+
listChatSessions,
|
|
1244
|
+
deleteChatSession,
|
|
1245
|
+
renameChatSession,
|
|
1246
|
+
getProfileValue,
|
|
1247
|
+
setProfileValue,
|
|
1248
|
+
listLearnedSkills,
|
|
1249
|
+
addLearnedSkill,
|
|
1250
|
+
deleteLearnedSkill,
|
|
1251
|
+
clearChatHistory,
|
|
1252
|
+
listSavedPictures,
|
|
1253
|
+
generateImages,
|
|
1254
|
+
getImageGenProviders,
|
|
1255
|
+
setDefaultImageProvider,
|
|
1256
|
+
getWorkspaceTree,
|
|
1257
|
+
createWorkspaceFile,
|
|
1258
|
+
createWorkspaceFolder,
|
|
1259
|
+
deleteWorkspaceItem,
|
|
1260
|
+
selectWorkspaceDirectory,
|
|
1261
|
+
submitToolApproval,
|
|
1262
|
+
proposeCodeEdits,
|
|
1263
|
+
applyCodeEdits,
|
|
1264
|
+
listen,
|
|
1265
|
+
readClipboardImage,
|
|
1266
|
+
}
|
|
1267
|
+
|
|
@@ -1,39 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const keptNonThought = new Set(
|
|
13
|
-
progress.filter((event) => event.type !== 'Thought').slice(-maxNonThought),
|
|
14
|
-
)
|
|
15
|
-
return progress.filter((event) => event.type === 'Thought' || keptNonThought.has(event))
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function hasAgentToolActivity(progress: AgentProgress[]): boolean {
|
|
19
|
-
return progress.some((event) => event.type === 'ToolStart' || event.type === 'ToolEnd')
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function mergeActivitySnapshots(
|
|
23
|
-
current: Record<string, AgentProgress[]>,
|
|
24
|
-
interactions: InteractionMemory[],
|
|
25
|
-
): Record<string, AgentProgress[]> {
|
|
26
|
-
const merged = { ...current }
|
|
27
|
-
for (const interaction of interactions) {
|
|
28
|
-
const key = String(interaction.id)
|
|
29
|
-
if (interaction.agentActivity?.length && !merged[key]) {
|
|
30
|
-
merged[key] = interaction.agentActivity
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return merged
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function parseAgentActivity(value: unknown): AgentProgress[] | undefined {
|
|
37
|
-
if (!Array.isArray(value)) return undefined
|
|
38
|
-
return value as AgentProgress[]
|
|
39
|
-
}
|
|
1
|
+
// Re-export everything from the shared module — do NOT add logic here.
|
|
2
|
+
// Edit src/renderer/shared/agentProgress.ts instead.
|
|
3
|
+
export type { AgentProgress, InteractionMemory } from '../shared/agentProgress'
|
|
4
|
+
export {
|
|
5
|
+
thoughtsFrom,
|
|
6
|
+
trimAgentProgress,
|
|
7
|
+
hasAgentToolActivity,
|
|
8
|
+
mergeActivitySnapshots,
|
|
9
|
+
parseAgentActivity,
|
|
10
|
+
parseFileChangesFromProgress,
|
|
11
|
+
} from '../shared/agentProgress'
|
|
@@ -1,47 +1,4 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// Re-export from the shared module — do NOT add logic here.
|
|
2
|
+
// Edit src/renderer/shared/calculator.ts instead.
|
|
3
|
+
export { evaluateArithmetic } from '../shared/calculator'
|
|
4
4
|
|
|
5
|
-
function parseExpression(): number {
|
|
6
|
-
let value = parseTerm()
|
|
7
|
-
while (tokens[index] === '+' || tokens[index] === '-') {
|
|
8
|
-
const operator = tokens[index++]
|
|
9
|
-
const right = parseTerm()
|
|
10
|
-
value = operator === '+' ? value + right : value - right
|
|
11
|
-
}
|
|
12
|
-
return value
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function parseTerm(): number {
|
|
16
|
-
let value = parseFactor()
|
|
17
|
-
while (tokens[index] === '*' || tokens[index] === '/') {
|
|
18
|
-
const operator = tokens[index++]
|
|
19
|
-
const right = parseFactor()
|
|
20
|
-
value = operator === '*' ? value * right : value / right
|
|
21
|
-
}
|
|
22
|
-
return value
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function parseFactor(): number {
|
|
26
|
-
if (tokens[index] === '+' || tokens[index] === '-') {
|
|
27
|
-
return tokens[index++] === '-' ? -parseFactor() : parseFactor()
|
|
28
|
-
}
|
|
29
|
-
if (tokens[index] === '(') {
|
|
30
|
-
index += 1
|
|
31
|
-
const value = parseExpression()
|
|
32
|
-
if (tokens[index++] !== ')') throw new Error('missing closing parenthesis')
|
|
33
|
-
return value
|
|
34
|
-
}
|
|
35
|
-
const match = tokens.slice(index).match(/^(?:\d+(?:\.\d*)?|\.\d+)/)
|
|
36
|
-
if (!match) throw new Error('expected a number')
|
|
37
|
-
index += match[0].length
|
|
38
|
-
return Number(match[0])
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (!tokens) throw new Error('expression is empty')
|
|
42
|
-
const result = parseExpression()
|
|
43
|
-
if (index !== tokens.length || !Number.isFinite(result)) {
|
|
44
|
-
throw new Error('invalid arithmetic expression')
|
|
45
|
-
}
|
|
46
|
-
return result
|
|
47
|
-
}
|