Release v0.89.1
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
After Width: | Height: | Size: 3.8 MiB |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "lime",
|
||||
"private": true,
|
||||
"version": "0.89.0",
|
||||
"version": "0.89.1",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=22.0.0"
|
||||
|
||||
|
After Width: | Height: | Size: 339 KiB |
|
Before Width: | Height: | Size: 881 KiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 257 KiB After Width: | Height: | Size: 339 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFBD4F"></stop><stop offset="100%" stop-color="#FF980E"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 228 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 50 KiB |
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#fff</color>
|
||||
<color name="ic_launcher_background">#f7f9d7</color>
|
||||
</resources>
|
||||
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 257 KiB After Width: | Height: | Size: 308 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 843 KiB After Width: | Height: | Size: 986 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 41 KiB |
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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> | void;
|
||||
onAddTextContext?: (payload: {
|
||||
content: string;
|
||||
name?: string;
|
||||
}) => Promise<void> | void;
|
||||
onAddLinkContext?: (payload: {
|
||||
url: string;
|
||||
name?: string;
|
||||
}) => Promise<void> | void;
|
||||
onAddFileContext?: (payload: {
|
||||
path: string;
|
||||
name?: string;
|
||||
}) => Promise<void> | void;
|
||||
onAddImage?: () => Promise<void> | void;
|
||||
onImportDocument?: () => Promise<void> | 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<string, SkillDetailInfo | null>;
|
||||
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<ThemeWorkbenchSidebarTab>("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 (
|
||||
<ThemeWorkbenchSidebarShell
|
||||
activeTab={activeTab}
|
||||
isVersionMode={isVersionMode}
|
||||
activeContextCount={contextPanelState.activeContextItems.length}
|
||||
branchCount={branchItems.length}
|
||||
visibleExecLogCount={execLogState.visibleExecLogEntries.length}
|
||||
activeContextCount={activeContextCount}
|
||||
branchCount={branchCount}
|
||||
visibleExecLogCount={visibleExecLogCount}
|
||||
onTabChange={setActiveTab}
|
||||
onRequestCollapse={onRequestCollapse}
|
||||
headerActionSlot={headerActionSlot}
|
||||
@@ -188,100 +51,14 @@ function ThemeWorkbenchSidebarComponent({
|
||||
>
|
||||
<ThemeWorkbenchSidebarPanels
|
||||
activeTab={activeTab}
|
||||
contextState={contextPanelState}
|
||||
contextConfig={{
|
||||
contextItems,
|
||||
contextBudget,
|
||||
contextSearchQuery,
|
||||
contextSearchMode,
|
||||
contextSearchLoading,
|
||||
contextSearchError,
|
||||
contextSearchBlockedReason,
|
||||
onContextSearchQueryChange,
|
||||
onContextSearchModeChange,
|
||||
onSubmitContextSearch,
|
||||
onToggleContextActive,
|
||||
onViewContextDetail,
|
||||
}}
|
||||
workflowState={workflowPanelState}
|
||||
workflowConfig={{
|
||||
isVersionMode,
|
||||
onNewTopic,
|
||||
onSwitchTopic,
|
||||
onDeleteTopic,
|
||||
branchItems,
|
||||
onSetBranchStatus,
|
||||
workflowSteps,
|
||||
onAddImage,
|
||||
onImportDocument,
|
||||
creationTaskEventsCount: creationTaskEvents.length,
|
||||
onViewRunDetail,
|
||||
activeRunDetail,
|
||||
activeRunDetailLoading,
|
||||
runMetadataText,
|
||||
runMetadataSummary,
|
||||
onCopyText: writeThemeWorkbenchClipboardText,
|
||||
onRevealArtifactInFinder: handleRevealArtifactInFinder,
|
||||
onOpenArtifactWithDefaultApp: handleOpenArtifactWithDefaultApp,
|
||||
}}
|
||||
execLogState={execLogState}
|
||||
execLogConfig={{
|
||||
onLoadMoreHistory,
|
||||
historyHasMore,
|
||||
historyLoading,
|
||||
}}
|
||||
contextPanelProps={contextPanelProps}
|
||||
workflowPanelProps={workflowPanelProps}
|
||||
execLogProps={execLogProps}
|
||||
/>
|
||||
</ThemeWorkbenchSidebarShell>
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
@@ -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> | 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<typeof ThemeWorkbenchWorkflowPanel>["branchItems"];
|
||||
onSetBranchStatus: ComponentProps<
|
||||
typeof ThemeWorkbenchWorkflowPanel
|
||||
>["onSetBranchStatus"];
|
||||
workflowSteps: ComponentProps<typeof ThemeWorkbenchWorkflowPanel>["workflowSteps"];
|
||||
onAddImage?: () => Promise<void> | void;
|
||||
onImportDocument?: () => Promise<void> | void;
|
||||
creationTaskEventsCount: number;
|
||||
onViewRunDetail?: (runId: string) => void;
|
||||
activeRunDetail?: AgentRun | null;
|
||||
activeRunDetailLoading?: boolean;
|
||||
runMetadataText: string;
|
||||
runMetadataSummary: ThemeWorkbenchRunMetadataSummary;
|
||||
onCopyText: (text: string) => Promise<void> | void;
|
||||
onRevealArtifactInFinder: (
|
||||
artifactPath: string,
|
||||
sessionId?: string | null,
|
||||
) => Promise<void> | void;
|
||||
onOpenArtifactWithDefaultApp: (
|
||||
artifactPath: string,
|
||||
sessionId?: string | null,
|
||||
) => Promise<void> | 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 (
|
||||
<ThemeWorkbenchContextPanel
|
||||
contextItems={contextConfig.contextItems}
|
||||
searchContextItems={contextState.searchContextItems}
|
||||
orderedContextItems={contextState.orderedContextItems}
|
||||
selectedSearchResult={contextState.selectedSearchResult}
|
||||
latestSearchLabel={contextState.latestSearchLabel}
|
||||
contextBudget={contextConfig.contextBudget}
|
||||
contextSearchQuery={contextConfig.contextSearchQuery}
|
||||
contextSearchMode={contextConfig.contextSearchMode}
|
||||
contextSearchLoading={contextConfig.contextSearchLoading}
|
||||
contextSearchError={contextConfig.contextSearchError}
|
||||
contextSearchBlockedReason={contextConfig.contextSearchBlockedReason}
|
||||
isSearchActionDisabled={contextState.isSearchActionDisabled}
|
||||
searchInputRef={contextState.searchInputRef}
|
||||
onContextSearchQueryChange={contextConfig.onContextSearchQueryChange}
|
||||
onContextSearchModeChange={contextConfig.onContextSearchModeChange}
|
||||
onSubmitContextSearch={contextConfig.onSubmitContextSearch}
|
||||
onOpenAddContextDialog={contextState.openAddContextDialog}
|
||||
onSelectSearchResult={contextState.handleSelectSearchResult}
|
||||
onToggleContextActive={contextConfig.onToggleContextActive}
|
||||
onViewContextDetail={contextConfig.onViewContextDetail}
|
||||
addContextDialogOpen={contextState.addContextDialogOpen}
|
||||
addTextDialogOpen={contextState.addTextDialogOpen}
|
||||
addLinkDialogOpen={contextState.addLinkDialogOpen}
|
||||
contextDraftText={contextState.contextDraftText}
|
||||
contextDraftLink={contextState.contextDraftLink}
|
||||
contextCreateLoading={contextState.contextCreateLoading}
|
||||
contextCreateError={contextState.contextCreateError}
|
||||
contextDropActive={contextState.contextDropActive}
|
||||
onCloseAllContextDialogs={contextState.closeAllContextDialogs}
|
||||
onChooseContextFile={contextState.handleChooseContextFile}
|
||||
onDropContextFile={contextState.handleDropContextFile}
|
||||
onOpenTextContextDialog={contextState.openTextContextDialog}
|
||||
onOpenLinkContextDialog={contextState.openLinkContextDialog}
|
||||
onContextDraftTextChange={contextState.handleContextDraftTextChange}
|
||||
onContextDraftLinkChange={contextState.handleContextDraftLinkChange}
|
||||
onContextDropActiveChange={contextState.handleContextDropActiveChange}
|
||||
onSubmitTextContext={contextState.handleSubmitTextContext}
|
||||
onSubmitLinkContext={contextState.handleSubmitLinkContext}
|
||||
/>
|
||||
);
|
||||
return <ThemeWorkbenchContextPanel {...contextPanelProps} />;
|
||||
}
|
||||
if (activeTab === "workflow") {
|
||||
return (
|
||||
<ThemeWorkbenchWorkflowPanel
|
||||
isVersionMode={workflowConfig.isVersionMode}
|
||||
onNewTopic={workflowConfig.onNewTopic}
|
||||
onSwitchTopic={workflowConfig.onSwitchTopic}
|
||||
onDeleteTopic={workflowConfig.onDeleteTopic}
|
||||
branchItems={workflowConfig.branchItems}
|
||||
onSetBranchStatus={workflowConfig.onSetBranchStatus}
|
||||
workflowSteps={workflowConfig.workflowSteps}
|
||||
completedSteps={workflowState.completedSteps}
|
||||
progressPercent={workflowState.progressPercent}
|
||||
onAddImage={workflowConfig.onAddImage}
|
||||
onImportDocument={workflowConfig.onImportDocument}
|
||||
creationTaskEventsCount={workflowConfig.creationTaskEventsCount}
|
||||
showCreationTasks={workflowState.showCreationTasks}
|
||||
onToggleCreationTasks={workflowState.toggleCreationTasks}
|
||||
groupedCreationTaskEvents={workflowState.groupedCreationTaskEvents}
|
||||
showActivityLogs={workflowState.showActivityLogs}
|
||||
onToggleActivityLogs={workflowState.toggleActivityLogs}
|
||||
groupedActivityLogs={workflowState.groupedActivityLogs}
|
||||
onViewRunDetail={workflowConfig.onViewRunDetail}
|
||||
activeRunDetail={workflowConfig.activeRunDetail}
|
||||
activeRunDetailLoading={workflowConfig.activeRunDetailLoading}
|
||||
activeRunStagesLabel={workflowState.activeRunStagesLabel}
|
||||
runMetadataText={workflowConfig.runMetadataText}
|
||||
runMetadataSummary={workflowConfig.runMetadataSummary}
|
||||
onCopyText={workflowConfig.onCopyText}
|
||||
onRevealArtifactInFinder={workflowConfig.onRevealArtifactInFinder}
|
||||
onOpenArtifactWithDefaultApp={workflowConfig.onOpenArtifactWithDefaultApp}
|
||||
/>
|
||||
);
|
||||
return <ThemeWorkbenchWorkflowPanel {...workflowPanelProps} />;
|
||||
}
|
||||
if (activeTab === "log") {
|
||||
return (
|
||||
<ThemeWorkbenchExecLog
|
||||
entries={execLogState.visibleExecLogEntries}
|
||||
totalEntriesCount={execLogState.execLogEntries.length}
|
||||
wasCleared={execLogState.wasExecLogCleared}
|
||||
onClear={execLogState.clearExecLog}
|
||||
onLoadMoreHistory={execLogConfig.onLoadMoreHistory}
|
||||
historyHasMore={execLogConfig.historyHasMore}
|
||||
historyLoading={execLogConfig.historyLoading}
|
||||
/>
|
||||
);
|
||||
return <ThemeWorkbenchExecLog {...execLogProps} />;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -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> | void;
|
||||
onRevealArtifactInFinder: (
|
||||
artifactPath: string,
|
||||
sessionId?: string | null,
|
||||
) => Promise<void> | 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,
|
||||
};
|
||||
}
|
||||
@@ -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)
|
||||
);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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> | void;
|
||||
onImportDocument?: () => Promise<void> | 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> | 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<string, SkillDetailInfo | null>;
|
||||
messages?: Message[];
|
||||
}
|
||||
|
||||
export interface ThemeWorkbenchSidebarProps
|
||||
extends ThemeWorkbenchSidebarShellContract,
|
||||
ThemeWorkbenchSidebarWorkflowContract,
|
||||
ThemeWorkbenchSidebarContextContract,
|
||||
ThemeWorkbenchSidebarExecLogContract {}
|
||||
@@ -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<BuildThemeWorkbenchContextPanelPropsParams, "contextPanelState"> {
|
||||
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<BuildThemeWorkbenchExecLogPropsParams, "execLogState"> {
|
||||
messages: Message[];
|
||||
skillDetailMap: Record<string, SkillDetailInfo | null>;
|
||||
}
|
||||
|
||||
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<string, SkillDetailInfo | null>;
|
||||
}
|
||||
|
||||
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,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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 [];
|
||||
|
||||
@@ -21,17 +21,17 @@ import {
|
||||
resolveThemeWorkbenchFileNameFromPath,
|
||||
} from "./themeWorkbenchSidebarShared";
|
||||
|
||||
type AddTextContextHandler = (payload: {
|
||||
export type ThemeWorkbenchAddTextContextAction = (payload: {
|
||||
content: string;
|
||||
name?: string;
|
||||
}) => Promise<void> | void;
|
||||
|
||||
type AddLinkContextHandler = (payload: {
|
||||
export type ThemeWorkbenchAddLinkContextAction = (payload: {
|
||||
url: string;
|
||||
name?: string;
|
||||
}) => Promise<void> | void;
|
||||
|
||||
type AddFileContextHandler = (payload: {
|
||||
export type ThemeWorkbenchAddFileContextAction = (payload: {
|
||||
path: string;
|
||||
name?: string;
|
||||
}) => Promise<void> | 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 {
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
};
|
||||
}
|
||||
@@ -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,
|
||||
|
||||