├── .gitmodules ├── agents ├── SRAgent │ ├── open_deep_research │ │ ├── answer.json │ │ ├── __init__.py │ │ ├── workflow │ │ │ ├── configuration.py │ │ │ └── state.py │ │ ├── state.py │ │ └── configuration.py │ ├── Nexusagent_SR │ │ ├── prompt │ │ │ └── __init__.py │ │ ├── tool │ │ │ ├── __init__.py │ │ │ ├── task_manager.py │ │ │ ├── pysr_config.py │ │ │ ├── agent_tool.py │ │ │ ├── summarize_report.py │ │ │ └── deepresearch.py │ │ ├── __init__.py │ │ └── subagent.py │ ├── nexus-ui │ │ ├── postcss.config.js │ │ ├── src │ │ │ ├── App.tsx │ │ │ ├── main.tsx │ │ │ ├── components │ │ │ │ ├── Badge.tsx │ │ │ │ ├── Card.tsx │ │ │ │ ├── Button.tsx │ │ │ │ ├── ResizablePanel.tsx │ │ │ │ └── Layout.tsx │ │ │ └── hooks │ │ │ │ └── useAgentConfig.ts │ │ ├── tsconfig.node.json │ │ ├── index.html │ │ ├── vite.config.ts │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── README.md │ │ └── tailwind.config.js │ ├── data │ │ └── README.md │ ├── start-nexus.sh │ ├── .gitignore │ ├── config │ │ ├── agent-config.json │ │ └── agent_config.py │ ├── requirements.txt │ ├── docs │ │ └── AGENT_CONFIGURATION_GUIDE.md │ └── README.md ├── dpa_calculator │ ├── __init__.py │ ├── reqirements.txt │ ├── .env.template │ └── agent.py ├── DPA_Agent │ ├── agent │ │ ├── __init__.py │ │ └── agent.py │ ├── ui │ │ ├── postcss.config.js │ │ ├── src │ │ │ ├── App.tsx │ │ │ ├── main.tsx │ │ │ ├── components │ │ │ │ ├── Badge.tsx │ │ │ │ ├── Card.tsx │ │ │ │ ├── MemoizedMarkdown.tsx │ │ │ │ ├── Button.tsx │ │ │ │ ├── ResizablePanel.tsx │ │ │ │ ├── MemoizedMessage.tsx │ │ │ │ ├── Layout.tsx │ │ │ │ └── MessageAnimation.tsx │ │ │ └── hooks │ │ │ │ └── useAgentConfig.ts │ │ ├── tsconfig.node.json │ │ ├── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── vite.config.ts │ │ ├── README.md │ │ └── tailwind.config.js │ ├── requirements.txt │ ├── config │ │ ├── README.md │ │ ├── agent-config.json │ │ └── agent_config.py │ ├── start-agent.sh │ ├── README.md │ └── docs │ │ └── CONFIG_GUIDE.md ├── adk_ui_starter │ ├── agent │ │ ├── __init__.py │ │ ├── agent.py │ │ └── server.py │ ├── ui │ │ ├── postcss.config.js │ │ ├── src │ │ │ ├── App.tsx │ │ │ ├── main.tsx │ │ │ ├── components │ │ │ │ ├── Badge.tsx │ │ │ │ ├── Card.tsx │ │ │ │ ├── MemoizedMarkdown.tsx │ │ │ │ ├── Button.tsx │ │ │ │ ├── ResizablePanel.tsx │ │ │ │ ├── MemoizedMessage.tsx │ │ │ │ ├── Layout.tsx │ │ │ │ └── MessageAnimation.tsx │ │ │ └── hooks │ │ │ │ └── useAgentConfig.ts │ │ ├── tsconfig.node.json │ │ ├── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── vite.config.ts │ │ ├── README.md │ │ └── tailwind.config.js │ ├── requirements.txt │ ├── config │ │ ├── README.md │ │ ├── agent-config.json │ │ └── agent_config.py │ ├── .gitignore │ ├── QUICKSTART.md │ ├── start-agent.sh │ ├── README.md │ ├── docs │ │ └── CONFIG_GUIDE.md │ ├── CLAUDE.md │ └── ui-introduction.md ├── paper_search_demo │ ├── __init__.py │ └── agent.py └── thermoelectric_mcp │ ├── __init__.py │ └── agent.py ├── LICENSE ├── .gitignore └── README.md /.gitmodules: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /agents/SRAgent/open_deep_research/answer.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /agents/dpa_calculator/__init__.py: -------------------------------------------------------------------------------- 1 | from . import agent -------------------------------------------------------------------------------- /agents/DPA_Agent/agent/__init__.py: -------------------------------------------------------------------------------- 1 | from . import agent 2 | -------------------------------------------------------------------------------- /agents/adk_ui_starter/agent/__init__.py: -------------------------------------------------------------------------------- 1 | from . import agent 2 | -------------------------------------------------------------------------------- /agents/paper_search_demo/__init__.py: -------------------------------------------------------------------------------- 1 | from . import agent 2 | -------------------------------------------------------------------------------- /agents/thermoelectric_mcp/__init__.py: -------------------------------------------------------------------------------- 1 | from . import agent 2 | -------------------------------------------------------------------------------- /agents/SRAgent/Nexusagent_SR/prompt/__init__.py: -------------------------------------------------------------------------------- 1 | from .agent_prompt import * -------------------------------------------------------------------------------- /agents/SRAgent/open_deep_research/__init__.py: -------------------------------------------------------------------------------- 1 | """Planning, research, and report generation.""" 2 | 3 | __version__ = "0.0.15" -------------------------------------------------------------------------------- /agents/dpa_calculator/reqirements.txt: -------------------------------------------------------------------------------- 1 | nest_asyncio 2 | python-dotenv 3 | numpy 4 | google-adk 5 | science-agent-sdk 6 | litellm 7 | -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/src/App.tsx: -------------------------------------------------------------------------------- 1 | import ChatInterface from './components/ChatInterface' 2 | 3 | function App() { 4 | return 5 | } 6 | 7 | export default App -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/src/App.tsx: -------------------------------------------------------------------------------- 1 | import ChatInterface from './components/ChatInterface' 2 | 3 | function App() { 4 | return 5 | } 6 | 7 | export default App -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/src/App.tsx: -------------------------------------------------------------------------------- 1 | import ChatInterface from './components/ChatInterface' 2 | 3 | function App() { 4 | return 5 | } 6 | 7 | export default App -------------------------------------------------------------------------------- /agents/dpa_calculator/.env.template: -------------------------------------------------------------------------------- 1 | BOHRIUM_EMAIL= 2 | BOHRIUM_PASSWORD= 3 | BOHRIUM_PROJECT_ID= 4 | 5 | AZURE_API_KEY= 6 | AZURE_API_BASE= 7 | AZURE_API_VERSION= 8 | -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App' 4 | import './styles/index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')!).render( 7 | 8 | ) -------------------------------------------------------------------------------- /agents/SRAgent/Nexusagent_SR/tool/__init__.py: -------------------------------------------------------------------------------- 1 | from .pysr import * 2 | from .agent_tool import * 3 | from .task_manager import * 4 | from .pysr_config import * 5 | from .summarize_report import * 6 | from .utils import * 7 | from .deepresearch import * -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App' 4 | import './styles/index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')!).render( 7 | 8 | ) -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App' 4 | import './styles/index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')!).render( 7 | 8 | ) -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } -------------------------------------------------------------------------------- /agents/DPA_Agent/requirements.txt: -------------------------------------------------------------------------------- 1 | # OpenAI and LLM 2 | openai 3 | litellm 4 | google-adk 5 | google-genai 6 | 7 | # Environment and configuration 8 | python-dotenv 9 | pydantic 10 | 11 | # HTTP and async 12 | httpx 13 | aiofiles 14 | aiohttp 15 | requests 16 | 17 | # WebSocket Server 18 | fastapi 19 | uvicorn[standard] 20 | 21 | # Type checking and development 22 | typing-extensions 23 | httpx[socks] 24 | 25 | # Arxiv 26 | arxiv -------------------------------------------------------------------------------- /agents/adk_ui_starter/requirements.txt: -------------------------------------------------------------------------------- 1 | # OpenAI and LLM 2 | openai 3 | litellm 4 | google-adk 5 | google-genai 6 | 7 | # Environment and configuration 8 | python-dotenv 9 | pydantic 10 | 11 | # HTTP and async 12 | httpx 13 | aiofiles 14 | aiohttp 15 | requests 16 | 17 | # WebSocket Server 18 | fastapi 19 | uvicorn[standard] 20 | 21 | # Type checking and development 22 | typing-extensions 23 | httpx[socks] 24 | 25 | # Arxiv 26 | arxiv -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | NexusAgent UI 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | NexusAgent UI 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | NexusAgent UI 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /agents/SRAgent/data/README.md: -------------------------------------------------------------------------------- 1 | # 示例数据说明 2 | 3 | 本目录包含用于演示 NexusAgent-SR 功能的示例数据集。 4 | 5 | ## 数据集列表 6 | 7 | ### hr_example.csv 8 | - **描述**: 生物物理神经元动力学系统数据 9 | - **变量**: 10 | - `x1`: 膜电位 11 | - `x2`: 快速激活变量(如快速离子通道) 12 | - `x3`: 慢速适应变量(如慢速钾或钙电流) 13 | - `y`: 膜电位变化率 (dx₁/dt) 14 | - **用途**: 推断膜电位变化的微分方程形式 15 | 16 | 17 | ## 数据格式要求 18 | 19 | 使用 NexusAgent-SR 时,输入数据应满足: 20 | 1. CSV 格式,第一行为列名 21 | 2. 最后一列为目标变量(y) 22 | 3. 其他列为特征变量(x1, x2, ...) 23 | 4. 数据应预先清洗,无缺失值 24 | 25 | ## 使用示例 26 | 27 | ```python 28 | # 在对话中使用数据 29 | "我正在进行符号回归任务,数据路径是 /path/to/data/hr_example.csv" 30 | ``` -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | import path from 'path' 4 | 5 | export default defineConfig({ 6 | plugins: [react()], 7 | resolve: { 8 | alias: { 9 | '@': path.resolve(__dirname, './src'), 10 | }, 11 | }, 12 | server: { 13 | port: 5173, 14 | proxy: { 15 | '/api': { 16 | target: 'http://localhost:8000', 17 | changeOrigin: true, 18 | }, 19 | '/ws': { 20 | target: 'ws://localhost:8000', 21 | ws: true, 22 | }, 23 | }, 24 | }, 25 | }) -------------------------------------------------------------------------------- /agents/SRAgent/Nexusagent_SR/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | NexusAgent Symbolic Regression 3 | 4 | A research-grade symbolic regression workflow orchestration system 5 | that automatically transforms raw data into scientifically interpretable mathematical models. 6 | """ 7 | 8 | from pathlib import Path 9 | from dotenv import load_dotenv 10 | 11 | # 加载环境变量 12 | env_path = Path(__file__).resolve().parent / ".env" 13 | load_dotenv(env_path, override=False) 14 | 15 | __version__ = "1.0.0" 16 | __author__ = "NexusAgent Team" 17 | __license__ = "MIT" 18 | 19 | # 从 subagent 导入 rootagent 20 | from Nexusagent_SR.subagent import rootagent 21 | 22 | __all__ = [ 23 | "rootagent", 24 | ] 25 | -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/src/components/Badge.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import classNames from 'classnames' 3 | 4 | interface BadgeProps { 5 | children: React.ReactNode 6 | variant?: 'success' | 'warning' | 'error' | 'info' 7 | className?: string 8 | } 9 | 10 | const Badge: React.FC = ({ 11 | children, 12 | variant = 'info', 13 | className 14 | }) => { 15 | const variantClasses = { 16 | success: 'badge-success', 17 | warning: 'badge-warning', 18 | error: 'badge-error', 19 | info: 'badge-info', 20 | } 21 | 22 | return ( 23 | 24 | {children} 25 | 26 | ) 27 | } 28 | 29 | export default Badge -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/src/components/Badge.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import classNames from 'classnames' 3 | 4 | interface BadgeProps { 5 | children: React.ReactNode 6 | variant?: 'success' | 'warning' | 'error' | 'info' 7 | className?: string 8 | } 9 | 10 | const Badge: React.FC = ({ 11 | children, 12 | variant = 'info', 13 | className 14 | }) => { 15 | const variantClasses = { 16 | success: 'badge-success', 17 | warning: 'badge-warning', 18 | error: 'badge-error', 19 | info: 'badge-info', 20 | } 21 | 22 | return ( 23 | 24 | {children} 25 | 26 | ) 27 | } 28 | 29 | export default Badge -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/src/components/Badge.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import classNames from 'classnames' 3 | 4 | interface BadgeProps { 5 | children: React.ReactNode 6 | variant?: 'success' | 'warning' | 'error' | 'info' 7 | className?: string 8 | } 9 | 10 | const Badge: React.FC = ({ 11 | children, 12 | variant = 'info', 13 | className 14 | }) => { 15 | const variantClasses = { 16 | success: 'badge-success', 17 | warning: 'badge-warning', 18 | error: 'badge-error', 19 | info: 'badge-info', 20 | } 21 | 22 | return ( 23 | 24 | {children} 25 | 26 | ) 27 | } 28 | 29 | export default Badge -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 5 | "module": "ESNext", 6 | "skipLibCheck": true, 7 | "moduleResolution": "bundler", 8 | "allowImportingTsExtensions": true, 9 | "resolveJsonModule": true, 10 | "isolatedModules": true, 11 | "noEmit": true, 12 | "jsx": "react-jsx", 13 | "strict": true, 14 | "noUnusedLocals": true, 15 | "noUnusedParameters": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "esModuleInterop": true, 18 | "forceConsistentCasingInFileNames": true, 19 | "baseUrl": ".", 20 | "paths": { 21 | "@/*": ["c/*"] 22 | } 23 | }, 24 | "include": ["c"], 25 | "references": [{ "path": "./tsconfig.node.json" }] 26 | } -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 5 | "module": "ESNext", 6 | "skipLibCheck": true, 7 | "moduleResolution": "bundler", 8 | "allowImportingTsExtensions": true, 9 | "resolveJsonModule": true, 10 | "isolatedModules": true, 11 | "noEmit": true, 12 | "jsx": "react-jsx", 13 | "strict": true, 14 | "noUnusedLocals": true, 15 | "noUnusedParameters": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "esModuleInterop": true, 18 | "forceConsistentCasingInFileNames": true, 19 | "baseUrl": ".", 20 | "paths": { 21 | "@/*": ["src/*"] 22 | } 23 | }, 24 | "include": ["src"], 25 | "references": [{ "path": "./tsconfig.node.json" }] 26 | } -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 5 | "module": "ESNext", 6 | "skipLibCheck": true, 7 | "moduleResolution": "bundler", 8 | "allowImportingTsExtensions": true, 9 | "resolveJsonModule": true, 10 | "isolatedModules": true, 11 | "noEmit": true, 12 | "jsx": "react-jsx", 13 | "strict": true, 14 | "noUnusedLocals": true, 15 | "noUnusedParameters": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "esModuleInterop": true, 18 | "forceConsistentCasingInFileNames": true, 19 | "baseUrl": ".", 20 | "paths": { 21 | "@/*": ["c/*"] 22 | } 23 | }, 24 | "include": ["c"], 25 | "references": [{ "path": "./tsconfig.node.json" }] 26 | } -------------------------------------------------------------------------------- /agents/DPA_Agent/config/README.md: -------------------------------------------------------------------------------- 1 | # 配置说明 2 | 3 | ## server 配置 4 | 5 | 在 `agent-config.json` 中的 `server` 部分用于配置前端开发服务器和访问控制: 6 | 7 | ```json 8 | "server": { 9 | "port": 50002, 10 | "allowedHosts": ["cofg1321640.bohrium.tech"] 11 | } 12 | ``` 13 | 14 | ### 配置项说明 15 | 16 | - **port**: 前端开发服务器端口(默认:50002) 17 | - **allowedHosts**: 额外允许访问的主机列表 18 | 19 | ### 默认允许的主机 20 | 21 | 以下主机始终被允许访问,无需在配置中声明: 22 | - `localhost` 23 | - `127.0.0.1` 24 | - `0.0.0.0` 25 | 26 | ### 使用示例 27 | 28 | 如果你需要允许额外的主机访问(例如远程服务器域名),只需在 `allowedHosts` 中添加: 29 | 30 | ```json 31 | "server": { 32 | "port": 50002, 33 | "allowedHosts": [ 34 | "example.com", 35 | "myserver.local", 36 | "192.168.1.100" 37 | ] 38 | } 39 | ``` 40 | 41 | 这些配置会同时应用于: 42 | 1. Vite 开发服务器的 `allowedHosts` 配置 43 | 2. WebSocket 服务器的 CORS 配置和 Host 验证 -------------------------------------------------------------------------------- /agents/adk_ui_starter/config/README.md: -------------------------------------------------------------------------------- 1 | # 配置说明 2 | 3 | ## server 配置 4 | 5 | 在 `agent-config.json` 中的 `server` 部分用于配置前端开发服务器和访问控制: 6 | 7 | ```json 8 | "server": { 9 | "port": 50002, 10 | "allowedHosts": ["cofg1321640.bohrium.tech"] 11 | } 12 | ``` 13 | 14 | ### 配置项说明 15 | 16 | - **port**: 前端开发服务器端口(默认:50002) 17 | - **allowedHosts**: 额外允许访问的主机列表 18 | 19 | ### 默认允许的主机 20 | 21 | 以下主机始终被允许访问,无需在配置中声明: 22 | - `localhost` 23 | - `127.0.0.1` 24 | - `0.0.0.0` 25 | 26 | ### 使用示例 27 | 28 | 如果你需要允许额外的主机访问(例如远程服务器域名),只需在 `allowedHosts` 中添加: 29 | 30 | ```json 31 | "server": { 32 | "port": 50002, 33 | "allowedHosts": [ 34 | "example.com", 35 | "myserver.local", 36 | "192.168.1.100" 37 | ] 38 | } 39 | ``` 40 | 41 | 这些配置会同时应用于: 42 | 1. Vite 开发服务器的 `allowedHosts` 配置 43 | 2. WebSocket 服务器的 CORS 配置和 Host 验证 -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/src/components/Card.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { motion } from 'framer-motion' 3 | import classNames from 'classnames' 4 | 5 | interface CardProps { 6 | children: React.ReactNode 7 | className?: string 8 | hoverable?: boolean 9 | onClick?: () => void 10 | } 11 | 12 | const Card: React.FC = ({ 13 | children, 14 | className, 15 | hoverable = false, 16 | onClick 17 | }) => { 18 | return ( 19 | 30 | {children} 31 | 32 | ) 33 | } 34 | 35 | export default Card -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/src/components/Card.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { motion } from 'framer-motion' 3 | import classNames from 'classnames' 4 | 5 | interface CardProps { 6 | children: React.ReactNode 7 | className?: string 8 | hoverable?: boolean 9 | onClick?: () => void 10 | } 11 | 12 | const Card: React.FC = ({ 13 | children, 14 | className, 15 | hoverable = false, 16 | onClick 17 | }) => { 18 | return ( 19 | 30 | {children} 31 | 32 | ) 33 | } 34 | 35 | export default Card -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/src/components/Card.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { motion } from 'framer-motion' 3 | import classNames from 'classnames' 4 | 5 | interface CardProps { 6 | children: React.ReactNode 7 | className?: string 8 | hoverable?: boolean 9 | onClick?: () => void 10 | } 11 | 12 | const Card: React.FC = ({ 13 | children, 14 | className, 15 | hoverable = false, 16 | onClick 17 | }) => { 18 | return ( 19 | 30 | {children} 31 | 32 | ) 33 | } 34 | 35 | export default Card -------------------------------------------------------------------------------- /agents/SRAgent/start-nexus.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "🚀 启动 NexusAgent 系统..." 4 | 5 | # 清理现有进程 6 | echo "清理现有进程..." 7 | pkill -f "nexus-websocket-server.py" 2>/dev/null 8 | pkill -f "vite" 2>/dev/null 9 | sleep 1 10 | 11 | # 创建输出目录 12 | mkdir -p output 13 | 14 | # 启动 WebSocket 服务器(集成了 Agent) 15 | echo "启动 NexusAgent WebSocket 服务器..." 16 | python nexus-websocket-server.py > websocket.log 2>&1 & 17 | WEBSOCKET_PID=$! 18 | 19 | # 启动前端 20 | echo "启动前端..." 21 | cd nexus-ui 22 | npm run dev > ../frontend.log 2>&1 & 23 | FRONTEND_PID=$! 24 | cd .. 25 | 26 | echo "" 27 | echo "✅ NexusAgent 系统已启动!" 28 | echo "WebSocket 服务器: http://localhost:8000 (PID: $WEBSOCKET_PID)" 29 | echo "前端界面: http://localhost:5173 (PID: $FRONTEND_PID)" 30 | echo "" 31 | echo "日志文件:" 32 | echo "- 服务器日志: websocket.log" 33 | echo "- 前端日志: frontend.log" 34 | echo "使用方法:" 35 | echo "在浏览器中打开 http://localhost:5173" 36 | echo "" 37 | echo "按 Ctrl+C 停止所有服务" 38 | echo "" 39 | 40 | # 捕获 Ctrl+C 41 | trap "echo '停止所有服务...'; kill $WEBSOCKET_PID $FRONTEND_PID 2>/dev/null; exit" INT 42 | 43 | # 保持脚本运行 44 | wait -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Yuzhi Zhang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "-ui", 3 | "version": "1.0.0", 4 | "description": "Beautiful Apple-style UI for Agent-", 5 | "private": true, 6 | "dependencies": { 7 | "react": "^18.2.0", 8 | "react-dom": "^18.2.0", 9 | "react-router-dom": "^6.20.0", 10 | "react-markdown": "^9.0.1", 11 | "remark-gfm": "^4.0.0", 12 | "react-syntax-highlighter": "^15.5.0", 13 | "framer-motion": "^10.16.0", 14 | "lucide-react": "^0.292.0", 15 | "axios": "^1.6.2", 16 | "socket.io-client": "^4.5.4", 17 | "date-fns": "^2.30.0", 18 | "classnames": "^2.3.2", 19 | "@tailwindcss/typography": "^0.5.10" 20 | }, 21 | "devDependencies": { 22 | "@types/react": "^18.2.0", 23 | "@types/react-dom": "^18.2.0", 24 | "@types/react-syntax-highlighter": "^15.5.11", 25 | "@vitejs/plugin-react": "^4.2.0", 26 | "autoprefixer": "^10.4.16", 27 | "postcss": "^8.4.32", 28 | "tailwindcss": "^3.3.6", 29 | "typescript": "^5.3.0", 30 | "vite": "^5.0.0" 31 | }, 32 | "scripts": { 33 | "dev": "vite", 34 | "build": "tsc && vite build", 35 | "preview": "vite preview", 36 | "type-check": "tsc --noEmit" 37 | } 38 | } -------------------------------------------------------------------------------- /agents/adk_ui_starter/agent/agent.py: -------------------------------------------------------------------------------- 1 | import os 2 | import asyncio 3 | from google.adk.agents import Agent 4 | from google.adk.models.lite_llm import LiteLlm 5 | from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset 6 | from google.adk.tools.mcp_tool.mcp_session_manager import SseServerParams 7 | from google.adk.runners import InMemoryRunner 8 | from google.adk.sessions import InMemorySessionService 9 | from google.adk.tools import FunctionTool 10 | from typing import Any, Dict 11 | import openai 12 | from dotenv import load_dotenv 13 | 14 | 15 | 16 | # Load environment variables from .env file 17 | load_dotenv(os.path.join(os.path.dirname(__file__), '.env')) 18 | 19 | # Use model from environment or default to deepseek 20 | model_type = os.getenv('MODEL', 'deepseek/deepseek-chat') 21 | 22 | 23 | toolset = MCPToolset( 24 | connection_params=SseServerParams( 25 | url="http://localhost:50001/sse", 26 | ), 27 | ) 28 | 29 | # Create agent 30 | root_agent = Agent( 31 | name="mcp_sse_agent", 32 | model=LiteLlm(model=model_type), 33 | instruction="You are an intelligent assistant capable of using external tools via MCP.", 34 | tools=[toolset] 35 | ) 36 | -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "-ui", 3 | "version": "1.0.0", 4 | "description": "Beautiful Apple-style UI for Agent-", 5 | "private": true, 6 | "dependencies": { 7 | "react": "^18.2.0", 8 | "react-dom": "^18.2.0", 9 | "react-router-dom": "^6.20.0", 10 | "react-markdown": "^9.0.1", 11 | "remark-gfm": "^4.0.0", 12 | "react-syntax-highlighter": "^15.5.0", 13 | "framer-motion": "^10.16.0", 14 | "lucide-react": "^0.292.0", 15 | "axios": "^1.6.2", 16 | "socket.io-client": "^4.5.4", 17 | "date-fns": "^2.30.0", 18 | "classnames": "^2.3.2", 19 | "@tailwindcss/typography": "^0.5.10" 20 | }, 21 | "devDependencies": { 22 | "@types/react": "^18.2.0", 23 | "@types/react-dom": "^18.2.0", 24 | "@types/react-syntax-highlighter": "^15.5.11", 25 | "@vitejs/plugin-react": "^4.2.0", 26 | "autoprefixer": "^10.4.16", 27 | "postcss": "^8.4.32", 28 | "tailwindcss": "^3.3.6", 29 | "typescript": "^5.3.0", 30 | "vite": "^5.0.0" 31 | }, 32 | "scripts": { 33 | "dev": "vite", 34 | "build": "tsc && vite build", 35 | "preview": "vite preview", 36 | "type-check": "tsc --noEmit" 37 | } 38 | } -------------------------------------------------------------------------------- /agents/SRAgent/.gitignore: -------------------------------------------------------------------------------- 1 | # Python 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | *.so 6 | .Python 7 | build/ 8 | develop-eggs/ 9 | dist/ 10 | downloads/ 11 | eggs/ 12 | .eggs/ 13 | lib/ 14 | lib64/ 15 | parts/ 16 | sdist/ 17 | var/ 18 | wheels/ 19 | *.egg-info/ 20 | .installed.cfg 21 | *.egg 22 | MANIFEST 23 | 24 | # Virtual Environment 25 | venv/ 26 | ENV/ 27 | env/ 28 | .venv 29 | 30 | # IDE 31 | .vscode/ 32 | .idea/ 33 | *.swp 34 | *.swo 35 | *~ 36 | .DS_Store 37 | 38 | # Environment variables 39 | .env 40 | .env.local 41 | .env.*.local 42 | 43 | # Logs 44 | logs/ 45 | *.log 46 | npm-debug.log* 47 | yarn-debug.log* 48 | yarn-error.log* 49 | 50 | # Node 51 | node_modules/ 52 | .npm 53 | .yarn-integrity 54 | 55 | # Build output 56 | output/ 57 | !output/.gitkeep 58 | *.tmp 59 | 60 | 61 | # Test coverage 62 | htmlcov/ 63 | .tox/ 64 | .coverage 65 | .coverage.* 66 | .cache 67 | nosetests.xml 68 | coverage.xml 69 | *.cover 70 | .hypothesis/ 71 | .pytest_cache/ 72 | 73 | # Jupyter Notebook 74 | .ipynb_checkpoints 75 | 76 | # Production build 77 | nexus-ui/dist/ 78 | nexus-ui/build/ 79 | 80 | # Misc 81 | .DS_Store 82 | .env.local 83 | .env.development.local 84 | .env.test.local 85 | .env.production.local -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nexus-ui", 3 | "version": "1.0.0", 4 | "description": "Beautiful Apple-style UI for NexusAgent-SR", 5 | "private": true, 6 | "dependencies": { 7 | "react": "^18.2.0", 8 | "react-dom": "^18.2.0", 9 | "react-router-dom": "^6.20.0", 10 | "react-markdown": "^9.0.1", 11 | "remark-gfm": "^4.0.0", 12 | "react-syntax-highlighter": "^15.5.0", 13 | "framer-motion": "^10.16.0", 14 | "lucide-react": "^0.292.0", 15 | "axios": "^1.6.2", 16 | "socket.io-client": "^4.5.4", 17 | "date-fns": "^2.30.0", 18 | "classnames": "^2.3.2", 19 | "@tailwindcss/typography": "^0.5.10" 20 | }, 21 | "devDependencies": { 22 | "@types/react": "^18.2.0", 23 | "@types/react-dom": "^18.2.0", 24 | "@types/react-syntax-highlighter": "^15.5.11", 25 | "@vitejs/plugin-react": "^4.2.0", 26 | "autoprefixer": "^10.4.16", 27 | "postcss": "^8.4.32", 28 | "tailwindcss": "^3.3.6", 29 | "typescript": "^5.3.0", 30 | "vite": "^5.0.0" 31 | }, 32 | "scripts": { 33 | "dev": "vite", 34 | "build": "tsc && vite build", 35 | "preview": "vite preview", 36 | "type-check": "tsc --noEmit" 37 | } 38 | } -------------------------------------------------------------------------------- /agents/adk_ui_starter/.gitignore: -------------------------------------------------------------------------------- 1 | # Python 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | *.so 6 | .Python 7 | build/ 8 | develop-eggs/ 9 | dist/ 10 | downloads/ 11 | eggs/ 12 | .eggs/ 13 | lib/ 14 | lib64/ 15 | parts/ 16 | sdist/ 17 | var/ 18 | wheels/ 19 | *.egg-info/ 20 | .installed.cfg 21 | *.egg 22 | MANIFEST 23 | 24 | # Virtual Environment 25 | venv/ 26 | ENV/ 27 | env/ 28 | .venv 29 | 30 | # IDE 31 | .vscode/ 32 | .idea/ 33 | *.swp 34 | *.swo 35 | *~ 36 | .DS_Store 37 | 38 | # Environment variables 39 | .env 40 | .env.local 41 | .env.*.local 42 | 43 | # Logs 44 | logs/ 45 | *.log 46 | npm-debug.log* 47 | yarn-debug.log* 48 | yarn-error.log* 49 | 50 | # Node 51 | node_modules/ 52 | .npm 53 | .yarn-integrity 54 | 55 | # Build output 56 | output/ 57 | !output/.gitkeep 58 | *.tmp 59 | 60 | 61 | # Test coverage 62 | htmlcov/ 63 | .tox/ 64 | .coverage 65 | .coverage.* 66 | .cache 67 | nosetests.xml 68 | coverage.xml 69 | *.cover 70 | .hypothesis/ 71 | .pytest_cache/ 72 | 73 | # Jupyter Notebook 74 | .ipynb_checkpoints 75 | 76 | # Production build 77 | -ui/dist/ 78 | -ui/build/ 79 | 80 | # Misc 81 | .DS_Store 82 | .env.local 83 | .env.development.local 84 | .env.test.local 85 | .env.production.local -------------------------------------------------------------------------------- /agents/adk_ui_starter/config/agent-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "agent": { 3 | "name": "Agent", 4 | "description": "Custom Agent", 5 | "welcomeMessage": "Welcome to chat with me", 6 | "module": "agent.agent", 7 | "rootAgent": "root_agent" 8 | }, 9 | "ui": { 10 | "title": "My Agent", 11 | "theme": { 12 | "primaryColor": "blue", 13 | "secondaryColor": "purple" 14 | }, 15 | "features": { 16 | "showFileExplorer": true, 17 | "showSessionList": true, 18 | "enableFileUpload": false 19 | } 20 | }, 21 | "files": { 22 | "outputDirectory": "output", 23 | "watchDirectories": ["output"], 24 | "fileExtensions": { 25 | "supported": ["json", "md", "txt", "csv", "py", "js", "ts", "log"], 26 | "defaultViewer": { 27 | "json": "code", 28 | "md": "markdown", 29 | "csv": "table", 30 | "default": "code" 31 | } 32 | } 33 | }, 34 | "websocket": { 35 | "host": "localhost", 36 | "port": 8000, 37 | "reconnectInterval": 3000, 38 | "maxReconnectAttempts": 10 39 | }, 40 | "session": { 41 | "persistent": false, 42 | "maxSessions": 50, 43 | "defaultSessionTitle": "New Session" 44 | }, 45 | "server": { 46 | "port": 50002, 47 | "allowedHosts": ["localhost", "127.0.0.1", "0.0.0.0", "*"] 48 | } 49 | } -------------------------------------------------------------------------------- /agents/DPA_Agent/config/agent-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "agent": { 3 | "name": "DPA Agent", 4 | "description": "DPA Agent", 5 | "welcomeMessage": "Start material simulation with starting a conversation.", 6 | "module": "agent.agent", 7 | "rootAgent": "root_agent" 8 | }, 9 | "ui": { 10 | "title": "DPA Agent", 11 | "theme": { 12 | "primaryColor": "blue", 13 | "secondaryColor": "green" 14 | }, 15 | "features": { 16 | "showFileExplorer": true, 17 | "showSessionList": true, 18 | "enableFileUpload": false 19 | } 20 | }, 21 | "files": { 22 | "outputDirectory": "output", 23 | "watchDirectories": ["output"], 24 | "fileExtensions": { 25 | "supported": ["json", "md", "txt", "csv", "py", "js", "ts", "log"], 26 | "defaultViewer": { 27 | "json": "code", 28 | "md": "markdown", 29 | "csv": "table", 30 | "default": "code" 31 | } 32 | } 33 | }, 34 | "websocket": { 35 | "host": "localhost", 36 | "port": 8000, 37 | "reconnectInterval": 3000, 38 | "maxReconnectAttempts": 10 39 | }, 40 | "session": { 41 | "persistent": false, 42 | "maxSessions": 50, 43 | "defaultSessionTitle": "New Session" 44 | }, 45 | "server": { 46 | "port": 50002, 47 | "allowedHosts": ["localhost", "127.0.0.1", "0.0.0.0", "*"] 48 | } 49 | } -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/src/components/MemoizedMarkdown.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactMarkdown from 'react-markdown'; 3 | import remarkGfm from 'remark-gfm'; 4 | import { createCodeComponent } from './EnhancedCodeBlock'; 5 | 6 | interface MemoizedMarkdownProps { 7 | children: string; 8 | className?: string; 9 | } 10 | 11 | export const MemoizedMarkdown = React.memo(({ children, className }) => { 12 | return ( 13 | 27 | {children} 28 | 29 | ); 30 | }, 31 | p({ children }: any) { 32 | return

{children}

; 33 | } 34 | }} 35 | > 36 | {children} 37 |
38 | ); 39 | }, (prevProps, nextProps) => { 40 | // 只有当内容真正改变时才重新渲染 41 | return prevProps.children === nextProps.children; 42 | }); 43 | 44 | MemoizedMarkdown.displayName = 'MemoizedMarkdown'; -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/src/components/MemoizedMarkdown.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactMarkdown from 'react-markdown'; 3 | import remarkGfm from 'remark-gfm'; 4 | import { createCodeComponent } from './EnhancedCodeBlock'; 5 | 6 | interface MemoizedMarkdownProps { 7 | children: string; 8 | className?: string; 9 | } 10 | 11 | export const MemoizedMarkdown = React.memo(({ children, className }) => { 12 | return ( 13 | 27 | {children} 28 | 29 | ); 30 | }, 31 | p({ children }: any) { 32 | return

{children}

; 33 | } 34 | }} 35 | > 36 | {children} 37 |
38 | ); 39 | }, (prevProps, nextProps) => { 40 | // 只有当内容真正改变时才重新渲染 41 | return prevProps.children === nextProps.children; 42 | }); 43 | 44 | MemoizedMarkdown.displayName = 'MemoizedMarkdown'; -------------------------------------------------------------------------------- /agents/paper_search_demo/agent.py: -------------------------------------------------------------------------------- 1 | import os 2 | import asyncio 3 | from google.adk.agents import Agent 4 | from google.adk.models.lite_llm import LiteLlm 5 | from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset 6 | from google.adk.tools.mcp_tool.mcp_session_manager import SseServerParams 7 | from google.adk.runners import InMemoryRunner 8 | from google.adk.sessions import InMemorySessionService 9 | from google.adk.tools import FunctionTool 10 | from typing import Any, Dict 11 | import openai 12 | 13 | # Set environment variables if needed 14 | 15 | #Use deepseek 16 | os.environ['DEEPSEEK_API_KEY'] = "" 17 | 18 | #Use gpt-4o 19 | os.environ["AZURE_OPENAI_ENDPOINT"] = "" 20 | os.environ["AZURE_OPENAI_API_KEY"] = "" 21 | os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"] = "" 22 | 23 | 24 | # Configure SSE params 25 | sse_params = SseServerParams( 26 | url="", 27 | ) 28 | 29 | toolset = MCPToolset( 30 | connection_params=SseServerParams( 31 | url="", 32 | ), 33 | ) 34 | 35 | 36 | use_model = "deepseek" 37 | 38 | if use_model == "deepseek": 39 | model = LiteLlm(model="deepseek/deepseek-chat") 40 | if use_model == "gpt-4o": 41 | model = LiteLlm(model="azure/gpt-4o") 42 | 43 | # Create agent 44 | root_agent = Agent( 45 | name="mcp_sse_agent", 46 | model=model, 47 | instruction="You are an intelligent assistant capable of using external tools via MCP.", 48 | tools=[toolset] 49 | ) 50 | -------------------------------------------------------------------------------- /agents/SRAgent/config/agent-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "agent": { 3 | "name": "NexusAgent SR", 4 | "description": "智能符号回归分析系统", 5 | "welcomeMessage": "输入您的数据文件路径,开始符号回归分析", 6 | "module": "Nexusagent_SR.subagent", 7 | "rootAgent": "rootagent" 8 | }, 9 | "ui": { 10 | "title": "My Agent", 11 | "theme": { 12 | "primaryColor": "blue", 13 | "secondaryColor": "purple" 14 | }, 15 | "features": { 16 | "showFileExplorer": true, 17 | "showSessionList": true, 18 | "enableFileUpload": false 19 | } 20 | }, 21 | "files": { 22 | "outputDirectory": "output", 23 | "watchDirectories": ["output"], 24 | "fileExtensions": { 25 | "supported": ["json", "md", "txt", "csv", "py", "js", "ts", "log"], 26 | "defaultViewer": { 27 | "json": "code", 28 | "md": "markdown", 29 | "csv": "table", 30 | "default": "code" 31 | } 32 | } 33 | }, 34 | "websocket": { 35 | "host": "localhost", 36 | "port": 8000, 37 | "reconnectInterval": 3000, 38 | "maxReconnectAttempts": 10 39 | }, 40 | "session": { 41 | "persistent": false, 42 | "maxSessions": 50, 43 | "defaultSessionTitle": "新对话" 44 | }, 45 | "tools": { 46 | "displayNames": { 47 | "generate_data_description_tool": "数据描述生成", 48 | "set_unary_operators_tool": "设置一元运算符", 49 | "run_symbolic_tool_pysr": "运行符号回归", 50 | "summarize_report_tool": "生成总结报告" 51 | }, 52 | "longRunningTools": [ 53 | ] 54 | } 55 | } -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/src/components/Button.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { motion } from 'framer-motion' 3 | import classNames from 'classnames' 4 | 5 | interface ButtonProps extends React.ButtonHTMLAttributes { 6 | variant?: 'primary' | 'secondary' | 'ghost' 7 | size?: 'sm' | 'md' | 'lg' 8 | icon?: React.ReactNode 9 | loading?: boolean 10 | } 11 | 12 | const Button: React.FC = ({ 13 | children, 14 | variant = 'primary', 15 | size = 'md', 16 | icon, 17 | loading = false, 18 | className, 19 | disabled, 20 | ...props 21 | }) => { 22 | const sizeClasses = { 23 | sm: 'px-3 py-1.5 text-sm', 24 | md: 'px-4 py-2', 25 | lg: 'px-6 py-3 text-lg', 26 | } 27 | 28 | const variantClasses = { 29 | primary: 'btn-primary', 30 | secondary: 'btn-secondary', 31 | ghost: 'btn-ghost', 32 | } 33 | 34 | return ( 35 | 49 | {loading ? ( 50 |
51 | ) : icon} 52 | {children} 53 | 54 | ) 55 | } 56 | 57 | export default Button -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/src/components/Button.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { motion } from 'framer-motion' 3 | import classNames from 'classnames' 4 | 5 | interface ButtonProps extends React.ButtonHTMLAttributes { 6 | variant?: 'primary' | 'secondary' | 'ghost' 7 | size?: 'sm' | 'md' | 'lg' 8 | icon?: React.ReactNode 9 | loading?: boolean 10 | } 11 | 12 | const Button: React.FC = ({ 13 | children, 14 | variant = 'primary', 15 | size = 'md', 16 | icon, 17 | loading = false, 18 | className, 19 | disabled, 20 | ...props 21 | }) => { 22 | const sizeClasses = { 23 | sm: 'px-3 py-1.5 text-sm', 24 | md: 'px-4 py-2', 25 | lg: 'px-6 py-3 text-lg', 26 | } 27 | 28 | const variantClasses = { 29 | primary: 'btn-primary', 30 | secondary: 'btn-secondary', 31 | ghost: 'btn-ghost', 32 | } 33 | 34 | return ( 35 | 49 | {loading ? ( 50 |
51 | ) : icon} 52 | {children} 53 | 54 | ) 55 | } 56 | 57 | export default Button -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/src/components/Button.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { motion } from 'framer-motion' 3 | import classNames from 'classnames' 4 | 5 | interface ButtonProps extends React.ButtonHTMLAttributes { 6 | variant?: 'primary' | 'secondary' | 'ghost' 7 | size?: 'sm' | 'md' | 'lg' 8 | icon?: React.ReactNode 9 | loading?: boolean 10 | } 11 | 12 | const Button: React.FC = ({ 13 | children, 14 | variant = 'primary', 15 | size = 'md', 16 | icon, 17 | loading = false, 18 | className, 19 | disabled, 20 | ...props 21 | }) => { 22 | const sizeClasses = { 23 | sm: 'px-3 py-1.5 text-sm', 24 | md: 'px-4 py-2', 25 | lg: 'px-6 py-3 text-lg', 26 | } 27 | 28 | const variantClasses = { 29 | primary: 'btn-primary', 30 | secondary: 'btn-secondary', 31 | ghost: 'btn-ghost', 32 | } 33 | 34 | return ( 35 | 49 | {loading ? ( 50 |
51 | ) : icon} 52 | {children} 53 | 54 | ) 55 | } 56 | 57 | export default Button -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | import path from 'path' 4 | import fs from 'fs' 5 | 6 | // 默认主机始终被允许 7 | const defaultHosts = ['localhost', '127.0.0.1', '0.0.0.0'] 8 | 9 | // 读取 agent-config.json 配置 10 | let serverConfig = { 11 | port: 50002, 12 | allowedHosts: defaultHosts 13 | } 14 | 15 | try { 16 | const configPath = path.resolve(__dirname, '../config/agent-config.json') 17 | const configData = fs.readFileSync(configPath, 'utf-8') 18 | const config = JSON.parse(configData) 19 | if (config.server) { 20 | // 合并默认主机和用户定义的额外主机 21 | const userHosts = config.server.allowedHosts || [] 22 | const allHosts = [...new Set([...defaultHosts, ...userHosts])] 23 | 24 | serverConfig = { 25 | port: config.server.port || 50002, 26 | allowedHosts: allHosts 27 | } 28 | } 29 | } catch (error) { 30 | console.warn('Failed to load agent-config.json, using defaults:', error) 31 | } 32 | 33 | export default defineConfig({ 34 | plugins: [react()], 35 | resolve: { 36 | alias: { 37 | '@': path.resolve(__dirname, './src'), 38 | }, 39 | }, 40 | server: { 41 | port: parseInt(process.env.FRONTEND_PORT || String(serverConfig.port)), 42 | allowedHosts: serverConfig.allowedHosts, 43 | host: '0.0.0.0', 44 | proxy: { 45 | '/api': { 46 | target: 'http://localhost:8000', 47 | changeOrigin: true, 48 | }, 49 | '/ws': { 50 | target: 'ws://localhost:8000', 51 | ws: true, 52 | changeOrigin: true, 53 | } 54 | } 55 | } 56 | }) // 添加缺失的闭合括号 -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | import path from 'path' 4 | import fs from 'fs' 5 | 6 | // 默认主机始终被允许 7 | const defaultHosts = ['localhost', '127.0.0.1', '0.0.0.0'] 8 | 9 | // 读取 agent-config.json 配置 10 | let serverConfig = { 11 | port: 50002, 12 | allowedHosts: defaultHosts 13 | } 14 | 15 | try { 16 | const configPath = path.resolve(__dirname, '../config/agent-config.json') 17 | const configData = fs.readFileSync(configPath, 'utf-8') 18 | const config = JSON.parse(configData) 19 | if (config.server) { 20 | // 合并默认主机和用户定义的额外主机 21 | const userHosts = config.server.allowedHosts || [] 22 | const allHosts = [...new Set([...defaultHosts, ...userHosts])] 23 | 24 | serverConfig = { 25 | port: config.server.port || 50002, 26 | allowedHosts: allHosts 27 | } 28 | } 29 | } catch (error) { 30 | console.warn('Failed to load agent-config.json, using defaults:', error) 31 | } 32 | 33 | export default defineConfig({ 34 | plugins: [react()], 35 | resolve: { 36 | alias: { 37 | '@': path.resolve(__dirname, './src'), 38 | }, 39 | }, 40 | server: { 41 | port: parseInt(process.env.FRONTEND_PORT || String(serverConfig.port)), 42 | allowedHosts: serverConfig.allowedHosts, 43 | allowedHosts: true, 44 | host: '0.0.0.0', 45 | proxy: { 46 | '/api': { 47 | target: 'http://localhost:8000', 48 | changeOrigin: true, 49 | }, 50 | '/ws': { 51 | target: 'ws://localhost:8000', 52 | ws: true, 53 | changeOrigin: true, 54 | } 55 | } 56 | } 57 | }) // 添加缺失的闭合括号 -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/README.md: -------------------------------------------------------------------------------- 1 | # Agent UI 2 | 3 | 一个优雅的UI界面,用于替代 Google ADK 的 web 界面,为 Agent- 提供美观的用户界面。 4 | 5 | ## 功能特性 6 | 7 | - 🎨 **Apple 风格设计** - 简约美观的界面设计 8 | - 📊 **实时任务监控** - 查看和管理符号回归任务 9 | - 📄 **文件查看器** - 支持 Markdown 和 JSON 文件的优雅展示 10 | - 🔄 **实时更新** - 通过 WebSocket 实现实时数据同步 11 | - ⚙️ **系统设置** - 配置 AI 模型、符号回归参数等 12 | 13 | ## 快速开始 14 | 15 | ### 前端启动 16 | 17 | ```bash 18 | cd -ui 19 | npm install 20 | npm run dev 21 | ``` 22 | 23 | 24 | ## 技术栈 25 | 26 | ### 前端 27 | - React 18 + TypeScript 28 | - Vite - 快速的开发构建工具 29 | - Tailwind CSS - 实用优先的 CSS 框架 30 | - Framer Motion - 流畅的动画效果 31 | - React Markdown - Markdown 渲染 32 | - Lucide React - 优雅的图标库 33 | 34 | ### 后端 35 | - FastAPI - 现代化的 Python Web 框架 36 | - WebSocket - 实时通信 37 | - Watchdog - 文件监控 38 | 39 | ## 项目结构 40 | 41 | ``` 42 | -ui/ 43 | ├──c/ 44 | │ ├── components/ # 可复用组件 45 | │ ├── pages/ # 页面组件 46 | │ ├── api/ # API 客户端 47 | │ ├── hooks/ # React Hooks 48 | │ └── styles/ # 样式文件 49 | ├── public/ # 静态资源 50 | └── ... 51 | 52 | ``` 53 | 54 | ## 主要页面 55 | 56 | 1. **Dashboard** - 系统概览和快速操作 57 | 2. **Tasks** - 任务管理和监控 58 | 3. **Files** - 文件浏览和查看 59 | 4. **Settings** - 系统配置 60 | 61 | ## API 端点 62 | 63 | - `GET /api/files/{path}` - 获取文件内容 64 | - `GET /api/tasks` - 获取所有任务 65 | - `POST /api/tasks` - 创建新任务 66 | - `GET /api/stats` - 获取系统统计 67 | - `WS /ws` - WebSocket 连接 68 | 69 | ## 开发说明 70 | 71 | ### 添加新组件 72 | 73 | 1. 在 `c/components` 创建组件文件 74 | 2. 使用 Apple 风格的设计规范 75 | 3. 利用 Tailwind CSS 类名 76 | 77 | ### 自定义主题 78 | 79 | 修改 `tailwind.config.js` 中的颜色配置: 80 | 81 | ```javascript 82 | colors: { 83 | 'apple-blue': '#0071e3', 84 | 'apple-green': '#34c759', 85 | // ... 86 | } 87 | ``` -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/README.md: -------------------------------------------------------------------------------- 1 | # Agent UI 2 | 3 | 一个优雅的UI界面,用于替代 Google ADK 的 web 界面,为 Agent- 提供美观的用户界面。 4 | 5 | ## 功能特性 6 | 7 | - 🎨 **Apple 风格设计** - 简约美观的界面设计 8 | - 📊 **实时任务监控** - 查看和管理符号回归任务 9 | - 📄 **文件查看器** - 支持 Markdown 和 JSON 文件的优雅展示 10 | - 🔄 **实时更新** - 通过 WebSocket 实现实时数据同步 11 | - ⚙️ **系统设置** - 配置 AI 模型、符号回归参数等 12 | 13 | ## 快速开始 14 | 15 | ### 前端启动 16 | 17 | ```bash 18 | cd -ui 19 | npm install 20 | npm run dev 21 | ``` 22 | 23 | 24 | ## 技术栈 25 | 26 | ### 前端 27 | - React 18 + TypeScript 28 | - Vite - 快速的开发构建工具 29 | - Tailwind CSS - 实用优先的 CSS 框架 30 | - Framer Motion - 流畅的动画效果 31 | - React Markdown - Markdown 渲染 32 | - Lucide React - 优雅的图标库 33 | 34 | ### 后端 35 | - FastAPI - 现代化的 Python Web 框架 36 | - WebSocket - 实时通信 37 | - Watchdog - 文件监控 38 | 39 | ## 项目结构 40 | 41 | ``` 42 | -ui/ 43 | ├──c/ 44 | │ ├── components/ # 可复用组件 45 | │ ├── pages/ # 页面组件 46 | │ ├── api/ # API 客户端 47 | │ ├── hooks/ # React Hooks 48 | │ └── styles/ # 样式文件 49 | ├── public/ # 静态资源 50 | └── ... 51 | 52 | ``` 53 | 54 | ## 主要页面 55 | 56 | 1. **Dashboard** - 系统概览和快速操作 57 | 2. **Tasks** - 任务管理和监控 58 | 3. **Files** - 文件浏览和查看 59 | 4. **Settings** - 系统配置 60 | 61 | ## API 端点 62 | 63 | - `GET /api/files/{path}` - 获取文件内容 64 | - `GET /api/tasks` - 获取所有任务 65 | - `POST /api/tasks` - 创建新任务 66 | - `GET /api/stats` - 获取系统统计 67 | - `WS /ws` - WebSocket 连接 68 | 69 | ## 开发说明 70 | 71 | ### 添加新组件 72 | 73 | 1. 在 `c/components` 创建组件文件 74 | 2. 使用 Apple 风格的设计规范 75 | 3. 利用 Tailwind CSS 类名 76 | 77 | ### 自定义主题 78 | 79 | 修改 `tailwind.config.js` 中的颜色配置: 80 | 81 | ```javascript 82 | colors: { 83 | 'apple-blue': '#0071e3', 84 | 'apple-green': '#34c759', 85 | // ... 86 | } 87 | ``` -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/README.md: -------------------------------------------------------------------------------- 1 | # NexusAgent UI 2 | 3 | 一个优雅的UI界面,用于替代 Google ADK 的 web 界面,为 NexusAgent-SR 提供美观的用户界面。 4 | 5 | ## 功能特性 6 | 7 | - 🎨 **Apple 风格设计** - 简约美观的界面设计 8 | - 📊 **实时任务监控** - 查看和管理符号回归任务 9 | - 📄 **文件查看器** - 支持 Markdown 和 JSON 文件的优雅展示 10 | - 🔄 **实时更新** - 通过 WebSocket 实现实时数据同步 11 | - ⚙️ **系统设置** - 配置 AI 模型、符号回归参数等 12 | 13 | ## 快速开始 14 | 15 | ### 前端启动 16 | 17 | ```bash 18 | cd nexus-ui 19 | npm install 20 | npm run dev 21 | ``` 22 | 23 | 24 | ## 技术栈 25 | 26 | ### 前端 27 | - React 18 + TypeScript 28 | - Vite - 快速的开发构建工具 29 | - Tailwind CSS - 实用优先的 CSS 框架 30 | - Framer Motion - 流畅的动画效果 31 | - React Markdown - Markdown 渲染 32 | - Lucide React - 优雅的图标库 33 | 34 | ### 后端 35 | - FastAPI - 现代化的 Python Web 框架 36 | - WebSocket - 实时通信 37 | - Watchdog - 文件监控 38 | 39 | ## 项目结构 40 | 41 | ``` 42 | nexus-ui/ 43 | ├── src/ 44 | │ ├── components/ # 可复用组件 45 | │ ├── pages/ # 页面组件 46 | │ ├── api/ # API 客户端 47 | │ ├── hooks/ # React Hooks 48 | │ └── styles/ # 样式文件 49 | ├── public/ # 静态资源 50 | └── ... 51 | 52 | ``` 53 | 54 | ## 主要页面 55 | 56 | 1. **Dashboard** - 系统概览和快速操作 57 | 2. **Tasks** - 任务管理和监控 58 | 3. **Files** - 文件浏览和查看 59 | 4. **Settings** - 系统配置 60 | 61 | ## API 端点 62 | 63 | - `GET /api/files/{path}` - 获取文件内容 64 | - `GET /api/tasks` - 获取所有任务 65 | - `POST /api/tasks` - 创建新任务 66 | - `GET /api/stats` - 获取系统统计 67 | - `WS /ws` - WebSocket 连接 68 | 69 | ## 开发说明 70 | 71 | ### 添加新组件 72 | 73 | 1. 在 `src/components` 创建组件文件 74 | 2. 使用 Apple 风格的设计规范 75 | 3. 利用 Tailwind CSS 类名 76 | 77 | ### 自定义主题 78 | 79 | 修改 `tailwind.config.js` 中的颜色配置: 80 | 81 | ```javascript 82 | colors: { 83 | 'apple-blue': '#0071e3', 84 | 'apple-green': '#34c759', 85 | // ... 86 | } 87 | ``` -------------------------------------------------------------------------------- /agents/adk_ui_starter/QUICKSTART.md: -------------------------------------------------------------------------------- 1 | # 🚀 5分钟快速开始 2 | 3 | ## 第一步:准备你的 Agent 4 | 5 | 确保你的 Agent 基于 Google ADK 开发,并导出为一个变量(如 `root_agent`)。 6 | 7 | ```python 8 | # your_agent.py 9 | from google.adk.agents import Agent 10 | from google.adk.models.lite_llm import LiteLlm 11 | 12 | root_agent = Agent( 13 | name="my_agent", 14 | model=LiteLlm(model="your-model"), 15 | instruction="你的 Agent 指令", 16 | tools=[...] 17 | ) 18 | ``` 19 | 20 | ## 第二步:配置文件 21 | 22 | 编辑 `config/agent-config.json`: 23 | 24 | ```json 25 | { 26 | "agent": { 27 | "name": "我的智能助手", 28 | "description": "一句话描述", 29 | "welcomeMessage": "欢迎使用!", 30 | "module": "your_agent", // 你的模块名 31 | "rootAgent": "root_agent" // 导出的变量名 32 | } 33 | } 34 | ``` 35 | 36 | ## 第三步:启动系统 37 | 38 | ```bash 39 | # 安装依赖 40 | pip install -r requirements.txt 41 | cd ui && npm install 42 | cd .. 43 | 44 | # 启动 45 | ./start-agent.sh 46 | ``` 47 | 48 | 打开浏览器访问 http://localhost:5173 49 | 50 | ## 🎨 可选:自定义 UI 51 | 52 | ### 修改主题颜色 53 | 编辑 `config/agent-config.json`: 54 | ```json 55 | "ui": { 56 | "theme": { 57 | "primaryColor": "blue", 58 | "secondaryColor": "purple" 59 | } 60 | } 61 | ``` 62 | 63 | ### 隐藏不需要的功能 64 | ```json 65 | "features": { 66 | "showFileExplorer": false, // 隐藏文件浏览器 67 | "showSessionList": false // 隐藏会话列表 68 | } 69 | ``` 70 | 71 | ## 📝 常见问题 72 | 73 | ### API Key 配置 74 | 在 `agent/.env` 文件中配置: 75 | ``` 76 | MODEL=deepseek/deepseek-chat 77 | DEEPSEEK_API_KEY=your_api_key 78 | ``` 79 | 80 | ### 端口冲突 81 | 修改 `websocket-server.py` 中的端口: 82 | ```python 83 | uvicorn.run(app, host="0.0.0.0", port=8001) # 改为其他端口 84 | ``` 85 | 86 | ## 🎯 最佳实践 87 | 88 | 1. **保持 Agent 简单** - UI 会自动处理复杂的交互 89 | 2. **使用标准工具格式** - 工具执行状态会自动显示 90 | 3. **返回 Markdown** - UI 会自动渲染格式 91 | -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./index.html", 5 | "./src/**/*.{js,ts,jsx,tsx}", 6 | ], 7 | darkMode: 'class', 8 | theme: { 9 | extend: { 10 | colors: { 11 | // Apple-inspired color palette 12 | 'apple-gray': { 13 | 50: '#fafafa', 14 | 100: '#f5f5f7', 15 | 200: '#e8e8ed', 16 | 300: '#d2d2d7', 17 | 400: '#86868b', 18 | 500: '#6e6e73', 19 | 600: '#48484a', 20 | 700: '#363639', 21 | 800: '#242426', 22 | 900: '#1d1d1f', 23 | }, 24 | 'apple-blue': '#0071e3', 25 | 'apple-green': '#34c759', 26 | 'apple-red': '#ff3b30', 27 | 'apple-yellow': '#ffcc00', 28 | 'apple-purple': '#af52de', 29 | 'apple-pink': '#ff2d55', 30 | }, 31 | fontFamily: { 32 | 'sf-pro': ['-apple-system', 'BlinkMacSystemFont', 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif'], 33 | }, 34 | animation: { 35 | 'fade-in': 'fadeIn 0.5s ease-in-out', 36 | 'slide-up': 'slideUp 0.3s ease-out', 37 | 'pulse-subtle': 'pulseSubtle 2s cubic-bezier(0.4, 0, 0.6, 1) infinite', 38 | }, 39 | keyframes: { 40 | fadeIn: { 41 | '0%': { opacity: '0' }, 42 | '100%': { opacity: '1' }, 43 | }, 44 | slideUp: { 45 | '0%': { transform: 'translateY(10px)', opacity: '0' }, 46 | '100%': { transform: 'translateY(0)', opacity: '1' }, 47 | }, 48 | pulseSubtle: { 49 | '0%, 100%': { opacity: '1' }, 50 | '50%': { opacity: '0.8' }, 51 | }, 52 | }, 53 | backdropBlur: { 54 | xs: '2px', 55 | }, 56 | }, 57 | }, 58 | plugins: [ 59 | require('@tailwindcss/typography'), 60 | ], 61 | } -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./index.html", 5 | "./src/**/*.{js,ts,jsx,tsx}", 6 | ], 7 | darkMode: 'class', 8 | theme: { 9 | extend: { 10 | colors: { 11 | // Apple-inspired color palette 12 | 'apple-gray': { 13 | 50: '#fafafa', 14 | 100: '#f5f5f7', 15 | 200: '#e8e8ed', 16 | 300: '#d2d2d7', 17 | 400: '#86868b', 18 | 500: '#6e6e73', 19 | 600: '#48484a', 20 | 700: '#363639', 21 | 800: '#242426', 22 | 900: '#1d1d1f', 23 | }, 24 | 'apple-blue': '#0071e3', 25 | 'apple-green': '#34c759', 26 | 'apple-red': '#ff3b30', 27 | 'apple-yellow': '#ffcc00', 28 | 'apple-purple': '#af52de', 29 | 'apple-pink': '#ff2d55', 30 | }, 31 | fontFamily: { 32 | 'sf-pro': ['-apple-system', 'BlinkMacSystemFont', 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif'], 33 | }, 34 | animation: { 35 | 'fade-in': 'fadeIn 0.5s ease-in-out', 36 | 'slide-up': 'slideUp 0.3s ease-out', 37 | 'pulse-subtle': 'pulseSubtle 2s cubic-bezier(0.4, 0, 0.6, 1) infinite', 38 | }, 39 | keyframes: { 40 | fadeIn: { 41 | '0%': { opacity: '0' }, 42 | '100%': { opacity: '1' }, 43 | }, 44 | slideUp: { 45 | '0%': { transform: 'translateY(10px)', opacity: '0' }, 46 | '100%': { transform: 'translateY(0)', opacity: '1' }, 47 | }, 48 | pulseSubtle: { 49 | '0%, 100%': { opacity: '1' }, 50 | '50%': { opacity: '0.8' }, 51 | }, 52 | }, 53 | backdropBlur: { 54 | xs: '2px', 55 | }, 56 | }, 57 | }, 58 | plugins: [ 59 | require('@tailwindcss/typography'), 60 | ], 61 | } -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./index.html", 5 | "./src/**/*.{js,ts,jsx,tsx}", 6 | ], 7 | darkMode: 'class', 8 | theme: { 9 | extend: { 10 | colors: { 11 | // Apple-inspired color palette 12 | 'apple-gray': { 13 | 50: '#fafafa', 14 | 100: '#f5f5f7', 15 | 200: '#e8e8ed', 16 | 300: '#d2d2d7', 17 | 400: '#86868b', 18 | 500: '#6e6e73', 19 | 600: '#48484a', 20 | 700: '#363639', 21 | 800: '#242426', 22 | 900: '#1d1d1f', 23 | }, 24 | 'apple-blue': '#0071e3', 25 | 'apple-green': '#34c759', 26 | 'apple-red': '#ff3b30', 27 | 'apple-yellow': '#ffcc00', 28 | 'apple-purple': '#af52de', 29 | 'apple-pink': '#ff2d55', 30 | }, 31 | fontFamily: { 32 | 'sf-pro': ['-apple-system', 'BlinkMacSystemFont', 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif'], 33 | }, 34 | animation: { 35 | 'fade-in': 'fadeIn 0.5s ease-in-out', 36 | 'slide-up': 'slideUp 0.3s ease-out', 37 | 'pulse-subtle': 'pulseSubtle 2s cubic-bezier(0.4, 0, 0.6, 1) infinite', 38 | }, 39 | keyframes: { 40 | fadeIn: { 41 | '0%': { opacity: '0' }, 42 | '100%': { opacity: '1' }, 43 | }, 44 | slideUp: { 45 | '0%': { transform: 'translateY(10px)', opacity: '0' }, 46 | '100%': { transform: 'translateY(0)', opacity: '1' }, 47 | }, 48 | pulseSubtle: { 49 | '0%, 100%': { opacity: '1' }, 50 | '50%': { opacity: '0.8' }, 51 | }, 52 | }, 53 | backdropBlur: { 54 | xs: '2px', 55 | }, 56 | }, 57 | }, 58 | plugins: [ 59 | require('@tailwindcss/typography'), 60 | ], 61 | } -------------------------------------------------------------------------------- /agents/SRAgent/Nexusagent_SR/tool/task_manager.py: -------------------------------------------------------------------------------- 1 | import threading 2 | import uuid 3 | from typing import Callable, Dict, Optional 4 | 5 | # Internal task status management 6 | _TASK_STORE = {} 7 | _ERROR_CACHE = {} 8 | _RESULT_CACHE = {} 9 | 10 | 11 | def submit_task(func: Callable[[], str]) -> str: 12 | """ 13 | Submit a background task (sync function), return task ID immediately. 14 | 15 | Args: 16 | func: function without parameters, returns str (execution result) 17 | 18 | Returns: 19 | task_id: for querying task status or result 20 | """ 21 | task_id = str(uuid.uuid4()) 22 | 23 | def worker(): 24 | try: 25 | result = func() 26 | _RESULT_CACHE[task_id] = result 27 | _TASK_STORE[task_id] = "completed" 28 | except Exception as e: 29 | _ERROR_CACHE[task_id] = str(e) 30 | _TASK_STORE[task_id] = "failed" 31 | 32 | _TASK_STORE[task_id] = "running" 33 | thread = threading.Thread(target=worker) 34 | thread.daemon = True 35 | thread.start() 36 | 37 | return task_id 38 | 39 | 40 | def get_task_status(task_id: str) -> str: 41 | """ 42 | Query task status. 43 | 44 | Returns: 45 | str: "✅ Completed" / "❌ Failed: ..." / "⏳ Running" / "❓ Unknown task" 46 | """ 47 | if _TASK_STORE.get(task_id) == "completed": 48 | return "✅ Completed" 49 | elif _TASK_STORE.get(task_id) == "failed": 50 | return f"❌ Failed: {_ERROR_CACHE[task_id]}" 51 | elif _TASK_STORE.get(task_id) == "running": 52 | return "⏳ Running" 53 | else: 54 | return "❓ Unknown task" 55 | 56 | 57 | def get_task_result(task_id: str) -> Optional[str]: 58 | """ 59 | Get task result (if completed). 60 | """ 61 | if _TASK_STORE.get(task_id) == "completed": 62 | return _RESULT_CACHE.get(task_id, "No result") 63 | return "Task not completed or failed" 64 | 65 | 66 | def get_task_error(task_id: str) -> Optional[str]: 67 | """ 68 | Get task failure information (if any). 69 | """ 70 | return _ERROR_CACHE.get(task_id, "No error information") -------------------------------------------------------------------------------- /agents/SRAgent/requirements.txt: -------------------------------------------------------------------------------- 1 | # Core dependencies 2 | pandas 3 | numpy 4 | sympy 5 | scipy 6 | pysr 7 | matplotlib 8 | seaborn 9 | 10 | # Machine Learning 11 | scikit-learn 12 | torch 13 | tensorboard 14 | joblib 15 | 16 | # OpenAI and LLM 17 | openai 18 | litellm 19 | google-adk 20 | google-genai 21 | 22 | # Search and Web Scraping 23 | exa-py 24 | tavily-python 25 | azure-search-documents 26 | azure-core 27 | duckduckgo-search 28 | beautifulsoup4 29 | markdownify 30 | 31 | # Environment and configuration 32 | python-dotenv 33 | pydantic 34 | 35 | # HTTP and async 36 | httpx 37 | aiofiles 38 | aiohttp 39 | requests 40 | 41 | # WebSocket Server 42 | fastapi 43 | uvicorn[standard] 44 | 45 | # Data handling 46 | openpyxl 47 | xlrd 48 | 49 | # Scientific computing 50 | tqdm 51 | psutil 52 | 53 | # Type checking and development 54 | typing-extensions 55 | httpx[socks] 56 | 57 | 58 | #deepresearch 59 | 60 | langgraph>=0.2.55 61 | langchain-community>=0.3.9 62 | langchain-openai>=0.3.7 63 | langchain-anthropic>=0.3.15 64 | langchain-mcp-adapters>=0.1.6 65 | langchain-deepseek>=0.1.2 66 | langchain-tavily 67 | langchain-groq>=0.2.4 68 | openai>=1.61.0 69 | tavily-python>=0.5.0 70 | arxiv>=2.1.3 71 | pymupdf>=1.25.3 72 | xmltodict>=0.14.2 73 | linkup-sdk>=0.2.3 74 | duckduckgo-search>=3.0.0 75 | exa-py>=1.8.8 76 | requests>=2.32.3 77 | beautifulsoup4==4.13.3 78 | python-dotenv>=1.0.1 79 | pytest 80 | httpx>=0.24.0 81 | markdownify>=0.11.6 82 | azure-identity>=1.21.0 83 | azure-search>=1.0.0b2 84 | azure-search-documents>=11.5.2 85 | rich>=13.0.0 86 | langgraph-cli[inmem]>=0.3.1 87 | langsmith>=0.3.37 88 | langchain-google-vertexai>=2.0.25 89 | langchain-google-genai>=2.1.5 90 | ipykernel>=6.29.5 91 | supabase>=2.15.3 92 | mcp>=1.9.4 93 | coverage>=7,<8 94 | beartype>=0.19,<0.22 95 | ipykernel>=6,<7 96 | ipython>=8,<9 97 | jax[cpu]>=0.4,<0.6 98 | jupyter>=1,<2 99 | mypy>=1,<2 100 | nbval>=0.11,<0.12 101 | pandas-stubs 102 | pre-commit>=3.0,<5 103 | pytest-cov>=5,<7 104 | pytest>=8,<9 105 | tensorboard>=2,<3 106 | torch>=2,<3 107 | types-openpyxl 108 | types-pytz -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/src/hooks/useAgentConfig.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react' 2 | import axios from 'axios' 3 | 4 | interface AgentConfig { 5 | agent: { 6 | name: string 7 | description: string 8 | welcomeMessage: string 9 | } 10 | ui: { 11 | title: string 12 | theme?: { 13 | primaryColor: string 14 | secondaryColor: string 15 | } 16 | features: { 17 | showFileExplorer: boolean 18 | showSessionList: boolean 19 | enableFileUpload?: boolean 20 | } 21 | } 22 | files: { 23 | outputDirectory: string 24 | watchDirectories: string[] 25 | } 26 | websocket: { 27 | host: string 28 | port: number 29 | reconnectInterval?: number 30 | } 31 | } 32 | 33 | const defaultConfig: AgentConfig = { 34 | agent: { 35 | name: 'Agent', 36 | description: '智能符号回归分析系统', 37 | welcomeMessage: '输入您的数据文件路径,开始符号回归分析' 38 | }, 39 | ui: { 40 | title: 'Agent', 41 | features: { 42 | showFileExplorer: true, 43 | showSessionList: true 44 | } 45 | }, 46 | files: { 47 | outputDirectory: 'output', 48 | watchDirectories: ['output'] 49 | }, 50 | websocket: { 51 | host: 'localhost', 52 | port: 8000 53 | } 54 | } 55 | 56 | export function useAgentConfig() { 57 | const [config, setConfig] = useState(defaultConfig) 58 | const [loading, setLoading] = useState(true) 59 | const [error, setError] = useState(null) 60 | 61 | useEffect(() => { 62 | const fetchConfig = async () => { 63 | try { 64 | const response = await axios.get('/api/config') 65 | setConfig(response.data) 66 | 67 | // Update document title 68 | if (response.data.ui?.title) { 69 | document.title = response.data.ui.title 70 | } 71 | } catch (err) { 72 | console.error('Failed to load agent config:', err) 73 | setError('Failed to load configuration') 74 | // Use default config on error 75 | } finally { 76 | setLoading(false) 77 | } 78 | } 79 | 80 | fetchConfig() 81 | }, []) 82 | 83 | return { config, loading, error } 84 | } -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/src/hooks/useAgentConfig.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react' 2 | import axios from 'axios' 3 | 4 | interface AgentConfig { 5 | agent: { 6 | name: string 7 | description: string 8 | welcomeMessage: string 9 | } 10 | ui: { 11 | title: string 12 | theme?: { 13 | primaryColor: string 14 | secondaryColor: string 15 | } 16 | features: { 17 | showFileExplorer: boolean 18 | showSessionList: boolean 19 | enableFileUpload?: boolean 20 | } 21 | } 22 | files: { 23 | outputDirectory: string 24 | watchDirectories: string[] 25 | } 26 | websocket: { 27 | host: string 28 | port: number 29 | reconnectInterval?: number 30 | } 31 | } 32 | 33 | const defaultConfig: AgentConfig = { 34 | agent: { 35 | name: 'Agent', 36 | description: '智能符号回归分析系统', 37 | welcomeMessage: '输入您的数据文件路径,开始符号回归分析' 38 | }, 39 | ui: { 40 | title: 'Agent', 41 | features: { 42 | showFileExplorer: true, 43 | showSessionList: true 44 | } 45 | }, 46 | files: { 47 | outputDirectory: 'output', 48 | watchDirectories: ['output'] 49 | }, 50 | websocket: { 51 | host: 'localhost', 52 | port: 8000 53 | } 54 | } 55 | 56 | export function useAgentConfig() { 57 | const [config, setConfig] = useState(defaultConfig) 58 | const [loading, setLoading] = useState(true) 59 | const [error, setError] = useState(null) 60 | 61 | useEffect(() => { 62 | const fetchConfig = async () => { 63 | try { 64 | const response = await axios.get('/api/config') 65 | setConfig(response.data) 66 | 67 | // Update document title 68 | if (response.data.ui?.title) { 69 | document.title = response.data.ui.title 70 | } 71 | } catch (err) { 72 | console.error('Failed to load agent config:', err) 73 | setError('Failed to load configuration') 74 | // Use default config on error 75 | } finally { 76 | setLoading(false) 77 | } 78 | } 79 | 80 | fetchConfig() 81 | }, []) 82 | 83 | return { config, loading, error } 84 | } -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/src/hooks/useAgentConfig.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react' 2 | import axios from 'axios' 3 | 4 | interface AgentConfig { 5 | agent: { 6 | name: string 7 | description: string 8 | welcomeMessage: string 9 | } 10 | ui: { 11 | title: string 12 | theme?: { 13 | primaryColor: string 14 | secondaryColor: string 15 | } 16 | features: { 17 | showFileExplorer: boolean 18 | showSessionList: boolean 19 | enableFileUpload?: boolean 20 | } 21 | } 22 | files: { 23 | outputDirectory: string 24 | watchDirectories: string[] 25 | } 26 | websocket: { 27 | host: string 28 | port: number 29 | reconnectInterval?: number 30 | } 31 | } 32 | 33 | const defaultConfig: AgentConfig = { 34 | agent: { 35 | name: 'NexusAgent SR', 36 | description: '智能符号回归分析系统', 37 | welcomeMessage: '输入您的数据文件路径,开始符号回归分析' 38 | }, 39 | ui: { 40 | title: 'NexusAgent SR', 41 | features: { 42 | showFileExplorer: true, 43 | showSessionList: true 44 | } 45 | }, 46 | files: { 47 | outputDirectory: 'output', 48 | watchDirectories: ['output'] 49 | }, 50 | websocket: { 51 | host: 'localhost', 52 | port: 8000 53 | } 54 | } 55 | 56 | export function useAgentConfig() { 57 | const [config, setConfig] = useState(defaultConfig) 58 | const [loading, setLoading] = useState(true) 59 | const [error, setError] = useState(null) 60 | 61 | useEffect(() => { 62 | const fetchConfig = async () => { 63 | try { 64 | const response = await axios.get('/api/config') 65 | setConfig(response.data) 66 | 67 | // Update document title 68 | if (response.data.ui?.title) { 69 | document.title = response.data.ui.title 70 | } 71 | } catch (err) { 72 | console.error('Failed to load agent config:', err) 73 | setError('Failed to load configuration') 74 | // Use default config on error 75 | } finally { 76 | setLoading(false) 77 | } 78 | } 79 | 80 | fetchConfig() 81 | }, []) 82 | 83 | return { config, loading, error } 84 | } -------------------------------------------------------------------------------- /agents/SRAgent/open_deep_research/workflow/configuration.py: -------------------------------------------------------------------------------- 1 | from open_deep_research.configuration import DEFAULT_REPORT_STRUCTURE, SearchAPI 2 | from dataclasses import dataclass, fields 3 | from typing import Optional, Dict, Any, Literal 4 | from langchain_core.runnables import RunnableConfig 5 | import os 6 | 7 | 8 | @dataclass(kw_only=True) 9 | class WorkflowConfiguration: 10 | """Configuration for the workflow/graph-based implementation (graph.py).""" 11 | # Common configuration 12 | report_structure: str = DEFAULT_REPORT_STRUCTURE 13 | search_api: SearchAPI = SearchAPI.TAVILY 14 | search_api_config: Optional[Dict[str, Any]] = None 15 | clarify_with_user: bool = False 16 | sections_user_approval: bool = False 17 | process_search_results: Literal["summarize", "split_and_rerank"] | None = "summarize" 18 | summarization_model_provider: str = "anthropic" 19 | summarization_model: str = "claude-3-5-haiku-latest" 20 | max_structured_output_retries: int = 3 21 | include_source_str: bool = False 22 | 23 | # Workflow-specific configuration 24 | number_of_queries: int = 2 # Number of search queries to generate per iteration 25 | max_search_depth: int = 2 # Maximum number of reflection + search iterations 26 | planner_provider: str = "anthropic" 27 | planner_model: str = "claude-3-7-sonnet-latest" 28 | planner_model_kwargs: Optional[Dict[str, Any]] = None 29 | writer_provider: str = "anthropic" 30 | writer_model: str = "claude-3-7-sonnet-latest" 31 | writer_model_kwargs: Optional[Dict[str, Any]] = None 32 | 33 | @classmethod 34 | def from_runnable_config( 35 | cls, config: Optional[RunnableConfig] = None 36 | ) -> "WorkflowConfiguration": 37 | """Create a WorkflowConfiguration instance from a RunnableConfig.""" 38 | configurable = ( 39 | config["configurable"] if config and "configurable" in config else {} 40 | ) 41 | values: dict[str, Any] = { 42 | f.name: os.environ.get(f.name.upper(), configurable.get(f.name)) 43 | for f in fields(cls) 44 | if f.init 45 | } 46 | return cls(**{k: v for k, v in values.items() if v}) -------------------------------------------------------------------------------- /agents/DPA_Agent/start-agent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "🚀 启动 Agent 系统..." 4 | 5 | # 清理现有进程 6 | echo "清理现有进程..." 7 | pkill -f "websocket-server.py" 2>/dev/null 8 | pkill -f "vite" 2>/dev/null 9 | sleep 1 10 | 11 | # 创建输出目录 12 | mkdir -p output 13 | 14 | # 获取配置信息 15 | CONFIG_FILE="config/agent-config.json" 16 | if [ -f "$CONFIG_FILE" ]; then 17 | FRONTEND_PORT=$(python -c "import json; c=json.load(open('$CONFIG_FILE')); print(c.get('server',{}).get('port',50002))" 2>/dev/null || echo "50002") 18 | WEBSOCKET_PORT=$(python -c "import json; c=json.load(open('$CONFIG_FILE')); print(c.get('websocket',{}).get('port',8000))" 2>/dev/null || echo "8000") 19 | ALLOWED_HOSTS=$(python -c "import json; c=json.load(open('$CONFIG_FILE')); hosts=c.get('server',{}).get('allowedHosts',[]); print(', '.join(hosts) if hosts else 'None')" 2>/dev/null || echo "None") 20 | else 21 | FRONTEND_PORT="50002" 22 | WEBSOCKET_PORT="8000" 23 | ALLOWED_HOSTS="None" 24 | fi 25 | 26 | # 启动 WebSocket 服务器(集成了 Agent) 27 | echo "启动 Agent WebSocket 服务器..." 28 | python websocket-server.py > websocket.log 2>&1 & 29 | WEBSOCKET_PID=$! 30 | 31 | # 启动前端 32 | echo "启动前端开发服务器..." 33 | cd ui 34 | npm run dev > ../frontend.log 2>&1 & 35 | FRONTEND_PID=$! 36 | cd .. 37 | 38 | # 等待服务启动 39 | sleep 2 40 | 41 | echo "" 42 | echo "╔══════════════════════════════════════════════════════════════════╗" 43 | echo "║ ✅ Agent 系统已成功启动! ║" 44 | echo "╚══════════════════════════════════════════════════════════════════╝" 45 | echo "" 46 | echo "📡 服务状态:" 47 | echo "├─ WebSocket 服务器: http://localhost:$WEBSOCKET_PORT (PID: $WEBSOCKET_PID)" 48 | echo "└─ 前端开发服务器: http://localhost:$FRONTEND_PORT (PID: $FRONTEND_PID)" 49 | echo "" 50 | echo "🌐 访问地址:" 51 | echo "├─ 本地访问: http://localhost:$FRONTEND_PORT" 52 | if [ "$ALLOWED_HOSTS" != "None" ]; then 53 | echo "└─ 额外允许的主机: $ALLOWED_HOSTS" 54 | fi 55 | echo "" 56 | echo "📁 日志文件:" 57 | echo "├─ 服务器日志: ./websocket.log" 58 | echo "└─ 前端日志: ./frontend.log" 59 | echo "" 60 | echo "💡 提示:" 61 | echo "• 在浏览器中打开上述地址开始使用" 62 | echo "• 使用 tail -f websocket.log 查看服务器日志" 63 | echo "• 按 Ctrl+C 停止所有服务" 64 | echo "" 65 | 66 | # 捕获 Ctrl+C 67 | trap "echo '停止所有服务...'; kill $WEBSOCKET_PID $FRONTEND_PID 2>/dev/null; exit" INT 68 | 69 | # 保持脚本运行 70 | wait -------------------------------------------------------------------------------- /agents/adk_ui_starter/start-agent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "🚀 启动 Agent 系统..." 4 | 5 | # 清理现有进程 6 | echo "清理现有进程..." 7 | pkill -f "websocket-server.py" 2>/dev/null 8 | pkill -f "vite" 2>/dev/null 9 | sleep 1 10 | 11 | # 创建输出目录 12 | mkdir -p output 13 | 14 | # 获取配置信息 15 | CONFIG_FILE="config/agent-config.json" 16 | if [ -f "$CONFIG_FILE" ]; then 17 | FRONTEND_PORT=$(python -c "import json; c=json.load(open('$CONFIG_FILE')); print(c.get('server',{}).get('port',50002))" 2>/dev/null || echo "50002") 18 | WEBSOCKET_PORT=$(python -c "import json; c=json.load(open('$CONFIG_FILE')); print(c.get('websocket',{}).get('port',8000))" 2>/dev/null || echo "8000") 19 | ALLOWED_HOSTS=$(python -c "import json; c=json.load(open('$CONFIG_FILE')); hosts=c.get('server',{}).get('allowedHosts',[]); print(', '.join(hosts) if hosts else 'None')" 2>/dev/null || echo "None") 20 | else 21 | FRONTEND_PORT="50002" 22 | WEBSOCKET_PORT="8000" 23 | ALLOWED_HOSTS="None" 24 | fi 25 | 26 | # 启动 WebSocket 服务器(集成了 Agent) 27 | echo "启动 Agent WebSocket 服务器..." 28 | python websocket-server.py > websocket.log 2>&1 & 29 | WEBSOCKET_PID=$! 30 | 31 | # 启动前端 32 | echo "启动前端开发服务器..." 33 | cd ui 34 | npm run dev > ../frontend.log 2>&1 & 35 | FRONTEND_PID=$! 36 | cd .. 37 | 38 | # 等待服务启动 39 | sleep 2 40 | 41 | echo "" 42 | echo "╔══════════════════════════════════════════════════════════════════╗" 43 | echo "║ ✅ Agent 系统已成功启动! ║" 44 | echo "╚══════════════════════════════════════════════════════════════════╝" 45 | echo "" 46 | echo "📡 服务状态:" 47 | echo "├─ WebSocket 服务器: http://localhost:$WEBSOCKET_PORT (PID: $WEBSOCKET_PID)" 48 | echo "└─ 前端开发服务器: http://localhost:$FRONTEND_PORT (PID: $FRONTEND_PID)" 49 | echo "" 50 | echo "🌐 访问地址:" 51 | echo "├─ 本地访问: http://localhost:$FRONTEND_PORT" 52 | if [ "$ALLOWED_HOSTS" != "None" ]; then 53 | echo "└─ 额外允许的主机: $ALLOWED_HOSTS" 54 | fi 55 | echo "" 56 | echo "📁 日志文件:" 57 | echo "├─ 服务器日志: ./websocket.log" 58 | echo "└─ 前端日志: ./frontend.log" 59 | echo "" 60 | echo "💡 提示:" 61 | echo "• 在浏览器中打开上述地址开始使用" 62 | echo "• 使用 tail -f websocket.log 查看服务器日志" 63 | echo "• 按 Ctrl+C 停止所有服务" 64 | echo "" 65 | 66 | # 捕获 Ctrl+C 67 | trap "echo '停止所有服务...'; kill $WEBSOCKET_PID $FRONTEND_PID 2>/dev/null; exit" INT 68 | 69 | # 保持脚本运行 70 | wait -------------------------------------------------------------------------------- /agents/SRAgent/Nexusagent_SR/tool/pysr_config.py: -------------------------------------------------------------------------------- 1 | """ 2 | Simple PySR configuration management 3 | """ 4 | 5 | import json 6 | import os 7 | from pathlib import Path 8 | from typing import Dict, List, Union, Optional 9 | 10 | 11 | def load_pysr_config(config_path: str = "output/task_config_pysr.json") -> Dict: 12 | """Load PySR configuration from JSON file""" 13 | if not os.path.exists(config_path): 14 | # Default configuration 15 | default_config = { 16 | "unary_operators": ["exp=e^x", "log=log(x)", "sin=sin(x)", "cos=cos(x)", "sqrt=sqrt(x)"], 17 | } 18 | save_pysr_config(default_config, config_path) 19 | return default_config 20 | 21 | with open(config_path, 'r', encoding='utf-8') as f: 22 | return json.load(f) 23 | 24 | 25 | def save_pysr_config(config: Dict, config_path: str = "output/task_config_pysr.json"): 26 | """Save PySR configuration to JSON file""" 27 | os.makedirs(os.path.dirname(config_path), exist_ok=True) 28 | with open(config_path, 'w', encoding='utf-8') as f: 29 | json.dump(config, f, indent=2, ensure_ascii=False) 30 | 31 | 32 | def create_pysr_config( 33 | unary_operators: List[str] = None, 34 | parameters: Optional[List[Union[float, str, int]]] = None, 35 | config_path: str = "output/task_config_pysr.json" 36 | ) -> Dict: 37 | """Create PySR configuration""" 38 | config = load_pysr_config(config_path) 39 | 40 | if unary_operators: 41 | config["unary_operators"] = unary_operators 42 | if parameters is not None: 43 | config["parameters"] = parameters 44 | 45 | save_pysr_config(config, config_path) 46 | return config 47 | 48 | 49 | def set_unary_operators(unary_operators: List[str], config_path: str = "output/task_config_pysr.json"): 50 | """Set unary operators""" 51 | config = load_pysr_config(config_path) 52 | config["unary_operators"] = unary_operators 53 | save_pysr_config(config, config_path) 54 | 55 | 56 | def set_binary_operators(binary_operators: List[str], config_path: str = "output/task_config_pysr.json"): 57 | """Set binary operators""" 58 | config = load_pysr_config(config_path) 59 | config["binary_operators"] = binary_operators 60 | save_pysr_config(config, config_path) 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /agents/dpa_calculator/agent.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import os 3 | from pathlib import Path 4 | from typing import Any, Dict 5 | 6 | import nest_asyncio 7 | from dotenv import load_dotenv 8 | from dp.agent.adapter.adk import CalculationMCPToolset 9 | from google.adk.agents import LlmAgent 10 | from google.adk.models.lite_llm import LiteLlm 11 | from google.adk.runners import Runner 12 | from google.adk.sessions import InMemorySessionService 13 | from google.adk.tools.mcp_tool.mcp_session_manager import SseServerParams 14 | from google.genai import types 15 | 16 | load_dotenv() 17 | nest_asyncio.apply() 18 | 19 | 20 | # Global Configuration 21 | BOHRIUM_EXECUTOR = { 22 | "type": "dispatcher", 23 | "machine": { 24 | "batch_type": "Bohrium", 25 | "context_type": "Bohrium", 26 | "remote_profile": { 27 | "email": os.getenv("BOHRIUM_EMAIL"), 28 | "password": os.getenv("BOHRIUM_PASSWORD"), 29 | "program_id": int(os.getenv("BOHRIUM_PROJECT_ID")), 30 | "input_data": { 31 | "image_name": "registry.dp.tech/dptech/dp/native/prod-19853/dpa-mcp:0.0.0", 32 | "job_type": "container", 33 | "platform": "ali", 34 | "scass_type": "1 * NVIDIA V100_32g" 35 | } 36 | } 37 | } 38 | } 39 | LOCAL_EXECUTOR = { 40 | "type": "local" 41 | } 42 | BOHRIUM_STORAGE = { 43 | "type": "bohrium", 44 | "username": os.getenv("BOHRIUM_EMAIL"), 45 | "password": os.getenv("BOHRIUM_PASSWORD"), 46 | "project_id": int(os.getenv("BOHRIUM_PROJECT_ID")) 47 | } 48 | 49 | 50 | server_url = "http://:/sse" 51 | 52 | # Initialize MCP tools and agent 53 | mcp_tools = CalculationMCPToolset( 54 | connection_params=SseServerParams(url=server_url), 55 | storage=BOHRIUM_STORAGE, 56 | executor=BOHRIUM_EXECUTOR 57 | ) 58 | 59 | 60 | root_agent = LlmAgent( 61 | model=LiteLlm(model="azure/gpt-4o"), 62 | name="dpa_calculations_agent", 63 | description="An agent specialized in computational research using Deep Potential", 64 | instruction=( 65 | "You are an expert in materials science and computational chemistry. " 66 | "Help users perform Deep Potential calculations including structure optimization, molecular dynamics and property calculations. " 67 | "Use default parameters if the users do not mention, but let users confirm them before submission. " 68 | "Always verify the input parameters to users and provide clear explanations of results." 69 | ), 70 | tools=[mcp_tools], 71 | ) 72 | -------------------------------------------------------------------------------- /agents/SRAgent/open_deep_research/workflow/state.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated, Optional 2 | from langgraph.graph import MessagesState 3 | from open_deep_research.state import Section, SearchQuery 4 | import operator 5 | from pydantic import BaseModel, Field 6 | 7 | class ClarifyWithUser(BaseModel): 8 | question: str = Field( 9 | description="A question to ask the user to clarify the report scope", 10 | ) 11 | 12 | class SectionOutput(BaseModel): 13 | section_content: str = Field( 14 | description="The content of the section.", 15 | ) 16 | 17 | class ReportStateInput(MessagesState): 18 | """InputState is only 'messages'""" 19 | already_clarified_topic: Optional[bool] = None # If the user has clarified the topic with the agent 20 | 21 | class ReportStateOutput(MessagesState): 22 | final_report: str 23 | # for evaluation purposes only 24 | # this is included only if configurable.include_source_str is True 25 | source_str: str # String of formatted source content from web search 26 | 27 | class ReportState(MessagesState): 28 | already_clarified_topic: Optional[bool] = None # If the user has clarified the topic with the agent 29 | feedback_on_report_plan: Annotated[list[str], operator.add] # List of feedback on the report plan 30 | sections: list[Section] # List of report sections 31 | completed_sections: Annotated[list, operator.add] # Send() API key 32 | report_sections_from_research: str # String of any completed sections from research to write final sections 33 | final_report: str # Final report 34 | # for evaluation purposes only 35 | # this is included only if configurable.include_source_str is True 36 | source_str: Annotated[str, operator.add] # String of formatted source content from web search 37 | 38 | class SectionState(MessagesState): 39 | section: Section # Report section 40 | search_iterations: int # Number of search iterations done 41 | search_queries: list[SearchQuery] # List of search queries 42 | source_str: str # String of formatted source content from web search 43 | report_sections_from_research: str # String of any completed sections from research to write final sections 44 | completed_sections: list[Section] # Final key we duplicate in outer state for Send() API 45 | 46 | class SectionOutputState(MessagesState): 47 | completed_sections: list[Section] # Final key we duplicate in outer state for Send() API 48 | # for evaluation purposes only 49 | # this is included only if configurable.include_source_str is True 50 | source_str: str # String of formatted source content from web search -------------------------------------------------------------------------------- /agents/thermoelectric_mcp/agent.py: -------------------------------------------------------------------------------- 1 | import os 2 | import nest_asyncio 3 | from dotenv import load_dotenv 4 | from dp.agent.adapter.adk import CalculationMCPToolset 5 | from google.adk.agents import LlmAgent 6 | from google.adk.models.lite_llm import LiteLlm 7 | from google.adk.sessions import InMemorySessionService 8 | from google.adk.tools.mcp_tool.mcp_toolset import SseServerParams 9 | 10 | # Load credentials 11 | nest_asyncio.apply() 12 | load_dotenv() 13 | 14 | # === Bohrium config === 15 | BOHRIUM_EXECUTOR = { 16 | "type": "dispatcher", 17 | "machine": { 18 | "batch_type": "Bohrium", 19 | "context_type": "Bohrium", 20 | "remote_profile": { 21 | "email": os.getenv("BOHRIUM_EMAIL"), 22 | "password": os.getenv("BOHRIUM_PASSWORD"), 23 | "program_id": int(os.getenv("BOHRIUM_PROJECT_ID")), 24 | "input_data": { 25 | "image_name": "registry.dp.tech/dptech/dp/native/prod-435364/agents:0.1.0", 26 | "job_type": "container", 27 | "platform": "ali", 28 | "scass_type": "c32_m128_cpu" 29 | } 30 | } 31 | }, 32 | "resources":{ 33 | "group_size": 1 34 | } 35 | } 36 | #BOHRIUM_EXECUTOR_MAP = { 37 | # "build_structure": BOHRIUM_EXECUTOR["enthalpy"], 38 | # "predict_thermoelectric_properties": BOHRIUM_EXECUTOR["enthalpy"], 39 | #} 40 | 41 | BOHRIUM_STORAGE = { 42 | "type": "bohrium", 43 | "username": os.getenv("BOHRIUM_EMAIL"), 44 | "password": os.getenv("BOHRIUM_PASSWORD"), 45 | "project_id": int(os.getenv("BOHRIUM_PROJECT_ID")) 46 | } 47 | 48 | # === Server config === 49 | server_url = "https://thermoelectricmcp000-uuid1750905361.app-space.dplink.cc/sse?token=d00381812368432b874f1e58b9cc2d6d" 50 | #server_url = "https://db346ccb62d491029b590bbbf0f5c412.app-space.dplink.cc/sse?token=b019009078d647848a702b6c33f281a2" 51 | session_service = InMemorySessionService() 52 | 53 | # === MCP toolset === 54 | mcp_tools = CalculationMCPToolset( 55 | connection_params=SseServerParams(url=server_url), 56 | storage=BOHRIUM_STORAGE, 57 | executor=BOHRIUM_EXECUTOR 58 | #executor_map=BOHRIUM_EXECUTOR_MAP 59 | ) 60 | 61 | # === Define agent === 62 | root_agent = LlmAgent( 63 | model=LiteLlm(model="azure/gpt-4o"), 64 | name="gpt_thermoelectric_agent", 65 | description="Helps with Deep Potential calculations and material thermoelectronic properties.", 66 | instruction=""" 67 | Use MCP tools when structure input is provided. Otherwise, respond naturally to user queries. 68 | If users did not provide necessary parameters of the functions, ALWAYS use default settings. 69 | """, 70 | tools=[mcp_tools] 71 | ) 72 | 73 | -------------------------------------------------------------------------------- /agents/DPA_Agent/README.md: -------------------------------------------------------------------------------- 1 | # Agent UI 2 | 3 | ## 这是什么? 4 | 5 | Agent UI 是一个通用的 Web 界面框架,目前开放为 Google ADK Agent 提供即插即用的用户界面。 6 | 7 | **核心特点:** 8 | - 提供完整的聊天界面、文件管理、会话管理功能 9 | - 通过配置文件即可接入任何 ADK Agent 10 | - 无需修改前端代码 11 | 12 | ## 系统架构 13 | 14 | ``` 15 | 采用前后端分离架构: 16 | 17 | ┌─────────────────┐ WebSocket ┌─────────────────┐ 18 | │ 前端 (React) │ ←───────────────→ │ 后端 (FastAPI) │ 19 | │ localhost:5173 │ │ localhost:8000 │ 20 | └─────────────────┘ └─────────────────┘ 21 | ↓ ↓ 22 | Vite + React Google ADK + Agent 23 | 24 | ``` 25 | 26 | ## 如何使用 27 | 28 | ### 前提条件 29 | - Python 3.10+ 30 | - Node.js 16+ 31 | - 一个基于 Google ADK 开发的 Agent 32 | 33 | ### 安装步骤 34 | 35 | 1. **安装依赖** 36 | ```bash 37 | # Python 依赖 38 | pip install -r requirements.txt 39 | 40 | # 前端依赖 41 | cd ui 42 | npm install 43 | cd .. 44 | ``` 45 | 46 | 2. **配置你的 Agent** 47 | 48 | 编辑 `config/agent-config.json`: 49 | ```json 50 | { 51 | "agent": { 52 | "module": "your_module_name", # 你的 Python 模块名 53 | "rootAgent": "your_agent_var" # Agent 导出的变量名 54 | } 55 | "server": { 56 | "port": 50001, # 此处修改port 57 | "allowedHosts": ["localhost", "127.0.0.1", "0.0.0.0", "*"] 58 | } 59 | 60 | 3. **配置 API Key** 61 | 62 | 创建 `agent/.env` 文件: 63 | ``` 64 | 65 | # LLM-related API 66 | DEEPSEEK_API_KEY=your_api_key 67 | 68 | # Bohrium-related information 69 | BOHRIUM_EMAIL=your_email 70 | BOHRIUM_PASSWORD=your_pwd 71 | BOHRIUM_PROJECT_ID=your_id 72 | ``` 73 | 74 | 4. **启动系统** 75 | ```bash 76 | ./start-agent.sh 77 | ``` 78 | 79 | 5. **访问界面** 80 | 81 | 打开浏览器访问 http://localhost:(port) 82 | 83 | 84 | ``` 85 | 86 | ## 目录结构 87 | 88 | . 89 | ├── agent/ # Agent 模块目录 90 | │ ├── agent.py # 默认 Agent 实现 91 | │ └── .env # 环境变量配置 92 | ├── config/ # 配置目录 93 | │ ├── agent-config.json # Agent 配置 94 | │ └── agent_config.py # 配置加载器 95 | ├── ui/ # 前端代码 96 | │ ├── src/ # React 源码 97 | │ └── package.json # 前端依赖 98 | ├── websocket-server.py # WebSocket 服务器 99 | ├── requirements.txt # Python 依赖 100 | └── start-agent.sh # 启动脚本 101 | 102 | ``` 103 | 104 | ## 功能列表 105 | 106 | - ✅ 实时聊天界面 107 | - ✅ Markdown 消息渲染 108 | - ✅ 代码语法高亮 109 | - ✅ 工具执行状态显示 110 | - ✅ 多会话管理 111 | - ✅ 文件浏览器 112 | - ✅ Shell 终端 113 | - ✅ 可调整面板布局 114 | 115 | ## 常见问题 116 | 117 | 1. **端口被占用** 118 | - 修改 `websocket-server.py` 中的端口号 119 | - 修改 `ui/vite.config.ts` 中的代理配置 120 | 121 | 2. **Agent 加载失败** 122 | - 确保模块路径正确 123 | - 确保 Agent 变量名正确 124 | - 检查 Python 导入路径 125 | 126 | 3. **API 认证失败** 127 | - 检查 `.env` 文件中的 API Key 128 | - 确保 API Key 有效 129 | 130 | -------------------------------------------------------------------------------- /agents/SRAgent/Nexusagent_SR/subagent.py: -------------------------------------------------------------------------------- 1 | """ 2 | NexusAgent Symbolic Regression Agent 3 | 4 | This module defines the main NexusAgent and its sub-agents for symbolic regression tasks. 5 | The agent orchestrates the entire workflow from data analysis to final report generation. 6 | """ 7 | 8 | import os 9 | import sys 10 | from pathlib import Path 11 | # Add the project root to Python path 12 | project_root = Path(__file__).resolve().parent.parent 13 | if str(project_root) not in sys.path: 14 | sys.path.insert(0, str(project_root)) 15 | 16 | from google.adk import Agent 17 | from google.adk.agents import LlmAgent 18 | 19 | from google.adk.models.lite_llm import LiteLlm 20 | from google.adk.agents import SequentialAgent 21 | 22 | from Nexusagent_SR.prompt.agent_prompt import ( 23 | research_agent_prompt, 24 | prior_agent_prompt, 25 | symbolic_agent_prompt, 26 | summarize_agent_prompt, 27 | ) 28 | from Nexusagent_SR.tool.agent_tool import * 29 | 30 | 31 | model = os.getenv("MODEL", "gpt-4o-mini") # Default to gpt-4o-mini if MODEL env var is not set 32 | 33 | 34 | research_agent = Agent( 35 | name="ResearchAgent", 36 | model=LiteLlm(model=model), 37 | description="Use to generate data description and save to a variable with the key `data_description`", 38 | tools=[ 39 | generate_data_description_tool, 40 | ], 41 | instruction=research_agent_prompt, 42 | output_key="data_description" 43 | ) 44 | 45 | prior_agent = Agent( 46 | name="PriorAgent", 47 | model=LiteLlm(model=model), 48 | description="Use to set the unary operators.", 49 | tools=[ 50 | set_unary_operators_tool 51 | ], 52 | instruction=prior_agent_prompt, 53 | ) 54 | 55 | 56 | symbolic_agent = Agent( 57 | name="SymbolicAgent", 58 | model=LiteLlm(model=model), 59 | description="Use to run symbolic regression with the csv_path,the csv_path is saved in the variable with the key `csv_path`", 60 | instruction=symbolic_agent_prompt, 61 | tools=[ 62 | run_symbolic_tool_pysr, 63 | ], 64 | output_key="symbolic_result" 65 | ) 66 | 67 | 68 | summarize_agent = Agent( 69 | name="SummarizeAgent", 70 | model=LiteLlm(model=model), 71 | description="Use to write the summarize report", 72 | instruction=summarize_agent_prompt, 73 | tools=[ 74 | summarize_report_tool, 75 | ], 76 | output_key="summarize_report" 77 | ) 78 | 79 | 80 | sr_iteration_agent = SequentialAgent( 81 | name="SRIterationAgent", 82 | description="Execute a single iteration: set configuration -> run symbolic regression -> generate summary -> refine the summarize report", 83 | sub_agents=[prior_agent, symbolic_agent, summarize_agent], 84 | ) 85 | 86 | 87 | 88 | rootagent = SequentialAgent( 89 | name="NexusAgent", 90 | description="Execute the symbolic regression workflow: research -> SR iteration", 91 | sub_agents=[research_agent,sr_iteration_agent], 92 | ) -------------------------------------------------------------------------------- /agents/SRAgent/open_deep_research/state.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated, List, TypedDict, Literal 2 | from pydantic import BaseModel, Field 3 | import operator 4 | 5 | class Section(BaseModel): 6 | name: str = Field( 7 | description="Name for this section of the report.", 8 | ) 9 | description: str = Field( 10 | description="Brief overview of the main topics and concepts to be covered in this section.", 11 | ) 12 | research: bool = Field( 13 | description="Whether to perform web research for this section of the report." 14 | ) 15 | content: str = Field( 16 | description="The content of the section." 17 | ) 18 | 19 | class Sections(BaseModel): 20 | sections: List[Section] = Field( 21 | description="Sections of the report.", 22 | ) 23 | 24 | class SearchQuery(BaseModel): 25 | search_query: str = Field(None, description="Query for web search.") 26 | 27 | class Queries(BaseModel): 28 | queries: List[SearchQuery] = Field( 29 | description="List of search queries.", 30 | ) 31 | 32 | class Feedback(BaseModel): 33 | grade: Literal["pass","fail"] = Field( 34 | description="Evaluation result indicating whether the response meets requirements ('pass') or needs revision ('fail')." 35 | ) 36 | follow_up_queries: List[SearchQuery] = Field( 37 | description="List of follow-up search queries.", 38 | ) 39 | 40 | class ReportStateInput(TypedDict): 41 | topic: str # Report topic 42 | 43 | class ReportStateOutput(TypedDict): 44 | final_report: str # Final report 45 | # for evaluation purposes only 46 | # this is included only if configurable.include_source_str is True 47 | source_str: str # String of formatted source content from web search 48 | 49 | class ReportState(TypedDict): 50 | topic: str # Report topic 51 | feedback_on_report_plan: Annotated[list[str], operator.add] # List of feedback on the report plan 52 | sections: list[Section] # List of report sections 53 | completed_sections: Annotated[list, operator.add] # Send() API key 54 | report_sections_from_research: str # String of any completed sections from research to write final sections 55 | final_report: str # Final report 56 | # for evaluation purposes only 57 | # this is included only if configurable.include_source_str is True 58 | source_str: Annotated[str, operator.add] # String of formatted source content from web search 59 | 60 | class SectionState(TypedDict): 61 | topic: str # Report topic 62 | section: Section # Report section 63 | search_iterations: int # Number of search iterations done 64 | search_queries: list[SearchQuery] # List of search queries 65 | source_str: str # String of formatted source content from web search 66 | report_sections_from_research: str # String of any completed sections from research to write final sections 67 | completed_sections: list[Section] # Final key we duplicate in outer state for Send() API 68 | 69 | class SectionOutputState(TypedDict): 70 | completed_sections: list[Section] # Final key we duplicate in outer state for Send() API 71 | # for evaluation purposes only 72 | # this is included only if configurable.include_source_str is True 73 | source_str: str # String of formatted source content from web search 74 | -------------------------------------------------------------------------------- /agents/adk_ui_starter/README.md: -------------------------------------------------------------------------------- 1 | # Agent UI 2 | 3 | ## 这是什么? 4 | 5 | Agent UI 是一个通用的 Web 界面框架,目前开放为 Google ADK Agent 提供即插即用的用户界面。 6 | 7 | **核心特点:** 8 | - 提供完整的聊天界面、文件管理、会话管理功能 9 | - 通过配置文件即可接入任何 ADK Agent 10 | - 无需修改前端代码 11 | 12 | ## 系统架构 13 | 14 | ``` 15 | 采用前后端分离架构: 16 | 17 | ┌─────────────────┐ WebSocket ┌─────────────────┐ 18 | │ 前端 (React) │ ←───────────────→ │ 后端 (FastAPI) │ 19 | │ localhost:5173 │ │ localhost:8000 │ 20 | └─────────────────┘ └─────────────────┘ 21 | ↓ ↓ 22 | Vite + React Google ADK + Agent 23 | 24 | ``` 25 | 26 | ## 如何使用 27 | 28 | ### 前提条件 29 | - Python 3.10+ 30 | - Node.js 16+ 31 | - 一个基于 Google ADK 开发的 Agent 32 | 33 | ### 安装步骤 34 | 35 | 1. **安装依赖** 36 | ```bash 37 | # Python 依赖 38 | pip install -r requirements.txt 39 | 40 | # 前端依赖 41 | cd ui 42 | npm install 43 | cd .. 44 | ``` 45 | 46 | 2. **配置你的 Agent** 47 | 48 | 编辑 `config/agent-config.json`: 49 | ```json 50 | { 51 | "agent": { 52 | "module": "your_module_name", # 你的 Python 模块名 53 | "rootAgent": "your_agent_var" # Agent 导出的变量名 54 | } 55 | } 56 | ``` 57 | 58 | 3. **配置 API Key** 59 | 60 | 创建 `agent/.env` 文件: 61 | ``` 62 | 63 | DEEPSEEK_API_KEY=your_api_key 64 | # 或者使用其他模型 65 | ``` 66 | 67 | 4. **启动系统** 68 | ```bash 69 | ./start-agent.sh 70 | ``` 71 | 72 | 5. **访问界面** 73 | 74 | 打开浏览器访问 http://localhost:5173 75 | 76 | ### 示例:替换为你的 Agent 77 | 78 | 假设你有一个 Agent 文件 `agent/my_agent.py`: 79 | 80 | ```python 81 | # my_agent.py 82 | from google.adk.agents import Agent 83 | from google.adk.models.lite_llm import LiteLlm 84 | 85 | my_assistant = Agent( 86 | name="my_assistant", 87 | model=LiteLlm(model="deepseek/deepseek-chat"), 88 | instruction="你是一个助手", 89 | tools=[] 90 | ) 91 | ``` 92 | 93 | 只需修改配置: 94 | ```json 95 | { 96 | "agent": { 97 | "module": "agent.my_agent", 98 | "rootAgent": "my_assistant" 99 | } 100 | } 101 | ``` 102 | 103 | ## 目录结构 104 | 105 | ``` 106 | . 107 | ├── agent/ # Agent 模块目录 108 | │ ├── agent.py # 默认 Agent 实现 109 | │ └── .env # 环境变量配置 110 | ├── config/ # 配置目录 111 | │ ├── agent-config.json # Agent 配置 112 | │ └── agent_config.py # 配置加载器 113 | ├── ui/ # 前端代码 114 | │ ├── src/ # React 源码 115 | │ └── package.json # 前端依赖 116 | ├── websocket-server.py # WebSocket 服务器 117 | ├── requirements.txt # Python 依赖 118 | └── start-agent.sh # 启动脚本 119 | ``` 120 | 121 | ## 功能列表 122 | 123 | - ✅ 实时聊天界面 124 | - ✅ Markdown 消息渲染 125 | - ✅ 代码语法高亮 126 | - ✅ 工具执行状态显示 127 | - ✅ 多会话管理 128 | - ✅ 文件浏览器 129 | - ✅ Shell 终端 130 | - ✅ 可调整面板布局 131 | 132 | ## 常见问题 133 | 134 | 1. **端口被占用** 135 | - 修改 `websocket-server.py` 中的端口号 136 | - 修改 `ui/vite.config.ts` 中的代理配置 137 | 138 | 2. **Agent 加载失败** 139 | - 确保模块路径正确 140 | - 确保 Agent 变量名正确 141 | - 检查 Python 导入路径 142 | 143 | 3. **API 认证失败** 144 | - 检查 `.env` 文件中的 API Key 145 | - 确保 API Key 有效 146 | 147 | ## 下一步 148 | 149 | - 查看 [CONFIG_GUIDE.md](docs/CONFIG_GUIDE.md) 了解详细配置 150 | - 查看 [QUICKSTART.md](QUICKSTART.md) 快速开始 151 | -------------------------------------------------------------------------------- /agents/SRAgent/config/agent_config.py: -------------------------------------------------------------------------------- 1 | """ 2 | Agent Configuration Loader 3 | 4 | This module provides a centralized configuration system for different agent implementations. 5 | To switch between different agents, modify the agent-config.json file. 6 | """ 7 | 8 | import json 9 | from pathlib import Path 10 | from typing import Dict, Any 11 | import importlib 12 | 13 | class AgentConfig: 14 | def __init__(self, config_path: str = "config/agent-config.json"): 15 | self.config_path = Path(config_path) 16 | self.config = self._load_config() 17 | 18 | def _load_config(self) -> Dict[str, Any]: 19 | """Load configuration from JSON file""" 20 | if not self.config_path.exists(): 21 | # Fallback to default config if file doesn't exist 22 | return self._get_default_config() 23 | 24 | with open(self.config_path, 'r', encoding='utf-8') as f: 25 | return json.load(f) 26 | 27 | def _get_default_config(self) -> Dict[str, Any]: 28 | """Provide default configuration for NexusAgent SR""" 29 | return { 30 | "agent": { 31 | "name": "My Agent", 32 | "description": "智能符号回归分析系统", 33 | "welcomeMessage": "输入您的数据文件路径,开始符号回归分析", 34 | "module": "Nexusagent_SR.subagent", 35 | "rootAgent": "rootagent" 36 | }, 37 | "ui": { 38 | "title": "NexusAgent SR", 39 | "features": { 40 | "showFileExplorer": True, 41 | "showSessionList": True 42 | } 43 | }, 44 | "files": { 45 | "outputDirectory": "output", 46 | "watchDirectories": ["output"] 47 | }, 48 | "websocket": { 49 | "host": "localhost", 50 | "port": 8000 51 | } 52 | } 53 | 54 | def get_agent(self): 55 | """Dynamically import and return the configured agent""" 56 | agent_config = self.config.get("agent", {}) 57 | module_name = agent_config.get("module", "Nexusagent_SR.subagent") 58 | agent_name = agent_config.get("rootAgent", "rootagent") 59 | 60 | try: 61 | module = importlib.import_module(module_name) 62 | return getattr(module, agent_name) 63 | except (ImportError, AttributeError) as e: 64 | raise ImportError(f"Failed to load agent {agent_name} from {module_name}: {e}") 65 | 66 | def get_ui_config(self) -> Dict[str, Any]: 67 | """Get UI-specific configuration""" 68 | return self.config.get("ui", {}) 69 | 70 | def get_files_config(self) -> Dict[str, Any]: 71 | """Get file handling configuration""" 72 | return self.config.get("files", {}) 73 | 74 | def get_websocket_config(self) -> Dict[str, Any]: 75 | """Get WebSocket configuration""" 76 | return self.config.get("websocket", {}) 77 | 78 | def get_tool_display_name(self, tool_name: str) -> str: 79 | """Get display name for a tool""" 80 | tools_config = self.config.get("tools", {}) 81 | display_names = tools_config.get("displayNames", {}) 82 | return display_names.get(tool_name, tool_name) 83 | 84 | def is_long_running_tool(self, tool_name: str) -> bool: 85 | """Check if a tool is marked as long-running""" 86 | tools_config = self.config.get("tools", {}) 87 | long_running = tools_config.get("longRunningTools", []) 88 | return tool_name in long_running 89 | 90 | # Singleton instance 91 | agent_config = AgentConfig() -------------------------------------------------------------------------------- /agents/adk_ui_starter/agent/server.py: -------------------------------------------------------------------------------- 1 | import arxiv 2 | import json 3 | import os 4 | from typing import List 5 | from mcp.server.fastmcp import FastMCP 6 | 7 | PAPER_DIR = "papers" 8 | 9 | # Initialize FastMCP server 10 | #mcp = FastMCP("research", host = "localhost", port=50001) 11 | mcp = FastMCP("research", host="0.0.0.0", port=50001) 12 | 13 | @mcp.tool() 14 | def search_papers(topic: str, max_results: int = 5) -> List[str]: 15 | """ 16 | Search for papers on arXiv based on a topic and store their information. 17 | 18 | Args: 19 | topic: The topic to search for 20 | max_results: Maximum number of results to retrieve (default: 5) 21 | 22 | Returns: 23 | List of paper IDs found in the search 24 | """ 25 | 26 | # Use arxiv to find the papers 27 | client = arxiv.Client() 28 | 29 | # Search for the most relevant articles matching the queried topic 30 | search = arxiv.Search( 31 | query=topic, 32 | max_results=max_results, 33 | sort_by=arxiv.SortCriterion.Relevance 34 | ) 35 | 36 | papers = client.results(search) 37 | 38 | # Create directory for this topic 39 | path = os.path.join(PAPER_DIR, topic.lower().replace(" ", "_")) 40 | os.makedirs(path, exist_ok=True) 41 | 42 | file_path = os.path.join(path, "papers_info.json") 43 | 44 | # Try to load existing papers info 45 | try: 46 | with open(file_path, "r") as json_file: 47 | papers_info = json.load(json_file) 48 | except (FileNotFoundError, json.JSONDecodeError): 49 | papers_info = {} 50 | 51 | # Process each paper and add to papers_info 52 | paper_ids = [] 53 | for paper in papers: 54 | paper_ids.append(paper.get_short_id()) 55 | paper_info = { 56 | 'title': paper.title, 57 | 'authors': [author.name for author in paper.authors], 58 | 'summary': paper.summary, 59 | 'pdf_url': paper.pdf_url, 60 | 'published': str(paper.published.date()) 61 | } 62 | papers_info[paper.get_short_id()] = paper_info 63 | 64 | # Save updated papers_info to json file 65 | with open(file_path, "w") as json_file: 66 | json.dump(papers_info, json_file, indent=2) 67 | 68 | print(f"Results are saved in: {file_path}") 69 | 70 | return paper_ids 71 | 72 | @mcp.tool() 73 | def extract_info(paper_id: str) -> str: 74 | """ 75 | Search for information about a specific paper across all topic directories. 76 | 77 | Args: 78 | paper_id: The ID of the paper to look for 79 | 80 | Returns: 81 | JSON string with paper information if found, error message if not found 82 | """ 83 | 84 | for item in os.listdir(PAPER_DIR): 85 | item_path = os.path.join(PAPER_DIR, item) 86 | if os.path.isdir(item_path): 87 | file_path = os.path.join(item_path, "papers_info.json") 88 | if os.path.isfile(file_path): 89 | try: 90 | with open(file_path, "r") as json_file: 91 | papers_info = json.load(json_file) 92 | if paper_id in papers_info: 93 | return json.dumps(papers_info[paper_id], indent=2) 94 | except (FileNotFoundError, json.JSONDecodeError) as e: 95 | print(f"Error reading {file_path}: {str(e)}") 96 | continue 97 | 98 | return f"There's no saved information related to paper {paper_id}." 99 | 100 | if __name__ == "__main__": 101 | # Initialize and run the server 102 | #mcp.run(transport='streamable-http') 103 | mcp.run(transport='sse') 104 | -------------------------------------------------------------------------------- /agents/DPA_Agent/docs/CONFIG_GUIDE.md: -------------------------------------------------------------------------------- 1 | # 配置指南 2 | 3 | 本文档详细说明 Agent UI Kit 的所有配置选项。 4 | 5 | ## 配置文件位置 6 | 7 | 主配置文件:`config/agent-config.json` 8 | 9 | ## 配置项详解 10 | 11 | ### 1. Agent 配置 12 | 13 | ```json 14 | { 15 | "agent": { 16 | "name": "显示名称", 17 | "description": "描述信息", 18 | "welcomeMessage": "欢迎消息", 19 | "module": "Python模块路径", 20 | "rootAgent": "Agent变量名" 21 | } 22 | } 23 | ``` 24 | 25 | **字段说明:** 26 | - `name`: 在 UI 中显示的 Agent 名称 27 | - `description`: Agent 的简短描述 28 | - `welcomeMessage`: 用户首次进入时的欢迎消息 29 | - `module`: Python 模块的导入路径(如 `agent.agent` 或 `my_module.sub_module`) 30 | - `rootAgent`: 模块中导出的 Agent 变量名 31 | 32 | **示例:** 33 | ```json 34 | { 35 | "agent": { 36 | "name": "代码助手", 37 | "description": "帮助编写和调试代码", 38 | "welcomeMessage": "你好!我可以帮你编写代码。", 39 | "module": "agents.code_assistant", 40 | "rootAgent": "assistant" 41 | } 42 | } 43 | ``` 44 | 45 | ### 2. UI 配置 46 | 47 | ```json 48 | { 49 | "ui": { 50 | "title": "浏览器标题", 51 | "theme": { 52 | "primaryColor": "主色调", 53 | "secondaryColor": "辅助色" 54 | }, 55 | "features": { 56 | "showFileExplorer": true, 57 | "showSessionList": true, 58 | "enableFileUpload": false 59 | } 60 | } 61 | } 62 | ``` 63 | 64 | **功能开关:** 65 | - `showFileExplorer`: 是否显示文件浏览器面板 66 | - `showSessionList`: 是否显示会话列表 67 | - `enableFileUpload`: 是否启用文件上传功能(开发中) 68 | 69 | ### 3. 文件管理配置 70 | 71 | ```json 72 | { 73 | "files": { 74 | "outputDirectory": "output", 75 | "watchDirectories": ["output", "results"], 76 | "fileExtensions": { 77 | "supported": ["json", "md", "txt", "csv", "py", "js", "ts", "log"], 78 | "defaultViewer": { 79 | "json": "code", 80 | "md": "markdown", 81 | "csv": "table", 82 | "default": "code" 83 | } 84 | } 85 | } 86 | } 87 | ``` 88 | 89 | **说明:** 90 | - `outputDirectory`: 默认输出目录 91 | - `watchDirectories`: 文件浏览器监视的目录列表 92 | - `supported`: 支持预览的文件扩展名 93 | - `defaultViewer`: 不同文件类型的默认查看器 94 | 95 | ### 4. WebSocket 配置 96 | 97 | ```json 98 | { 99 | "websocket": { 100 | "host": "localhost", 101 | "port": 8000, 102 | "reconnectInterval": 3000, 103 | "maxReconnectAttempts": 10 104 | } 105 | } 106 | ``` 107 | 108 | **参数说明:** 109 | - `reconnectInterval`: 断线重连间隔(毫秒) 110 | - `maxReconnectAttempts`: 最大重连次数 111 | 112 | ### 5. 会话配置 113 | 114 | ```json 115 | { 116 | "session": { 117 | "persistent": false, 118 | "maxSessions": 50, 119 | "defaultSessionTitle": "新对话" 120 | } 121 | } 122 | ``` 123 | 124 | 125 | 126 | **用途:** 127 | - `displayNames`: 将工具内部名称映射为用户友好的显示名称 128 | - `longRunningTools`: 标记为长时间运行的工具,UI 会显示特殊状态 129 | 130 | ## 环境变量配置 131 | 132 | ### Agent 环境变量 133 | 134 | 在 `agent/.env` 文件中配置: 135 | 136 | ```bash 137 | # 模型选择 138 | MODEL=deepseek/deepseek-chat 139 | 140 | # API Keys 141 | DEEPSEEK_API_KEY=your_key_here 142 | 143 | ``` 144 | 145 | 146 | ## 配置加载顺序 147 | 148 | 1. 默认配置(代码中的默认值) 149 | 2. 配置文件(agent-config.json) 150 | 3. 环境变量(最高优先级) 151 | 152 | ## 配置验证 153 | 154 | 系统启动时会自动验证配置: 155 | - 检查必需字段是否存在 156 | - 验证模块是否可以导入 157 | - 确认 Agent 变量是否存在 158 | 159 | ## 动态配置 160 | 161 | 配置通过 API 端点暴露给前端: 162 | ``` 163 | GET /api/config 164 | ``` 165 | 166 | 前端通过 `useAgentConfig` Hook 获取配置: 167 | ```typescript 168 | const { config, loading, error } = useAgentConfig() 169 | ``` 170 | 171 | ## 最佳实践 172 | 173 | 1. **保持配置简洁** - 只修改需要的部分 174 | 2. **使用环境变量管理密钥** - 不要在配置文件中硬编码 175 | 3. **测试配置** - 修改后总是重启并测试 176 | 4. **版本控制** - 将配置文件纳入版本控制(除了 .env) 177 | 178 | ## 故障排除 179 | 180 | ### 配置未生效 181 | 1. 确保保存了配置文件 182 | 2. 重启 WebSocket 服务器 183 | 3. 清除浏览器缓存 184 | 185 | ### Agent 加载失败 186 | 1. 检查模块路径拼写 187 | 2. 确保 Python 可以导入该模块 188 | 3. 验证变量名是否正确 189 | 190 | ### UI 功能异常 191 | 1. 检查 features 配置 192 | 2. 确保布尔值格式正确(true/false) 193 | 3. 查看浏览器控制台错误 -------------------------------------------------------------------------------- /agents/adk_ui_starter/docs/CONFIG_GUIDE.md: -------------------------------------------------------------------------------- 1 | # 配置指南 2 | 3 | 本文档详细说明 Agent UI Kit 的所有配置选项。 4 | 5 | ## 配置文件位置 6 | 7 | 主配置文件:`config/agent-config.json` 8 | 9 | ## 配置项详解 10 | 11 | ### 1. Agent 配置 12 | 13 | ```json 14 | { 15 | "agent": { 16 | "name": "显示名称", 17 | "description": "描述信息", 18 | "welcomeMessage": "欢迎消息", 19 | "module": "Python模块路径", 20 | "rootAgent": "Agent变量名" 21 | } 22 | } 23 | ``` 24 | 25 | **字段说明:** 26 | - `name`: 在 UI 中显示的 Agent 名称 27 | - `description`: Agent 的简短描述 28 | - `welcomeMessage`: 用户首次进入时的欢迎消息 29 | - `module`: Python 模块的导入路径(如 `agent.agent` 或 `my_module.sub_module`) 30 | - `rootAgent`: 模块中导出的 Agent 变量名 31 | 32 | **示例:** 33 | ```json 34 | { 35 | "agent": { 36 | "name": "代码助手", 37 | "description": "帮助编写和调试代码", 38 | "welcomeMessage": "你好!我可以帮你编写代码。", 39 | "module": "agents.code_assistant", 40 | "rootAgent": "assistant" 41 | } 42 | } 43 | ``` 44 | 45 | ### 2. UI 配置 46 | 47 | ```json 48 | { 49 | "ui": { 50 | "title": "浏览器标题", 51 | "theme": { 52 | "primaryColor": "主色调", 53 | "secondaryColor": "辅助色" 54 | }, 55 | "features": { 56 | "showFileExplorer": true, 57 | "showSessionList": true, 58 | "enableFileUpload": false 59 | } 60 | } 61 | } 62 | ``` 63 | 64 | **功能开关:** 65 | - `showFileExplorer`: 是否显示文件浏览器面板 66 | - `showSessionList`: 是否显示会话列表 67 | - `enableFileUpload`: 是否启用文件上传功能(开发中) 68 | 69 | ### 3. 文件管理配置 70 | 71 | ```json 72 | { 73 | "files": { 74 | "outputDirectory": "output", 75 | "watchDirectories": ["output", "results"], 76 | "fileExtensions": { 77 | "supported": ["json", "md", "txt", "csv", "py", "js", "ts", "log"], 78 | "defaultViewer": { 79 | "json": "code", 80 | "md": "markdown", 81 | "csv": "table", 82 | "default": "code" 83 | } 84 | } 85 | } 86 | } 87 | ``` 88 | 89 | **说明:** 90 | - `outputDirectory`: 默认输出目录 91 | - `watchDirectories`: 文件浏览器监视的目录列表 92 | - `supported`: 支持预览的文件扩展名 93 | - `defaultViewer`: 不同文件类型的默认查看器 94 | 95 | ### 4. WebSocket 配置 96 | 97 | ```json 98 | { 99 | "websocket": { 100 | "host": "localhost", 101 | "port": 8000, 102 | "reconnectInterval": 3000, 103 | "maxReconnectAttempts": 10 104 | } 105 | } 106 | ``` 107 | 108 | **参数说明:** 109 | - `reconnectInterval`: 断线重连间隔(毫秒) 110 | - `maxReconnectAttempts`: 最大重连次数 111 | 112 | ### 5. 会话配置 113 | 114 | ```json 115 | { 116 | "session": { 117 | "persistent": false, 118 | "maxSessions": 50, 119 | "defaultSessionTitle": "新对话" 120 | } 121 | } 122 | ``` 123 | 124 | 125 | 126 | **用途:** 127 | - `displayNames`: 将工具内部名称映射为用户友好的显示名称 128 | - `longRunningTools`: 标记为长时间运行的工具,UI 会显示特殊状态 129 | 130 | ## 环境变量配置 131 | 132 | ### Agent 环境变量 133 | 134 | 在 `agent/.env` 文件中配置: 135 | 136 | ```bash 137 | # 模型选择 138 | MODEL=deepseek/deepseek-chat 139 | 140 | # API Keys 141 | DEEPSEEK_API_KEY=your_key_here 142 | 143 | ``` 144 | 145 | 146 | ## 配置加载顺序 147 | 148 | 1. 默认配置(代码中的默认值) 149 | 2. 配置文件(agent-config.json) 150 | 3. 环境变量(最高优先级) 151 | 152 | ## 配置验证 153 | 154 | 系统启动时会自动验证配置: 155 | - 检查必需字段是否存在 156 | - 验证模块是否可以导入 157 | - 确认 Agent 变量是否存在 158 | 159 | ## 动态配置 160 | 161 | 配置通过 API 端点暴露给前端: 162 | ``` 163 | GET /api/config 164 | ``` 165 | 166 | 前端通过 `useAgentConfig` Hook 获取配置: 167 | ```typescript 168 | const { config, loading, error } = useAgentConfig() 169 | ``` 170 | 171 | ## 最佳实践 172 | 173 | 1. **保持配置简洁** - 只修改需要的部分 174 | 2. **使用环境变量管理密钥** - 不要在配置文件中硬编码 175 | 3. **测试配置** - 修改后总是重启并测试 176 | 4. **版本控制** - 将配置文件纳入版本控制(除了 .env) 177 | 178 | ## 故障排除 179 | 180 | ### 配置未生效 181 | 1. 确保保存了配置文件 182 | 2. 重启 WebSocket 服务器 183 | 3. 清除浏览器缓存 184 | 185 | ### Agent 加载失败 186 | 1. 检查模块路径拼写 187 | 2. 确保 Python 可以导入该模块 188 | 3. 验证变量名是否正确 189 | 190 | ### UI 功能异常 191 | 1. 检查 features 配置 192 | 2. 确保布尔值格式正确(true/false) 193 | 3. 查看浏览器控制台错误 -------------------------------------------------------------------------------- /agents/SRAgent/Nexusagent_SR/tool/agent_tool.py: -------------------------------------------------------------------------------- 1 | from Nexusagent_SR.tool.task_manager import get_task_status, get_task_result 2 | from Nexusagent_SR.tool.pysr import run_symbolic_pysr 3 | from Nexusagent_SR.tool.pysr_config import set_unary_operators,set_binary_operators 4 | from Nexusagent_SR.tool.summarize_report import summarize_report 5 | from Nexusagent_SR.tool.iteration_manager import iteration_manager 6 | from Nexusagent_SR.tool.deepresearch import deepresearch_agent 7 | from pathlib import Path 8 | 9 | async def run_symbolic_tool_pysr(csv_path: str): 10 | """ 11 | run symbolic regression with pysr 12 | Args: 13 | csv_path: str, the path of the csv file 14 | Returns: 15 | result: str, the result of the symbolic regression 16 | the different columns are: 17 | complexity: the complexity of the expression 18 | mse: the mse of the expression 19 | expression: the expression 20 | 21 | you should save the result to a variable with the key `symbolic_result` 22 | 23 | """ 24 | result = await run_symbolic_pysr(csv_path=csv_path) 25 | return result 26 | 27 | def get_task_status_tool(task_id: str): 28 | """ 29 | get the status of the task 30 | Args: 31 | task_id: str, the id of the task 32 | Returns: 33 | status: str, the status of the task 34 | """ 35 | return get_task_status(task_id) 36 | 37 | 38 | def get_task_result_tool(task_id: str): 39 | """ 40 | get the result of the task 41 | Args: 42 | task_id: str, the id of the task 43 | Returns: 44 | result: str, the result of the task 45 | """ 46 | return get_task_result(task_id) 47 | 48 | 49 | async def summarize_report_tool(): 50 | """ 51 | summarize the report 52 | 53 | return: str, the summarize report 54 | """ 55 | report = await summarize_report() 56 | return report 57 | 58 | 59 | async def set_unary_operators_tool(unary_operators: list[str]): 60 | """ 61 | set the pysr unary operators 62 | Args: 63 | unary_operators: list, the unary operators 64 | the value is the unary operator name 65 | [str, str] 66 | you can only use the operators in the following list, do not use any other operators. 67 | ["exp", "log", "sin", "cos", "sqrt","inv","square","cube","abs","sign","log1p"] 68 | Returns: 69 | "success set unary operators" 70 | example: 71 | unary_operators = ["exp", "log", "sin", "cos", "sqrt"] 72 | """ 73 | set_unary_operators(unary_operators) 74 | 75 | return f"success set unary operators: {unary_operators}" 76 | 77 | 78 | 79 | 80 | 81 | async def generate_data_description_tool(data_description: str): 82 | """ 83 | generate the data description 84 | Args: 85 | data_description: str, user request, must be comprehensive and detailed 86 | Returns: 87 | the report of the data description 88 | example: 89 | data_description = "The data is about the relationship between the age and the height of the students,x1 is the age,x2 is the height" 90 | generate_data_description_tool(data_description) 91 | """ 92 | #mock the data description 93 | data_description_report = await deepresearch_agent(data_description) 94 | return data_description_report 95 | 96 | 97 | async def write_summarize_report_tool(report: str): 98 | """ 99 | write the summarize report to a file 100 | Args: 101 | report: str, the report content 102 | Returns: 103 | "success write summarize report" 104 | """ 105 | with open("output/summarize_report.md", "w") as f: 106 | f.write(report) 107 | return "success write summarize report" 108 | 109 | 110 | 111 | 112 | def get_iteration_history_tool(): 113 | """ 114 | Get iteration history for refine_agent analysis 115 | Returns: 116 | str: History summary 117 | """ 118 | return iteration_manager.get_history_summary() 119 | 120 | -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/src/components/ResizablePanel.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useRef, useEffect, useCallback } from 'react'; 2 | 3 | interface ResizablePanelProps { 4 | direction: 'horizontal' | 'vertical'; 5 | minSize?: number; 6 | maxSize?: number; 7 | defaultSize?: number; 8 | onResize?: (size: number) => void; 9 | children: React.ReactNode; 10 | className?: string; 11 | resizeBarClassName?: string; 12 | resizeBarPosition?: 'start' | 'end'; 13 | } 14 | 15 | export const ResizablePanel: React.FC = ({ 16 | direction, 17 | minSize = 100, 18 | maxSize = 800, 19 | defaultSize = 300, 20 | onResize, 21 | children, 22 | className = '', 23 | resizeBarClassName = '', 24 | resizeBarPosition = 'end' 25 | }) => { 26 | const [size, setSize] = useState(defaultSize); 27 | const [iesizing, setIesizing] = useState(false); 28 | const panelRef = useRef(null); 29 | const startPoef = useRef(0); 30 | const startSizeRef = useRef(0); 31 | 32 | const handleMouseDown = useCallback((e: React.MouseEvent) => { 33 | e.preventDefault(); 34 | setIesizing(true); 35 | startPoef.current = direction === 'horizontal' ? e.clientX : e.clientY; 36 | startSizeRef.current = size; 37 | }, [direction, size]); 38 | 39 | const handleMouseMove = useCallback((e: MouseEvent) => { 40 | if (!iesizing) return; 41 | 42 | const currentPos = direction === 'horizontal' ? e.clientX : e.clientY; 43 | let diff = currentPos - startPoef.current; 44 | 45 | // Reverse the diff for 'start' position 46 | if (resizeBarPosition === 'start') { 47 | diff = -diff; 48 | } 49 | 50 | const newSize = Math.max(minSize, Math.min(maxSize, startSizeRef.current + diff)); 51 | 52 | setSize(newSize); 53 | onResize?.(newSize); 54 | }, [iesizing, direction, minSize, maxSize, onResize, resizeBarPosition]); 55 | 56 | const handleMouseUp = useCallback(() => { 57 | setIesizing(false); 58 | }, []); 59 | 60 | useEffect(() => { 61 | if (iesizing) { 62 | document.addEventListener('mousemove', handleMouseMove); 63 | document.addEventListener('mouseup', handleMouseUp); 64 | document.body.style.cursor = direction === 'horizontal' ? 'col-resize' : 'row-resize'; 65 | document.body.style.userSelect = 'none'; 66 | 67 | return () => { 68 | document.removeEventListener('mousemove', handleMouseMove); 69 | document.removeEventListener('mouseup', handleMouseUp); 70 | document.body.style.cursor = ''; 71 | document.body.style.userSelect = ''; 72 | }; 73 | } 74 | }, [iesizing, handleMouseMove, handleMouseUp, direction]); 75 | 76 | const resizeBarStyle = direction === 'horizontal' 77 | ? `absolute top-0 ${resizeBarPosition === 'end' ? 'right-0' : 'left-0'} w-2 h-full cursor-col-resize hover:bg-blue-500 transition-colors group` 78 | : `absolute ${resizeBarPosition === 'end' ? 'bottom-0' : 'top-0'} left-0 w-full h-2 cursor-row-resize hover:bg-blue-500 transition-colors group`; 79 | 80 | const panelStyle = direction === 'horizontal' 81 | ? { width: `${size}px` } 82 | : { height: `${size}px` }; 83 | 84 | return ( 85 |
90 | {children} 91 |
97 | {/* Visual indicator */} 98 |
103 | {/* Larger hit area */} 104 |
107 |
108 |
109 | ); 110 | }; -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/src/components/ResizablePanel.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useRef, useEffect, useCallback } from 'react'; 2 | 3 | interface ResizablePanelProps { 4 | direction: 'horizontal' | 'vertical'; 5 | minSize?: number; 6 | maxSize?: number; 7 | defaultSize?: number; 8 | onResize?: (size: number) => void; 9 | children: React.ReactNode; 10 | className?: string; 11 | resizeBarClassName?: string; 12 | resizeBarPosition?: 'start' | 'end'; 13 | } 14 | 15 | export const ResizablePanel: React.FC = ({ 16 | direction, 17 | minSize = 100, 18 | maxSize = 800, 19 | defaultSize = 300, 20 | onResize, 21 | children, 22 | className = '', 23 | resizeBarClassName = '', 24 | resizeBarPosition = 'end' 25 | }) => { 26 | const [size, setSize] = useState(defaultSize); 27 | const [iesizing, setIesizing] = useState(false); 28 | const panelRef = useRef(null); 29 | const startPoef = useRef(0); 30 | const startSizeRef = useRef(0); 31 | 32 | const handleMouseDown = useCallback((e: React.MouseEvent) => { 33 | e.preventDefault(); 34 | setIesizing(true); 35 | startPoef.current = direction === 'horizontal' ? e.clientX : e.clientY; 36 | startSizeRef.current = size; 37 | }, [direction, size]); 38 | 39 | const handleMouseMove = useCallback((e: MouseEvent) => { 40 | if (!iesizing) return; 41 | 42 | const currentPos = direction === 'horizontal' ? e.clientX : e.clientY; 43 | let diff = currentPos - startPoef.current; 44 | 45 | // Reverse the diff for 'start' position 46 | if (resizeBarPosition === 'start') { 47 | diff = -diff; 48 | } 49 | 50 | const newSize = Math.max(minSize, Math.min(maxSize, startSizeRef.current + diff)); 51 | 52 | setSize(newSize); 53 | onResize?.(newSize); 54 | }, [iesizing, direction, minSize, maxSize, onResize, resizeBarPosition]); 55 | 56 | const handleMouseUp = useCallback(() => { 57 | setIesizing(false); 58 | }, []); 59 | 60 | useEffect(() => { 61 | if (iesizing) { 62 | document.addEventListener('mousemove', handleMouseMove); 63 | document.addEventListener('mouseup', handleMouseUp); 64 | document.body.style.cursor = direction === 'horizontal' ? 'col-resize' : 'row-resize'; 65 | document.body.style.userSelect = 'none'; 66 | 67 | return () => { 68 | document.removeEventListener('mousemove', handleMouseMove); 69 | document.removeEventListener('mouseup', handleMouseUp); 70 | document.body.style.cursor = ''; 71 | document.body.style.userSelect = ''; 72 | }; 73 | } 74 | }, [iesizing, handleMouseMove, handleMouseUp, direction]); 75 | 76 | const resizeBarStyle = direction === 'horizontal' 77 | ? `absolute top-0 ${resizeBarPosition === 'end' ? 'right-0' : 'left-0'} w-2 h-full cursor-col-resize hover:bg-blue-500 transition-colors group` 78 | : `absolute ${resizeBarPosition === 'end' ? 'bottom-0' : 'top-0'} left-0 w-full h-2 cursor-row-resize hover:bg-blue-500 transition-colors group`; 79 | 80 | const panelStyle = direction === 'horizontal' 81 | ? { width: `${size}px` } 82 | : { height: `${size}px` }; 83 | 84 | return ( 85 |
90 | {children} 91 |
97 | {/* Visual indicator */} 98 |
103 | {/* Larger hit area */} 104 |
107 |
108 |
109 | ); 110 | }; -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/src/components/ResizablePanel.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useRef, useEffect, useCallback } from 'react'; 2 | 3 | interface ResizablePanelProps { 4 | direction: 'horizontal' | 'vertical'; 5 | minSize?: number; 6 | maxSize?: number; 7 | defaultSize?: number; 8 | onResize?: (size: number) => void; 9 | children: React.ReactNode; 10 | className?: string; 11 | resizeBarClassName?: string; 12 | resizeBarPosition?: 'start' | 'end'; 13 | } 14 | 15 | export const ResizablePanel: React.FC = ({ 16 | direction, 17 | minSize = 100, 18 | maxSize = 800, 19 | defaultSize = 300, 20 | onResize, 21 | children, 22 | className = '', 23 | resizeBarClassName = '', 24 | resizeBarPosition = 'end' 25 | }) => { 26 | const [size, setSize] = useState(defaultSize); 27 | const [isResizing, setIsResizing] = useState(false); 28 | const panelRef = useRef(null); 29 | const startPosRef = useRef(0); 30 | const startSizeRef = useRef(0); 31 | 32 | const handleMouseDown = useCallback((e: React.MouseEvent) => { 33 | e.preventDefault(); 34 | setIsResizing(true); 35 | startPosRef.current = direction === 'horizontal' ? e.clientX : e.clientY; 36 | startSizeRef.current = size; 37 | }, [direction, size]); 38 | 39 | const handleMouseMove = useCallback((e: MouseEvent) => { 40 | if (!isResizing) return; 41 | 42 | const currentPos = direction === 'horizontal' ? e.clientX : e.clientY; 43 | let diff = currentPos - startPosRef.current; 44 | 45 | // Reverse the diff for 'start' position 46 | if (resizeBarPosition === 'start') { 47 | diff = -diff; 48 | } 49 | 50 | const newSize = Math.max(minSize, Math.min(maxSize, startSizeRef.current + diff)); 51 | 52 | setSize(newSize); 53 | onResize?.(newSize); 54 | }, [isResizing, direction, minSize, maxSize, onResize, resizeBarPosition]); 55 | 56 | const handleMouseUp = useCallback(() => { 57 | setIsResizing(false); 58 | }, []); 59 | 60 | useEffect(() => { 61 | if (isResizing) { 62 | document.addEventListener('mousemove', handleMouseMove); 63 | document.addEventListener('mouseup', handleMouseUp); 64 | document.body.style.cursor = direction === 'horizontal' ? 'col-resize' : 'row-resize'; 65 | document.body.style.userSelect = 'none'; 66 | 67 | return () => { 68 | document.removeEventListener('mousemove', handleMouseMove); 69 | document.removeEventListener('mouseup', handleMouseUp); 70 | document.body.style.cursor = ''; 71 | document.body.style.userSelect = ''; 72 | }; 73 | } 74 | }, [isResizing, handleMouseMove, handleMouseUp, direction]); 75 | 76 | const resizeBarStyle = direction === 'horizontal' 77 | ? `absolute top-0 ${resizeBarPosition === 'end' ? 'right-0' : 'left-0'} w-2 h-full cursor-col-resize hover:bg-blue-500 transition-colors group` 78 | : `absolute ${resizeBarPosition === 'end' ? 'bottom-0' : 'top-0'} left-0 w-full h-2 cursor-row-resize hover:bg-blue-500 transition-colors group`; 79 | 80 | const panelStyle = direction === 'horizontal' 81 | ? { width: `${size}px` } 82 | : { height: `${size}px` }; 83 | 84 | return ( 85 |
90 | {children} 91 |
97 | {/* Visual indicator */} 98 |
103 | {/* Larger hit area */} 104 |
107 |
108 |
109 | ); 110 | }; -------------------------------------------------------------------------------- /agents/DPA_Agent/config/agent_config.py: -------------------------------------------------------------------------------- 1 | """ 2 | Agent Configuration Loader 3 | 4 | This module provides a centralized configuration system for different agent implementations. 5 | To switch between different agents, modify the agent-config.json file. 6 | """ 7 | 8 | import json 9 | from pathlib import Path 10 | from typing import Dict, Any 11 | import importlib 12 | 13 | class AgentConfig: 14 | def __init__(self, config_path: str = "config/agent-config.json"): 15 | self.config_path = Path(config_path) 16 | self.config = self._load_config() 17 | 18 | def _load_config(self) -> Dict[str, Any]: 19 | """Load configuration from JSON file""" 20 | if not self.config_path.exists(): 21 | # Fallback to default config if file doesn't exist 22 | return self._get_default_config() 23 | 24 | with open(self.config_path, 'r', encoding='utf-8') as f: 25 | return json.load(f) 26 | 27 | def _get_default_config(self) -> Dict[str, Any]: 28 | """Provide default configuration for Agent""" 29 | return { 30 | "agent": { 31 | "name": "My Agent", 32 | "description": "智能符号回归分析系统", 33 | "welcomeMessage": "输入您的数据文件路径,开始符号回归分析", 34 | "module": "agent.subagent", 35 | "rootAgent": "rootagent" 36 | }, 37 | "ui": { 38 | "title": "Agent", 39 | "features": { 40 | "showFileExplorer": True, 41 | "showSessionList": True 42 | } 43 | }, 44 | "files": { 45 | "outputDirectory": "output", 46 | "watchDirectories": ["output"] 47 | }, 48 | "websocket": { 49 | "host": "localhost", 50 | "port": 8000 51 | } 52 | } 53 | 54 | def get_agent(self): 55 | """Dynamically import and return the configured agent""" 56 | agentconfig = self.config.get("agent", {}) 57 | module_name = agentconfig.get("module", "agent.subagent") 58 | agentname = agentconfig.get("rootAgent", "rootagent") 59 | 60 | try: 61 | module = importlib.import_module(module_name) 62 | return getattr(module, agentname) 63 | except (ImportError, AttributeError) as e: 64 | raise ImportError(f"Failed to load agent {agentname} from {module_name}: {e}") 65 | 66 | def get_ui_config(self) -> Dict[str, Any]: 67 | """Get UI-specific configuration""" 68 | return self.config.get("ui", {}) 69 | 70 | def get_files_config(self) -> Dict[str, Any]: 71 | """Get file handling configuration""" 72 | return self.config.get("files", {}) 73 | 74 | def get_websocket_config(self) -> Dict[str, Any]: 75 | """Get WebSocket configuration""" 76 | return self.config.get("websocket", {}) 77 | 78 | def get_tool_display_name(self, tool_name: str) -> str: 79 | """Get display name for a tool""" 80 | tools_config = self.config.get("tools", {}) 81 | display_names = tools_config.get("displayNames", {}) 82 | return display_names.get(tool_name, tool_name) 83 | 84 | def is_long_running_tool(self, tool_name: str) -> bool: 85 | """Check if a tool is marked as long-running""" 86 | tools_config = self.config.get("tools", {}) 87 | long_running = tools_config.get("longRunningTools", []) 88 | return tool_name in long_running 89 | 90 | def get_server_config(self) -> Dict[str, Any]: 91 | """Get server configuration including port and allowed hosts""" 92 | # 默认主机始终被允许 93 | default_hosts = ["localhost", "127.0.0.1", "0.0.0.0"] 94 | 95 | server_config = self.config.get("server", {}) 96 | 97 | # 合并默认主机和用户定义的额外主机 98 | user_hosts = server_config.get("allowedHosts", []) 99 | all_hosts = list(set(default_hosts + user_hosts)) # 使用 set 去重 100 | 101 | return { 102 | "port": server_config.get("port", 50002), 103 | "allowedHosts": all_hosts 104 | } 105 | 106 | # Singleton instance 107 | agentconfig = AgentConfig() -------------------------------------------------------------------------------- /agents/adk_ui_starter/config/agent_config.py: -------------------------------------------------------------------------------- 1 | """ 2 | Agent Configuration Loader 3 | 4 | This module provides a centralized configuration system for different agent implementations. 5 | To switch between different agents, modify the agent-config.json file. 6 | """ 7 | 8 | import json 9 | from pathlib import Path 10 | from typing import Dict, Any 11 | import importlib 12 | 13 | class AgentConfig: 14 | def __init__(self, config_path: str = "config/agent-config.json"): 15 | self.config_path = Path(config_path) 16 | self.config = self._load_config() 17 | 18 | def _load_config(self) -> Dict[str, Any]: 19 | """Load configuration from JSON file""" 20 | if not self.config_path.exists(): 21 | # Fallback to default config if file doesn't exist 22 | return self._get_default_config() 23 | 24 | with open(self.config_path, 'r', encoding='utf-8') as f: 25 | return json.load(f) 26 | 27 | def _get_default_config(self) -> Dict[str, Any]: 28 | """Provide default configuration for Agent""" 29 | return { 30 | "agent": { 31 | "name": "My Agent", 32 | "description": "智能符号回归分析系统", 33 | "welcomeMessage": "输入您的数据文件路径,开始符号回归分析", 34 | "module": "agent.subagent", 35 | "rootAgent": "rootagent" 36 | }, 37 | "ui": { 38 | "title": "Agent", 39 | "features": { 40 | "showFileExplorer": True, 41 | "showSessionList": True 42 | } 43 | }, 44 | "files": { 45 | "outputDirectory": "output", 46 | "watchDirectories": ["output"] 47 | }, 48 | "websocket": { 49 | "host": "localhost", 50 | "port": 8000 51 | } 52 | } 53 | 54 | def get_agent(self): 55 | """Dynamically import and return the configured agent""" 56 | agentconfig = self.config.get("agent", {}) 57 | module_name = agentconfig.get("module", "agent.subagent") 58 | agentname = agentconfig.get("rootAgent", "rootagent") 59 | 60 | try: 61 | module = importlib.import_module(module_name) 62 | return getattr(module, agentname) 63 | except (ImportError, AttributeError) as e: 64 | raise ImportError(f"Failed to load agent {agentname} from {module_name}: {e}") 65 | 66 | def get_ui_config(self) -> Dict[str, Any]: 67 | """Get UI-specific configuration""" 68 | return self.config.get("ui", {}) 69 | 70 | def get_files_config(self) -> Dict[str, Any]: 71 | """Get file handling configuration""" 72 | return self.config.get("files", {}) 73 | 74 | def get_websocket_config(self) -> Dict[str, Any]: 75 | """Get WebSocket configuration""" 76 | return self.config.get("websocket", {}) 77 | 78 | def get_tool_display_name(self, tool_name: str) -> str: 79 | """Get display name for a tool""" 80 | tools_config = self.config.get("tools", {}) 81 | display_names = tools_config.get("displayNames", {}) 82 | return display_names.get(tool_name, tool_name) 83 | 84 | def is_long_running_tool(self, tool_name: str) -> bool: 85 | """Check if a tool is marked as long-running""" 86 | tools_config = self.config.get("tools", {}) 87 | long_running = tools_config.get("longRunningTools", []) 88 | return tool_name in long_running 89 | 90 | def get_server_config(self) -> Dict[str, Any]: 91 | """Get server configuration including port and allowed hosts""" 92 | # 默认主机始终被允许 93 | default_hosts = ["localhost", "127.0.0.1", "0.0.0.0"] 94 | 95 | server_config = self.config.get("server", {}) 96 | 97 | # 合并默认主机和用户定义的额外主机 98 | user_hosts = server_config.get("allowedHosts", []) 99 | all_hosts = list(set(default_hosts + user_hosts)) # 使用 set 去重 100 | 101 | return { 102 | "port": server_config.get("port", 50002), 103 | "allowedHosts": all_hosts 104 | } 105 | 106 | # Singleton instance 107 | agentconfig = AgentConfig() -------------------------------------------------------------------------------- /agents/SRAgent/Nexusagent_SR/tool/summarize_report.py: -------------------------------------------------------------------------------- 1 | """ 2 | Summarize Report Tool 3 | 4 | This module generates comprehensive analysis reports for symbolic regression results, 5 | combining the best expressions with mechanism analysis and data descriptions. 6 | """ 7 | 8 | import ast 9 | import os 10 | import json 11 | import re 12 | from pathlib import Path 13 | from typing import List, Optional, Union 14 | 15 | # Ensure loading .env file 16 | import Nexusagent_SR # noqa: F401 17 | from litellm import completion 18 | 19 | from openai import AzureOpenAI 20 | from Nexusagent_SR.prompt.agent_prompt import build_SUMMARIZE_PROMPT 21 | from Nexusagent_SR.tool.iteration_manager import register_summary_report_tool 22 | from Nexusagent_SR.tool.utils import get_best_expression 23 | 24 | 25 | 26 | async def summarize_report() -> str: 27 | """ 28 | Generate comprehensive analysis report using the latest OpenAI Python + Azure setup. 29 | 30 | This function reads mechanism tags, data descriptions, and best expressions, 31 | then generates a detailed analysis report combining all findings. 32 | 33 | Returns: 34 | str: Generated analysis report content 35 | 36 | Raises: 37 | FileNotFoundError: If required input files are missing 38 | Exception: If report generation fails 39 | """ 40 | try: 41 | # Check and read mechanism tags 42 | # mechanism_tags_path = Path("output/mechanism_tags.txt") 43 | # if not mechanism_tags_path.exists(): 44 | # raise FileNotFoundError("mechanism_tags.txt not found in output directory") 45 | # mechanism_tags = mechanism_tags_path.read_text(encoding='utf-8').strip() 46 | 47 | # Check and read data description (try multiple possible locations) 48 | data_description = None 49 | 50 | data_description = Path(f"output/deepresearch_report.md").read_text().strip() 51 | 52 | # Check and read best expressions 53 | best_expressions = get_best_expression() 54 | if best_expressions: 55 | print(f"Best expression: {best_expressions}") 56 | else: 57 | print("No best expression found") 58 | 59 | 60 | # Generate the analysis report 61 | prompt = build_SUMMARIZE_PROMPT(best_expressions, data_description) 62 | 63 | response = completion( 64 | model=os.getenv("MODEL"), 65 | temperature=0, 66 | max_tokens=8192, 67 | messages=[ 68 | { 69 | "role": "system", 70 | "content": "You are a professional in mathematical modeling and scientific analysis, " 71 | "skilled at interpreting symbolic regression results and generating comprehensive reports." 72 | }, 73 | { 74 | "role": "user", 75 | "content": prompt 76 | }, 77 | ], 78 | ) 79 | 80 | content = response["choices"][0]["message"]["content"].strip() 81 | 82 | # Save the generated report 83 | output_path = Path("output/summarize.txt") 84 | output_path.parent.mkdir(parents=True, exist_ok=True) 85 | 86 | with open(output_path, "w", encoding="utf-8") as f: 87 | f.write(content) 88 | 89 | # Register summary report to iteration history 90 | try: 91 | result = register_summary_report_tool(content) 92 | print(f"Summary report registration result: {result}") 93 | except Exception as e: 94 | print(f"Error occurred when registering summary report: {e}") 95 | 96 | return content 97 | 98 | except FileNotFoundError as e: 99 | error_msg = f"Required input file missing: {e}" 100 | # Save error message to output for debugging 101 | with open("output/summarize_error.txt", "w", encoding="utf-8") as f: 102 | f.write(error_msg) 103 | raise FileNotFoundError(error_msg) 104 | 105 | except Exception as e: 106 | error_msg = f"Failed to generate analysis report: {e}" 107 | with open("output/summarize_error.txt", "w", encoding="utf-8") as f: 108 | f.write(error_msg) 109 | raise Exception(error_msg) -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # UV 98 | # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | #uv.lock 102 | 103 | # poetry 104 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 105 | # This is especially recommended for binary packages to ensure reproducibility, and is more 106 | # commonly ignored for libraries. 107 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 108 | #poetry.lock 109 | 110 | # pdm 111 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 112 | #pdm.lock 113 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 114 | # in version control. 115 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control 116 | .pdm.toml 117 | .pdm-python 118 | .pdm-build/ 119 | 120 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 121 | __pypackages__/ 122 | 123 | # Celery stuff 124 | celerybeat-schedule 125 | celerybeat.pid 126 | 127 | # SageMath parsed files 128 | *.sage.py 129 | 130 | # Environments 131 | .env 132 | .venv 133 | env/ 134 | venv/ 135 | ENV/ 136 | env.bak/ 137 | venv.bak/ 138 | 139 | # Spyder project settings 140 | .spyderproject 141 | .spyproject 142 | 143 | # Rope project settings 144 | .ropeproject 145 | 146 | # mkdocs documentation 147 | /site 148 | 149 | # mypy 150 | .mypy_cache/ 151 | .dmypy.json 152 | dmypy.json 153 | 154 | # Pyre type checker 155 | .pyre/ 156 | 157 | # pytype static type analyzer 158 | .pytype/ 159 | 160 | # Cython debug symbols 161 | cython_debug/ 162 | 163 | # PyCharm 164 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 165 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 166 | # and can be added to the global gitignore or merged into this file. For a more nuclear 167 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 168 | #.idea/ 169 | 170 | # Ruff stuff: 171 | .ruff_cache/ 172 | 173 | # PyPI configuration file 174 | .pypirc 175 | .DS_Store 176 | .vscode 177 | .log -------------------------------------------------------------------------------- /agents/DPA_Agent/agent/agent.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import os 3 | import sys 4 | from pathlib import Path 5 | from typing import Any, Dict 6 | 7 | import nest_asyncio 8 | from dotenv import load_dotenv 9 | from dp.agent.adapter.adk import CalculationMCPToolset 10 | from google.adk import Agent 11 | from google.adk.agents import LlmAgent, SequentialAgent 12 | from google.adk.models.lite_llm import LiteLlm 13 | from google.adk.runners import Runner 14 | from google.adk.sessions import InMemorySessionService 15 | from google.adk.tools.mcp_tool.mcp_session_manager import SseServerParams 16 | from google.genai import types 17 | 18 | # Add the project root to Python path 19 | project_root = Path(__file__).resolve().parent.parent 20 | if str(project_root) not in sys.path: 21 | sys.path.insert(0, str(project_root)) 22 | 23 | load_dotenv() 24 | nest_asyncio.apply() 25 | 26 | # Global Configuration 27 | BOHRIUM_EXECUTOR_CALC = { 28 | "type": "dispatcher", 29 | "machine": { 30 | "batch_type": "Bohrium", 31 | "context_type": "Bohrium", 32 | "remote_profile": { 33 | "email": os.getenv("BOHRIUM_EMAIL"), 34 | "password": os.getenv("BOHRIUM_PASSWORD"), 35 | "program_id": int(os.getenv("BOHRIUM_PROJECT_ID")), 36 | "input_data": { 37 | "image_name": "registry.dp.tech/dptech/dp/native/prod-19853/dpa-mcp:dev-0704", 38 | "job_type": "container", 39 | "platform": "ali", 40 | "scass_type": "1 * NVIDIA V100_32g" 41 | } 42 | } 43 | } 44 | } 45 | BOHRIUM_EXECUTOR_TE = { 46 | "type": "dispatcher", 47 | "machine": { 48 | "batch_type": "Bohrium", 49 | "context_type": "Bohrium", 50 | "remote_profile": { 51 | "email": os.getenv("BOHRIUM_EMAIL"), 52 | "password": os.getenv("BOHRIUM_PASSWORD"), 53 | "program_id": int(os.getenv("BOHRIUM_PROJECT_ID")), 54 | "input_data": { 55 | "image_name": "registry.dp.tech/dptech/dp/native/prod-435364/agents:0.1.0", 56 | "job_type": "container", 57 | "platform": "ali", 58 | "scass_type": "1 * NVIDIA V100_32g" 59 | } 60 | } 61 | } 62 | } 63 | LOCAL_EXECUTOR = { 64 | "type": "local" 65 | } 66 | HTTPS_STORAGE = { 67 | "type": "https", 68 | "plugin": { 69 | "type": "bohrium", 70 | "username": os.getenv("BOHRIUM_EMAIL"), 71 | "password": os.getenv("BOHRIUM_PASSWORD"), 72 | "project_id": int(os.getenv("BOHRIUM_PROJECT_ID")) 73 | } 74 | } 75 | 76 | print('-----', HTTPS_STORAGE) 77 | 78 | 79 | mcp_tools_dpa = CalculationMCPToolset( 80 | connection_params=SseServerParams(url="https://dpa-uuid1750659890.app-space.dplink.cc/sse?token=a0d87a7abf8d47cb92403018fd4a9468"), 81 | # connection_params=SseServerParams(url="http://pfmx1355864.bohrium.tech:50002/sse"), 82 | storage=HTTPS_STORAGE, 83 | executor=None, 84 | executor_map={ 85 | "build_structure": None 86 | } 87 | ) 88 | mcp_tools_thermoelectric = CalculationMCPToolset( 89 | connection_params=SseServerParams(url="https://thermoelectricmcp000-uuid1750905361.app-space.dplink.cc/sse?token=1c1f2140a5504ebcb680f6a7fa2c03db"), 90 | storage=HTTPS_STORAGE, 91 | executor=BOHRIUM_EXECUTOR_TE 92 | ) 93 | # mcp_tools_superconductor = CalculationMCPToolset( 94 | # connection_params=SseServerParams(url="https://superconductor-ambient-010-uuid1750845273.app-space.dplink.cc/sse?token=57578d394b564682943a723697f992b1"), 95 | # storage=HTTPS_STORAGE, 96 | # executor=None 97 | # ) 98 | root_agent = LlmAgent( 99 | model=LiteLlm(model="deepseek/deepseek-chat"), 100 | name="dpa_agent", 101 | description="An agent specialized in computational research using Deep Potential", 102 | instruction=( 103 | "You are an expert in materials science and computational chemistry. " 104 | "Help users perform Deep Potential calculations including structure optimization, molecular dynamics and property calculations. " 105 | "Use default parameters if the users do not mention, but let users confirm them before submission. " 106 | "Always verify the input parameters to users and provide clear explanations of results." 107 | ), 108 | tools=[ 109 | mcp_tools_dpa, 110 | mcp_tools_thermoelectric, 111 | # mcp_tools_superconductor 112 | ], 113 | ) 114 | -------------------------------------------------------------------------------- /agents/adk_ui_starter/CLAUDE.md: -------------------------------------------------------------------------------- 1 | # CLAUDE.md 2 | 用中文回答我 3 | This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. 4 | 5 | ## Project Overview 6 | 7 | This is an Agent system built with Google ADK (Agent Development Kit) that provides a WebSocket-based chat interface with a React frontend. The system is designed to be extensible for building custom AI agents. 8 | 9 | ## Commands 10 | 11 | ### Starting the System 12 | ```bash 13 | # Start both backend and frontend 14 | ./start-agent.sh 15 | 16 | # Or manually: 17 | # Backend (WebSocket server on port 8000) 18 | python websocket-server.py 19 | 20 | # Frontend (React app on port 5173) 21 | cd ui && npm run dev 22 | ``` 23 | 24 | ### Frontend Development 25 | ```bash 26 | cd ui 27 | npm install # Install dependencies 28 | npm run dev # Start development server 29 | npm run build # Build for production 30 | npm run type-check # Run TypeScript type checking 31 | ``` 32 | 33 | ### Python Development 34 | ```bash 35 | # Install Python dependencies 36 | pip install -r requirements.txt 37 | 38 | # The project uses Google ADK - no specific test runner configured 39 | ``` 40 | 41 | ## Architecture 42 | 43 | ### Core Components 44 | 45 | 1. **WebSocket Server** (`websocket-server.py`): 46 | - FastAPI-based server providing WebSocket connections 47 | - Manages sessions and agent interactions 48 | - Uses Google ADK's Runner and InMemorySessionService 49 | - Handles multiple concurrent client connections 50 | 51 | 2. **Agent Configuration** (`config/agent_config.py`): 52 | - Dynamic agent loading system 53 | - Configurable via `config/agent-config.json` 54 | - Default configuration points to `agent.agent.root_agent` 55 | 56 | 3. **Frontend** (`ui/`): 57 | - React + TypeScript + Vite 58 | - WebSocket client for real-time communication 59 | - Session management with persistent UI state 60 | - File explorer for output directory 61 | 62 | 4. **Agent Implementation** (`agent/agent.py`): 63 | - Uses Google ADK Agent framework 64 | - Configurable with LiteLLM for model selection 65 | - Currently configured for DeepSeek or Azure OpenAI GPT-4 66 | 67 | ### Key Design Patterns 68 | 69 | 1. **Session Management**: Each WebSocket connection maintains its own session context with isolated Runner and SessionService instances. 70 | 71 | 2. **Message Protocol**: JSON-based WebSocket messages with types: 'user', 'assistant', 'tool', 'system', 'error', 'complete' 72 | 73 | 3. **Tool Execution**: Agent tools are executed asynchronously with status updates sent via WebSocket 74 | 75 | 4. **File Watching**: Output directory is monitored and file changes are broadcast to connected clients 76 | 77 | ## Environment Configuration 78 | 79 | Create `agent/.env` file with: 80 | ```bash 81 | # For DeepSeek 82 | MODEL=deepseek/deepseek-chat 83 | DEEPSEEK_API_KEY=your_key_here 84 | 85 | # For Azure OpenAI 86 | AZURE_OPENAI_ENDPOINT=your_endpoint 87 | AZURE_OPENAI_API_KEY=your_key 88 | AZURE_OPENAI_DEPLOYMENT_NAME=your_deployment 89 | 90 | # Optional search tools 91 | TAVILY_API_KEY=your_key 92 | ``` 93 | 94 | ## Important Implementation Details 95 | 96 | 1. **Agent Module Loading**: The system dynamically imports agents based on `agent-config.json`. The default expects `root_agent` from module `agent`. 97 | 98 | 2. **WebSocket Connection Lifecycle**: Each connection gets a unique user_id and maintains independent state. Disconnections are handled gracefully. 99 | 100 | 3. **Error Handling**: Tool execution errors and agent failures are caught and sent as error messages to the client. 101 | 102 | 4. **File Output**: Results are typically written to the `output/` directory which is watched by the file explorer component. 103 | 104 | ## Common Development Tasks 105 | 106 | ### Adding a New Agent 107 | 1. Create your agent module in `agent/` 108 | 2. Update `config/agent-config.json` to point to your agent 109 | 3. Ensure your agent exports the expected variable name (default: `root_agent`) 110 | 111 | ### Extending the UI 112 | See `docs/UI_EXTENSION_GUIDE.md` for detailed instructions on: 113 | - Adding new components 114 | - Extending message types 115 | - Creating new pages 116 | - Custom WebSocket handlers 117 | 118 | ### Modifying WebSocket Protocol 119 | 1. Update message handlers in `websocket-server.py` 120 | 2. Add corresponding TypeScript types in frontend 121 | 3. Update `ChatInterface.tsx` to handle new message types -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/src/components/MemoizedMessage.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Bot, User } from 'lucide-react'; 3 | import ReactMarkdown from 'react-markdown'; 4 | import remarkGfm from 'remark-gfm'; 5 | import { createCodeComponent } from './EnhancedCodeBlock'; 6 | import { MemoizedMarkdown } from './MemoizedMarkdown'; 7 | import { StreamingText } from './MessageAnimation'; 8 | 9 | interface MessageProps { 10 | id: string; 11 | role: 'user' | 'assistant' | 'tool'; 12 | content: string; 13 | timestamp: Date; 14 | isLastMessage?: boolean; 15 | isStreaming?: boolean; 16 | } 17 | 18 | export const MemoizedMessage = React.memo(({ 19 | id, 20 | role, 21 | content, 22 | timestamp, 23 | isLastMessage = false, 24 | isStreaming = false 25 | }) => { 26 | return ( 27 | <> 28 | {role !== 'user' && ( 29 |
30 |
31 | 32 |
33 |
34 | )} 35 | 36 |
37 |
44 | {role === 'tool' ? ( 45 |
46 | 47 | {content} 48 | 49 |
50 | ) : role === 'assistant' ? ( 51 |
52 | 65 | {children} 66 | 67 | ) 68 | }, 69 | p({ children }: any) { 70 | if (isLastMessage && isStreaming) { 71 | return ( 72 |

73 | 77 |

78 | ) 79 | } 80 | return

{children}

81 | } 82 | }} 83 | > 84 | {content} 85 |
86 |
87 | ) : ( 88 |

{content}

89 | )} 90 |
91 |

92 | {timestamp.toLocaleTimeString('zh-CN')} 93 |

94 |
95 | 96 | {role === 'user' && ( 97 |
98 |
99 | 100 |
101 |
102 | )} 103 | 104 | ); 105 | }, (prevProps, nextProps) => { 106 | // 只有当这些关键属性改变时才重新渲染 107 | return prevProps.id === nextProps.id && 108 | prevProps.content === nextProps.content && 109 | prevProps.isStreaming === nextProps.isStreaming && 110 | prevProps.isLastMessage === nextProps.isLastMessage; 111 | }); 112 | 113 | MemoizedMessage.displayName = 'MemoizedMessage'; -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/src/components/MemoizedMessage.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Bot, User } from 'lucide-react'; 3 | import ReactMarkdown from 'react-markdown'; 4 | import remarkGfm from 'remark-gfm'; 5 | import { createCodeComponent } from './EnhancedCodeBlock'; 6 | import { MemoizedMarkdown } from './MemoizedMarkdown'; 7 | import { StreamingText } from './MessageAnimation'; 8 | 9 | interface MessageProps { 10 | id: string; 11 | role: 'user' | 'assistant' | 'tool'; 12 | content: string; 13 | timestamp: Date; 14 | isLastMessage?: boolean; 15 | isStreaming?: boolean; 16 | } 17 | 18 | export const MemoizedMessage = React.memo(({ 19 | id, 20 | role, 21 | content, 22 | timestamp, 23 | isLastMessage = false, 24 | isStreaming = false 25 | }) => { 26 | return ( 27 | <> 28 | {role !== 'user' && ( 29 |
30 |
31 | 32 |
33 |
34 | )} 35 | 36 |
37 |
44 | {role === 'tool' ? ( 45 |
46 | 47 | {content} 48 | 49 |
50 | ) : role === 'assistant' ? ( 51 |
52 | 65 | {children} 66 | 67 | ) 68 | }, 69 | p({ children }: any) { 70 | if (isLastMessage && isStreaming) { 71 | return ( 72 |

73 | 77 |

78 | ) 79 | } 80 | return

{children}

81 | } 82 | }} 83 | > 84 | {content} 85 |
86 |
87 | ) : ( 88 |

{content}

89 | )} 90 |
91 |

92 | {timestamp.toLocaleTimeString('zh-CN')} 93 |

94 |
95 | 96 | {role === 'user' && ( 97 |
98 |
99 | 100 |
101 |
102 | )} 103 | 104 | ); 105 | }, (prevProps, nextProps) => { 106 | // 只有当这些关键属性改变时才重新渲染 107 | return prevProps.id === nextProps.id && 108 | prevProps.content === nextProps.content && 109 | prevProps.isStreaming === nextProps.isStreaming && 110 | prevProps.isLastMessage === nextProps.isLastMessage; 111 | }); 112 | 113 | MemoizedMessage.displayName = 'MemoizedMessage'; -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui-introduction.md: -------------------------------------------------------------------------------- 1 | # Agent 前端实现介绍 2 | 3 | ## 1. Agent 定义 4 | 5 | ### 1.1 什么是 Agent 6 | Agent 是一个基于 Google ADK(Agent Development Kit)构建的智能符号回归系统。它通过多智能体协作,自动将原始数据转换为可解释的数学模型。 7 | 8 | 9 | ### 1.2 Agent 配置 10 | 通过 `config/agent-config.json` 文件可以灵活配置不同的 Agent 实现: 11 | 12 | ```json 13 | { 14 | "agent": { 15 | "name": "agent", 16 | "module": "agent", 17 | "rootAgent": "root_agent" 18 | } 19 | } 20 | ``` 21 | 22 | ## 2. 后端架构 23 | 24 | ### 2.1 WebSocket 服务器 25 | 后端基于 FastAPI 框架,提供 WebSocket 实时通信能力: 26 | 27 | - **文件**: `-websocket-server.py` 28 | - **端口**: 8000 29 | - **主要功能**: 30 | - WebSocket 连接管理 31 | - 会话(Session)管理 32 | - 消息路由和处理 33 | - 文件系统访问 API 34 | - Shell 命令执行(安全限制) 35 | 36 | ### 2.2 核心组件 37 | 38 | #### SessionManager 39 | 管理所有客户端连接和会话: 40 | ```python 41 | class SessionManager: 42 | - active_connections: 活跃的 WebSocket 连接 43 | - sessions: 所有会话数据 44 | - runners: 每个会话的 ADK Runner 实例 45 | - session_services: 会话持久化服务 46 | ``` 47 | 48 | #### Runner 集成 49 | 每个会话都有独立的 Runner 实例,用于执行 Agent 任务: 50 | ```python 51 | runner = Runner( 52 | agent=rootagent, 53 | session_service=session_service, 54 | app_name=self.app_name 55 | ) 56 | ``` 57 | 58 | ## 3. 前端与后端连接 59 | 60 | ### 3.1 WebSocket 通信协议 61 | 前端通过 WebSocket 与后端建立双向通信连接: 62 | 63 | ```typescript 64 | // 前端连接代码 (ChatInterface.tsx) 65 | const websocket = new WebSocket('ws://localhost:8000/ws') 66 | ``` 67 | 68 | ### 3.2 消息类型 69 | 系统定义了多种消息类型用于不同的交互场景: 70 | 71 | #### 用户消息 72 | ```json 73 | { 74 | "type": "message", 75 | "content": "用户输入的内容" 76 | } 77 | ``` 78 | 79 | #### 会话管理 80 | ```json 81 | { 82 | "type": "create_session" | "switch_session" | "delete_session", 83 | "session_id": "会话ID" 84 | } 85 | ``` 86 | 87 | #### 工具执行状态 88 | ```json 89 | { 90 | "type": "tool", 91 | "tool_name": "工具名称", 92 | "status": "executing" | "completed", 93 | "is_long_running": true/false, 94 | "result": "执行结果" 95 | } 96 | ``` 97 | 98 | #### Shell 命令 99 | ```json 100 | { 101 | "type": "shell_command", 102 | "command": "要执行的命令" 103 | } 104 | ``` 105 | 106 | ### 3.3 实时状态同步 107 | - **连接状态**: 实时显示 WebSocket 连接状态(已连接/连接中/未连接) 108 | - **工具执行**: 实时展示长时间运行的工具状态 109 | - **会话切换**: 支持多会话并行,历史记录独立保存 110 | 111 | ## 4. 前端功能实现 112 | 113 | ### 4.1 技术栈 114 | - **框架**: React 18 + TypeScript 115 | - **构建工具**: Vite 116 | - **样式**: TailwindCSS 117 | - **UI 组件**: 118 | - Framer Motion(动画) 119 | - Lucide React(图标) 120 | - React Markdown(Markdown 渲染) 121 | - React Syntax Highlighter(代码高亮) 122 | 123 | ### 4.2 核心功能 124 | 125 | #### 聊天界面 126 | - **组件**: `ChatInterface.tsx` 127 | - **功能**: 128 | - 实时消息收发 129 | - Markdown 格式支持 130 | - 代码语法高亮 131 | - 工具执行状态展示 132 | - 消息历史记录 133 | 134 | #### 会话管理 135 | - **组件**: `SessionList.tsx` 136 | - **功能**: 137 | - 创建新会话 138 | - 切换会话 139 | - 删除会话 140 | - 会话标题自动生成 141 | 142 | #### 文件浏览器 143 | - **组件**: `FileExplorer.tsx` 144 | - **功能**: 145 | - 浏览输出目录文件树 146 | - 预览文件内容 147 | - 支持多种文件格式(JSON、Markdown、CSV 等) 148 | - 文件内容语法高亮 149 | 150 | #### Shell 终端 151 | - **组件**: `ShellTerminal.tsx` 152 | - **功能**: 153 | - 执行 Shell 命令 154 | - 命令历史记录 155 | - 输出实时展示 156 | - 安全限制(危险命令黑名单) 157 | 158 | #### 可调整面板 159 | - **组件**: `ResizablePanel.tsx` 160 | - **功能**: 161 | - 支持拖拽调整面板大小 162 | - 最小/最大尺寸限制 163 | - 流畅的调整动画 164 | 165 | ### 4.3 配置系统 166 | 通过 `useAgentConfig` Hook 加载后端配置: 167 | ```typescript 168 | const { config, loading } = useAgentConfig() 169 | // 配置包含:agent 信息、UI 设置、文件路径等 170 | ``` 171 | 172 | ### 4.4 用户体验优化 173 | - **加载状态**: 思考中的动画提示 174 | - **错误处理**: 友好的错误信息展示 175 | - **自动滚动**: 新消息自动滚动到底部 176 | - **响应式设计**: 适配不同屏幕尺寸 177 | - **暗色模式**: 支持明暗主题切换 178 | 179 | ## 5. 可迁移性 180 | 181 | ### 5.1 架构解耦 182 | 系统采用了高度解耦的架构设计: 183 | 184 | #### Agent 层可替换 185 | 通过修改 `agent-config.json`,可以轻松切换不同的 Agent 实现: 186 | ```json 187 | { 188 | "agent": { 189 | "module": "your_agentmodule", 190 | "rootAgent": "your_root_agent" 191 | } 192 | } 193 | ``` 194 | 195 | #### 前后端分离 196 | - 前端完全独立,通过 WebSocket 协议通信 197 | - 后端提供标准化的 WebSocket 消息接口 198 | - 文件访问通过 RESTful API 199 | 200 | ### 5.2 扩展性 201 | #### 添加新的 Agent 202 | 1. 在新模块中定义 Agent 203 | 2. 更新 `agent-config.json` 配置 204 | 3. 无需修改前端或 WebSocket 服务器 205 | 206 | #### 添加新的前端功能 207 | 1. 创建新的 React 组件 208 | 2. 定义新的消息类型 209 | 3. 在 WebSocket 服务器中添加消息处理逻辑 210 | 211 | #### 自定义 UI 主题 212 | 通过 TailwindCSS 配置文件自定义样式主题 213 | 214 | ### 5.3 部署灵活性 215 | - **前端**: 可独立部署为静态网站 216 | - **后端**: 支持 Docker 容器化部署 217 | - **配置**: 通过环境变量和配置文件管理 218 | 219 | ### 5.4 技术栈通用性 220 | - 使用行业标准技术(React、WebSocket、FastAPI) 221 | - 遵循 RESTful 和 WebSocket 标准协议 222 | - 代码结构清晰,易于理解和维护 223 | 224 | ## 总结 225 | 226 | Agent 前端实现了一个现代化的 AI Agent 交互界面,通过 WebSocket 实现了与后端 Agent 的实时通信。系统架构解耦、功能完善、易于扩展,为智能符号回归任务提供了直观、高效的用户界面。 227 | -------------------------------------------------------------------------------- /agents/SRAgent/docs/AGENT_CONFIGURATION_GUIDE.md: -------------------------------------------------------------------------------- 1 | # Agent Configuration Guide 2 | 3 | ## Overview 4 | 5 | The NexusAgent UI system is designed to be agent-agnostic. You can easily switch between different agent implementations by modifying the configuration file. 6 | 7 | ## Configuration File 8 | 9 | The main configuration file is located at `config/agent-config.json`. 10 | 11 | ## Switching Agents 12 | 13 | To use a different agent with the UI, follow these steps: 14 | 15 | ### 1. Update the Agent Configuration 16 | 17 | Edit `config/agent-config.json`: 18 | 19 | ```json 20 | { 21 | "agent": { 22 | "name": "Your Agent Name", 23 | "description": "Your agent description", 24 | "welcomeMessage": "Welcome message for users", 25 | "module": "your_module.submodule", // Python module path 26 | "rootAgent": "your_agent_instance" // Agent instance name 27 | } 28 | } 29 | ``` 30 | 31 | ### 2. Example Configurations 32 | 33 | #### NexusAgent SR (Default) 34 | ```json 35 | { 36 | "agent": { 37 | "name": "NexusAgent SR", 38 | "description": "智能符号回归分析系统", 39 | "welcomeMessage": "输入您的数据文件路径,开始符号回归分析", 40 | "module": "Nexusagent_SR.subagent", 41 | "rootAgent": "rootagent" 42 | } 43 | } 44 | ``` 45 | 46 | #### Custom Research Agent 47 | ```json 48 | { 49 | "agent": { 50 | "name": "Research Assistant", 51 | "description": "AI-powered research system", 52 | "welcomeMessage": "What would you like to research today?", 53 | "module": "research_agent.main", 54 | "rootAgent": "research_agent" 55 | } 56 | } 57 | ``` 58 | 59 | ### 3. UI Customization 60 | 61 | Customize the UI appearance and features: 62 | 63 | ```json 64 | { 65 | "ui": { 66 | "title": "Your App Title", 67 | "theme": { 68 | "primaryColor": "blue", 69 | "secondaryColor": "purple" 70 | }, 71 | "features": { 72 | "showFileExplorer": true, // Show/hide file explorer 73 | "showSessionList": true, // Show/hide session management 74 | "enableFileUpload": false // Enable file upload feature 75 | } 76 | } 77 | } 78 | ``` 79 | 80 | ### 4. File Management 81 | 82 | Configure which directories to watch and display: 83 | 84 | ```json 85 | { 86 | "files": { 87 | "outputDirectory": "output", // Default output directory 88 | "watchDirectories": ["output", "results"], // Directories to display 89 | "fileExtensions": { 90 | "supported": ["json", "md", "txt", "csv", "py"], 91 | "defaultViewer": { 92 | "json": "code", 93 | "md": "markdown", 94 | "csv": "table" 95 | } 96 | } 97 | } 98 | } 99 | ``` 100 | 101 | ### 5. Tool Display Names 102 | 103 | Customize how tools are displayed in the UI: 104 | 105 | ```json 106 | { 107 | "tools": { 108 | "displayNames": { 109 | "your_tool_name": "User-Friendly Name", 110 | "another_tool": "Another Display Name" 111 | }, 112 | "longRunningTools": [ 113 | "heavy_computation_tool", 114 | "data_processing_tool" 115 | ] 116 | } 117 | } 118 | ``` 119 | 120 | ## Implementation Requirements 121 | 122 | For your agent to work with this UI system, it must: 123 | 124 | 1. **Be compatible with Google ADK**: The agent should work with Google's Agent Development Kit 125 | 2. **Use standard message format**: Messages should follow the format used by the WebSocket server 126 | 3. **Implement required methods**: Your agent should handle user messages and return appropriate responses 127 | 128 | ## Quick Start 129 | 130 | 1. Install your agent module: 131 | ```bash 132 | pip install your-agent-package 133 | ``` 134 | 135 | 2. Update `config/agent-config.json` with your agent details 136 | 137 | 3. Restart the server: 138 | ```bash 139 | ./start-nexus.sh 140 | ``` 141 | 142 | 4. The UI will automatically load your agent configuration 143 | 144 | ## Environment Variables 145 | 146 | You can also use environment variables to override configuration: 147 | 148 | ```bash 149 | export AGENT_MODULE=my_agent.main 150 | export AGENT_NAME=my_agent 151 | export UI_TITLE="My Custom Agent" 152 | ``` 153 | 154 | ## Troubleshooting 155 | 156 | - **Agent not loading**: Check that the module path and agent name are correct 157 | - **UI not updating**: Clear browser cache and reload 158 | - **WebSocket errors**: Ensure your agent is compatible with the message format 159 | 160 | ## Example: Creating a Compatible Agent 161 | 162 | ```python 163 | from google.adk import Agent 164 | from google.adk.models import LiteLlm 165 | 166 | # Your agent implementation 167 | my_agent = Agent( 168 | name="MyAgent", 169 | model=LiteLlm(model="gpt-4"), 170 | description="My custom agent", 171 | tools=[...], 172 | instruction="..." 173 | ) 174 | 175 | # Export as the root agent 176 | rootagent = my_agent 177 | ``` -------------------------------------------------------------------------------- /agents/SRAgent/open_deep_research/configuration.py: -------------------------------------------------------------------------------- 1 | import os 2 | from enum import Enum 3 | from dataclasses import dataclass, fields, field 4 | from typing import Any, Optional, Dict, Literal 5 | 6 | from langchain_core.runnables import RunnableConfig 7 | 8 | DEFAULT_REPORT_STRUCTURE = """Use this structure to create a report on the user-provided topic: 9 | 10 | 1. Introduction (no research needed) 11 | - Brief overview of the topic area 12 | 13 | 2. Main Body Sections: 14 | - Each section should focus on a sub-topic of the user-provided topic 15 | 16 | 3. Conclusion 17 | - Aim for 1 structural element (either a list or table) that distills the main body sections 18 | - Provide a concise summary of the report""" 19 | 20 | class SearchAPI(Enum): 21 | PERPLEXITY = "perplexity" 22 | TAVILY = "tavily" 23 | EXA = "exa" 24 | ARXIV = "arxiv" 25 | PUBMED = "pubmed" 26 | LINKUP = "linkup" 27 | DUCKDUCKGO = "duckduckgo" 28 | GOOGLESEARCH = "googlesearch" 29 | NONE = "none" 30 | 31 | @dataclass(kw_only=True) 32 | class WorkflowConfiguration: 33 | """Configuration for the workflow/graph-based implementation (graph.py).""" 34 | # Common configuration 35 | report_structure: str = DEFAULT_REPORT_STRUCTURE 36 | search_api: SearchAPI = SearchAPI.TAVILY 37 | search_api_config: Optional[Dict[str, Any]] = None 38 | process_search_results: Literal["summarize", "split_and_rerank"] | None = None 39 | summarization_model_provider: str = "anthropic" 40 | summarization_model: str = "claude-3-5-haiku-latest" 41 | max_structured_output_retries: int = 3 42 | include_source_str: bool = False 43 | base_url: Optional[str] = None # Base URL for the API, if needed 44 | api_key: Optional[str] = None # API key for authentication, if needed 45 | # Workflow-specific configuration 46 | number_of_queries: int = 2 # Number of search queries to generate per iteration 47 | max_search_depth: int = 2 # Maximum number of reflection + search iterations 48 | planner_provider: str = "anthropic" 49 | planner_model: str = "claude-3-7-sonnet-latest" 50 | planner_model_kwargs: Optional[Dict[str, Any]] = None 51 | writer_provider: str = "anthropic" 52 | writer_model: str = "claude-3-7-sonnet-latest" 53 | writer_model_kwargs: Optional[Dict[str, Any]] = None 54 | 55 | @classmethod 56 | def from_runnable_config( 57 | cls, config: Optional[RunnableConfig] = None 58 | ) -> "WorkflowConfiguration": 59 | """Create a WorkflowConfiguration instance from a RunnableConfig.""" 60 | 61 | configurable = ( 62 | config["configurable"] if config and "configurable" in config.keys() else {} 63 | ) 64 | values: dict[str, Any] = { 65 | f.name: os.environ.get(f.name.upper(), configurable.get(f.name)) 66 | for f in fields(cls) 67 | if f.init 68 | } 69 | return cls(**{k: v for k, v in values.items() if v}) 70 | 71 | @dataclass(kw_only=True) 72 | class MultiAgentConfiguration: 73 | """Configuration for the multi-agent implementation (multi_agent.py).""" 74 | # Common configuration 75 | search_api: SearchAPI = SearchAPI.TAVILY 76 | search_api_config: Optional[Dict[str, Any]] = None 77 | process_search_results: Literal["summarize", "split_and_rerank"] | None = None 78 | summarization_model_provider: str = "anthropic" 79 | summarization_model: str = "claude-3-5-haiku-latest" 80 | include_source_str: bool = False 81 | 82 | # Multi-agent specific configuration 83 | number_of_queries: int = 2 # Number of search queries to generate per section 84 | supervisor_model: str = "anthropic:claude-3-7-sonnet-latest" 85 | researcher_model: str = "anthropic:claude-3-7-sonnet-latest" 86 | ask_for_clarification: bool = False # Whether to ask for clarification from the user 87 | # MCP server configuration 88 | mcp_server_config: Optional[Dict[str, Any]] = None 89 | mcp_prompt: Optional[str] = None 90 | mcp_tools_to_include: Optional[list[str]] = None 91 | 92 | @classmethod 93 | def from_runnable_config( 94 | cls, config: Optional[RunnableConfig] = None 95 | ) -> "MultiAgentConfiguration": 96 | """Create a MultiAgentConfiguration instance from a RunnableConfig.""" 97 | configurable = ( 98 | config["configurable"] if config and "configurable" in config else {} 99 | ) 100 | values: dict[str, Any] = { 101 | f.name: os.environ.get(f.name.upper(), configurable.get(f.name)) 102 | for f in fields(cls) 103 | if f.init 104 | } 105 | return cls(**{k: v for k, v in values.items() if v}) 106 | 107 | # Keep the old Configuration class for backward compatibility 108 | Configuration = WorkflowConfiguration 109 | -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/src/components/Layout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link, useLocation } from 'react-router-dom' 3 | import { 4 | LayoutDashboard, 5 | ListTodo, 6 | FileText, 7 | Settings, 8 | Brain, 9 | Activity, 10 | Sparkles 11 | } from 'lucide-react' 12 | import { motion } from 'framer-motion' 13 | 14 | interface LayoutProps { 15 | children: React.ReactNode 16 | } 17 | 18 | const Layout: React.FC = ({ children }) => { 19 | const location = useLocation() 20 | 21 | const navigation = [ 22 | { name: 'Dashboard', href: '/', icon: LayoutDashboard }, 23 | { name: 'Tasks', href: '/tasks', icon: ListTodo }, 24 | { name: 'Files', href: '/files', icon: FileText }, 25 | { name: 'Settings', href: '/settings', icon: Settings }, 26 | ] 27 | 28 | const isActive = (path: string) => { 29 | if (path === '/') { 30 | return location.pathname === '/' 31 | } 32 | return location.pathname.startsWith(path) 33 | } 34 | 35 | return ( 36 |
37 | {/* Sidebar */} 38 |
39 |
40 | {/* Logo */} 41 |
42 |
43 | 44 |
45 |
46 |

Agent

47 |

Symbolic Regression

48 |
49 |
50 | 51 | {/* Navigation */} 52 | 71 | 72 | {/* Status */} 73 |
74 |
75 |
76 | Agent Status 77 | 78 |
79 |
80 |
81 | Connected 82 |
83 |
84 |
85 |
86 |
87 | 88 | {/* Main Content */} 89 |
90 | {/* Header */} 91 |
92 |
93 |
94 | 95 |

96 | {navigation.find(item => isActive(item.href))?.name || 'Dashboard'} 97 |

98 |
99 |
100 | 101 | {new Date().toLocaleDateString('zh-CN', { 102 | year: 'numeric', 103 | month: 'long', 104 | day: 'numeric' 105 | })} 106 | 107 |
108 |
109 |
110 | 111 | {/* Page Content */} 112 |
113 | 120 | {children} 121 | 122 |
123 |
124 |
125 | ) 126 | } 127 | 128 | export default Layout -------------------------------------------------------------------------------- /agents/SRAgent/nexus-ui/src/components/Layout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link, useLocation } from 'react-router-dom' 3 | import { 4 | LayoutDashboard, 5 | ListTodo, 6 | FileText, 7 | Settings, 8 | Brain, 9 | Activity, 10 | Sparkles 11 | } from 'lucide-react' 12 | import { motion } from 'framer-motion' 13 | 14 | interface LayoutProps { 15 | children: React.ReactNode 16 | } 17 | 18 | const Layout: React.FC = ({ children }) => { 19 | const location = useLocation() 20 | 21 | const navigation = [ 22 | { name: 'Dashboard', href: '/', icon: LayoutDashboard }, 23 | { name: 'Tasks', href: '/tasks', icon: ListTodo }, 24 | { name: 'Files', href: '/files', icon: FileText }, 25 | { name: 'Settings', href: '/settings', icon: Settings }, 26 | ] 27 | 28 | const isActive = (path: string) => { 29 | if (path === '/') { 30 | return location.pathname === '/' 31 | } 32 | return location.pathname.startsWith(path) 33 | } 34 | 35 | return ( 36 |
37 | {/* Sidebar */} 38 |
39 |
40 | {/* Logo */} 41 |
42 |
43 | 44 |
45 |
46 |

NexusAgent

47 |

Symbolic Regression

48 |
49 |
50 | 51 | {/* Navigation */} 52 | 71 | 72 | {/* Status */} 73 |
74 |
75 |
76 | Agent Status 77 | 78 |
79 |
80 |
81 | Connected 82 |
83 |
84 |
85 |
86 |
87 | 88 | {/* Main Content */} 89 |
90 | {/* Header */} 91 |
92 |
93 |
94 | 95 |

96 | {navigation.find(item => isActive(item.href))?.name || 'Dashboard'} 97 |

98 |
99 |
100 | 101 | {new Date().toLocaleDateString('zh-CN', { 102 | year: 'numeric', 103 | month: 'long', 104 | day: 'numeric' 105 | })} 106 | 107 |
108 |
109 |
110 | 111 | {/* Page Content */} 112 |
113 | 120 | {children} 121 | 122 |
123 |
124 |
125 | ) 126 | } 127 | 128 | export default Layout -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/src/components/Layout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link, useLocation } from 'react-router-dom' 3 | import { 4 | LayoutDashboard, 5 | ListTodo, 6 | FileText, 7 | Settings, 8 | Brain, 9 | Activity, 10 | Sparkles 11 | } from 'lucide-react' 12 | import { motion } from 'framer-motion' 13 | 14 | interface LayoutProps { 15 | children: React.ReactNode 16 | } 17 | 18 | const Layout: React.FC = ({ children }) => { 19 | const location = useLocation() 20 | 21 | const navigation = [ 22 | { name: 'Dashboard', href: '/', icon: LayoutDashboard }, 23 | { name: 'Tasks', href: '/tasks', icon: ListTodo }, 24 | { name: 'Files', href: '/files', icon: FileText }, 25 | { name: 'Settings', href: '/settings', icon: Settings }, 26 | ] 27 | 28 | const isActive = (path: string) => { 29 | if (path === '/') { 30 | return location.pathname === '/' 31 | } 32 | return location.pathname.startsWith(path) 33 | } 34 | 35 | return ( 36 |
37 | {/* Sidebar */} 38 |
39 |
40 | {/* Logo */} 41 |
42 |
43 | 44 |
45 |
46 |

Agent

47 |

Symbolic Regression

48 |
49 |
50 | 51 | {/* Navigation */} 52 | 71 | 72 | {/* Status */} 73 |
74 |
75 |
76 | Agent Status 77 | 78 |
79 |
80 |
81 | Connected 82 |
83 |
84 |
85 |
86 |
87 | 88 | {/* Main Content */} 89 |
90 | {/* Header */} 91 |
92 |
93 |
94 | 95 |

96 | {navigation.find(item => isActive(item.href))?.name || 'Dashboard'} 97 |

98 |
99 |
100 | 101 | {new Date().toLocaleDateString('zh-CN', { 102 | year: 'numeric', 103 | month: 'long', 104 | day: 'numeric' 105 | })} 106 | 107 |
108 |
109 |
110 | 111 | {/* Page Content */} 112 |
113 | 120 | {children} 121 | 122 |
123 |
124 |
125 | ) 126 | } 127 | 128 | export default Layout -------------------------------------------------------------------------------- /agents/SRAgent/Nexusagent_SR/tool/deepresearch.py: -------------------------------------------------------------------------------- 1 | # Import required modules and initialize the builder from open_deep_research 2 | import uuid 3 | from langgraph.checkpoint.memory import MemorySaver 4 | from open_deep_research.graph import builder 5 | import Nexusagent_SR 6 | import os 7 | 8 | memory = MemorySaver() 9 | graph = builder.compile(checkpointer=memory) 10 | # Define report structure template and configure the research workflow 11 | # This sets parameters for models, search tools, and report organization 12 | 13 | REPORT_STRUCTURE = """Use this structure to create a report on the user-provided topic: 14 | # {{Title}} 15 | 16 | ## 1. Variable Introduction 17 | - **x₁:** 18 | - **x₂:** 19 | - **…** 20 | - **y (target):** 21 | 22 | --- 23 | 24 | ## 2. Background Equations 25 | | Equation Name | Mathematical Form | Brief Description | 26 | | ------------- | ----------------- | ----------------- | 27 | | | | | 28 | | | | | 29 | 30 | --- 31 | 32 | ## 3. Physically Motivated Functional Terms 33 | - 34 | - 35 | - 36 | 37 | --- 38 | 39 | ## 4. Recommended Unary Operators 40 | - **Include:** 41 | - **Exclude:** 42 | 43 | --- 44 | 45 | ## 5. Summary 46 | - 47 | - **Final list of endorsed unary operators:** 48 | 49 | """ 50 | 51 | 52 | task=""" 53 | \n 54 | Your task is to write a report on the user-provided topic. 55 | 56 | Read the user’s problem statement and any accompanying data descriptions, perform targeted literature/web searches as needed, and produce a prior-informed technical report with the exact section titles and ordering shown below. 57 | 58 | Report Structure 59 | 1. Variable Introduction 60 | • For each variable x₁, x₂, … (and the target y), state its physical or biological meaning, units (if given), and measurement context. 61 | 2. Background Equations 62 | • Conduct an in-depth search to identify multiple canonical or widely cited governing equations relevant to the user’s system. 63 | • For each equation, provide: 64 | • The full mathematical expression 65 | • A one-sentence description of its functional role in modeling the system dynamics 66 | 3. Physically Motivated Functional Terms 67 | • Extract from the equations in §2 the most common physically meaningful terms. 68 | • Explain briefly why each term frequently appears in this class of models. 69 | 4. Recommended Unary Operators 70 | • Based on §§2-3, recommend which unary operators should be included or excluded in the symbolic-regression search space. 71 | • Justify each recommendation with concrete references or empirical rationale—avoid speculation. 72 | 5. Summary 73 | • Concisely recap key insights and restate the final list of endorsed unary operators. 74 | 75 | The user's topic is: 76 | {topic} 77 | """ 78 | 79 | # Define research topic about Model Context Protocol 80 | # Run the graph workflow until first interruption (waiting for user feedback) 81 | 82 | async def deepresearch_agent(topic): 83 | # Configuration option 3: Use OpenAI o3 for both planning and writing (selected option) 84 | thread = {"configurable": {"thread_id": str(uuid.uuid4()), 85 | "search_api": os.getenv("SEARCH_TOOL","gemini"), 86 | "planner_provider": "deepseek", 87 | "planner_model": os.getenv("DEEPRESEARCH_MODEL","deepseek-chat"), 88 | "writer_provider": "deepseek", 89 | "writer_model": os.getenv("DEEPRESEARCH_MODEL","deepseek-chat"), 90 | "max_search_depth": 2, 91 | "report_structure": REPORT_STRUCTURE, 92 | "base_url": os.getenv("DEEPRESEARCH_ENDPOINT","https://api.deepresearch.ai/v1"), 93 | "api_key": os.getenv("DEEPSEEK_API_KEY","gemini-api-key"),} 94 | } 95 | topic = task.format(topic=topic) 96 | async for event in graph.astream({"topic": topic}, thread, stream_mode="updates"): 97 | if '__interrupt__' in event: 98 | interrupt_value = event['__interrupt__'][0].value 99 | 100 | # Display the final generated report 101 | # Retrieve the completed report from the graph's state and format it for display 102 | 103 | final_state = graph.get_state(thread) 104 | report = final_state.values.get('completed_sections') 105 | print(len(report)) 106 | # print(report[0].content) 107 | report_content = "\n\n".join(section["content"] for section in report) 108 | 109 | with open("output/deepresearch_report.md", "w", encoding="utf-8") as f: 110 | f.write(report_content) 111 | return report_content 112 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **Build Your Agent** 2 | 3 |

4 | An open-source initiative by the DeepModeling community for constructing intelligent agents in scientific research 5 |

6 | 7 | --- 8 | 9 | ## **Overview** 10 | 11 | Build Your Agent is a comprehensive collection of production-ready intelligent agents designed for real-world scientific research challenges. Our mission is to democratize AI agent development by providing well-architected examples that demonstrate practical design patterns and implementation methods. 12 | 13 | We focus on creating agents that follow a systematic architecture: **Perception → Planning → Execution → Feedback**, enabling researchers to tackle complex scientific problems with AI-powered assistance. 14 | 15 | ## **🚀 Featured Agents** 16 | 17 | ### **1. SRAgent - Advanced Symbolic Regression System** 18 | [`agents/SRAgent/`](agents/SRAgent) 19 | 20 | Transform raw data into interpretable mathematical models through multi-agent collaboration. 21 | - **Features**: Deep literature research, automatic report generation, iterative optimization 22 | - **Use Case**: Discovering mathematical relationships in experimental data 23 | 24 | ### **2. DPA Calculator - Materials Science Computation** 25 | [`agents/dpa_calculator/`](agents/dpa_calculator) 26 | 27 | Perform advanced materials calculations using Deep Potential models on Bohrium platform. 28 | - **Features**: Structure optimization, phonon calculations, natural language interface 29 | - **Use Case**: Materials property prediction and structure analysis 30 | 31 | ### **3. Paper Search Demo - Research Literature Assistant** 32 | [`agents/paper_search_demo/`](agents/paper_search_demo) 33 | 34 | A beginner-friendly agent for searching and analyzing scientific papers from arXiv. 35 | - **Features**: Paper retrieval, literature analysis, MCP integration 36 | - **Use Case**: Literature review and research exploration 37 | 38 | ### **4. Thermoelectric MCP - Specialized Materials Analysis** 39 | [`agents/thermoelectric_mcp/`](agents/thermoelectric_mcp) 40 | 41 | Calculate thermoelectric properties of materials using advanced computational methods. 42 | - **Features**: Property predictions, cloud-based calculations 43 | - **Use Case**: Thermoelectric materials research and optimization 44 | 45 | ### **5. ADK UI Starter - Universal Agent Interface** 46 | [`agents/adk_ui_starter/`](agents/adk_ui_starter) 47 | 48 | A plug-and-play web UI framework for any Google ADK agent - no frontend coding required. 49 | - **Features**: Zero-code integration, real-time chat, file management 50 | - **Use Case**: Rapid agent deployment with professional UI 51 | 52 | 53 | ## **🎯 Application Scenarios** 54 | 55 | Build Your Agent supports diverse scientific research workflows: 56 | 57 | - **Literature Review & Synthesis**: Automated paper search, analysis, and review generation 58 | - **Materials Design & Optimization**: Structure prediction, property calculation, and screening 59 | - **Mathematical Modeling**: Symbolic regression and equation discovery from data 60 | - **Drug Discovery**: Molecule screening based on multiple drug-likeness properties 61 | - **Omics Data Analysis**: Cross-domain data integration and automated analysis 62 | - **Custom Research Workflows**: Extensible framework for domain-specific applications 63 | 64 | ## **🚦 Getting Started** 65 | 66 | 1. **Choose an Agent**: Select from our featured agents based on your research needs 67 | 2. **Follow Setup Guide**: Each agent includes detailed installation and configuration instructions 68 | 3. **Customize & Extend**: Modify agents for your specific requirements or build new ones 69 | 4. **Deploy & Share**: Use our UI framework for rapid deployment and collaboration 70 | 71 | ## **📚 Documentation & Resources** 72 | 73 | - **Agent Development Guides**: Step-by-step tutorials for building custom agents 74 | - **Architecture Documentation**: Detailed explanation of the Perception → Planning → Execution → Feedback pattern 75 | - **API References**: Comprehensive documentation for all agent tools and interfaces 76 | - **Example Notebooks**: Jupyter notebooks demonstrating agent capabilities 77 | 78 | ## **🤝 Community & Contribution** 79 | 80 | Build Your Agent is an open-source project welcoming contributions from the global research community: 81 | 82 | - **Submit New Agents**: Share your domain-specific agents 83 | - **Improve Existing Agents**: Enhance features and capabilities 84 | - **Report Issues**: Help us improve by reporting bugs and suggesting features 85 | - **Join Discussions**: Participate in our community forums and development discussions 86 | 87 | ## **🌟 Vision** 88 | 89 | We envision a future where every researcher has access to intelligent AI assistants tailored to their specific domain. By providing high-quality examples and a robust framework, we aim to accelerate scientific discovery through the democratization of AI agent technology. 90 | 91 | ## **📄 License** 92 | 93 | This project is licensed under the terms specified in the [LICENSE](LICENSE) file. 94 | 95 | --- 96 | 97 |

98 | Start building your intelligent research assistant today! 99 |

100 | -------------------------------------------------------------------------------- /agents/SRAgent/README.md: -------------------------------------------------------------------------------- 1 | # NexusAgent-SR 2 | 3 | > 🔬 **基于Google ADK的符号回归智能代理系统** 4 | > 自动将原始数据转换为可解释的数学模型 5 | 6 | [![License: MulanPSL-2.0](https://img.shields.io/badge/License-MulanPSL--2.0-blue.svg)](http://license.coscl.org.cn/MulanPSL2) 7 | [![Python 3.11+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/) 8 | 9 | ## ✨ 系统特性 10 | 11 | - 🤖 **多智能代理协同** - 基于Google ADK框架的智能代理编排系统 12 | - 📊 **自动数据分析** - 生成详细的数据特征描述和背景研究 13 | - 🔍 **深度文献调研** - 基于AI的领域知识提取 14 | - ⚡ **高效符号回归** - 基于PySR的高性能符号回归 15 | - 📝 **智能报告生成** - 自动生成科学研究报告并迭代优化 16 | 17 | ## 🚀 快速开始 18 | 19 | ### 环境配置 20 | 21 | 1. **安装依赖** 22 | ```bash 23 | pip install -r requirements.txt 24 | 25 | cd nexus-ui 26 | npm install >/dev/null 2>&1 27 | 28 | ``` 29 | 30 | 2. **配置环境变量** 31 | 在项目Nexusagent_SR内创建 `.env` 文件: 32 | ```bash 33 | # 模型配置 34 | DEEPRESEARCH_MODEL=deepseek-chat 35 | DEEPRESEARCH_ENDPOINT=https://api.deepseek.com 36 | 37 | TAVILY_API_KEY= 38 | SEARCH_TOOL=tavily 39 | 40 | #LLM model 41 | MODEL=deepseek/deepseek-chat 42 | DEEPSEEK_API_KEY= 43 | 44 | ``` 45 | 46 | 47 | 系统启动后,可通过Web界面与NexusAgent进行交互。 48 | 49 | ## 💻 用户界面 (UI) 50 | 51 | NexusAgent-SR 提供了现代化的 Web 用户界面,让您可以更直观地与系统交互。 52 | 53 | ### UI 特性 54 | 55 | - 🎨 **现代化设计** - 基于 React + TailwindCSS 的响应式界面 56 | - 💬 **实时对话** - WebSocket 支持的实时消息通信 57 | - 📁 **文件管理** - 直接在界面中查看输出文件和结果 58 | - 🔄 **任务状态** - 实时显示工具执行和任务进度 59 | - 🌓 **深色模式** - 支持明暗主题切换 60 | 61 | ### 启动 UI 62 | 63 | ```bash 64 | # 使用启动脚本 65 | 66 | ./start-nexus.sh 67 | 68 | ``` 69 | 70 | 访问 http://localhost:5173 即可使用界面。 71 | 72 | ### UI 架构 73 | 74 | - **前端**: React + TypeScript + Vite 75 | - **后端**: FastAPI + WebSocket 76 | - **通信**: 实时双向 WebSocket 连接 77 | 78 | 更多 UI 扩展信息请参考 [UI 扩展指南](docs/UI_EXTENSION_GUIDE.md)。 79 | 80 | ## 🏗️ 核心架构 81 | 82 | ### 智能代理编排 (`agent.py`) 83 | 84 | 系统由以下智能代理组成: 85 | 86 | ``` 87 | root_agent (NexusAgent) 88 | ├── research_agent # 数据分析与描述生成 89 | └── sr_iteration_agent # 符号回归迭代流程 90 | ├── prior_agent # 先验知识配置 91 | ├── symbolic_agent # 符号回归执行 92 | └── summarize_agent # 结果总结生成 93 | ``` 94 | 95 | **主要代理功能:** 96 | - **ResearchAgent**: 生成数据特征描述 97 | - **PriorAgent**: 设置算子和映射配置 98 | - **SymbolicAgent**: 执行符号回归算法 99 | - **SummarizeAgent**: 生成科学研究报告 100 | 101 | ### 工具集合 (`tool/`) 102 | 103 | | 工具模块 | 主要功能 | 说明 | 104 | |---------|---------|------| 105 | | `pysr.py` | 标准符号回归 | 基于PySR的多变量符号回归 | 106 | | `deepresearch.py` | 深度研究 | AI驱动的文献调研和知识提取 | 107 | | `summarize_report.py` | 报告生成 | 自动生成科学研究报告 | 108 | | `iteration_manager.py` | 迭代管理 | 管理多轮实验的历史记录 | 109 | | `task_manager.py` | 任务管理 | 异步任务状态跟踪 | 110 | | `utils.py` | 工具函数 | 数据处理和表达式简化 | 111 | 112 | ## 📊 使用方式 113 | 114 | ### 1. Web界面交互 115 | 116 | 启动 `adk web` 后,在Web界面中输入任务描述: 117 | 118 | ``` 119 | I am working on a standard symbolic regression task. The dataset describes a biophysical neuronal dynamic system, in which: • x₁ represents the membrane potential, • x₂ is a fast activation variable (e.g., associated with fast ion channels), • x₃ is a slow adaptation variable (e.g., representing slow potassium or calcium currents). The objective is to infer the form of the differential equation governing the change in membrane potential, i.e.,   y = dx₁/dt as a function of x₁, x₂, and x₃. It is assumed that the system does not involve magnetic flux modulation.csv path is data/hr_example.csv 120 | 121 | ``` 122 | 123 | 124 | 125 | 126 | ## 📋 输出结果 127 | 128 | - **📊 最优表达式**: 发现的数学方程 129 | - **📈 复杂度分析**: 模型复杂度和精度评估 130 | - **📝 科学报告**: 包含背景、方法、结果的完整报告 131 | - **🔍 研究文献**: 相关领域的文献调研结果 132 | - **📁 结果文件**: 133 | - `output/summarize_report.md` - 总结报告 134 | - `results.json` - 完整的符号回归结果 135 | - `best.txt` - 最优表达式 136 | 137 | ## 🛠️ 开发说明 138 | 139 | ### 目录结构 140 | ``` 141 | NexusAgent/ 142 | ├── Nexusagent_SR/ # 核心代理模块 143 | │ ├── agent.py # 主代理编排(已弃用) 144 | │ ├── subagent.py # 新的代理实现 145 | │ ├── prompt/ # 提示词模板 146 | │ ├── tool/ # 工具集合 147 | │ └── .env # 环境配置 148 | ├── nexus-ui/ # 前端界面 149 | │ ├── src/ # React 源代码 150 | │ │ ├── components/ # UI 组件 151 | │ │ └── styles/ # 样式文件 152 | │ └── package.json # 前端依赖 153 | ├── data/ # 示例数据 154 | ├── output/ # 输出结果 155 | ├── docs/ # 文档 156 | │ └── UI_EXTENSION_GUIDE.md # UI 扩展指南 157 | ├── nexus-websocket-server.py # WebSocket 服务器 158 | └── start-nexus.sh # 启动脚本 159 | 160 | ``` 161 | 162 | ### 扩展开发 163 | - 添加新的符号回归算法: 扩展 `tool/pysr*.py` 164 | - 集成新的AI模型: 修改 `subagent.py` 中的模型配置 165 | - 自定义提示词: 编辑 `prompt/agent_prompt.py` 166 | - 新增工具函数: 在 `tool/agent_tool.py` 中注册 167 | - 扩展 UI 功能: 参考 [UI 扩展指南](docs/UI_EXTENSION_GUIDE.md) 168 | - 添加新的 WebSocket 消息类型: 修改 `nexus-websocket-server.py` 169 | 170 | ## 🔧 故障排除 171 | 172 | ### 常见问题 173 | 174 | 1. **WebSocket 连接失败** 175 | - 确保后端服务器在 8000 端口运行 176 | - 检查防火墙设置 177 | 178 | 2. **前端无法加载** 179 | - 确保已安装 Node.js 和 npm 180 | - 运行 `npm install` 安装依赖 181 | 182 | 3. **代理执行超时** 183 | - 检查 API 密钥配置 184 | - 确认网络代理设置正确 185 | 186 | ## 🤝 贡献 187 | 188 | 欢迎提交 Issue 和 Pull Request! 189 | 190 | ## 📞 联系方式 191 | 192 | 如有问题或建议,请通过 GitHub Issues 联系我们。 193 | 194 | -------------------------------------------------------------------------------- /agents/DPA_Agent/ui/src/components/MessageAnimation.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, useRef } from 'react'; 2 | import { motion, AnimatePresence } from 'framer-motion'; 3 | 4 | interface TypewriterEffectProps { 5 | text: string; 6 | speed?: number; 7 | onComplete?: () => void; 8 | className?: string; 9 | } 10 | 11 | export const TypewriterEffect: React.FC = ({ 12 | text, 13 | speed = 30, 14 | onComplete, 15 | className = '' 16 | }) => { 17 | const [displayedText, setDisplayedText] = useState(''); 18 | const [currentIndex, setCurrentIndex] = useState(0); 19 | const intervalRef = useRef(null); 20 | 21 | useEffect(() => { 22 | if (currentIndex < text.length) { 23 | intervalRef.current = setTimeout(() => { 24 | setDisplayedText(prev => prev + text[currentIndex]); 25 | setCurrentIndex(prev => prev + 1); 26 | }, speed); 27 | } else if (onComplete) { 28 | onComplete(); 29 | } 30 | 31 | return () => { 32 | if (intervalRef.current) { 33 | clearTimeout(intervalRef.current); 34 | } 35 | }; 36 | }, [currentIndex, text, speed, onComplete]); 37 | 38 | return ( 39 | 40 | {displayedText} 41 | {currentIndex < text.length && ( 42 | 47 | )} 48 | 49 | ); 50 | }; 51 | 52 | interface MessageAnimationProps { 53 | children: React.ReactNode; 54 | isNew?: boolean; 55 | type?: 'user' | 'assistant' | 'tool' | 'system'; 56 | } 57 | 58 | export const MessageAnimation: React.FC = ({ 59 | children, 60 | isNew = false, 61 | type = 'user' 62 | }) => { 63 | const messageVariants = { 64 | initial: { 65 | opacity: 0, 66 | y: 20, 67 | scale: 0.95, 68 | }, 69 | animate: { 70 | opacity: 1, 71 | y: 0, 72 | scale: 1, 73 | transition: { 74 | duration: 0.3, 75 | ease: [0.22, 1, 0.36, 1], // Apple-style easing 76 | } 77 | }, 78 | exit: { 79 | opacity: 0, 80 | scale: 0.95, 81 | transition: { 82 | duration: 0.2 83 | } 84 | } 85 | }; 86 | 87 | const pulseVariants = { 88 | initial: { scale: 1 }, 89 | pulse: { 90 | scale: [1, 1.02, 1], 91 | transition: { 92 | duration: 0.3, 93 | ease: "easeInOut" 94 | } 95 | } 96 | }; 97 | 98 | return ( 99 | 100 | 108 | {isNew && type === 'assistant' && ( 109 | 114 | {children} 115 | 116 | )} 117 | {(!isNew || type !== 'assistant') && children} 118 | 119 | 120 | ); 121 | }; 122 | 123 | interface StreamingTextProps { 124 | text: string; 125 | isStreaming: boolean; 126 | className?: string; 127 | } 128 | 129 | export const StreamingText: React.FC = ({ 130 | text, 131 | isStreaming, 132 | className = '' 133 | }) => { 134 | const [displayedText, setDisplayedText] = useState(''); 135 | const textRef = useRef(text); 136 | 137 | useEffect(() => { 138 | if (text !== textRef.current) { 139 | const newChars = text.slice(textRef.current.length); 140 | if (newChars.length > 0) { 141 | setDisplayedText(prev => prev + newChars); 142 | } 143 | textRef.current = text; 144 | } 145 | }, [text]); 146 | 147 | useEffect(() => { 148 | setDisplayedText(text); 149 | }, []); 150 | 151 | return ( 152 | 153 | {displayedText} 154 | {isStreaming && ( 155 | 160 | )} 161 | 162 | ); 163 | }; 164 | 165 | // Loading dots animation 166 | export const LoadingDots: React.FC = () => { 167 | return ( 168 |
169 | {[0, 1, 2].map((i) => ( 170 | 184 | ))} 185 |
186 | ); 187 | }; -------------------------------------------------------------------------------- /agents/adk_ui_starter/ui/src/components/MessageAnimation.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, useRef } from 'react'; 2 | import { motion, AnimatePresence } from 'framer-motion'; 3 | 4 | interface TypewriterEffectProps { 5 | text: string; 6 | speed?: number; 7 | onComplete?: () => void; 8 | className?: string; 9 | } 10 | 11 | export const TypewriterEffect: React.FC = ({ 12 | text, 13 | speed = 30, 14 | onComplete, 15 | className = '' 16 | }) => { 17 | const [displayedText, setDisplayedText] = useState(''); 18 | const [currentIndex, setCurrentIndex] = useState(0); 19 | const intervalRef = useRef(null); 20 | 21 | useEffect(() => { 22 | if (currentIndex < text.length) { 23 | intervalRef.current = setTimeout(() => { 24 | setDisplayedText(prev => prev + text[currentIndex]); 25 | setCurrentIndex(prev => prev + 1); 26 | }, speed); 27 | } else if (onComplete) { 28 | onComplete(); 29 | } 30 | 31 | return () => { 32 | if (intervalRef.current) { 33 | clearTimeout(intervalRef.current); 34 | } 35 | }; 36 | }, [currentIndex, text, speed, onComplete]); 37 | 38 | return ( 39 | 40 | {displayedText} 41 | {currentIndex < text.length && ( 42 | 47 | )} 48 | 49 | ); 50 | }; 51 | 52 | interface MessageAnimationProps { 53 | children: React.ReactNode; 54 | isNew?: boolean; 55 | type?: 'user' | 'assistant' | 'tool' | 'system'; 56 | } 57 | 58 | export const MessageAnimation: React.FC = ({ 59 | children, 60 | isNew = false, 61 | type = 'user' 62 | }) => { 63 | const messageVariants = { 64 | initial: { 65 | opacity: 0, 66 | y: 20, 67 | scale: 0.95, 68 | }, 69 | animate: { 70 | opacity: 1, 71 | y: 0, 72 | scale: 1, 73 | transition: { 74 | duration: 0.3, 75 | ease: [0.22, 1, 0.36, 1], // Apple-style easing 76 | } 77 | }, 78 | exit: { 79 | opacity: 0, 80 | scale: 0.95, 81 | transition: { 82 | duration: 0.2 83 | } 84 | } 85 | }; 86 | 87 | const pulseVariants = { 88 | initial: { scale: 1 }, 89 | pulse: { 90 | scale: [1, 1.02, 1], 91 | transition: { 92 | duration: 0.3, 93 | ease: "easeInOut" 94 | } 95 | } 96 | }; 97 | 98 | return ( 99 | 100 | 108 | {isNew && type === 'assistant' && ( 109 | 114 | {children} 115 | 116 | )} 117 | {(!isNew || type !== 'assistant') && children} 118 | 119 | 120 | ); 121 | }; 122 | 123 | interface StreamingTextProps { 124 | text: string; 125 | isStreaming: boolean; 126 | className?: string; 127 | } 128 | 129 | export const StreamingText: React.FC = ({ 130 | text, 131 | isStreaming, 132 | className = '' 133 | }) => { 134 | const [displayedText, setDisplayedText] = useState(''); 135 | const textRef = useRef(text); 136 | 137 | useEffect(() => { 138 | if (text !== textRef.current) { 139 | const newChars = text.slice(textRef.current.length); 140 | if (newChars.length > 0) { 141 | setDisplayedText(prev => prev + newChars); 142 | } 143 | textRef.current = text; 144 | } 145 | }, [text]); 146 | 147 | useEffect(() => { 148 | setDisplayedText(text); 149 | }, []); 150 | 151 | return ( 152 | 153 | {displayedText} 154 | {isStreaming && ( 155 | 160 | )} 161 | 162 | ); 163 | }; 164 | 165 | // Loading dots animation 166 | export const LoadingDots: React.FC = () => { 167 | return ( 168 |
169 | {[0, 1, 2].map((i) => ( 170 | 184 | ))} 185 |
186 | ); 187 | }; --------------------------------------------------------------------------------