diff --git a/config/sub_agent.py b/config/sub_agent.py index 7eeecdc..4854912 100644 --- a/config/sub_agent.py +++ b/config/sub_agent.py @@ -1,8 +1,15 @@ """子智能体相关配置。""" import os +from pathlib import Path -from .paths import _resolve_repo_path, DATA_DIR, DEFAULT_PROJECT_PATH +from .paths import ( + _resolve_repo_path, + _REPO_ROOT, + DATA_DIR, + DEFAULT_PROJECT_PATH, + resolve_deploy_config, +) # 子智能体服务 SUB_AGENT_SERVICE_BASE_URL = os.environ.get("SUB_AGENT_SERVICE_URL", "http://127.0.0.1:8092") @@ -17,6 +24,32 @@ SUB_AGENT_STATE_FILE = _resolve_repo_path(os.environ.get("SUB_AGENT_STATE_FILE", SUB_AGENT_PROJECT_RESULTS_DIR = _resolve_repo_path(os.environ.get("SUB_AGENT_PROJECT_RESULTS_DIR", ""), f"{DEFAULT_PROJECT_PATH}/sub_agent_results") SUB_AGENT_MAX_ACTIVE = int(os.environ.get("SUB_AGENT_MAX_ACTIVE", "5")) + +def resolve_sub_agent_models_config() -> str: + """解析子智能体模型配置文件路径,回退链(高→低): + + 1. ``~/.agents//config/sub_agent_models.json``(部署者真实配置) + 2. 源码树 ``config/sub_agent_models.json``(仓库内种子) + 3. 源码树 ``easyagent/models.json``(旧版 easyagent 配置位置) + 4. 源码树 ``config/sub_agent_models.json.example``(示例兜底) + + 都不存在时返回部署目录下的目标路径,由调用方处理不存在。 + """ + # 先走标准回退链:部署 → config/种子 → config/.example + standard = resolve_deploy_config("sub_agent_models.json") + standard_path = Path(standard) + if standard_path.exists(): + return str(standard_path) + # 最后回退到旧 easyagent/models.json + legacy = _REPO_ROOT / "easyagent" / "models.json" + if legacy.exists(): + return str(legacy) + return standard # 返回部署目录路径,由调用方处理不存在 + + +# 子智能体模型配置文件(可通过环境变量覆盖,否则走回退链解析) +SUB_AGENT_MODELS_CONFIG_FILE = os.environ.get("SUB_AGENT_MODELS_CONFIG_FILE", "") or resolve_sub_agent_models_config() + __all__ = [ "SUB_AGENT_SERVICE_BASE_URL", "SUB_AGENT_DEFAULT_TIMEOUT", @@ -25,4 +58,6 @@ __all__ = [ "SUB_AGENT_PROJECT_RESULTS_DIR", "SUB_AGENT_STATE_FILE", "SUB_AGENT_MAX_ACTIVE", + "SUB_AGENT_MODELS_CONFIG_FILE", + "resolve_sub_agent_models_config", ] diff --git a/config/sub_agent_models.json.example b/config/sub_agent_models.json.example new file mode 100644 index 0000000..b5afd5e --- /dev/null +++ b/config/sub_agent_models.json.example @@ -0,0 +1,15 @@ +{ + "tavily_api_key": "", + "default_model": "", + "models": [ + { + "url": "https://api.example.com/v1", + "name": "example-model", + "apikey": "${YOUR_API_KEY_ENV}", + "modes": "快速,思考", + "multimodal": "", + "max_output": 32000, + "max_context": 256000 + } + ] +} diff --git a/easyagent/models.json b/easyagent/models.json index a26599c..605e82e 100644 --- a/easyagent/models.json +++ b/easyagent/models.json @@ -1,6 +1,6 @@ { "tavily_api_key": "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", - "default_model": "kimi-k2.5", + "default_model": "deepseek-v4-flash", "models": [ { "url": "https://coding.dashscope.aliyuncs.com/v1", @@ -12,11 +12,11 @@ "max_context": 256000 }, { - "url": "https://dashscope.aliyuncs.com/compatible-mode/v1", - "name": "qwen3.5-plus", - "apikey": "sk-64af1343e67d46d7a902ef5bcf6817ad", + "url": "https://opencode.ai/zen/go/v1", + "name": "deepseek-v4-flash", + "apikey": "sk-j0NdTvEDoqqkKCHEAFXXYneEsuXEiOXNCgLeZARJmfYUBf2Riym7KPFWq1amkB6z", "modes": "快速,思考", - "multimodal": "图片", + "multimodal": "", "max_output": 32768, "max_context": 256000 }, diff --git a/easyagent/src/batch/index.js b/easyagent/src/batch/index.js index 388a09c..f44373d 100644 --- a/easyagent/src/batch/index.js +++ b/easyagent/src/batch/index.js @@ -26,6 +26,7 @@ function parseArgs() { agentId: null, modelKey: null, thinkingMode: null, + configFile: null, timeout: 600, }; @@ -51,6 +52,8 @@ function parseArgs() { config.thinkingMode = String(args[++i] || '').trim().toLowerCase(); } else if (arg === '--timeout' && i + 1 < args.length) { config.timeout = parseInt(args[++i], 10); + } else if (arg === '--config-file' && i + 1 < args.length) { + config.configFile = args[++i]; } } @@ -113,7 +116,7 @@ async function main() { // 加载模型配置 const modelConfig = require('../config'); - const ensuredConfig = modelConfig.ensureConfig(); + const ensuredConfig = modelConfig.ensureConfig(config.configFile); if (!ensuredConfig.valid_models || ensuredConfig.valid_models.length === 0) { writeOutput(config.outputFile, { diff --git a/easyagent/src/config.js b/easyagent/src/config.js index 78538b9..22e704e 100644 --- a/easyagent/src/config.js +++ b/easyagent/src/config.js @@ -98,14 +98,18 @@ function buildConfig(raw, filePath) { }; } -function ensureConfig() { - const file = DEFAULT_CONFIG_PATH; +function ensureConfig(customPath) { + const file = customPath || DEFAULT_CONFIG_PATH; if (!fs.existsSync(file)) { const template = { tavily_api_key: '', default_model: '', models: [], }; + const dir = path.dirname(file); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } fs.writeFileSync(file, JSON.stringify(template, null, 2), 'utf8'); } const content = fs.readFileSync(file, 'utf8'); diff --git a/modules/sub_agent_manager.py b/modules/sub_agent_manager.py index 76856ff..a5203d3 100644 --- a/modules/sub_agent_manager.py +++ b/modules/sub_agent_manager.py @@ -16,6 +16,7 @@ from config import ( OUTPUT_FORMATS, SUB_AGENT_DEFAULT_TIMEOUT, SUB_AGENT_MAX_ACTIVE, + SUB_AGENT_MODELS_CONFIG_FILE, SUB_AGENT_STATE_FILE, SUB_AGENT_STATUS_POLL_INTERVAL, SUB_AGENT_TASKS_BASE_DIR, @@ -393,6 +394,7 @@ class SubAgentManager: "--progress-file", progress_file, "--agent-id", str(agent_id), "--timeout", str(timeout_seconds), + "--config-file", SUB_AGENT_MODELS_CONFIG_FILE, ] if model_key: cmd.extend(["--model-key", model_key])