集成系统通知,并在Agent响应完成后发出通知

This commit is contained in:
xintaofei
2026-03-21 18:39:28 +08:00
parent e41a37cd4f
commit a9e0a742ac
17 changed files with 144 additions and 12 deletions

View File

@@ -21,6 +21,7 @@
"@tanstack/react-virtual": "^3.13.18",
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-dialog": "^2.6.0",
"@tauri-apps/plugin-notification": "^2.3.3",
"@tauri-apps/plugin-opener": "^2",
"@tauri-apps/plugin-process": "^2.3.1",
"@tauri-apps/plugin-updater": "^2.10.0",

10
pnpm-lock.yaml generated
View File

@@ -41,6 +41,9 @@ importers:
'@tauri-apps/plugin-dialog':
specifier: ^2.6.0
version: 2.6.0
'@tauri-apps/plugin-notification':
specifier: ^2.3.3
version: 2.3.3
'@tauri-apps/plugin-opener':
specifier: ^2
version: 2.5.3
@@ -2530,6 +2533,9 @@ packages:
'@tauri-apps/plugin-dialog@2.6.0':
resolution: {integrity: sha512-q4Uq3eY87TdcYzXACiYSPhmpBA76shgmQswGkSVio4C82Sz2W4iehe9TnKYwbq7weHiL88Yw19XZm7v28+Micg==}
'@tauri-apps/plugin-notification@2.3.3':
resolution: {integrity: sha512-Zw+ZH18RJb41G4NrfHgIuofJiymusqN+q8fGUIIV7vyCH+5sSn5coqRv/MWB9qETsUs97vmU045q7OyseCV3Qg==}
'@tauri-apps/plugin-opener@2.5.3':
resolution: {integrity: sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ==}
@@ -9074,6 +9080,10 @@ snapshots:
dependencies:
'@tauri-apps/api': 2.10.1
'@tauri-apps/plugin-notification@2.3.3':
dependencies:
'@tauri-apps/api': 2.10.1
'@tauri-apps/plugin-opener@2.5.3':
dependencies:
'@tauri-apps/api': 2.10.1

98
src-tauri/Cargo.lock generated
View File

@@ -818,6 +818,7 @@ dependencies = [
"tauri",
"tauri-build",
"tauri-plugin-dialog",
"tauri-plugin-notification",
"tauri-plugin-opener",
"tauri-plugin-process",
"tauri-plugin-updater",
@@ -2960,6 +2961,18 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
[[package]]
name = "mac-notification-sys"
version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29a16783dd1a47849b8c8133c9cd3eb2112cfbc6901670af3dba47c8bbfb07d3"
dependencies = [
"cc",
"objc2",
"objc2-foundation",
"time",
]
[[package]]
name = "markup5ever"
version = "0.14.1"
@@ -3219,6 +3232,20 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "notify-rust"
version = "4.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21af20a1b50be5ac5861f74af1a863da53a11c38684d9818d82f1c42f7fdc6c2"
dependencies = [
"futures-lite",
"log",
"mac-notification-sys",
"serde",
"tauri-winrt-notification",
"zbus",
]
[[package]]
name = "num-bigint"
version = "0.4.6"
@@ -3976,7 +4003,7 @@ checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07"
dependencies = [
"base64 0.22.1",
"indexmap 2.13.0",
"quick-xml",
"quick-xml 0.38.4",
"serde",
"time",
]
@@ -4192,6 +4219,15 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "quick-xml"
version = "0.37.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb"
dependencies = [
"memchr",
]
[[package]]
name = "quick-xml"
version = "0.38.4"
@@ -4247,6 +4283,16 @@ dependencies = [
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.5",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
@@ -4267,6 +4313,16 @@ dependencies = [
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.5",
]
[[package]]
name = "rand_core"
version = "0.5.1"
@@ -4285,6 +4341,15 @@ dependencies = [
"getrandom 0.2.17",
]
[[package]]
name = "rand_core"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
dependencies = [
"getrandom 0.3.4",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
@@ -6153,6 +6218,25 @@ dependencies = [
"url",
]
[[package]]
name = "tauri-plugin-notification"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01fc2c5ff41105bd1f7242d8201fdf3efd70749b82fa013a17f2126357d194cc"
dependencies = [
"log",
"notify-rust",
"rand 0.9.2",
"serde",
"serde_json",
"serde_repr",
"tauri",
"tauri-plugin",
"thiserror 2.0.18",
"time",
"url",
]
[[package]]
name = "tauri-plugin-opener"
version = "2.5.3"
@@ -6334,6 +6418,18 @@ dependencies = [
"toml 0.9.11+spec-1.1.0",
]
[[package]]
name = "tauri-winrt-notification"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b1e66e07de489fe43a46678dd0b8df65e0c973909df1b60ba33874e297ba9b9"
dependencies = [
"quick-xml 0.37.5",
"thiserror 2.0.18",
"windows 0.61.3",
"windows-version",
]
[[package]]
name = "tempfile"
version = "3.24.0"

View File

@@ -55,6 +55,7 @@ keyring = { version = "3", features = ["apple-native", "windows-native", "sync-s
tauri-plugin-window-state = "2"
tauri-plugin-updater = "2"
tauri-plugin-process = "2"
tauri-plugin-notification = "2"
[target.'cfg(target_os = "windows")'.dependencies]

View File

@@ -22,6 +22,7 @@
},
"dialog:default",
"updater:default",
"process:default"
"process:default",
"notification:default"
]
}

View File

@@ -40,6 +40,7 @@ pub fn run() {
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_updater::Builder::new().build())
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_notification::init())
.manage(ConnectionManager::new())
.manage(TerminalManager::new())
.manage(windows::SettingsWindowState::new())

View File

@@ -42,6 +42,7 @@ import {
CONNECTION_IDLE_TIMEOUT_MS,
IDLE_SWEEP_INTERVAL_MS,
} from "@/lib/constants"
import { notifyTurnComplete } from "@/lib/notification"
import { useAlertContext, type AlertAction } from "@/contexts/alert-context"
// ── Shared types (re-exported for consumers) ──
@@ -1545,6 +1546,17 @@ export function AcpConnectionsProvider({ children }: { children: ReactNode }) {
}
}
}
// Send OS notification when window is not focused
{
const nc = storeRef.current.connections.get(contextKey)
if (nc) {
const agentLabel = AGENT_LABELS[nc.agentType]
notifyTurnComplete(
"Codeg",
t("notificationTurnComplete", { agent: agentLabel }),
).catch(() => {})
}
}
break
}
case "error":

View File

@@ -1311,7 +1311,8 @@
"autoLinkPreflightFailed": "فشل فحص ما قبل التشغيل للربط التلقائي: {message}",
"connectFailedTitle": "فشل اتصال {agent}",
"toolFallbackTitle": "أداة",
"eventErrorTitle": "خطأ الوكيل"
"eventErrorTitle": "خطأ الوكيل",
"notificationTurnComplete": "{agent} أنهى الاستجابة"
},
"connectionLifecycle": {
"tasks": {

View File

@@ -1311,7 +1311,8 @@
"autoLinkPreflightFailed": "Auto-Link-Preflight fehlgeschlagen: {message}",
"connectFailedTitle": "{agent} Verbindung fehlgeschlagen",
"toolFallbackTitle": "Werkzeug",
"eventErrorTitle": "Agentenfehler"
"eventErrorTitle": "Agentenfehler",
"notificationTurnComplete": "{agent} hat die Antwort abgeschlossen"
},
"connectionLifecycle": {
"tasks": {

View File

@@ -1311,7 +1311,8 @@
"autoLinkPreflightFailed": "Auto-link preflight failed: {message}",
"connectFailedTitle": "{agent} connection failed",
"toolFallbackTitle": "Tool",
"eventErrorTitle": "Agent Error"
"eventErrorTitle": "Agent Error",
"notificationTurnComplete": "{agent} has finished responding"
},
"connectionLifecycle": {
"tasks": {

View File

@@ -1311,7 +1311,8 @@
"autoLinkPreflightFailed": "Falló la verificación previa del autovínculo: {message}",
"connectFailedTitle": "Falló la conexión de {agent}",
"toolFallbackTitle": "Herramienta",
"eventErrorTitle": "Error del agente"
"eventErrorTitle": "Error del agente",
"notificationTurnComplete": "{agent} ha terminado de responder"
},
"connectionLifecycle": {
"tasks": {

View File

@@ -1311,7 +1311,8 @@
"autoLinkPreflightFailed": "Échec de la vérification préalable de l'auto-liaison : {message}",
"connectFailedTitle": "Échec de la connexion de {agent}",
"toolFallbackTitle": "Outil",
"eventErrorTitle": "Erreur de l'agent"
"eventErrorTitle": "Erreur de l'agent",
"notificationTurnComplete": "{agent} a terminé de répondre"
},
"connectionLifecycle": {
"tasks": {

View File

@@ -1311,7 +1311,8 @@
"autoLinkPreflightFailed": "自動リンクの事前チェックに失敗しました: {message}",
"connectFailedTitle": "{agent} の接続に失敗しました",
"toolFallbackTitle": "ツール",
"eventErrorTitle": "エージェントエラー"
"eventErrorTitle": "エージェントエラー",
"notificationTurnComplete": "{agent} の応答が完了しました"
},
"connectionLifecycle": {
"tasks": {

View File

@@ -1311,7 +1311,8 @@
"autoLinkPreflightFailed": "자동 연결 사전 점검 실패: {message}",
"connectFailedTitle": "{agent} 연결 실패",
"toolFallbackTitle": "도구",
"eventErrorTitle": "에이전트 오류"
"eventErrorTitle": "에이전트 오류",
"notificationTurnComplete": "{agent} 응답이 완료되었습니다"
},
"connectionLifecycle": {
"tasks": {

View File

@@ -1311,7 +1311,8 @@
"autoLinkPreflightFailed": "Pré-voo do vínculo automático falhou: {message}",
"connectFailedTitle": "Falha na conexão de {agent}",
"toolFallbackTitle": "Ferramenta",
"eventErrorTitle": "Erro do agente"
"eventErrorTitle": "Erro do agente",
"notificationTurnComplete": "{agent} terminou de responder"
},
"connectionLifecycle": {
"tasks": {

View File

@@ -1311,7 +1311,8 @@
"autoLinkPreflightFailed": "自动链接预检查失败:{message}",
"connectFailedTitle": "{agent} 连接失败",
"toolFallbackTitle": "工具",
"eventErrorTitle": "Agent 错误"
"eventErrorTitle": "Agent 错误",
"notificationTurnComplete": "{agent} 已完成响应"
},
"connectionLifecycle": {
"tasks": {

View File

@@ -1311,7 +1311,8 @@
"autoLinkPreflightFailed": "自動連結預檢查失敗:{message}",
"connectFailedTitle": "{agent} 連線失敗",
"toolFallbackTitle": "工具",
"eventErrorTitle": "Agent 錯誤"
"eventErrorTitle": "Agent 錯誤",
"notificationTurnComplete": "{agent} 已完成回應"
},
"connectionLifecycle": {
"tasks": {