diff --git a/.gitignore b/.gitignore index 0a97c9dd1..4ede4dca6 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,8 @@ docs/prd/ docs/roadmap/ docs/gongzonghao/ docs/bussniss/ +docs/oem/ + # Issues tracking (internal use only) .issues/ @@ -63,3 +65,8 @@ openspec # Build artifacts (alternate cargo target dirs) src-tauri/target*/ + +logo-lime.png + +lime.db + diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 22d2e2a87..92d234e7f 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,8 +1,10 @@ -## Lime v0.89.0 +## Lime v0.89.1 ### ✨ 主要更新 - **品牌正式更名为 Lime**:主程序名称、仓库链接、安装包命名、Tauri `productName` / `identifier`、深链 scheme、浏览器桥扩展目录与发布文案已统一从 `Proxycast` 切换到 `Lime` +- **品牌图标与启动形象刷新**:应用图标、安装包图标、通知图标与启动页专用 Logo 已统一替换为新的青柠小龙虾主视觉,启动页继续保留独立图像资源 +- **ThemeWorkbench 侧边栏完成职责拆分**:上下文面板、工作流面板、执行日志与编排状态拆成独立构建模块,侧边栏主组件进一步收口 - **版本事实源继续收口**:统一 `package.json`、Cargo workspace / package、两份 Tauri 配置与 `RELEASE_NOTES.md` 的版本入口,发布流程继续只读取这一套版本源 - **运行时命名继续收口**:Tool Calling、Web Search、Durable Memory、workspace sandbox、真实测试与浏览器桥接等运行时环境变量统一以 `LIME_*` / `__LIME_*` 为现役事实源,旧 `PROXYCAST_*` 仅保留兼容读取 - **生态入口同步完成**:README、插件升级入口、About 页、扩展说明与下载地址等对外入口统一使用 `Lime` @@ -28,4 +30,4 @@ --- -**完整变更**: v0.88.0...v0.89.0 +**完整变更**: v0.89.0...v0.89.1 diff --git a/lime-claw.png b/lime-claw.png new file mode 100644 index 000000000..87daf40a1 Binary files /dev/null and b/lime-claw.png differ diff --git a/package.json b/package.json index 2f1f05a6e..dfda46a31 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "lime", "private": true, - "version": "0.89.0", + "version": "0.89.1", "type": "module", "engines": { "node": ">=22.0.0" diff --git a/public/icon.png b/public/icon.png new file mode 100644 index 000000000..6c43e5485 Binary files /dev/null and b/public/icon.png differ diff --git a/public/logo-splash.png b/public/logo-splash.png index 032e89e46..110f754f7 100644 Binary files a/public/logo-splash.png and b/public/logo-splash.png differ diff --git a/public/logo.png b/public/logo.png index cf14b17a7..6c43e5485 100644 Binary files a/public/logo.png and b/public/logo.png differ diff --git a/public/vite.svg b/public/vite.svg deleted file mode 100644 index 6a4109910..000000000 --- a/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 7c479fe15..8dcb69f64 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -5071,7 +5071,7 @@ dependencies = [ [[package]] name = "lime" -version = "0.89.0" +version = "0.89.1" dependencies = [ "anyhow", "arboard", @@ -5174,7 +5174,7 @@ dependencies = [ [[package]] name = "lime-agent" -version = "0.89.0" +version = "0.89.1" dependencies = [ "aster-core", "async-trait", @@ -5199,7 +5199,7 @@ dependencies = [ [[package]] name = "lime-browser-runtime" -version = "0.89.0" +version = "0.89.1" dependencies = [ "chrono", "futures", @@ -5216,7 +5216,7 @@ dependencies = [ [[package]] name = "lime-config" -version = "0.89.0" +version = "0.89.1" dependencies = [ "async-trait", "lime-core", @@ -5232,7 +5232,7 @@ dependencies = [ [[package]] name = "lime-core" -version = "0.89.0" +version = "0.89.1" dependencies = [ "aster-models", "async-trait", @@ -5272,7 +5272,7 @@ dependencies = [ [[package]] name = "lime-credential" -version = "0.89.0" +version = "0.89.1" dependencies = [ "axum 0.7.9", "base64 0.22.1", @@ -5307,7 +5307,7 @@ dependencies = [ [[package]] name = "lime-gateway" -version = "0.89.0" +version = "0.89.1" dependencies = [ "axum 0.7.9", "chrono", @@ -5328,7 +5328,7 @@ dependencies = [ [[package]] name = "lime-infra" -version = "0.89.0" +version = "0.89.1" dependencies = [ "chrono", "dashmap 5.5.3", @@ -5348,7 +5348,7 @@ dependencies = [ [[package]] name = "lime-mcp" -version = "0.89.0" +version = "0.89.1" dependencies = [ "async-trait", "dirs 5.0.1", @@ -5380,7 +5380,7 @@ dependencies = [ [[package]] name = "lime-processor" -version = "0.89.0" +version = "0.89.1" dependencies = [ "async-trait", "lime-core", @@ -5399,7 +5399,7 @@ dependencies = [ [[package]] name = "lime-providers" -version = "0.89.0" +version = "0.89.1" dependencies = [ "anyhow", "async-stream", @@ -5453,7 +5453,7 @@ dependencies = [ [[package]] name = "lime-server" -version = "0.89.0" +version = "0.89.1" dependencies = [ "aster-core", "async-stream", @@ -5498,7 +5498,7 @@ dependencies = [ [[package]] name = "lime-server-utils" -version = "0.89.0" +version = "0.89.1" dependencies = [ "axum 0.7.9", "futures", @@ -5513,7 +5513,7 @@ dependencies = [ [[package]] name = "lime-services" -version = "0.89.0" +version = "0.89.1" dependencies = [ "anyhow", "aster-core", @@ -5555,7 +5555,7 @@ dependencies = [ [[package]] name = "lime-skills" -version = "0.89.0" +version = "0.89.1" dependencies = [ "async-trait", "dirs 5.0.1", @@ -5573,7 +5573,7 @@ dependencies = [ [[package]] name = "lime-terminal" -version = "0.89.0" +version = "0.89.1" dependencies = [ "async-trait", "base64 0.22.1", @@ -5600,7 +5600,7 @@ dependencies = [ [[package]] name = "lime-websocket" -version = "0.89.0" +version = "0.89.1" dependencies = [ "axum 0.7.9", "chrono", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 150b761b4..38a040985 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.89.0" +version = "0.89.1" edition = "2021" authors = ["coso"] repository = "https://github.com/aiclientproxy/lime" @@ -191,7 +191,7 @@ version = "2.4" [package] name = "lime" -version = "0.89.0" +version = "0.89.1" description = "AI API Proxy Desktop App" authors = ["you"] edition = "2021" diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png index 2a4faff18..498d870d8 100644 Binary files a/src-tauri/icons/128x128.png and b/src-tauri/icons/128x128.png differ diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png index bda5fda39..580f8c981 100644 Binary files a/src-tauri/icons/128x128@2x.png and b/src-tauri/icons/128x128@2x.png differ diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png index 0c8012a14..dfa273813 100644 Binary files a/src-tauri/icons/32x32.png and b/src-tauri/icons/32x32.png differ diff --git a/src-tauri/icons/64x64.png b/src-tauri/icons/64x64.png index 5efab6a5c..6712a979a 100644 Binary files a/src-tauri/icons/64x64.png and b/src-tauri/icons/64x64.png differ diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png index 0f695699a..64dea9199 100644 Binary files a/src-tauri/icons/Square107x107Logo.png and b/src-tauri/icons/Square107x107Logo.png differ diff --git a/src-tauri/icons/Square142x142Logo.png b/src-tauri/icons/Square142x142Logo.png index 1e590689e..fbfff8631 100644 Binary files a/src-tauri/icons/Square142x142Logo.png and b/src-tauri/icons/Square142x142Logo.png differ diff --git a/src-tauri/icons/Square150x150Logo.png b/src-tauri/icons/Square150x150Logo.png index bb51a844a..f7807486b 100644 Binary files a/src-tauri/icons/Square150x150Logo.png and b/src-tauri/icons/Square150x150Logo.png differ diff --git a/src-tauri/icons/Square284x284Logo.png b/src-tauri/icons/Square284x284Logo.png index 7d3577aa1..cec981255 100644 Binary files a/src-tauri/icons/Square284x284Logo.png and b/src-tauri/icons/Square284x284Logo.png differ diff --git a/src-tauri/icons/Square30x30Logo.png b/src-tauri/icons/Square30x30Logo.png index 2b132f254..cbc30fd3e 100644 Binary files a/src-tauri/icons/Square30x30Logo.png and b/src-tauri/icons/Square30x30Logo.png differ diff --git a/src-tauri/icons/Square310x310Logo.png b/src-tauri/icons/Square310x310Logo.png index b6f5d9fd7..834149a0e 100644 Binary files a/src-tauri/icons/Square310x310Logo.png and b/src-tauri/icons/Square310x310Logo.png differ diff --git a/src-tauri/icons/Square44x44Logo.png b/src-tauri/icons/Square44x44Logo.png index 5b64ef61d..c96583e69 100644 Binary files a/src-tauri/icons/Square44x44Logo.png and b/src-tauri/icons/Square44x44Logo.png differ diff --git a/src-tauri/icons/Square71x71Logo.png b/src-tauri/icons/Square71x71Logo.png index 465b03cce..936fe3731 100644 Binary files a/src-tauri/icons/Square71x71Logo.png and b/src-tauri/icons/Square71x71Logo.png differ diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png index d5dc68250..a8ce35ebb 100644 Binary files a/src-tauri/icons/Square89x89Logo.png and b/src-tauri/icons/Square89x89Logo.png differ diff --git a/src-tauri/icons/StoreLogo.png b/src-tauri/icons/StoreLogo.png index 724883cc2..b091cf9e0 100644 Binary files a/src-tauri/icons/StoreLogo.png and b/src-tauri/icons/StoreLogo.png differ diff --git a/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png index 7e49dc8a3..509fbeaac 100644 Binary files a/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png and b/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png index ff64b1920..772a368a0 100644 Binary files a/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png and b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png index 7e49dc8a3..fabf63f9c 100644 Binary files a/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png and b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png index e593a85b5..2b29a0813 100644 Binary files a/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png and b/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png index 5422ba007..1a64f037f 100644 Binary files a/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png and b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png index e593a85b5..9ab9d814d 100644 Binary files a/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png and b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png index 64aa676b7..c56e8c9cd 100644 Binary files a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png and b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png index ae74f98ba..26e81ff6b 100644 Binary files a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png and b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png index 64aa676b7..1cdfe25f0 100644 Binary files a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png and b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png index 785e9e508..a849f1a82 100644 Binary files a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png and b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png index 54a5726ce..f9ee50fa4 100644 Binary files a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png and b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png index 785e9e508..c07a03c90 100644 Binary files a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png and b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png index 0e1bdc8e7..dd8f14253 100644 Binary files a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png and b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png index e3527a3a5..38fc662f5 100644 Binary files a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png and b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png index 0e1bdc8e7..7af18da65 100644 Binary files a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png and b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/android/values/ic_launcher_background.xml b/src-tauri/icons/android/values/ic_launcher_background.xml index ea9c223a6..c8472d041 100644 --- a/src-tauri/icons/android/values/ic_launcher_background.xml +++ b/src-tauri/icons/android/values/ic_launcher_background.xml @@ -1,4 +1,4 @@ - #fff + #f7f9d7 \ No newline at end of file diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns index 6dcb21619..952180eac 100644 Binary files a/src-tauri/icons/icon.icns and b/src-tauri/icons/icon.icns differ diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico index f3350d6d7..7ac0b62a3 100644 Binary files a/src-tauri/icons/icon.ico and b/src-tauri/icons/icon.ico differ diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png index cf14b17a7..103155d85 100644 Binary files a/src-tauri/icons/icon.png and b/src-tauri/icons/icon.png differ diff --git a/src-tauri/icons/ios/AppIcon-20x20@1x.png b/src-tauri/icons/ios/AppIcon-20x20@1x.png index 081427459..9d7357501 100644 Binary files a/src-tauri/icons/ios/AppIcon-20x20@1x.png and b/src-tauri/icons/ios/AppIcon-20x20@1x.png differ diff --git a/src-tauri/icons/ios/AppIcon-20x20@2x-1.png b/src-tauri/icons/ios/AppIcon-20x20@2x-1.png index 38168805a..424873d0c 100644 Binary files a/src-tauri/icons/ios/AppIcon-20x20@2x-1.png and b/src-tauri/icons/ios/AppIcon-20x20@2x-1.png differ diff --git a/src-tauri/icons/ios/AppIcon-20x20@2x.png b/src-tauri/icons/ios/AppIcon-20x20@2x.png index 38168805a..424873d0c 100644 Binary files a/src-tauri/icons/ios/AppIcon-20x20@2x.png and b/src-tauri/icons/ios/AppIcon-20x20@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-20x20@3x.png b/src-tauri/icons/ios/AppIcon-20x20@3x.png index f85259367..87b56e23c 100644 Binary files a/src-tauri/icons/ios/AppIcon-20x20@3x.png and b/src-tauri/icons/ios/AppIcon-20x20@3x.png differ diff --git a/src-tauri/icons/ios/AppIcon-29x29@1x.png b/src-tauri/icons/ios/AppIcon-29x29@1x.png index 861f6079d..0183beb9f 100644 Binary files a/src-tauri/icons/ios/AppIcon-29x29@1x.png and b/src-tauri/icons/ios/AppIcon-29x29@1x.png differ diff --git a/src-tauri/icons/ios/AppIcon-29x29@2x-1.png b/src-tauri/icons/ios/AppIcon-29x29@2x-1.png index d4310dd0d..d74bdcf19 100644 Binary files a/src-tauri/icons/ios/AppIcon-29x29@2x-1.png and b/src-tauri/icons/ios/AppIcon-29x29@2x-1.png differ diff --git a/src-tauri/icons/ios/AppIcon-29x29@2x.png b/src-tauri/icons/ios/AppIcon-29x29@2x.png index d4310dd0d..d74bdcf19 100644 Binary files a/src-tauri/icons/ios/AppIcon-29x29@2x.png and b/src-tauri/icons/ios/AppIcon-29x29@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-29x29@3x.png b/src-tauri/icons/ios/AppIcon-29x29@3x.png index e10149d64..f79a4ed1f 100644 Binary files a/src-tauri/icons/ios/AppIcon-29x29@3x.png and b/src-tauri/icons/ios/AppIcon-29x29@3x.png differ diff --git a/src-tauri/icons/ios/AppIcon-40x40@1x.png b/src-tauri/icons/ios/AppIcon-40x40@1x.png index 38168805a..424873d0c 100644 Binary files a/src-tauri/icons/ios/AppIcon-40x40@1x.png and b/src-tauri/icons/ios/AppIcon-40x40@1x.png differ diff --git a/src-tauri/icons/ios/AppIcon-40x40@2x-1.png b/src-tauri/icons/ios/AppIcon-40x40@2x-1.png index a1332e36b..ffc4fd576 100644 Binary files a/src-tauri/icons/ios/AppIcon-40x40@2x-1.png and b/src-tauri/icons/ios/AppIcon-40x40@2x-1.png differ diff --git a/src-tauri/icons/ios/AppIcon-40x40@2x.png b/src-tauri/icons/ios/AppIcon-40x40@2x.png index a1332e36b..ffc4fd576 100644 Binary files a/src-tauri/icons/ios/AppIcon-40x40@2x.png and b/src-tauri/icons/ios/AppIcon-40x40@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-40x40@3x.png b/src-tauri/icons/ios/AppIcon-40x40@3x.png index 780605a51..a2abb123c 100644 Binary files a/src-tauri/icons/ios/AppIcon-40x40@3x.png and b/src-tauri/icons/ios/AppIcon-40x40@3x.png differ diff --git a/src-tauri/icons/ios/AppIcon-512@2x.png b/src-tauri/icons/ios/AppIcon-512@2x.png index 044e5d72e..cb8aa7113 100644 Binary files a/src-tauri/icons/ios/AppIcon-512@2x.png and b/src-tauri/icons/ios/AppIcon-512@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-60x60@2x.png b/src-tauri/icons/ios/AppIcon-60x60@2x.png index 780605a51..a2abb123c 100644 Binary files a/src-tauri/icons/ios/AppIcon-60x60@2x.png and b/src-tauri/icons/ios/AppIcon-60x60@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-60x60@3x.png b/src-tauri/icons/ios/AppIcon-60x60@3x.png index 022defd24..4cff0a45c 100644 Binary files a/src-tauri/icons/ios/AppIcon-60x60@3x.png and b/src-tauri/icons/ios/AppIcon-60x60@3x.png differ diff --git a/src-tauri/icons/ios/AppIcon-76x76@1x.png b/src-tauri/icons/ios/AppIcon-76x76@1x.png index b18b2d7bc..674fcc172 100644 Binary files a/src-tauri/icons/ios/AppIcon-76x76@1x.png and b/src-tauri/icons/ios/AppIcon-76x76@1x.png differ diff --git a/src-tauri/icons/ios/AppIcon-76x76@2x.png b/src-tauri/icons/ios/AppIcon-76x76@2x.png index 15be3489d..a9cfa572b 100644 Binary files a/src-tauri/icons/ios/AppIcon-76x76@2x.png and b/src-tauri/icons/ios/AppIcon-76x76@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png b/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png index fa51def78..7b36d76ec 100644 Binary files a/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png and b/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png differ diff --git a/src-tauri/tauri.conf.headless.json b/src-tauri/tauri.conf.headless.json index d1a31ebca..dbd2871c8 100644 --- a/src-tauri/tauri.conf.headless.json +++ b/src-tauri/tauri.conf.headless.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Lime", - "version": "0.89.0", + "version": "0.89.1", "identifier": "com.lime.app", "build": { "beforeDevCommand": "npm run dev:web-bridge", diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 5ccae1a73..ee89143b7 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Lime", - "version": "0.89.0", + "version": "0.89.1", "identifier": "com.lime.app", "build": { "beforeDevCommand": "npm run dev", diff --git a/src/components/agent/chat/components/ThemeWorkbenchSidebar.tsx b/src/components/agent/chat/components/ThemeWorkbenchSidebar.tsx index 042cd5860..de11be735 100644 --- a/src/components/agent/chat/components/ThemeWorkbenchSidebar.tsx +++ b/src/components/agent/chat/components/ThemeWorkbenchSidebar.tsx @@ -1,186 +1,49 @@ -import React, { - memo, - type ReactNode, - useMemo, - useState, -} from "react"; -import type { StepStatus } from "@/components/content-creator/types"; -import type { SkillDetailInfo } from "@/lib/api/skill-execution"; -import type { TopicBranchItem, TopicBranchStatus } from "../hooks/useTopicBranchBoard"; -import type { SidebarActivityLog } from "../hooks/useThemeContextWorkspace"; -import type { Message } from "../types"; -import type { AgentRun } from "@/lib/api/executionRun"; +import React, { memo, useState } from "react"; import { ThemeWorkbenchSidebarShell, type ThemeWorkbenchSidebarTab, } from "./ThemeWorkbenchSidebarShell"; import { ThemeWorkbenchSidebarPanels } from "./ThemeWorkbenchSidebarPanels"; -import type { - ThemeWorkbenchContextBudget, - ThemeWorkbenchContextItem, -} from "./themeWorkbenchContextData"; -import { - parseThemeWorkbenchRunMetadataSummary, - type ThemeWorkbenchCreationTaskEvent, -} from "./themeWorkbenchWorkflowData"; -import { useThemeWorkbenchContextPanelState } from "./useThemeWorkbenchContextPanelState"; -import { useThemeWorkbenchArtifactActions } from "./useThemeWorkbenchArtifactActions"; -import { useThemeWorkbenchExecLogState } from "./useThemeWorkbenchExecLogState"; -import { useThemeWorkbenchSidebarTelemetry } from "./useThemeWorkbenchSidebarTelemetry"; -import { useThemeWorkbenchWorkflowPanelState } from "./useThemeWorkbenchWorkflowPanelState"; -import { - formatThemeWorkbenchRunMetadata, - writeThemeWorkbenchClipboardText, -} from "./themeWorkbenchSidebarShared"; - -type BranchMode = "topic" | "version"; - -interface ThemeWorkbenchSidebarProps { - branchMode?: BranchMode; - onNewTopic: () => void; - onSwitchTopic: (topicId: string) => void; - onDeleteTopic: (topicId: string) => void; - branchItems: TopicBranchItem[]; - onSetBranchStatus: (topicId: string, status: TopicBranchStatus) => void; - workflowSteps: Array<{ id: string; title: string; status: StepStatus }>; - contextSearchQuery: string; - onContextSearchQueryChange: (value: string) => void; - contextSearchMode: "web" | "social"; - onContextSearchModeChange: (value: "web" | "social") => void; - contextSearchLoading: boolean; - contextSearchError?: string | null; - contextSearchBlockedReason?: string | null; - onSubmitContextSearch: () => Promise | void; - onAddTextContext?: (payload: { - content: string; - name?: string; - }) => Promise | void; - onAddLinkContext?: (payload: { - url: string; - name?: string; - }) => Promise | void; - onAddFileContext?: (payload: { - path: string; - name?: string; - }) => Promise | void; - onAddImage?: () => Promise | void; - onImportDocument?: () => Promise | void; - contextItems: ThemeWorkbenchContextItem[]; - onToggleContextActive: (contextId: string) => void; - onViewContextDetail?: (contextId: string) => void; - contextBudget: ThemeWorkbenchContextBudget; - activityLogs: SidebarActivityLog[]; - creationTaskEvents?: ThemeWorkbenchCreationTaskEvent[]; - onViewRunDetail?: (runId: string) => void; - activeRunDetail?: AgentRun | null; - activeRunDetailLoading?: boolean; - onRequestCollapse?: () => void; - historyHasMore?: boolean; - historyLoading?: boolean; - onLoadMoreHistory?: () => void; - skillDetailMap?: Record; - headerActionSlot?: ReactNode; - topSlot?: ReactNode; - /** 完整的对话消息列表,用于执行日志 tab */ - messages?: Message[]; -} +import { buildThemeWorkbenchSidebarOrchestrationSource } from "./buildThemeWorkbenchSidebarOrchestrationSource"; +import { createThemeWorkbenchSidebarOrchestrationInput } from "./themeWorkbenchSidebarOrchestrationContract"; +import { type ThemeWorkbenchSidebarProps } from "./themeWorkbenchSidebarContract"; +import { areThemeWorkbenchSidebarPropsEqual } from "./themeWorkbenchSidebarComparator"; +import { useThemeWorkbenchSidebarOrchestration } from "./useThemeWorkbenchSidebarOrchestration"; function ThemeWorkbenchSidebarComponent({ branchMode = "version", - onNewTopic, - onSwitchTopic, - onDeleteTopic, - branchItems, - onSetBranchStatus, - workflowSteps, - contextSearchQuery, - onContextSearchQueryChange, - contextSearchMode, - onContextSearchModeChange, - contextSearchLoading, - contextSearchError, - contextSearchBlockedReason, - onSubmitContextSearch, - onAddTextContext, - onAddLinkContext, - onAddFileContext, - onAddImage, - onImportDocument, - contextItems, - onToggleContextActive, - onViewContextDetail, - contextBudget, - activityLogs, - creationTaskEvents = [], - onViewRunDetail, - activeRunDetail, - activeRunDetailLoading = false, onRequestCollapse, - historyHasMore = false, - historyLoading = false, - onLoadMoreHistory, - skillDetailMap = {}, headerActionSlot, topSlot, - messages = [], + ...props }: ThemeWorkbenchSidebarProps) { const [activeTab, setActiveTab] = useState("context"); const isVersionMode = branchMode === "version"; - const runMetadataText = useMemo( - () => formatThemeWorkbenchRunMetadata(activeRunDetail?.metadata ?? null), - [activeRunDetail?.metadata], + const orchestrationInput = createThemeWorkbenchSidebarOrchestrationInput( + buildThemeWorkbenchSidebarOrchestrationSource({ + isVersionMode, + props, + }), ); - const runMetadataSummary = useMemo( - () => parseThemeWorkbenchRunMetadataSummary(activeRunDetail?.metadata ?? null), - [activeRunDetail?.metadata], - ); - const runDetailSessionId = activeRunDetail?.session_id?.trim() || null; - const { handleRevealArtifactInFinder, handleOpenArtifactWithDefaultApp } = - useThemeWorkbenchArtifactActions({ - runDetailSessionId, - }); - const workflowPanelState = useThemeWorkbenchWorkflowPanelState({ - workflowSteps, - activityLogs, - creationTaskEvents, - runMetadataSummary, - }); - const contextPanelState = useThemeWorkbenchContextPanelState({ - contextItems, - contextSearchQuery, - contextSearchLoading, - contextSearchBlockedReason, - onAddTextContext, - onAddLinkContext, - onAddFileContext, - }); - - useThemeWorkbenchSidebarTelemetry({ + const { + branchCount, + activeContextCount, + visibleExecLogCount, + contextPanelProps, + workflowPanelProps, + execLogProps, + } = useThemeWorkbenchSidebarOrchestration({ activeTab, - showActivityLogs: workflowPanelState.showActivityLogs, - contextSearchLoading, - branchItemsCount: branchItems.length, - workflowStepsCount: workflowSteps.length, - contextItemsCount: contextItems.length, - activeContextCount: contextPanelState.activeContextItems.length, - activityLogsCount: activityLogs.length, - creationTaskEventsCount: creationTaskEvents.length, - hasActiveRunDetail: Boolean(activeRunDetail), - }); - const execLogState = useThemeWorkbenchExecLogState({ - messages, - groupedActivityLogs: workflowPanelState.groupedActivityLogs, - groupedCreationTaskEvents: workflowPanelState.groupedCreationTaskEvents, - skillDetailMap, + input: orchestrationInput, }); return ( ); } -function areThemeWorkbenchSidebarPropsEqual( - previous: ThemeWorkbenchSidebarProps, - next: ThemeWorkbenchSidebarProps, -): boolean { - return ( - previous.branchMode === next.branchMode && - previous.onNewTopic === next.onNewTopic && - previous.onSwitchTopic === next.onSwitchTopic && - previous.onDeleteTopic === next.onDeleteTopic && - previous.branchItems === next.branchItems && - previous.onSetBranchStatus === next.onSetBranchStatus && - previous.workflowSteps === next.workflowSteps && - previous.contextSearchQuery === next.contextSearchQuery && - previous.onContextSearchQueryChange === next.onContextSearchQueryChange && - previous.contextSearchMode === next.contextSearchMode && - previous.onContextSearchModeChange === next.onContextSearchModeChange && - previous.contextSearchLoading === next.contextSearchLoading && - previous.contextSearchError === next.contextSearchError && - previous.contextSearchBlockedReason === next.contextSearchBlockedReason && - previous.onSubmitContextSearch === next.onSubmitContextSearch && - previous.onAddTextContext === next.onAddTextContext && - previous.onAddLinkContext === next.onAddLinkContext && - previous.onAddFileContext === next.onAddFileContext && - previous.onAddImage === next.onAddImage && - previous.onImportDocument === next.onImportDocument && - previous.contextItems === next.contextItems && - previous.onToggleContextActive === next.onToggleContextActive && - previous.contextBudget.activeCount === next.contextBudget.activeCount && - previous.contextBudget.activeCountLimit === next.contextBudget.activeCountLimit && - previous.contextBudget.estimatedTokens === next.contextBudget.estimatedTokens && - previous.contextBudget.tokenLimit === next.contextBudget.tokenLimit && - previous.activityLogs === next.activityLogs && - previous.creationTaskEvents === next.creationTaskEvents && - previous.onViewRunDetail === next.onViewRunDetail && - previous.activeRunDetail === next.activeRunDetail && - previous.activeRunDetailLoading === next.activeRunDetailLoading && - previous.onRequestCollapse === next.onRequestCollapse && - previous.historyHasMore === next.historyHasMore && - previous.historyLoading === next.historyLoading && - previous.onLoadMoreHistory === next.onLoadMoreHistory && - previous.skillDetailMap === next.skillDetailMap && - previous.headerActionSlot === next.headerActionSlot && - previous.topSlot === next.topSlot && - previous.messages === next.messages - ); -} - export const ThemeWorkbenchSidebar = memo( ThemeWorkbenchSidebarComponent, areThemeWorkbenchSidebarPropsEqual, diff --git a/src/components/agent/chat/components/ThemeWorkbenchSidebarPanels.tsx b/src/components/agent/chat/components/ThemeWorkbenchSidebarPanels.tsx index b7937bc9a..7b70782ce 100644 --- a/src/components/agent/chat/components/ThemeWorkbenchSidebarPanels.tsx +++ b/src/components/agent/chat/components/ThemeWorkbenchSidebarPanels.tsx @@ -1,170 +1,28 @@ -import type { ComponentProps } from "react"; -import type { AgentRun } from "@/lib/api/executionRun"; import { ThemeWorkbenchContextPanel } from "./ThemeWorkbenchContextPanel"; import { ThemeWorkbenchExecLog } from "./ThemeWorkbenchExecLog"; import { ThemeWorkbenchWorkflowPanel } from "./ThemeWorkbenchWorkflowPanel"; import type { ThemeWorkbenchSidebarTab } from "./ThemeWorkbenchSidebarShell"; -import type { - ThemeWorkbenchContextBudget, - ThemeWorkbenchContextItem, -} from "./themeWorkbenchContextData"; -import type { ThemeWorkbenchRunMetadataSummary } from "./themeWorkbenchWorkflowData"; -import type { ThemeWorkbenchContextPanelState } from "./useThemeWorkbenchContextPanelState"; -import type { ThemeWorkbenchExecLogState } from "./useThemeWorkbenchExecLogState"; -import type { ThemeWorkbenchWorkflowPanelState } from "./useThemeWorkbenchWorkflowPanelState"; +import type { ThemeWorkbenchSidebarContentProps } from "./themeWorkbenchSidebarContentContract"; -interface ThemeWorkbenchSidebarPanelsProps { +export interface ThemeWorkbenchSidebarPanelsProps + extends ThemeWorkbenchSidebarContentProps { activeTab: ThemeWorkbenchSidebarTab; - contextState: ThemeWorkbenchContextPanelState; - contextConfig: { - contextItems: ThemeWorkbenchContextItem[]; - contextBudget: ThemeWorkbenchContextBudget; - contextSearchQuery: string; - contextSearchMode: "web" | "social"; - contextSearchLoading: boolean; - contextSearchError?: string | null; - contextSearchBlockedReason?: string | null; - onContextSearchQueryChange: (value: string) => void; - onContextSearchModeChange: (value: "web" | "social") => void; - onSubmitContextSearch: () => Promise | void; - onToggleContextActive: (contextId: string) => void; - onViewContextDetail?: (contextId: string) => void; - }; - workflowState: ThemeWorkbenchWorkflowPanelState; - workflowConfig: { - isVersionMode: boolean; - onNewTopic: () => void; - onSwitchTopic: (topicId: string) => void; - onDeleteTopic: (topicId: string) => void; - branchItems: ComponentProps["branchItems"]; - onSetBranchStatus: ComponentProps< - typeof ThemeWorkbenchWorkflowPanel - >["onSetBranchStatus"]; - workflowSteps: ComponentProps["workflowSteps"]; - onAddImage?: () => Promise | void; - onImportDocument?: () => Promise | void; - creationTaskEventsCount: number; - onViewRunDetail?: (runId: string) => void; - activeRunDetail?: AgentRun | null; - activeRunDetailLoading?: boolean; - runMetadataText: string; - runMetadataSummary: ThemeWorkbenchRunMetadataSummary; - onCopyText: (text: string) => Promise | void; - onRevealArtifactInFinder: ( - artifactPath: string, - sessionId?: string | null, - ) => Promise | void; - onOpenArtifactWithDefaultApp: ( - artifactPath: string, - sessionId?: string | null, - ) => Promise | void; - }; - execLogState: ThemeWorkbenchExecLogState; - execLogConfig: { - onLoadMoreHistory?: () => void; - historyHasMore: boolean; - historyLoading: boolean; - }; } export function ThemeWorkbenchSidebarPanels({ activeTab, - contextState, - contextConfig, - workflowState, - workflowConfig, - execLogState, - execLogConfig, + contextPanelProps, + workflowPanelProps, + execLogProps, }: ThemeWorkbenchSidebarPanelsProps) { if (activeTab === "context") { - return ( - - ); + return ; } if (activeTab === "workflow") { - return ( - - ); + return ; } if (activeTab === "log") { - return ( - - ); + return ; } return null; } diff --git a/src/components/agent/chat/components/buildThemeWorkbenchContextPanelProps.ts b/src/components/agent/chat/components/buildThemeWorkbenchContextPanelProps.ts new file mode 100644 index 000000000..6aee72547 --- /dev/null +++ b/src/components/agent/chat/components/buildThemeWorkbenchContextPanelProps.ts @@ -0,0 +1,75 @@ +import type { ThemeWorkbenchSidebarContextPanelProps } from "./themeWorkbenchSidebarContentContract"; +import type { ThemeWorkbenchContextPanelState } from "./useThemeWorkbenchContextPanelState"; + +export interface BuildThemeWorkbenchContextPanelPropsParams { + contextPanelState: ThemeWorkbenchContextPanelState; + contextBudget: ThemeWorkbenchSidebarContextPanelProps["contextBudget"]; + contextItems: ThemeWorkbenchSidebarContextPanelProps["contextItems"]; + contextSearchBlockedReason?: ThemeWorkbenchSidebarContextPanelProps["contextSearchBlockedReason"]; + contextSearchError?: ThemeWorkbenchSidebarContextPanelProps["contextSearchError"]; + contextSearchLoading: ThemeWorkbenchSidebarContextPanelProps["contextSearchLoading"]; + contextSearchMode: ThemeWorkbenchSidebarContextPanelProps["contextSearchMode"]; + contextSearchQuery: ThemeWorkbenchSidebarContextPanelProps["contextSearchQuery"]; + onContextSearchModeChange: ThemeWorkbenchSidebarContextPanelProps["onContextSearchModeChange"]; + onContextSearchQueryChange: ThemeWorkbenchSidebarContextPanelProps["onContextSearchQueryChange"]; + onSubmitContextSearch: ThemeWorkbenchSidebarContextPanelProps["onSubmitContextSearch"]; + onToggleContextActive: ThemeWorkbenchSidebarContextPanelProps["onToggleContextActive"]; + onViewContextDetail?: ThemeWorkbenchSidebarContextPanelProps["onViewContextDetail"]; +} + +export function buildThemeWorkbenchContextPanelProps({ + contextBudget, + contextItems, + contextPanelState, + contextSearchBlockedReason, + contextSearchError, + contextSearchLoading, + contextSearchMode, + contextSearchQuery, + onContextSearchModeChange, + onContextSearchQueryChange, + onSubmitContextSearch, + onToggleContextActive, + onViewContextDetail, +}: BuildThemeWorkbenchContextPanelPropsParams): ThemeWorkbenchSidebarContextPanelProps { + return { + contextItems, + searchContextItems: contextPanelState.searchContextItems, + orderedContextItems: contextPanelState.orderedContextItems, + selectedSearchResult: contextPanelState.selectedSearchResult, + latestSearchLabel: contextPanelState.latestSearchLabel, + contextBudget, + contextSearchQuery, + contextSearchMode, + contextSearchLoading, + contextSearchError, + contextSearchBlockedReason, + isSearchActionDisabled: contextPanelState.isSearchActionDisabled, + searchInputRef: contextPanelState.searchInputRef, + onContextSearchQueryChange, + onContextSearchModeChange, + onSubmitContextSearch, + onOpenAddContextDialog: contextPanelState.openAddContextDialog, + onSelectSearchResult: contextPanelState.handleSelectSearchResult, + onToggleContextActive, + onViewContextDetail, + addContextDialogOpen: contextPanelState.addContextDialogOpen, + addTextDialogOpen: contextPanelState.addTextDialogOpen, + addLinkDialogOpen: contextPanelState.addLinkDialogOpen, + contextDraftText: contextPanelState.contextDraftText, + contextDraftLink: contextPanelState.contextDraftLink, + contextCreateLoading: contextPanelState.contextCreateLoading, + contextCreateError: contextPanelState.contextCreateError, + contextDropActive: contextPanelState.contextDropActive, + onCloseAllContextDialogs: contextPanelState.closeAllContextDialogs, + onChooseContextFile: contextPanelState.handleChooseContextFile, + onDropContextFile: contextPanelState.handleDropContextFile, + onOpenTextContextDialog: contextPanelState.openTextContextDialog, + onOpenLinkContextDialog: contextPanelState.openLinkContextDialog, + onContextDraftTextChange: contextPanelState.handleContextDraftTextChange, + onContextDraftLinkChange: contextPanelState.handleContextDraftLinkChange, + onContextDropActiveChange: contextPanelState.handleContextDropActiveChange, + onSubmitTextContext: contextPanelState.handleSubmitTextContext, + onSubmitLinkContext: contextPanelState.handleSubmitLinkContext, + }; +} diff --git a/src/components/agent/chat/components/buildThemeWorkbenchExecLogProps.ts b/src/components/agent/chat/components/buildThemeWorkbenchExecLogProps.ts new file mode 100644 index 000000000..29431b51f --- /dev/null +++ b/src/components/agent/chat/components/buildThemeWorkbenchExecLogProps.ts @@ -0,0 +1,26 @@ +import type { ThemeWorkbenchSidebarExecLogProps } from "./themeWorkbenchSidebarContentContract"; +import type { ThemeWorkbenchExecLogState } from "./useThemeWorkbenchExecLogState"; + +export interface BuildThemeWorkbenchExecLogPropsParams { + execLogState: ThemeWorkbenchExecLogState; + historyHasMore?: ThemeWorkbenchSidebarExecLogProps["historyHasMore"]; + historyLoading?: ThemeWorkbenchSidebarExecLogProps["historyLoading"]; + onLoadMoreHistory?: ThemeWorkbenchSidebarExecLogProps["onLoadMoreHistory"]; +} + +export function buildThemeWorkbenchExecLogProps({ + execLogState, + historyHasMore = false, + historyLoading = false, + onLoadMoreHistory, +}: BuildThemeWorkbenchExecLogPropsParams): ThemeWorkbenchSidebarExecLogProps { + return { + entries: execLogState.visibleExecLogEntries, + totalEntriesCount: execLogState.execLogEntries.length, + wasCleared: execLogState.wasExecLogCleared, + onClear: execLogState.clearExecLog, + onLoadMoreHistory, + historyHasMore, + historyLoading, + }; +} diff --git a/src/components/agent/chat/components/buildThemeWorkbenchSidebarOrchestrationSource.ts b/src/components/agent/chat/components/buildThemeWorkbenchSidebarOrchestrationSource.ts new file mode 100644 index 000000000..db8cd03db --- /dev/null +++ b/src/components/agent/chat/components/buildThemeWorkbenchSidebarOrchestrationSource.ts @@ -0,0 +1,64 @@ +import type { + ThemeWorkbenchSidebarContextContract, + ThemeWorkbenchSidebarExecLogContract, + ThemeWorkbenchSidebarWorkflowContract, +} from "./themeWorkbenchSidebarContract"; +import type { ThemeWorkbenchSidebarOrchestrationSource } from "./themeWorkbenchSidebarOrchestrationContract"; + +type ThemeWorkbenchSidebarOrchestrationSourceProps = + ThemeWorkbenchSidebarContextContract & + ThemeWorkbenchSidebarWorkflowContract & + ThemeWorkbenchSidebarExecLogContract; + +interface BuildThemeWorkbenchSidebarOrchestrationSourceParams { + isVersionMode: boolean; + props: ThemeWorkbenchSidebarOrchestrationSourceProps; +} + +export function buildThemeWorkbenchSidebarOrchestrationSource({ + isVersionMode, + props, +}: BuildThemeWorkbenchSidebarOrchestrationSourceParams): ThemeWorkbenchSidebarOrchestrationSource { + return { + isVersionMode, + context: { + contextBudget: props.contextBudget, + contextItems: props.contextItems, + contextSearchBlockedReason: props.contextSearchBlockedReason, + contextSearchError: props.contextSearchError, + contextSearchLoading: props.contextSearchLoading, + contextSearchMode: props.contextSearchMode, + contextSearchQuery: props.contextSearchQuery, + onAddFileContext: props.onAddFileContext, + onAddLinkContext: props.onAddLinkContext, + onAddTextContext: props.onAddTextContext, + onContextSearchModeChange: props.onContextSearchModeChange, + onContextSearchQueryChange: props.onContextSearchQueryChange, + onSubmitContextSearch: props.onSubmitContextSearch, + onToggleContextActive: props.onToggleContextActive, + onViewContextDetail: props.onViewContextDetail, + }, + workflow: { + activeRunDetail: props.activeRunDetail, + activeRunDetailLoading: props.activeRunDetailLoading, + activityLogs: props.activityLogs, + branchItems: props.branchItems, + creationTaskEvents: props.creationTaskEvents, + onAddImage: props.onAddImage, + onDeleteTopic: props.onDeleteTopic, + onImportDocument: props.onImportDocument, + onNewTopic: props.onNewTopic, + onSetBranchStatus: props.onSetBranchStatus, + onSwitchTopic: props.onSwitchTopic, + onViewRunDetail: props.onViewRunDetail, + workflowSteps: props.workflowSteps, + }, + execLog: { + historyHasMore: props.historyHasMore, + historyLoading: props.historyLoading, + messages: props.messages, + onLoadMoreHistory: props.onLoadMoreHistory, + skillDetailMap: props.skillDetailMap, + }, + }; +} diff --git a/src/components/agent/chat/components/buildThemeWorkbenchWorkflowPanelProps.ts b/src/components/agent/chat/components/buildThemeWorkbenchWorkflowPanelProps.ts new file mode 100644 index 000000000..9d94109e4 --- /dev/null +++ b/src/components/agent/chat/components/buildThemeWorkbenchWorkflowPanelProps.ts @@ -0,0 +1,77 @@ +import type { ThemeWorkbenchSidebarWorkflowPanelProps } from "./themeWorkbenchSidebarContentContract"; +import { writeThemeWorkbenchClipboardText } from "./themeWorkbenchSidebarShared"; +import type { ThemeWorkbenchWorkflowPanelState } from "./useThemeWorkbenchWorkflowPanelState"; + +export interface BuildThemeWorkbenchWorkflowPanelPropsParams { + isVersionMode: ThemeWorkbenchSidebarWorkflowPanelProps["isVersionMode"]; + activeRunDetail: ThemeWorkbenchSidebarWorkflowPanelProps["activeRunDetail"]; + activeRunDetailLoading: ThemeWorkbenchSidebarWorkflowPanelProps["activeRunDetailLoading"]; + branchItems: ThemeWorkbenchSidebarWorkflowPanelProps["branchItems"]; + creationTaskEventsCount: ThemeWorkbenchSidebarWorkflowPanelProps["creationTaskEventsCount"]; + onAddImage?: ThemeWorkbenchSidebarWorkflowPanelProps["onAddImage"]; + onDeleteTopic: ThemeWorkbenchSidebarWorkflowPanelProps["onDeleteTopic"]; + onImportDocument?: ThemeWorkbenchSidebarWorkflowPanelProps["onImportDocument"]; + onNewTopic: ThemeWorkbenchSidebarWorkflowPanelProps["onNewTopic"]; + onOpenArtifactWithDefaultApp: ( + artifactPath: string, + sessionId?: string | null, + ) => Promise | void; + onRevealArtifactInFinder: ( + artifactPath: string, + sessionId?: string | null, + ) => Promise | void; + onSetBranchStatus: ThemeWorkbenchSidebarWorkflowPanelProps["onSetBranchStatus"]; + onSwitchTopic: ThemeWorkbenchSidebarWorkflowPanelProps["onSwitchTopic"]; + onViewRunDetail?: ThemeWorkbenchSidebarWorkflowPanelProps["onViewRunDetail"]; + workflowPanelState: ThemeWorkbenchWorkflowPanelState; + workflowSteps: ThemeWorkbenchSidebarWorkflowPanelProps["workflowSteps"]; +} + +export function buildThemeWorkbenchWorkflowPanelProps({ + isVersionMode, + branchItems, + creationTaskEventsCount, + onAddImage, + onDeleteTopic, + onImportDocument, + onNewTopic, + onOpenArtifactWithDefaultApp, + onRevealArtifactInFinder, + onSetBranchStatus, + onSwitchTopic, + onViewRunDetail, + workflowPanelState, + workflowSteps, + activeRunDetail, + activeRunDetailLoading, +}: BuildThemeWorkbenchWorkflowPanelPropsParams): ThemeWorkbenchSidebarWorkflowPanelProps { + return { + isVersionMode, + onNewTopic, + onSwitchTopic, + onDeleteTopic, + branchItems, + onSetBranchStatus, + workflowSteps, + completedSteps: workflowPanelState.completedSteps, + progressPercent: workflowPanelState.progressPercent, + onAddImage, + onImportDocument, + creationTaskEventsCount, + showCreationTasks: workflowPanelState.showCreationTasks, + onToggleCreationTasks: workflowPanelState.toggleCreationTasks, + groupedCreationTaskEvents: workflowPanelState.groupedCreationTaskEvents, + showActivityLogs: workflowPanelState.showActivityLogs, + onToggleActivityLogs: workflowPanelState.toggleActivityLogs, + groupedActivityLogs: workflowPanelState.groupedActivityLogs, + onViewRunDetail, + activeRunDetail, + activeRunDetailLoading, + activeRunStagesLabel: workflowPanelState.activeRunStagesLabel, + runMetadataText: workflowPanelState.runMetadataText, + runMetadataSummary: workflowPanelState.runMetadataSummary, + onCopyText: writeThemeWorkbenchClipboardText, + onRevealArtifactInFinder, + onOpenArtifactWithDefaultApp, + }; +} diff --git a/src/components/agent/chat/components/themeWorkbenchSidebarComparator.ts b/src/components/agent/chat/components/themeWorkbenchSidebarComparator.ts new file mode 100644 index 000000000..e92f78bdb --- /dev/null +++ b/src/components/agent/chat/components/themeWorkbenchSidebarComparator.ts @@ -0,0 +1,103 @@ +import type { + ThemeWorkbenchSidebarContextContract, + ThemeWorkbenchSidebarExecLogContract, + ThemeWorkbenchSidebarProps, + ThemeWorkbenchSidebarShellContract, + ThemeWorkbenchSidebarWorkflowContract, +} from "./themeWorkbenchSidebarContract"; + +function areThemeWorkbenchContextBudgetsEqual( + previous: ThemeWorkbenchSidebarProps["contextBudget"], + next: ThemeWorkbenchSidebarProps["contextBudget"], +): boolean { + return ( + previous.activeCount === next.activeCount && + previous.activeCountLimit === next.activeCountLimit && + previous.estimatedTokens === next.estimatedTokens && + previous.tokenLimit === next.tokenLimit + ); +} + +function areThemeWorkbenchSidebarShellPropsEqual( + previous: ThemeWorkbenchSidebarShellContract, + next: ThemeWorkbenchSidebarShellContract, +): boolean { + return ( + previous.branchMode === next.branchMode && + previous.onRequestCollapse === next.onRequestCollapse && + previous.headerActionSlot === next.headerActionSlot && + previous.topSlot === next.topSlot + ); +} + +function areThemeWorkbenchSidebarContextPropsEqual( + previous: ThemeWorkbenchSidebarContextContract, + next: ThemeWorkbenchSidebarContextContract, +): boolean { + return ( + previous.contextSearchQuery === next.contextSearchQuery && + previous.onContextSearchQueryChange === next.onContextSearchQueryChange && + previous.contextSearchMode === next.contextSearchMode && + previous.onContextSearchModeChange === next.onContextSearchModeChange && + previous.contextSearchLoading === next.contextSearchLoading && + previous.contextSearchError === next.contextSearchError && + previous.contextSearchBlockedReason === next.contextSearchBlockedReason && + previous.onSubmitContextSearch === next.onSubmitContextSearch && + previous.onAddTextContext === next.onAddTextContext && + previous.onAddLinkContext === next.onAddLinkContext && + previous.onAddFileContext === next.onAddFileContext && + previous.contextItems === next.contextItems && + previous.onToggleContextActive === next.onToggleContextActive && + previous.onViewContextDetail === next.onViewContextDetail && + areThemeWorkbenchContextBudgetsEqual( + previous.contextBudget, + next.contextBudget, + ) + ); +} + +function areThemeWorkbenchSidebarWorkflowPropsEqual( + previous: ThemeWorkbenchSidebarWorkflowContract, + next: ThemeWorkbenchSidebarWorkflowContract, +): boolean { + return ( + previous.onNewTopic === next.onNewTopic && + previous.onSwitchTopic === next.onSwitchTopic && + previous.onDeleteTopic === next.onDeleteTopic && + previous.branchItems === next.branchItems && + previous.onSetBranchStatus === next.onSetBranchStatus && + previous.workflowSteps === next.workflowSteps && + previous.onAddImage === next.onAddImage && + previous.onImportDocument === next.onImportDocument && + previous.activityLogs === next.activityLogs && + previous.creationTaskEvents === next.creationTaskEvents && + previous.onViewRunDetail === next.onViewRunDetail && + previous.activeRunDetail === next.activeRunDetail && + previous.activeRunDetailLoading === next.activeRunDetailLoading + ); +} + +function areThemeWorkbenchSidebarExecLogPropsEqual( + previous: ThemeWorkbenchSidebarExecLogContract, + next: ThemeWorkbenchSidebarExecLogContract, +): boolean { + return ( + previous.historyHasMore === next.historyHasMore && + previous.historyLoading === next.historyLoading && + previous.onLoadMoreHistory === next.onLoadMoreHistory && + previous.skillDetailMap === next.skillDetailMap && + previous.messages === next.messages + ); +} + +export function areThemeWorkbenchSidebarPropsEqual( + previous: ThemeWorkbenchSidebarProps, + next: ThemeWorkbenchSidebarProps, +): boolean { + return ( + areThemeWorkbenchSidebarShellPropsEqual(previous, next) && + areThemeWorkbenchSidebarContextPropsEqual(previous, next) && + areThemeWorkbenchSidebarWorkflowPropsEqual(previous, next) && + areThemeWorkbenchSidebarExecLogPropsEqual(previous, next) + ); +} diff --git a/src/components/agent/chat/components/themeWorkbenchSidebarContentContract.ts b/src/components/agent/chat/components/themeWorkbenchSidebarContentContract.ts new file mode 100644 index 000000000..31ddfd9d6 --- /dev/null +++ b/src/components/agent/chat/components/themeWorkbenchSidebarContentContract.ts @@ -0,0 +1,22 @@ +import type { ComponentProps } from "react"; +import { ThemeWorkbenchContextPanel } from "./ThemeWorkbenchContextPanel"; +import { ThemeWorkbenchExecLog } from "./ThemeWorkbenchExecLog"; +import { ThemeWorkbenchWorkflowPanel } from "./ThemeWorkbenchWorkflowPanel"; + +export type ThemeWorkbenchSidebarContextPanelProps = ComponentProps< + typeof ThemeWorkbenchContextPanel +>; + +export type ThemeWorkbenchSidebarWorkflowPanelProps = ComponentProps< + typeof ThemeWorkbenchWorkflowPanel +>; + +export type ThemeWorkbenchSidebarExecLogProps = ComponentProps< + typeof ThemeWorkbenchExecLog +>; + +export interface ThemeWorkbenchSidebarContentProps { + contextPanelProps: ThemeWorkbenchSidebarContextPanelProps; + workflowPanelProps: ThemeWorkbenchSidebarWorkflowPanelProps; + execLogProps: ThemeWorkbenchSidebarExecLogProps; +} diff --git a/src/components/agent/chat/components/themeWorkbenchSidebarContract.ts b/src/components/agent/chat/components/themeWorkbenchSidebarContract.ts new file mode 100644 index 000000000..d15405a0c --- /dev/null +++ b/src/components/agent/chat/components/themeWorkbenchSidebarContract.ts @@ -0,0 +1,77 @@ +import type { ReactNode } from "react"; +import type { StepStatus } from "@/components/content-creator/types"; +import type { SkillDetailInfo } from "@/lib/api/skill-execution"; +import type { AgentRun } from "@/lib/api/executionRun"; +import type { + TopicBranchItem, + TopicBranchStatus, +} from "../hooks/useTopicBranchBoard"; +import type { SidebarActivityLog } from "../hooks/useThemeContextWorkspace"; +import type { Message } from "../types"; +import type { + ThemeWorkbenchContextBudget, + ThemeWorkbenchContextItem, +} from "./themeWorkbenchContextData"; +import type { ThemeWorkbenchCreationTaskEvent } from "./themeWorkbenchWorkflowData"; +import type { + ThemeWorkbenchAddFileContextAction, + ThemeWorkbenchAddLinkContextAction, + ThemeWorkbenchAddTextContextAction, +} from "./useThemeWorkbenchContextPanelState"; + +export type BranchMode = "topic" | "version"; + +export interface ThemeWorkbenchSidebarShellContract { + branchMode?: BranchMode; + onRequestCollapse?: () => void; + headerActionSlot?: ReactNode; + topSlot?: ReactNode; +} + +export interface ThemeWorkbenchSidebarWorkflowContract { + onNewTopic: () => void; + onSwitchTopic: (topicId: string) => void; + onDeleteTopic: (topicId: string) => void; + branchItems: TopicBranchItem[]; + onSetBranchStatus: (topicId: string, status: TopicBranchStatus) => void; + workflowSteps: Array<{ id: string; title: string; status: StepStatus }>; + onAddImage?: () => Promise | void; + onImportDocument?: () => Promise | void; + activityLogs: SidebarActivityLog[]; + creationTaskEvents?: ThemeWorkbenchCreationTaskEvent[]; + onViewRunDetail?: (runId: string) => void; + activeRunDetail?: AgentRun | null; + activeRunDetailLoading?: boolean; +} + +export interface ThemeWorkbenchSidebarContextContract { + contextSearchQuery: string; + onContextSearchQueryChange: (value: string) => void; + contextSearchMode: "web" | "social"; + onContextSearchModeChange: (value: "web" | "social") => void; + contextSearchLoading: boolean; + contextSearchError?: string | null; + contextSearchBlockedReason?: string | null; + onSubmitContextSearch: () => Promise | void; + onAddTextContext?: ThemeWorkbenchAddTextContextAction; + onAddLinkContext?: ThemeWorkbenchAddLinkContextAction; + onAddFileContext?: ThemeWorkbenchAddFileContextAction; + contextItems: ThemeWorkbenchContextItem[]; + onToggleContextActive: (contextId: string) => void; + onViewContextDetail?: (contextId: string) => void; + contextBudget: ThemeWorkbenchContextBudget; +} + +export interface ThemeWorkbenchSidebarExecLogContract { + historyHasMore?: boolean; + historyLoading?: boolean; + onLoadMoreHistory?: () => void; + skillDetailMap?: Record; + messages?: Message[]; +} + +export interface ThemeWorkbenchSidebarProps + extends ThemeWorkbenchSidebarShellContract, + ThemeWorkbenchSidebarWorkflowContract, + ThemeWorkbenchSidebarContextContract, + ThemeWorkbenchSidebarExecLogContract {} diff --git a/src/components/agent/chat/components/themeWorkbenchSidebarOrchestrationContract.ts b/src/components/agent/chat/components/themeWorkbenchSidebarOrchestrationContract.ts new file mode 100644 index 000000000..6f15976ed --- /dev/null +++ b/src/components/agent/chat/components/themeWorkbenchSidebarOrchestrationContract.ts @@ -0,0 +1,102 @@ +import type { SkillDetailInfo } from "@/lib/api/skill-execution"; +import type { SidebarActivityLog } from "../hooks/useThemeContextWorkspace"; +import type { Message } from "../types"; +import type { BuildThemeWorkbenchContextPanelPropsParams } from "./buildThemeWorkbenchContextPanelProps"; +import type { BuildThemeWorkbenchExecLogPropsParams } from "./buildThemeWorkbenchExecLogProps"; +import type { BuildThemeWorkbenchWorkflowPanelPropsParams } from "./buildThemeWorkbenchWorkflowPanelProps"; +import type { ThemeWorkbenchCreationTaskEvent } from "./themeWorkbenchWorkflowData"; +import type { + ThemeWorkbenchAddFileContextAction, + ThemeWorkbenchAddLinkContextAction, + ThemeWorkbenchAddTextContextAction, +} from "./useThemeWorkbenchContextPanelState"; + +export interface ThemeWorkbenchSidebarContextOrchestrationInput + extends Omit { + onAddTextContext?: ThemeWorkbenchAddTextContextAction; + onAddLinkContext?: ThemeWorkbenchAddLinkContextAction; + onAddFileContext?: ThemeWorkbenchAddFileContextAction; +} + +export interface ThemeWorkbenchSidebarWorkflowOrchestrationInput + extends Omit< + BuildThemeWorkbenchWorkflowPanelPropsParams, + | "creationTaskEventsCount" + | "isVersionMode" + | "onOpenArtifactWithDefaultApp" + | "onRevealArtifactInFinder" + | "workflowPanelState" + > { + activityLogs: SidebarActivityLog[]; + creationTaskEvents: ThemeWorkbenchCreationTaskEvent[]; +} + +export interface ThemeWorkbenchSidebarExecLogOrchestrationInput + extends Omit { + messages: Message[]; + skillDetailMap: Record; +} + +export interface ThemeWorkbenchSidebarOrchestrationInput { + isVersionMode: boolean; + context: ThemeWorkbenchSidebarContextOrchestrationInput; + workflow: ThemeWorkbenchSidebarWorkflowOrchestrationInput; + execLog: ThemeWorkbenchSidebarExecLogOrchestrationInput; +} + +export type ThemeWorkbenchSidebarContextOrchestrationSource = + ThemeWorkbenchSidebarContextOrchestrationInput; + +export interface ThemeWorkbenchSidebarWorkflowOrchestrationSource + extends Omit< + ThemeWorkbenchSidebarWorkflowOrchestrationInput, + "creationTaskEvents" + > { + creationTaskEvents?: ThemeWorkbenchCreationTaskEvent[]; +} + +export interface ThemeWorkbenchSidebarExecLogOrchestrationSource + extends Omit< + ThemeWorkbenchSidebarExecLogOrchestrationInput, + "messages" | "skillDetailMap" + > { + messages?: Message[]; + skillDetailMap?: Record; +} + +export interface ThemeWorkbenchSidebarOrchestrationSource { + isVersionMode: boolean; + context: ThemeWorkbenchSidebarContextOrchestrationSource; + workflow: ThemeWorkbenchSidebarWorkflowOrchestrationSource; + execLog: ThemeWorkbenchSidebarExecLogOrchestrationSource; +} + +export function createThemeWorkbenchSidebarOrchestrationInput( + source: ThemeWorkbenchSidebarOrchestrationSource, +): ThemeWorkbenchSidebarOrchestrationInput { + const { isVersionMode, context, workflow, execLog } = source; + const { creationTaskEvents = [], activeRunDetailLoading = false } = workflow; + const { + historyHasMore = false, + historyLoading = false, + messages = [], + skillDetailMap = {}, + } = execLog; + + return { + isVersionMode, + context, + workflow: { + ...workflow, + activeRunDetailLoading, + creationTaskEvents, + }, + execLog: { + ...execLog, + historyHasMore, + historyLoading, + messages, + skillDetailMap, + }, + }; +} diff --git a/src/components/agent/chat/components/themeWorkbenchSidebarShared.ts b/src/components/agent/chat/components/themeWorkbenchSidebarShared.ts index 209c82a27..c2df9b498 100644 --- a/src/components/agent/chat/components/themeWorkbenchSidebarShared.ts +++ b/src/components/agent/chat/components/themeWorkbenchSidebarShared.ts @@ -1,15 +1,3 @@ -export function formatThemeWorkbenchRunMetadata(raw: string | null): string { - if (!raw || !raw.trim()) { - return "-"; - } - try { - const parsed = JSON.parse(raw); - return JSON.stringify(parsed, null, 2); - } catch { - return raw; - } -} - export function formatThemeWorkbenchActionErrorMessage( prefix: string, error: unknown, diff --git a/src/components/agent/chat/components/themeWorkbenchWorkflowData.ts b/src/components/agent/chat/components/themeWorkbenchWorkflowData.ts index a95268d13..885d53884 100644 --- a/src/components/agent/chat/components/themeWorkbenchWorkflowData.ts +++ b/src/components/agent/chat/components/themeWorkbenchWorkflowData.ts @@ -40,6 +40,18 @@ export interface ThemeWorkbenchRunMetadataSummary { artifactPaths: string[]; } +export function formatThemeWorkbenchRunMetadata(raw: string | null): string { + if (!raw || !raw.trim()) { + return "-"; + } + try { + const parsed = JSON.parse(raw); + return JSON.stringify(parsed, null, 2); + } catch { + return raw; + } +} + function normalizeArtifactPaths(raw?: string[]): string[] { if (!Array.isArray(raw)) { return []; diff --git a/src/components/agent/chat/components/useThemeWorkbenchContextPanelState.ts b/src/components/agent/chat/components/useThemeWorkbenchContextPanelState.ts index e03bac1f5..cabd21d1c 100644 --- a/src/components/agent/chat/components/useThemeWorkbenchContextPanelState.ts +++ b/src/components/agent/chat/components/useThemeWorkbenchContextPanelState.ts @@ -21,17 +21,17 @@ import { resolveThemeWorkbenchFileNameFromPath, } from "./themeWorkbenchSidebarShared"; -type AddTextContextHandler = (payload: { +export type ThemeWorkbenchAddTextContextAction = (payload: { content: string; name?: string; }) => Promise | void; -type AddLinkContextHandler = (payload: { +export type ThemeWorkbenchAddLinkContextAction = (payload: { url: string; name?: string; }) => Promise | void; -type AddFileContextHandler = (payload: { +export type ThemeWorkbenchAddFileContextAction = (payload: { path: string; name?: string; }) => Promise | void; @@ -41,9 +41,9 @@ interface UseThemeWorkbenchContextPanelStateParams { contextSearchQuery: string; contextSearchLoading: boolean; contextSearchBlockedReason?: string | null; - onAddTextContext?: AddTextContextHandler; - onAddLinkContext?: AddLinkContextHandler; - onAddFileContext?: AddFileContextHandler; + onAddTextContext?: ThemeWorkbenchAddTextContextAction; + onAddLinkContext?: ThemeWorkbenchAddLinkContextAction; + onAddFileContext?: ThemeWorkbenchAddFileContextAction; } export interface ThemeWorkbenchContextPanelState { diff --git a/src/components/agent/chat/components/useThemeWorkbenchSidebarOrchestration.ts b/src/components/agent/chat/components/useThemeWorkbenchSidebarOrchestration.ts new file mode 100644 index 000000000..1ae7b114b --- /dev/null +++ b/src/components/agent/chat/components/useThemeWorkbenchSidebarOrchestration.ts @@ -0,0 +1,122 @@ +import type { ThemeWorkbenchSidebarTab } from "./ThemeWorkbenchSidebarShell"; +import type { ThemeWorkbenchSidebarContentProps } from "./themeWorkbenchSidebarContentContract"; +import type { ThemeWorkbenchSidebarOrchestrationInput } from "./themeWorkbenchSidebarOrchestrationContract"; +import { buildThemeWorkbenchContextPanelProps } from "./buildThemeWorkbenchContextPanelProps"; +import { buildThemeWorkbenchExecLogProps } from "./buildThemeWorkbenchExecLogProps"; +import { buildThemeWorkbenchWorkflowPanelProps } from "./buildThemeWorkbenchWorkflowPanelProps"; +import { useThemeWorkbenchArtifactActions } from "./useThemeWorkbenchArtifactActions"; +import { useThemeWorkbenchContextPanelState } from "./useThemeWorkbenchContextPanelState"; +import { useThemeWorkbenchExecLogState } from "./useThemeWorkbenchExecLogState"; +import { useThemeWorkbenchSidebarTelemetry } from "./useThemeWorkbenchSidebarTelemetry"; +import { useThemeWorkbenchWorkflowPanelState } from "./useThemeWorkbenchWorkflowPanelState"; + +interface UseThemeWorkbenchSidebarOrchestrationParams { + activeTab: ThemeWorkbenchSidebarTab; + input: ThemeWorkbenchSidebarOrchestrationInput; +} + +export interface ThemeWorkbenchSidebarOrchestration { + branchCount: number; + isVersionMode: boolean; + activeContextCount: number; + visibleExecLogCount: number; + contextPanelProps: ThemeWorkbenchSidebarContentProps["contextPanelProps"]; + workflowPanelProps: ThemeWorkbenchSidebarContentProps["workflowPanelProps"]; + execLogProps: ThemeWorkbenchSidebarContentProps["execLogProps"]; +} + +export function useThemeWorkbenchSidebarOrchestration({ + activeTab, + input, +}: UseThemeWorkbenchSidebarOrchestrationParams): ThemeWorkbenchSidebarOrchestration { + const { isVersionMode, context, workflow, execLog } = input; + const branchCount = workflow.branchItems.length; + const runDetailSessionId = workflow.activeRunDetail?.session_id?.trim() || null; + const { handleRevealArtifactInFinder, handleOpenArtifactWithDefaultApp } = + useThemeWorkbenchArtifactActions({ + runDetailSessionId, + }); + + const workflowPanelState = useThemeWorkbenchWorkflowPanelState({ + workflowSteps: workflow.workflowSteps, + activityLogs: workflow.activityLogs, + creationTaskEvents: workflow.creationTaskEvents, + activeRunMetadata: workflow.activeRunDetail?.metadata ?? null, + }); + + const contextPanelState = useThemeWorkbenchContextPanelState({ + contextItems: context.contextItems, + contextSearchQuery: context.contextSearchQuery, + contextSearchLoading: context.contextSearchLoading, + contextSearchBlockedReason: context.contextSearchBlockedReason, + onAddTextContext: context.onAddTextContext, + onAddLinkContext: context.onAddLinkContext, + onAddFileContext: context.onAddFileContext, + }); + + useThemeWorkbenchSidebarTelemetry({ + activeTab, + showActivityLogs: workflowPanelState.showActivityLogs, + contextSearchLoading: context.contextSearchLoading, + branchItemsCount: branchCount, + workflowStepsCount: workflow.workflowSteps.length, + contextItemsCount: context.contextItems.length, + activeContextCount: contextPanelState.activeContextItems.length, + activityLogsCount: workflow.activityLogs.length, + creationTaskEventsCount: workflow.creationTaskEvents.length, + hasActiveRunDetail: Boolean(workflow.activeRunDetail), + }); + + const execLogState = useThemeWorkbenchExecLogState({ + messages: execLog.messages, + groupedActivityLogs: workflowPanelState.groupedActivityLogs, + groupedCreationTaskEvents: workflowPanelState.groupedCreationTaskEvents, + skillDetailMap: execLog.skillDetailMap, + }); + + return { + branchCount, + isVersionMode, + activeContextCount: contextPanelState.activeContextItems.length, + visibleExecLogCount: execLogState.visibleExecLogEntries.length, + contextPanelProps: buildThemeWorkbenchContextPanelProps({ + contextBudget: context.contextBudget, + contextItems: context.contextItems, + contextPanelState, + contextSearchBlockedReason: context.contextSearchBlockedReason, + contextSearchError: context.contextSearchError, + contextSearchLoading: context.contextSearchLoading, + contextSearchMode: context.contextSearchMode, + contextSearchQuery: context.contextSearchQuery, + onContextSearchModeChange: context.onContextSearchModeChange, + onContextSearchQueryChange: context.onContextSearchQueryChange, + onSubmitContextSearch: context.onSubmitContextSearch, + onToggleContextActive: context.onToggleContextActive, + onViewContextDetail: context.onViewContextDetail, + }), + workflowPanelProps: buildThemeWorkbenchWorkflowPanelProps({ + isVersionMode, + branchItems: workflow.branchItems, + creationTaskEventsCount: workflow.creationTaskEvents.length, + onAddImage: workflow.onAddImage, + onDeleteTopic: workflow.onDeleteTopic, + onImportDocument: workflow.onImportDocument, + onNewTopic: workflow.onNewTopic, + onOpenArtifactWithDefaultApp: handleOpenArtifactWithDefaultApp, + onRevealArtifactInFinder: handleRevealArtifactInFinder, + onSetBranchStatus: workflow.onSetBranchStatus, + onSwitchTopic: workflow.onSwitchTopic, + onViewRunDetail: workflow.onViewRunDetail, + workflowPanelState, + workflowSteps: workflow.workflowSteps, + activeRunDetail: workflow.activeRunDetail, + activeRunDetailLoading: workflow.activeRunDetailLoading, + }), + execLogProps: buildThemeWorkbenchExecLogProps({ + execLogState, + historyHasMore: execLog.historyHasMore, + historyLoading: execLog.historyLoading, + onLoadMoreHistory: execLog.onLoadMoreHistory, + }), + }; +} diff --git a/src/components/agent/chat/components/useThemeWorkbenchWorkflowPanelState.ts b/src/components/agent/chat/components/useThemeWorkbenchWorkflowPanelState.ts index e40a0d838..f2b5566da 100644 --- a/src/components/agent/chat/components/useThemeWorkbenchWorkflowPanelState.ts +++ b/src/components/agent/chat/components/useThemeWorkbenchWorkflowPanelState.ts @@ -4,7 +4,9 @@ import type { SidebarActivityLog } from "../hooks/useThemeContextWorkspace"; import { buildThemeWorkbenchActivityLogGroups, buildThemeWorkbenchCreationTaskGroups, + formatThemeWorkbenchRunMetadata, formatThemeWorkbenchStagesLabel, + parseThemeWorkbenchRunMetadataSummary, type ThemeWorkbenchCreationTaskEvent, type ThemeWorkbenchRunMetadataSummary, } from "./themeWorkbenchWorkflowData"; @@ -13,7 +15,7 @@ interface UseThemeWorkbenchWorkflowPanelStateParams { workflowSteps: Array<{ id: string; title: string; status: StepStatus }>; activityLogs: SidebarActivityLog[]; creationTaskEvents: ThemeWorkbenchCreationTaskEvent[]; - runMetadataSummary: ThemeWorkbenchRunMetadataSummary; + activeRunMetadata: string | null; } export interface ThemeWorkbenchWorkflowPanelState { @@ -24,6 +26,8 @@ export interface ThemeWorkbenchWorkflowPanelState { typeof buildThemeWorkbenchCreationTaskGroups >; activeRunStagesLabel: string | null; + runMetadataText: string; + runMetadataSummary: ThemeWorkbenchRunMetadataSummary; showActivityLogs: boolean; showCreationTasks: boolean; toggleActivityLogs: () => void; @@ -34,7 +38,7 @@ export function useThemeWorkbenchWorkflowPanelState({ workflowSteps, activityLogs, creationTaskEvents, - runMetadataSummary, + activeRunMetadata, }: UseThemeWorkbenchWorkflowPanelStateParams): ThemeWorkbenchWorkflowPanelState { const [showActivityLogs, setShowActivityLogs] = useState(false); const [showCreationTasks, setShowCreationTasks] = useState(true); @@ -57,6 +61,16 @@ export function useThemeWorkbenchWorkflowPanelState({ [creationTaskEvents], ); + const runMetadataSummary = useMemo( + () => parseThemeWorkbenchRunMetadataSummary(activeRunMetadata), + [activeRunMetadata], + ); + + const runMetadataText = useMemo( + () => formatThemeWorkbenchRunMetadata(activeRunMetadata), + [activeRunMetadata], + ); + const activeRunStagesLabel = useMemo( () => formatThemeWorkbenchStagesLabel(runMetadataSummary.stages), [runMetadataSummary.stages], @@ -76,6 +90,8 @@ export function useThemeWorkbenchWorkflowPanelState({ groupedActivityLogs, groupedCreationTaskEvents, activeRunStagesLabel, + runMetadataText, + runMetadataSummary, showActivityLogs, showCreationTasks, toggleActivityLogs,