diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fe0700367dadb174fd971914010ab3ed6e5bb771 --- /dev/null +++ b/.gitignore @@ -0,0 +1,233 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# IDE Files +.vscode/ +!.vscode/launch.json +!.vscode/settings.json +.idea/ +*.swp +*.swo +*~ +.serena/ + +# Dependencies +node_modules/ +.pnp +.pnp.js +jspm_packages/ +bower_components/ + +# Build Output +build/ +dist/ +out/ +.next/ +.swc/ +.nuxt/ +.output/ +.vuepress/dist/ +.temp/ +.cache/ +target/ +.turbo +.pybuilder/ +*.egg-info/ +.installed.cfg +*.egg +@generated + +# Testing +coverage/ +.nyc_output/ +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +.pytest_tmpdir_* +test_data/ +test_results/ +test-run-comment.md + +# Playwright +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ +playwright-report/ +screenshots/ + +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +logs/ +app.log +debug.log +error.log +menu-analysis.log +*.log.* + +# Environment Variables +.env +.env.local +.env.development.local +.env.test.local +.env.production.local +.env.bak +.env.backup + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +develop-eggs/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +pip-wheel-metadata/ +MANIFEST +*.manifest +*.spec +pip-log.txt +pip-delete-this-directory.txt +.ipynb_checkpoints +profile_default/ +ipython_config.py +.python-version +Pipfile.lock +poetry.lock +__pypackages__/ +celerybeat-schedule +celerybeat.pid +*.sage.py +env/ +venv/ +.venv/ +ENV/ +env.bak/ +venv.bak/ +.spyderproject +.spyproject +.ropeproject +/site +.mypy_cache/ +.dmypy.json +dmypy.json +.pyre/ +.pytype/ +cython_debug/ +*.pyc +*.pyo +*.pyd + +# Database +*.sqlite +*.sqlite-shm +*.sqlite-wal +*.sqlite3 +*.sqlite3-journal +*.qdrant + +# Temporary Files +tmp/ +temp/ +*.tmp +*.temp +.tmp/ + +# Data Files +data/ +*.csv +*.json.bak +*.pickle +*.pkl +*.analysis.json +progress.json +results/ +examples/results/ + +# OS Generated Files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db +*.pem + +# Runtime Files +*.pid +*.tgz +*.tar.gz +.npm +.node_repl_history +.yarn-integrity + +# Translations +*.mo +*.pot + +# Documentation +docs/_build/ + +# Frameworks & Tools +.scrapy +instance/ +.webassets-cache +local_settings.py +.grunt +__snapshots__ +cdk_outputs.json +**/.langgraph_api +TODO.local.md +publish-output.txt + +# Vector Database & ML +qdrant_storage/ +embeddings_cache/ +.cache/ + +# Lock Files +*-lock.yaml +*-lock.json + +# Config Backups +config.bak + +# Docker +docker-compose.override.yml +.dockerignore + +# Project Specific +frontend/node_modules/ +frontend/dist/ +frontend/.next/ +frontend/.nuxt/ +frontend/.output/ +frontend/.vuepress/dist/ +frontend/.temp/ +frontend/.cache/ +backend/__pycache__/ +backend/*.pyc +backend/dist/ +backend/build/ +backend/.env +backend/.env.* \ No newline at end of file diff --git a/CopilotKit/.eslintrc.js b/CopilotKit/.eslintrc.js new file mode 100644 index 0000000000000000000000000000000000000000..274569ad647adcb26838fd1b53e2378e584b01ab --- /dev/null +++ b/CopilotKit/.eslintrc.js @@ -0,0 +1,10 @@ +module.exports = { + root: true, + // This tells ESLint to load the config from the package `eslint-config-custom` + extends: ["custom"], + settings: { + next: { + rootDir: ["examples/*/"], + }, + }, +}; diff --git a/CopilotKit/.npmrc b/CopilotKit/.npmrc new file mode 100644 index 0000000000000000000000000000000000000000..ded82e2f63f337df34ae03e82d7daabe1852845e --- /dev/null +++ b/CopilotKit/.npmrc @@ -0,0 +1 @@ +auto-install-peers = true diff --git a/CopilotKit/.prettierignore b/CopilotKit/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..211bdc4ec9605740ea59ecb6f3c2abe1b4fd2f9b --- /dev/null +++ b/CopilotKit/.prettierignore @@ -0,0 +1,4 @@ +README.md +node_modules +dist +**/@generated \ No newline at end of file diff --git a/CopilotKit/.prettierrc b/CopilotKit/.prettierrc new file mode 100644 index 0000000000000000000000000000000000000000..a80ba039021eeba77ba93ade653c09cc15c9695d --- /dev/null +++ b/CopilotKit/.prettierrc @@ -0,0 +1,7 @@ +{ + "semi": true, + "trailingComma": "all", + "singleQuote": false, + "printWidth": 100, + "tabWidth": 2 +} \ No newline at end of file diff --git a/CopilotKit/package.json b/CopilotKit/package.json new file mode 100644 index 0000000000000000000000000000000000000000..f2d6e3c33eeb718094fbd9cb26b76edaabea3d6e --- /dev/null +++ b/CopilotKit/package.json @@ -0,0 +1,44 @@ +{ + "private": false, + "scripts": { + "build": "turbo build", + "dev": "turbo dev --concurrency 14", + "lint": "turbo lint", + "clean": "turbo clean", + "test": "turbo test", + "docs": "echo 'Skipping docs generation'", + "check-types": "turbo check-types", + "format": "prettier --write \"**/*.{ts,tsx,md}\"", + "check-prettier": "prettier --check \"**/*.{ts,tsx,md}\"", + "freshbuild": "pnpm -w clean && pnpm i && pnpm -w build", + "precommit": "echo 'Skipping precommit hooks'", + "prepublish": "turbo run build" + }, + "devDependencies": { + "@changesets/cli": "^2.27.10", + "@types/node": "^18.11.17", + "eslint": "^8.56.0", + "glob": "^10.3.12", + "install": "^0.13.0", + "npm": "^10.7.0", + "prettier": "^3.2.5", + "prettier-plugin-tailwindcss": "^0.1.11", + "ts-node": "^10.9.2", + "turbo": "^2.0.6", + "typescript": "^5.2.3" + }, + "packageManager": "pnpm@9.5.0", + "keywords": [ + "copilotkit", + "copilot", + "react", + "nextjs", + "nodejs", + "ai", + "assistant", + "javascript", + "automation", + "textarea" + ], + "name": "CopilotKit" +} diff --git a/CopilotKit/packages/copilot-chat/backend/env.example b/CopilotKit/packages/copilot-chat/backend/env.example new file mode 100644 index 0000000000000000000000000000000000000000..57583737e50c5b83973a4e1b616829b73d9f7ddc --- /dev/null +++ b/CopilotKit/packages/copilot-chat/backend/env.example @@ -0,0 +1,6 @@ +# 服务器配置 +SERVER_PORT=8005 + +# DeepSeek 配置 +DEEPSEEK_API_KEY=your_deepseek_api_key_here +DEEPSEEK_MODEL=deepseek-chat \ No newline at end of file diff --git a/CopilotKit/packages/copilot-chat/backend/requirements.txt b/CopilotKit/packages/copilot-chat/backend/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..56995e1b13134f0e216055efbc390de5ec86b3ac --- /dev/null +++ b/CopilotKit/packages/copilot-chat/backend/requirements.txt @@ -0,0 +1,14 @@ +fastapi>=0.100.0 +uvicorn[standard]>=0.23.0 +pydantic>=2.0.0 +python-dotenv>=1.0.0 +httpx[socks]>=0.24.0 +openai>=1.0.0 +aiofiles>=23.0.0 +python-multipart>=0.0.6 +structlog>=23.0.0 +sse-starlette>=2.0.0 +reactivex>=4.0.4 +aiohttp>=3.9.0 +jsonschema>=4.20.0 +requests>=2.31.0 \ No newline at end of file diff --git a/CopilotKit/packages/copilot-chat/backend/server.py b/CopilotKit/packages/copilot-chat/backend/server.py new file mode 100644 index 0000000000000000000000000000000000000000..2d719ab7e5c4dc2bbd861ff87baa8550d792be1f --- /dev/null +++ b/CopilotKit/packages/copilot-chat/backend/server.py @@ -0,0 +1,285 @@ +#!/usr/bin/env python3 +""" +CopilotKit Debug Example Next - Backend Server (使用 create_copilot_app API) +基于 copilot-server 的 FastAPI 后端服务,使用新的 create_copilot_app API +""" + +import os +import sys +import logging +from datetime import datetime +from typing import Dict, Any, List +from pathlib import Path + +import uvicorn +from dotenv import load_dotenv + +# 添加 copilot-server 到路径 +current_dir = Path(__file__).parent +project_root = current_dir.parent.parent.parent.parent +runtime_python_path = project_root / "CopilotKit" / "packages" / "copilot-server" +sys.path.insert(0, str(runtime_python_path)) + +try: + from copilotkit_runtime import ( + CopilotRuntime, + CopilotRuntimeConstructorParams, + DeepSeekAdapter, + create_copilot_app, + Action, + Parameter + ) +except ImportError as e: + print(f"错误: 无法导入 copilot-server 模块: {e}") + print(f"请确保 copilot-server 路径正确: {runtime_python_path}") + sys.exit(1) + +# 加载环境变量 +load_dotenv() + +# 配置日志 +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + handlers=[ + logging.StreamHandler(), + logging.FileHandler('backend.log') + ] +) + +logger = logging.getLogger(__name__) + + +def create_demo_actions() -> List[Action]: + """创建演示动作""" + + async def get_current_time(arguments: Dict[str, Any]) -> str: + """获取当前时间""" + timezone = arguments.get("timezone", "UTC") + try: + current_time = datetime.now() + formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") + + logger.info(f"⏰ 获取当前时间: {formatted_time} ({timezone})") + return f"当前时间 ({timezone}): {formatted_time}" + except Exception as e: + logger.error(f"获取时间失败: {e}") + return f"获取时间失败: {str(e)}" + + async def calculate(arguments: Dict[str, Any]) -> str: + """计算数学表达式""" + expression = arguments.get("expression", "") + try: + # 简单的安全计算 + if any(op in expression for op in ['import', 'exec', 'eval', '__', 'open', 'file']): + return "不安全的表达式,计算被拒绝" + + # 只允许基本的数学运算 + allowed_chars = set('0123456789+-*/()., ') + if not all(c in allowed_chars for c in expression): + return "包含不允许的字符,只支持基本数学运算" + + result = eval(expression) + logger.info(f"🧮 计算: {expression} = {result}") + return f"计算结果: {expression} = {result}" + except ZeroDivisionError: + return "错误: 除零操作" + except Exception as e: + logger.error(f"计算失败: {e}") + return f"计算错误: {str(e)}" + + async def get_user_info(arguments: Dict[str, Any]) -> str: + """获取用户信息""" + user_id = arguments.get("user_id", "default") + try: + # 模拟用户数据 + users_db = { + "default": {"name": "演示用户", "role": "guest", "last_login": "2024-01-15"}, + "admin": {"name": "管理员", "role": "admin", "last_login": "2024-01-16"}, + "user1": {"name": "张三", "role": "user", "last_login": "2024-01-14"} + } + + user_info = users_db.get(user_id, { + "name": "未知用户", + "role": "guest", + "last_login": "从未登录" + }) + + result = f"用户信息 - 姓名: {user_info['name']}, 角色: {user_info['role']}, 最后登录: {user_info['last_login']}" + logger.info(f"👤 获取用户信息: {user_id} -> {user_info}") + return result + except Exception as e: + logger.error(f"获取用户信息失败: {e}") + return f"获取用户信息失败: {str(e)}" + + async def check_status(arguments: Dict[str, Any]) -> str: + """检查系统状态""" + service = arguments.get("service", "system") + try: + # 模拟系统状态检查 + status_db = { + "system": {"status": "运行中", "uptime": "24小时", "cpu": "45%", "memory": "62%"}, + "database": {"status": "正常", "connections": "8/100", "response_time": "12ms"}, + "api": {"status": "正常", "requests_per_min": "150", "error_rate": "0.1%"}, + "cache": {"status": "正常", "hit_rate": "89%", "memory_usage": "34%"} + } + + service_status = status_db.get(service, { + "status": "未知服务", + "message": f"服务 '{service}' 不存在" + }) + + if "message" in service_status: + result = service_status["message"] + else: + status_info = ", ".join([f"{k}: {v}" for k, v in service_status.items()]) + result = f"{service.upper()} 状态 - {status_info}" + + logger.info(f"📊 检查状态: {service} -> {service_status}") + return result + except Exception as e: + logger.error(f"状态检查失败: {e}") + return f"状态检查失败: {str(e)}" + + # 创建动作列表 + actions = [ + Action( + name="get_current_time", + description="获取当前时间,可指定时区", + parameters=[ + Parameter( + name="timezone", + type="string", + description="时区,例如: UTC, Asia/Shanghai, America/New_York", + required=False + ) + ], + handler=get_current_time + ), + Action( + name="calculate", + description="计算数学表达式,支持基本的四则运算", + parameters=[ + Parameter( + name="expression", + type="string", + description="要计算的数学表达式,例如: 2+3*4, (10-5)/2", + required=True + ) + ], + handler=calculate + ), + Action( + name="get_user_info", + description="获取用户信息", + parameters=[ + Parameter( + name="user_id", + type="string", + description="用户ID,可选值: default, admin, user1", + required=False + ) + ], + handler=get_user_info + ), + Action( + name="check_status", + description="检查系统或服务状态", + parameters=[ + Parameter( + name="service", + type="string", + description="服务名称,可选值: system, database, api, cache", + required=False + ) + ], + handler=check_status + ) + ] + + return actions + + +def main(): + """主函数""" + logger.info("🚀 启动CopilotKit Debug Example (使用 create_copilot_app API)") + + try: + # 获取DeepSeek API密钥 + deepseek_api_key = os.getenv("DEEPSEEK_API_KEY") + if not deepseek_api_key or deepseek_api_key == "test_key": + logger.warning("⚠️ 未设置有效的DEEPSEEK_API_KEY环境变量") + # 可以继续运行,但聊天功能将不可用 + deepseek_api_key = "test_key" + + # 创建DeepSeek适配器 + deepseek_adapter = DeepSeekAdapter( + api_key=deepseek_api_key, + model=os.getenv("DEEPSEEK_MODEL", "deepseek-chat"), + base_url=os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com/v1") + ) + + # 创建演示动作 + demo_actions = create_demo_actions() + + # 创建运行时 + runtime = CopilotRuntime( + CopilotRuntimeConstructorParams( + actions=demo_actions + ) + ) + + # 使用 create_copilot_app API 创建应用 + app = create_copilot_app( + runtime=runtime, + service_adapter=deepseek_adapter, + title="CopilotKit Debug Example (New API)", + version="0.1.0", + cors_origins=["*"], + prefix="/api/copilotkit" + ) + + # 添加自定义路由 + @app.get("/debug/new-api") + async def debug_new_api(): + """调试新API端点""" + return { + "message": "使用新的 create_copilot_app API 创建的应用", + "api": "create_copilot_app", + "runtime": "CopilotKit Python Runtime", + "version": "0.1.0", + "actions_count": len(demo_actions), + "actions": [action.name for action in demo_actions], + "timestamp": datetime.utcnow().isoformat() + } + + logger.info(f"✅ 创建CopilotRuntime成功,注册了 {len(demo_actions)} 个动作") + logger.info(f"🔧 配置DeepSeek适配器: {deepseek_adapter.model}") + logger.info("🌐 使用 create_copilot_app API 创建FastAPI应用") + + # 启动服务器 + port = int(os.getenv("SERVER_PORT", "8005")) # 支持环境变量配置端口 + host = "localhost" + + logger.info(f"📡 服务器配置:") + logger.info(f" - 地址: {host}:{port}") + logger.info(f" - API文档: http://{host}:{port}/docs") + logger.info(f" - 健康检查: http://{host}:{port}/api/health") + logger.info(f" - 新API调试: http://{host}:{port}/debug/new-api") + logger.info(f" - CopilotKit Hello: http://{host}:{port}/copilotkit/hello") + + uvicorn.run( + app, + host=host, + port=port, + log_level="info", + reload=False + ) + + except Exception as e: + logger.error(f"❌ 启动失败: {e}") + sys.exit(1) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/CopilotKit/packages/copilot-chat/frontend/.eslintrc.cjs b/CopilotKit/packages/copilot-chat/frontend/.eslintrc.cjs new file mode 100644 index 0000000000000000000000000000000000000000..1fc4b5e26f624a2676c297c9e014f29d1b22a132 --- /dev/null +++ b/CopilotKit/packages/copilot-chat/frontend/.eslintrc.cjs @@ -0,0 +1,27 @@ +module.exports = { + root: true, + env: { browser: true, es2020: true }, + extends: [ + 'eslint:recommended', + '@typescript-eslint/recommended', + 'plugin:react/recommended', + 'plugin:react-hooks/recommended', + 'plugin:react/jsx-runtime' + ], + ignorePatterns: ['dist', '.eslintrc.cjs'], + parser: '@typescript-eslint/parser', + plugins: ['react-refresh'], + rules: { + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + 'react/prop-types': 'off', + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + }, + settings: { + react: { + version: 'detect', + }, + }, +} \ No newline at end of file diff --git a/CopilotKit/packages/copilot-chat/frontend/index.html b/CopilotKit/packages/copilot-chat/frontend/index.html new file mode 100644 index 0000000000000000000000000000000000000000..34a708cf4d24590fc6044cf003ab759e09ec1145 --- /dev/null +++ b/CopilotKit/packages/copilot-chat/frontend/index.html @@ -0,0 +1,14 @@ + + +
+ + + +👋 您好!我是 AI 助手
+我可以帮助您查找和使用各种功能,有什么可以帮助您的吗?
+{textMessage.content}
++ CopilotKit 遇到了一个错误。请尝试刷新页面或联系支持。 +
+ {error && process.env.NODE_ENV === "development" && ( +
+ {error.message}
+ {"\n"}
+ {error.stack}
+
+ ( + Component: React.ComponentType
,
+ errorBoundaryProps?: Omit