Files
tzt ce0f6170d3 chore: T-P-1 工作区收敛——并行会话成果与历史未入库文件整理入库
- 入库历史遗漏源码/测试:router_system 9 模块(agent/executors/inference/knowledge/
  memory/planner/skills/trace)、tests 11 个测试文件、config/knowledge 领域知识
- 入库根目录方案文档(v2/v3/可行性×2)、references 文献(arxiv 14-18/cnki_open/
  参考文献清单)、research 论文素材(routerarena/paper/中文文献 PDF)
- 前端构建产物刷新(新 hash);webapp 误写文档删除
- gitignore 增补:deepseek-harness、research/_refs、.mimosa/.zcode、网关日志/pid、
  临时调试脚本、tests/e2e/node_modules、AI代理功能开发/prefix
- 基线确认:318 passed
2026-09-05 08:28:25 +08:00

83 lines
3.2 KiB
Python
Raw Permalink 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.
# SPDX-FileCopyrightText: Copyright contributors to the RouterArena project
# SPDX-License-Identifier: Apache-2.0
#
# 本文件 vendored 自 RouteWorks/RouterArenahttps://github.com/RouteWorks/RouterArena
# 2026-08-19 拉取,commit on main),仅保留本项目适配所需最小接口定义。
# 原始完整代码与本项目无关;如 RouterArena 接口变化,需同步更新本文件。
"""RouterArena BaseRouter 最小 vendored 实现(适配本系统需要)。
仅保留以下能力:
- 配置加载与模型列表提取
- 模型名校验
- 抽象方法 _get_prediction
去掉了原项目对 generate_prediction_file 路径的硬编码(用 ConfigResolver 解耦)。
"""
from __future__ import annotations
import json
import os
from abc import ABC, abstractmethod
from typing import Any, Dict, List, Optional
class BaseRouter(ABC):
"""Abstract base class for router implementations.
子类必须实现 _get_prediction(query) -> str,返回 config.models 中存在的模型名。
"""
def __init__(
self,
router_name: str,
config_path: Optional[str] = None,
):
self.router_name = router_name
# 允许外部注入 config_path,避免 RouterArena 仓库的硬编码路径依赖
if config_path is None:
config_path = self._default_config_path()
self.config_path = config_path
self.config = self._load_config()
self.models = self._extract_models()
def _default_config_path(self) -> str:
# 默认查找约定:<project>/router_inference/config/<router_name>.json
# 优先尝试项目内 research/routerarena/config/,再退到 RouterArena 约定路径
here = os.path.dirname(os.path.abspath(__file__))
candidate = os.path.join(here, "config", f"{self.router_name}.json")
if os.path.exists(candidate):
return candidate
return candidate # 不存在时让 _load_config 抛 FileNotFoundError,给出明确路径
def _load_config(self) -> Dict[str, Any]:
if not os.path.exists(self.config_path):
raise FileNotFoundError(f"Config file not found: {self.config_path}")
with open(self.config_path, "r", encoding="utf-8") as f:
config = json.load(f)
if "pipeline_params" not in config:
raise ValueError(f"Invalid config: missing 'pipeline_params' in {self.config_path}")
if "models" not in config["pipeline_params"]:
raise ValueError(f"Invalid config: missing 'models' in pipeline_params")
return config
def _extract_models(self) -> List[str]:
return list(self.config["pipeline_params"]["models"])
def _validate_model(self, model_name: str) -> None:
if model_name not in self.models:
raise ValueError(
f"Model '{model_name}' not in router config. "
f"Available: {self.models}"
)
@abstractmethod
def _get_prediction(self, query: str) -> str:
"""根据 query 返回 config.models 中存在的目标模型名。"""
raise NotImplementedError
def get_prediction(self, query: str) -> str:
model_name = self._get_prediction(query)
self._validate_model(model_name)
return model_name