Files
beaver_project/app-instance/backend/beaver/interfaces/cli/main.py
steven_li 30ab74ffb2 feat(engine): 添加MCP连接管理和工具集成功能
- 集成MCP连接管理器,支持MCP服务器连接
- 添加多种内置工具:ClarifyTool、CronTool、DelegateTool、ExecuteCodeTool、
  PatchFileTool、ProcessTool、SendMessageTool、SpawnTool、TerminalTool、
  TodoTool、WebFetchTool、WebSearchTool、WriteFileTool等
- 实现工具注册和装配功能
- 添加技能选择上下文参数
- 支持思考模式控制参数thinking_enabled

feat(coordinator): 重构任务执行计划器参数命名

- 将learning_candidate_enabled重命名为allow_candidate_generation
- 更新TeamGraphScheduler中的参数传递
- 修改LocalAgentRunner中的相关参数处理
- 更新README文档中的相应描述

refactor(context): 标准化工具调用参数格式

- 添加_json导入用于参数序列化
- 实现_provider_tool_calls方法标准化OpenAI兼容的工具调用载荷
- 修复工具调用中参数非字符串类型的序列化问题

refactor(session): 优化消息历史记录过滤逻辑

- 修改get_messages_as_conversation为基于运行状态过滤消息
- 排除未完成、失败或错误结束的运行记录
- 改进对话历史的可见性控制机制

fix(store): 修复FTS索引重建逻辑

- 添加异常处理防止FTS索引创建失败
- 实现_rebuild_fts_index方法重新构建全文搜索索引
- 优化索引触发器和表的维护流程
2026-05-14 09:43:48 +08:00

85 lines
2.8 KiB
Python

"""CLI entry for Beaver."""
from pathlib import Path
try:
import typer
except ModuleNotFoundError: # pragma: no cover - fallback for skeleton-only environments
class _FallbackTyper:
def __init__(self, *_args, **_kwargs) -> None:
pass
def command(self):
def decorator(func):
return func
return decorator
def __call__(self) -> None:
raise RuntimeError("typer is not installed")
@staticmethod
def echo(message: str) -> None:
print(message)
@staticmethod
def Option(default=None, *_args, **_kwargs):
return default
typer = _FallbackTyper() # type: ignore[assignment]
from beaver.services.agent_service import AgentService
from beaver.services.hermes_migration import HermesMigrationService
from beaver.skills.specs import SkillSpecStore
app = typer.Typer(help="Beaver backend CLI") if hasattr(typer, "Typer") else typer
@app.command()
def run(
message: str | None = typer.Option(None, "--message", "-m", help="Run one direct Beaver request."),
workspace: str | None = typer.Option(None, "--workspace", help="Workspace root for this run."),
config: str | None = typer.Option(None, "--config", help="Backend config path for this run."),
) -> None:
"""Thin CLI wrapper around AgentService.
CLI 现在不再自己维护执行逻辑,只负责:
1. 解析命令行参数
2. 调 AgentService
3. 打印结果
"""
service = AgentService(workspace=workspace, config_path=config)
if not message:
service.create_loop()
typer.echo("Beaver engine booted.")
return
result = service.run_direct(message, source="cli")
typer.echo(result.output_text)
@app.command("migrate-hermes")
def migrate_hermes(
repo: str = typer.Option(..., "--repo", help="Local checkout of https://github.com/NousResearch/hermes-agent."),
workspace: str | None = typer.Option(None, "--workspace", help="Workspace root to import skills into."),
manifest: str | None = typer.Option(None, "--manifest", help="Path for hermes_migration_manifest.json."),
dry_run: bool = typer.Option(False, "--dry-run", help="Only write the manifest without importing skills."),
) -> None:
"""Import no-credential Hermes Agent skills and write a manifest."""
service = AgentService(workspace=workspace)
loaded = service.create_loop().boot()
store = loaded.skill_spec_store or SkillSpecStore(loaded.workspace)
migration = HermesMigrationService(store, manifest_path=Path(manifest) if manifest else None)
result = migration.migrate(repo, dry_run=dry_run)
typer.echo(
f"Hermes migration complete: {len(result['included'])} included, "
f"{len(result['skipped'])} skipped."
)
def main() -> None:
"""Project script entrypoint."""
app()