agent-Specialization/config/paths.py
JOJO 4fcd0ccc4d feat(multi-agent): 子智能体系统升级
- prompt改造:子智能体注入AGENTS.md/执行环境/工作区信息/skills/项目记忆
- 工具增加:read_skill/recall_project_memory/todo_create/todo_update_task/save_webpage
- 上下文压缩:深度压缩机制,记录current_context_tokens,默认150k阈值可配置
- 模型升级:sub_agent_models.json支持thinkmode_status/extra_parameter,与主智能体对齐
- 角色管理三层结构:源码树预设multi_agent_roles/ + 运行态host/web预设 + web按用户隔离
- 启动同步:initialize_system调用sync_preset_roles同步预设到host和web运行态
- 模式判断:API用session.host_mode,工具用data_dir路径判断,不依赖IS_HOST_MODE
- 前端:个人空间新增子智能体管理页(角色CRUD/压缩阈值/模型选择),复用个人空间样式
- 入口改造:登录页移除多智能体按钮,QuickMenu加模式切换项,运行中对话禁止切换
- 工具调整:多智能体模式create_sub_agent去掉timeout/deliverables_dir参数
- skill禁止:sub-agent-guide在多智能体模式下禁止阅读
- .agents/统一为.astrion/路径修复
2026-07-14 02:28:45 +08:00

217 lines
8.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""项目路径与目录配置。
运行态数据存放在 ``~/.astrion/astrion/`` 下:
::
~/.astrion/astrion/ ← data_root默认可通过 ASTRION_DATA_ROOT 覆盖)
├── settings.json ← 唯一配置文件
├── config/ ← 部署级 JSONhost/web 模式共享
├── host/ ← host 模式(单用户)
│ ├── data/ ← 对话/记忆/数据库
│ └── logs/
└── web/ ← web 模式(多用户)
├── users/ ← 每用户独立工作区
│ └── <name>/data/
└── logs/
路径解析优先级(从高到低):
1. 具体目录环境变量(``DATA_DIR`` / ``LOGS_DIR`` / ``USER_SPACE_DIR`` /
``API_USER_SPACE_DIR``)——单独覆盖某个目录,最高优先级;
2. ``ASTRION_DATA_ROOT`` ——整体搬迁数据根目录;
3. 兜底默认值 ``~/.astrion/astrion``。
注意:``config/*.json`` 分两类,不再一概锚定源码树:
- **开发者配置 / 程序能力**``docker_risk_markers.json`` / ``skill_hints.json``
是程序行为的一部分,随版本演进,仍锚定源码树。
- **部署者自定义配置**``custom_models`` / ``host_workspaces`` /
``auto_approval`` / ``goal_review`` / ``forbidden_commands`` /
``host_sandbox_policy``):因部署/机器而异、或含密钥,外置到
``<data_root>/config/``(即 ``DEPLOY_CONFIG_DIR``)。读取走
``resolve_deploy_config``,回退链为:部署目录 -> 源码树 ``.json`` ->
源码树 ``.json.example``。
"""
import json
import os
from pathlib import Path
_REPO_ROOT = Path(__file__).resolve().parents[1]
def _norm(path: Path) -> Path:
"""展开 ``~``、转绝对路径并归一化。相对路径相对仓库根目录展开。"""
path = path.expanduser()
if not path.is_absolute():
path = _REPO_ROOT / path
return path.resolve()
def _env(name: str) -> str:
return str(os.environ.get(name, "") or "").strip()
def _resolve_repo_path(raw_value: str, default: str) -> str:
"""解析锚定在源码树的路径(配置文件、提示词等)。
相对路径相对仓库根目录展开,绝对路径与 ``~`` 原样支持。
"""
candidate = str(raw_value or "").strip() or str(default)
return str(_norm(Path(candidate)))
def _runtime_mode() -> str:
"""运行模式:``host`` 或 ``web``。
仅当 ``TERMINAL_SANDBOX_MODE=host`` 时为 host 模式。
优先从 settings.json 读取,其次环境变量,最后默认 host。
"""
# 尝试从已加载的 settings.json 中读取
mode = _env("TERMINAL_SANDBOX_MODE").lower()
if mode == "host":
return "host"
if mode == "web" or mode == "docker":
return "web"
return "host"
# ── 数据根目录data_root──
# 优先级ASTRION_DATA_ROOT 环境变量 > 默认 ~/.astrion/astrion
_DEFAULT_DATA_ROOT = Path("~/.astrion/astrion")
RUNTIME_ROOT = str(_norm(Path(_env("ASTRION_DATA_ROOT") or _DEFAULT_DATA_ROOT)))
_MODE = _runtime_mode()
def _runtime_dir(env_name: str, subdir: str) -> str:
"""解析运行态子目录。
优先级:具体目录环境变量 > data_root/{mode}/subdir。
具体目录变量支持相对路径(相对仓库根目录)、绝对路径与 ``~``。
"""
raw = _env(env_name)
if raw:
return str(_norm(Path(raw)))
return str(Path(RUNTIME_ROOT) / _MODE / subdir)
# ── 运行态目录(默认落在 <data_root>/<mode>/ 下)──
DATA_DIR = _runtime_dir("DATA_DIR", "data")
LOGS_DIR = _runtime_dir("LOGS_DIR", "logs")
USER_SPACE_DIR = _runtime_dir("USER_SPACE_DIR", "users")
# API 专用用户与工作区(与网页用户隔离)
API_USER_SPACE_DIR = _runtime_dir("API_USER_SPACE_DIR", "api/users")
# ── 用户自定义 skill 归档目录host 模式全局docker/web 模式可与 per-user 并存)──
CUSTOM_SKILLS_DIR = str(Path(RUNTIME_ROOT) / _MODE / "agentskills")
# ── 是否宿主机模式 ──
IS_HOST_MODE = _MODE == "host"
# ── 固定 web 模式路径host 模式下作为额外数据源,同时读取)──
_WEB_ROOT = Path(RUNTIME_ROOT) / "web"
WEB_DATA_DIR = str(_WEB_ROOT / "data")
WEB_USER_SPACE_DIR = str(_WEB_ROOT / "users")
# ── 部署级配置目录 —— 放在 data_root 根下,两个模式共享 ──
_DEFAULT_DEPLOY_CONFIG = Path(RUNTIME_ROOT) / "config"
DEPLOY_CONFIG_DIR = str(_norm(Path(_env("DEPLOY_CONFIG_DIR") or _DEFAULT_DEPLOY_CONFIG)))
# 源码树内的配置种子目录(首次运行/开发环境的默认内容来源)。
_SEED_CONFIG_DIR = _REPO_ROOT / "config"
def deploy_config_path(filename: str) -> str:
"""部署级配置文件应写入/读取的位置(``<data_root>/config`` 下)。
用于会被运行时写回的文件(如 host_workspaces / host_sandbox_policy
始终指向部署目录,不回退源码树。
"""
return str(Path(DEPLOY_CONFIG_DIR) / filename)
def resolve_deploy_config(filename: str) -> str:
"""解析部署级配置的只读路径,回退链(高→低):
1. ``<data_root>/config/<filename>``(部署者真实配置)
2. 源码树 ``config/<filename>``(仓库内种子)
3. 源码树 ``config/<filename>.example``(示例兜底)
都不存在时返回部署目录下的目标路径,由调用方处理「文件不存在」。
仅用于定位,不在此做拷贝(拷贝交给 setup / 迁移脚本)。
"""
deployed = Path(DEPLOY_CONFIG_DIR) / filename
if deployed.exists():
return str(deployed)
seed = _SEED_CONFIG_DIR / filename
if seed.exists():
return str(seed)
example = _SEED_CONFIG_DIR / f"{filename}.example"
if example.exists():
return str(example)
return str(deployed)
# ── 启动工作区 ──
DEFAULT_PROJECT_PATH = _resolve_repo_path(os.environ.get("DEFAULT_PROJECT_PATH", ""), "./project")
HOST_PROJECT_PATH = _resolve_repo_path(os.environ.get("HOST_PROJECT_PATH", ""), DEFAULT_PROJECT_PATH)
# ── 源码树内的配置与资源(不随运行态根目录迁移)──
PROMPTS_DIR = _resolve_repo_path(os.environ.get("PROMPTS_DIR", ""), "./prompts")
AGENT_SKILLS_DIR = _resolve_repo_path(os.environ.get("AGENT_SKILLS_DIR", ""), "./agentskills")
# 多智能体预设角色目录(源码树内,随版本分发)
PRESET_ROLES_DIR = _resolve_repo_path(os.environ.get("PRESET_ROLES_DIR", ""), "./multi_agent_roles")
# 运行态预设/自定义角色目录host 模式:预设+自定义同目录web 模式:仅预设)
CUSTOM_ROLES_DIR = str(Path(RUNTIME_ROOT) / _MODE / "mutiagents" / "agents")
# web 模式预设角色目录web 模式下使用host 模式下不用)
WEB_PRESET_ROLES_DIR = str(Path(RUNTIME_ROOT) / "web" / "mutiagents" / "agents")
WORKSPACE_SKILLS_DIRNAME = ".astrion/skills"
WORKSPACE_MEMORY_DIRNAME = ".astrion/memory"
WORKSPACE_REVIEW_DIRNAME = ".astrion/review"
HOST_WORKSPACES_FILE = _resolve_repo_path(
os.environ.get("HOST_WORKSPACES_FILE", ""),
deploy_config_path("host_workspaces.json"),
)
# ── 基于 DATA_DIR 派生的数据文件 ──
USERS_DB_FILE = f"{DATA_DIR}/users.json"
INVITE_CODES_FILE = f"{DATA_DIR}/invite_codes.json"
ADMIN_POLICY_FILE = f"{DATA_DIR}/admin_policy.json"
API_USERS_DB_FILE = f"{DATA_DIR}/api_users.json"
API_TOKENS_FILE = f"{DATA_DIR}/api_tokens.json"
API_USAGE_FILE = f"{DATA_DIR}/api_usage.json"
__all__ = [
"RUNTIME_ROOT",
"DEFAULT_PROJECT_PATH",
"HOST_WORKSPACES_FILE",
"HOST_PROJECT_PATH",
"PROMPTS_DIR",
"DATA_DIR",
"LOGS_DIR",
"AGENT_SKILLS_DIR",
"WORKSPACE_SKILLS_DIRNAME",
"WORKSPACE_MEMORY_DIRNAME",
"WORKSPACE_REVIEW_DIRNAME",
"IS_HOST_MODE",
"USER_SPACE_DIR",
"WEB_DATA_DIR",
"WEB_USER_SPACE_DIR",
"USERS_DB_FILE",
"INVITE_CODES_FILE",
"ADMIN_POLICY_FILE",
"API_USER_SPACE_DIR",
"CUSTOM_SKILLS_DIR",
"PRESET_ROLES_DIR",
"CUSTOM_ROLES_DIR",
"WEB_PRESET_ROLES_DIR",
"API_USERS_DB_FILE",
"API_TOKENS_FILE",
"API_USAGE_FILE",
"DEPLOY_CONFIG_DIR",
"deploy_config_path",
"resolve_deploy_config",
]