# -*- coding: utf-8 -*- """全局配置:端口、数据目录、令牌有效期、认证开关。 所有路径/开关均可通过环境变量覆盖,便于部署和测试: PINEAGENTS_DEMO_HOST / PINEAGENTS_DEMO_PORT 监听地址(默认 127.0.0.1:8090) PINEAGENTS_DEMO_DATA_DIR JSON 数据目录(默认 <项目根>/data) PINEAGENTS_DEMO_AUTH_ENABLED 认证开关(默认 true) """ from __future__ import annotations import os from pathlib import Path # 项目根目录 = 本文件的上上级(app/config.py -> <根>) BASE_DIR = Path(__file__).resolve().parent.parent # --------------------------------------------------------------------------- # 数据目录(JSON "数据库" 所在位置) # --------------------------------------------------------------------------- # 约定:data/ 下每个文件对应一张"表",下一个阶段换成真正的数据库时, # 文件名/键名即为表名,字段即为列。见 README「JSON 格式与未来数据库映射」。 DATA_DIR = Path( os.environ.get("PINEAGENTS_DEMO_DATA_DIR", str(BASE_DIR / "data")), ).resolve() # 数据库连接(异步)。开发默认 SQLite+aiosqlite;生产用 MySQL+asyncmy(环境变量覆盖)。 # 示例 MySQL:PINEAGENTS_DEMO_DATABASE_URL=mysql+asyncmy://user:pass@127.0.0.1:3306/opc?charset=utf8mb4 DATABASE_URL = os.environ.get( "PINEAGENTS_DEMO_DATABASE_URL", f"sqlite+aiosqlite:///{DATA_DIR / 'app.db'}", ) # Redis(缓存/会话/限流/分布式锁),空则降级内存。 REDIS_URL = os.environ.get("REDIS_URL", "redis://127.0.0.1:6379/0") # OSS 对象存储(aioboto3,兼容阿里云 OSS / MinIO);空则文件落本地上传目录。 OSS_ENDPOINT = os.environ.get("OSS_ENDPOINT", "") OSS_ACCESS_KEY = os.environ.get("OSS_ACCESS_KEY", "") OSS_SECRET_KEY = os.environ.get("OSS_SECRET_KEY", "") OSS_BUCKET = os.environ.get("OSS_BUCKET", "opc-files") USERS_FILE = DATA_DIR / "users.json" TOKENS_FILE = DATA_DIR / "tokens.json" AGENTS_FILE = DATA_DIR / "agents.json" # 智能体初始化 md 模板(镜像本地 md_files 结构;qa 已统一为 PineAgents 品牌)。 # 目录://*.md(通用)、/qa//*.md、 # /local//*.md TEMPLATES_DIR = BASE_DIR / "templates" # 首次启动时用于初始化 data/ 的种子数据(提交到仓库,数据可读)。 SEED_DIR = BASE_DIR / "data" / "seed" SEED_USERS_FILE = SEED_DIR / "demo_users.json" # --------------------------------------------------------------------------- # 服务监听 # --------------------------------------------------------------------------- HOST = os.environ.get("PINEAGENTS_DEMO_HOST", "127.0.0.1") PORT = int(os.environ.get("PINEAGENTS_DEMO_PORT", "8090")) # --------------------------------------------------------------------------- # 认证与令牌 # --------------------------------------------------------------------------- # 演示服务默认开启认证(PineAgents 主后端把 /auth/* 转发到本服务)。 AUTH_ENABLED = ( os.environ.get("PINEAGENTS_DEMO_AUTH_ENABLED", "true").strip().lower() in ("true", "1", "yes") ) # 令牌有效期(秒):默认 7 天;-1/0 表示永久(按 100 年封顶)。 DEFAULT_TOKEN_EXPIRY_SECONDS = 7 * 24 * 3600 PERMANENT_TOKEN_SECONDS = 100 * 365 * 24 * 3600 TOKEN_EXPIRY_MAX = PERMANENT_TOKEN_SECONDS # --------------------------------------------------------------------------- # JWT # --------------------------------------------------------------------------- JWT_SECRET = os.environ.get( "PINEAGENTS_DEMO_JWT_SECRET", "dev-insecure-change-me-0123456789abcdef", ) JWT_ALGORITHM = os.environ.get("PINEAGENTS_DEMO_JWT_ALGORITHM", "HS256") JWT_ACCESS_EXPIRY_SECONDS = DEFAULT_TOKEN_EXPIRY_SECONDS def resolve_token_expiry(expires_in: int | None) -> int: """把前端传来的 ``expires_in`` 归一化为秒数。 - None → 默认 7 天 - <= 0(含 -1/0)→ 永久(100 年) - 其他 → 按最大值封顶 """ if expires_in is None: return DEFAULT_TOKEN_EXPIRY_SECONDS if expires_in <= 0: return PERMANENT_TOKEN_SECONDS return min(expires_in, TOKEN_EXPIRY_MAX)