diff --git a/README.md b/README.md index c46f8878c..778485728 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,8 @@ Each agent has a `soul.md` (personality), `memory.md` (long-term memory), and a - 2-core CPU / 4 GB RAM / 30 GB disk (minimum) - Network access to LLM API endpoints +> **Ubuntu/Debian note:** If you use the system Python 3.12 package, also install `python3.12-venv`; otherwise `bash setup.sh` will fail when creating the backend virtual environment. + > **Note:** Clawith does not run any AI models locally — all LLM inference is handled by external API providers (OpenAI, Anthropic, etc.). The local deployment is a standard web application with Docker orchestration. #### Recommended Configurations diff --git a/README_zh-CN.md b/README_zh-CN.md index 4ffaf07d1..5c80bd868 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -67,6 +67,8 @@ Agent 可以在运行时**发现并安装新工具**([Smithery](https://smithe - 2 核 CPU / 4 GB 内存 / 30 GB 磁盘(最低配置) - 可访问 LLM API +> **Ubuntu/Debian 额外说明:** 如果使用系统 Python 3.12,请同时安装 `python3.12-venv`,否则 `bash setup.sh` 在创建后端虚拟环境时会失败。 + > **说明:** Clawith 不在本地运行任何 AI 模型——所有 LLM 推理均由外部 API 提供商处理(OpenAI、Anthropic 等)。本地部署本质上是一个标准 Web 应用 + Docker 编排。 #### 各场景推荐配置 diff --git a/backend/app/api/wecom.py b/backend/app/api/wecom.py index 8aaa30469..be2107d70 100644 --- a/backend/app/api/wecom.py +++ b/backend/app/api/wecom.py @@ -32,7 +32,7 @@ from app.models.identity import IdentityProvider, SSOScanSession from app.models.user import User from app.services.activity_logger import log_activity -from app.services.auth_provider import auth_provider_registry +from app.services.auth_registry import auth_provider_registry from app.services.channel_session import find_or_create_channel_session from app.services.channel_user_service import channel_user_service from app.services.platform_service import platform_service @@ -686,7 +686,13 @@ async def wecom_callback( # 2. Extract user info and login/register via RegistrationService try: - auth_provider = auth_provider_registry.get_provider(provider) + auth_provider = await auth_provider_registry.get_provider( + db, + "wecom", + str(tenant_id) if tenant_id else None, + ) + if not auth_provider: + raise HTTPException(status_code=404, detail="WeCom provider not available") token_data = await auth_provider.exchange_code_for_token(code) access_token_str = token_data.get("access_token") @@ -698,9 +704,11 @@ async def wecom_callback( return HTMLResponse("Auth failed: No UserId returned") # Find or Create User (handles Identity and OrgMember linking) - user = await auth_provider.find_or_create_user( + user, _ = await auth_provider.find_or_create_user( db, user_info, tenant_id=tenant_id or provider.tenant_id ) + except HTTPException: + raise except Exception as e: logger.exception(f"WeCom login/register error: {e}") return HTMLResponse(f"Auth failed: {str(e)}") diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 8ca796a73..1f90b313a 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -2,7 +2,7 @@ name = "clawith-backend" version = "0.1.0" description = "Clawith - Enterprise Digital Employee Platform Backend" -requires-python = ">=3.11" +requires-python = ">=3.12" dependencies = [ "fastapi[standard]>=0.115.0", "uvicorn[standard]>=0.30.0", diff --git a/setup.sh b/setup.sh index 2e0f695ca..b1fcf30e6 100755 --- a/setup.sh +++ b/setup.sh @@ -131,7 +131,8 @@ if PG_BIN_DIR=$(find_psql 2>/dev/null); then # Try to create role and database ROLE_EXISTS=false - if psql -h localhost -p $PG_PORT -U "$USER" -d postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='clawith'" 2>/dev/null | grep -q 1; then + # Use --no-password so existing PostgreSQL setups don't hang on an interactive prompt. + if psql -w -h localhost -p $PG_PORT -U "$USER" -d postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='clawith'" 2>/dev/null | grep -q 1; then ROLE_EXISTS=true echo -e " ${GREEN}✓${NC} Role 'clawith' already exists" elif sudo -u postgres psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='clawith'" 2>/dev/null | grep -q 1; then @@ -141,8 +142,8 @@ if PG_BIN_DIR=$(find_psql 2>/dev/null); then if [ "$ROLE_EXISTS" = false ]; then # Try 1: as current user - if createuser -h localhost -p $PG_PORT clawith 2>/dev/null; then - psql -h localhost -p $PG_PORT -U "$USER" -d postgres -c "ALTER ROLE clawith WITH LOGIN PASSWORD 'clawith';" &>/dev/null + if createuser -w -h localhost -p $PG_PORT clawith 2>/dev/null; then + psql -w -h localhost -p $PG_PORT -U "$USER" -d postgres -c "ALTER ROLE clawith WITH LOGIN PASSWORD 'clawith';" &>/dev/null echo -e " ${GREEN}✓${NC} Created PostgreSQL role: clawith" # Try 2: via sudo -u postgres (standard Linux setup) elif sudo -u postgres createuser clawith 2>/dev/null && \ @@ -156,7 +157,7 @@ if PG_BIN_DIR=$(find_psql 2>/dev/null); then if [ -n "$PG_BIN_DIR" ] || command -v psql &>/dev/null; then DB_EXISTS=false - if psql -h localhost -p $PG_PORT -U "$USER" -lqt 2>/dev/null | cut -d\| -f1 | grep -qw clawith; then + if psql -w -h localhost -p $PG_PORT -U "$USER" -lqt 2>/dev/null | cut -d\| -f1 | grep -qw clawith; then DB_EXISTS=true elif sudo -u postgres psql -lqt 2>/dev/null | cut -d\| -f1 | grep -qw clawith; then DB_EXISTS=true @@ -165,7 +166,7 @@ if PG_BIN_DIR=$(find_psql 2>/dev/null); then if [ "$DB_EXISTS" = true ]; then echo -e " ${GREEN}✓${NC} Database 'clawith' already exists" else - if createdb -h localhost -p $PG_PORT -O clawith clawith 2>/dev/null || \ + if createdb -w -h localhost -p $PG_PORT -O clawith clawith 2>/dev/null || \ sudo -u postgres createdb -O clawith clawith 2>/dev/null; then echo -e " ${GREEN}✓${NC} Created database: clawith" fi @@ -246,14 +247,14 @@ if [ -z "$PG_BIN_DIR" ] && ! (PGPASSWORD=clawith psql -h localhost -p 5432 -U cl done # Create role and database if command -v psql &>/dev/null; then - if ! psql -h localhost -p $PG_PORT -U postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='clawith'" 2>/dev/null | grep -q 1; then - sudo -u postgres createuser clawith 2>/dev/null || createuser -h localhost -p $PG_PORT clawith 2>/dev/null || true + if ! psql -w -h localhost -p $PG_PORT -U postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='clawith'" 2>/dev/null | grep -q 1; then + sudo -u postgres createuser clawith 2>/dev/null || createuser -w -h localhost -p $PG_PORT clawith 2>/dev/null || true sudo -u postgres psql -c "ALTER ROLE clawith WITH LOGIN PASSWORD 'clawith';" 2>/dev/null || \ - psql -h localhost -p $PG_PORT -U postgres -c "ALTER ROLE clawith WITH LOGIN PASSWORD 'clawith';" 2>/dev/null || true + psql -w -h localhost -p $PG_PORT -U postgres -c "ALTER ROLE clawith WITH LOGIN PASSWORD 'clawith';" 2>/dev/null || true echo -e " ${GREEN}✓${NC} Created role: clawith" fi - if ! psql -h localhost -p $PG_PORT -U postgres -lqt 2>/dev/null | cut -d\| -f1 | grep -qw clawith; then - sudo -u postgres createdb -O clawith clawith 2>/dev/null || createdb -h localhost -p $PG_PORT -O clawith clawith 2>/dev/null || true + if ! psql -w -h localhost -p $PG_PORT -U postgres -lqt 2>/dev/null | cut -d\| -f1 | grep -qw clawith; then + sudo -u postgres createdb -O clawith clawith 2>/dev/null || createdb -w -h localhost -p $PG_PORT -O clawith clawith 2>/dev/null || true echo -e " ${GREEN}✓${NC} Created database: clawith" fi PG_MANAGED_BY_US=false # System manages PG now @@ -320,13 +321,13 @@ if [ -z "$PG_BIN_DIR" ] && ! (PGPASSWORD=clawith psql -h localhost -p 5432 -U cl fi # Create role and database - if ! psql -h localhost -p "$PG_PORT" -U postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='clawith'" 2>/dev/null | grep -q 1; then - createuser -h localhost -p "$PG_PORT" -U postgres clawith 2>/dev/null || true - psql -h localhost -p "$PG_PORT" -U postgres -c "ALTER ROLE clawith WITH LOGIN PASSWORD 'clawith';" &>/dev/null + if ! psql -w -h localhost -p "$PG_PORT" -U postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='clawith'" 2>/dev/null | grep -q 1; then + createuser -w -h localhost -p "$PG_PORT" -U postgres clawith 2>/dev/null || true + psql -w -h localhost -p "$PG_PORT" -U postgres -c "ALTER ROLE clawith WITH LOGIN PASSWORD 'clawith';" &>/dev/null echo -e " ${GREEN}✓${NC} Created role: clawith" fi - if ! psql -h localhost -p "$PG_PORT" -U postgres -lqt 2>/dev/null | cut -d\| -f1 | grep -qw clawith; then - createdb -h localhost -p "$PG_PORT" -U postgres -O clawith clawith 2>/dev/null + if ! psql -w -h localhost -p "$PG_PORT" -U postgres -lqt 2>/dev/null | cut -d\| -f1 | grep -qw clawith; then + createdb -w -h localhost -p "$PG_PORT" -U postgres -O clawith clawith 2>/dev/null echo -e " ${GREEN}✓${NC} Created database: clawith" fi else @@ -366,8 +367,15 @@ cd "$ROOT/backend" if [ ! -d ".venv" ]; then echo " Creating Python virtual environment..." - $PYTHON_BIN -m venv .venv - echo -e " ${GREEN}✓${NC} Virtual environment created" + if $PYTHON_BIN -m venv .venv; then + echo -e " ${GREEN}✓${NC} Virtual environment created" + else + echo -e " ${RED}✗${NC} Failed to create Python virtual environment." + echo " On Ubuntu/Debian, install the venv package first:" + echo " sudo apt install python3.12-venv" + echo " Then re-run: bash setup.sh" + exit 1 + fi fi if [ "$INSTALL_DEV" = true ]; then