feat: Add evaluation hooks, skill adaptation and team pipeline config
- Add EvaluationHook for post-execution agent evaluation - Add SkillAdaptationHook for dynamic skill adaptation - Add team/ directory with team coordination logic - Add TEAM_PIPELINE.yaml for smoke_fullstack pipeline config - Update RuntimeView, TraderView and RuntimeSettingsPanel UI - Add runtimeApi and websocket services - Add runtime_state.json to smoke_fullstack state Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ and frontend development server.
|
||||
"""
|
||||
# flake8: noqa: E501
|
||||
# pylint: disable=R0912, R0915
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
@@ -17,7 +18,10 @@ from pathlib import Path
|
||||
from typing import Optional
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
import typer
|
||||
import yaml
|
||||
from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
from rich.prompt import Confirm
|
||||
@@ -27,7 +31,12 @@ from dotenv import load_dotenv
|
||||
from backend.agents.agent_workspace import load_agent_workspace_config
|
||||
from backend.agents.prompt_loader import PromptLoader
|
||||
from backend.agents.skills_manager import SkillsManager
|
||||
from backend.agents.team_pipeline_config import (
|
||||
ensure_team_pipeline_config,
|
||||
load_team_pipeline_config,
|
||||
)
|
||||
from backend.agents.workspace_manager import WorkspaceManager
|
||||
from backend.config.constants import ANALYST_TYPES
|
||||
from backend.data.market_ingest import ingest_symbols
|
||||
from backend.data.market_store import MarketStore
|
||||
from backend.enrich.llm_enricher import get_explain_model_info, llm_enrichment_enabled
|
||||
@@ -42,6 +51,8 @@ ingest_app = typer.Typer(help="Ingest Polygon market data into the research ware
|
||||
app.add_typer(ingest_app, name="ingest")
|
||||
skills_app = typer.Typer(help="Inspect and manage per-agent skills.")
|
||||
app.add_typer(skills_app, name="skills")
|
||||
team_app = typer.Typer(help="Inspect and manage run-scoped team pipeline config.")
|
||||
app.add_typer(team_app, name="team")
|
||||
|
||||
console = Console()
|
||||
_prompt_loader = PromptLoader()
|
||||
@@ -95,8 +106,8 @@ def handle_history_cleanup(config_name: str, auto_clean: bool = False) -> None:
|
||||
)
|
||||
else:
|
||||
console.print(f" Directory size: [cyan]{size_mb:.1f} MB[/cyan]")
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as e:
|
||||
logger.debug(f"Could not calculate directory size: {e}")
|
||||
|
||||
# Show last modified time
|
||||
state_dir = base_data_dir / "state"
|
||||
@@ -197,7 +208,8 @@ def run_data_updater(project_root: Path) -> None:
|
||||
console.print(
|
||||
"[yellow] Data updater module not available, skipping update[/yellow]\n",
|
||||
)
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
logger.debug(f"Data updater check failed: {e}")
|
||||
console.print(
|
||||
"[yellow] Data updater check failed, skipping update[/yellow]\n",
|
||||
)
|
||||
@@ -777,6 +789,78 @@ def skills_disable(
|
||||
console.print(f"Disabled skills: {', '.join(result['disabled_skills']) or '-'}")
|
||||
|
||||
|
||||
@skills_app.command("install")
|
||||
def skills_install(
|
||||
agent_id: str = typer.Option(..., "--agent-id", "-a", help="Target agent id."),
|
||||
source: str = typer.Option(
|
||||
...,
|
||||
"--source",
|
||||
"-s",
|
||||
help="External skill source: directory path, zip path, or http(s) zip URL.",
|
||||
),
|
||||
config_name: str = typer.Option(
|
||||
"default",
|
||||
"--config-name",
|
||||
"-c",
|
||||
help="Run config name.",
|
||||
),
|
||||
name: Optional[str] = typer.Option(
|
||||
None,
|
||||
"--name",
|
||||
help="Optional override skill name.",
|
||||
),
|
||||
activate: bool = typer.Option(
|
||||
True,
|
||||
"--activate/--no-activate",
|
||||
help="Enable the skill for this agent immediately.",
|
||||
),
|
||||
):
|
||||
"""Install an external skill into one agent's local skill directory."""
|
||||
_require_agent_asset_dir(config_name, agent_id)
|
||||
skills_manager = SkillsManager(project_root=get_project_root())
|
||||
result = skills_manager.install_external_skill_for_agent(
|
||||
config_name=config_name,
|
||||
agent_id=agent_id,
|
||||
source=source,
|
||||
skill_name=name,
|
||||
activate=activate,
|
||||
)
|
||||
console.print(
|
||||
f"[green]Installed[/green] `{result['skill_name']}` to `{agent_id}`",
|
||||
)
|
||||
console.print(f"Path: {result['target_dir']}")
|
||||
console.print(f"Activated: {result['activated']}")
|
||||
warnings = result.get("warnings") or []
|
||||
if warnings:
|
||||
console.print(f"Warnings: {'; '.join(warnings)}")
|
||||
|
||||
|
||||
@team_app.command("show")
|
||||
def team_show(
|
||||
config_name: str = typer.Option(
|
||||
"default",
|
||||
"--config-name",
|
||||
"-c",
|
||||
help="Run config name.",
|
||||
),
|
||||
):
|
||||
"""Show TEAM_PIPELINE.yaml for one run."""
|
||||
project_root = get_project_root()
|
||||
ensure_team_pipeline_config(
|
||||
project_root=project_root,
|
||||
config_name=config_name,
|
||||
default_analysts=list(ANALYST_TYPES.keys()),
|
||||
)
|
||||
config = load_team_pipeline_config(project_root, config_name)
|
||||
console.print(
|
||||
Panel.fit(
|
||||
yaml.safe_dump(config, allow_unicode=True, sort_keys=False),
|
||||
title=f"TEAM_PIPELINE ({config_name})",
|
||||
border_style="cyan",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@app.command()
|
||||
def backtest(
|
||||
start: Optional[str] = typer.Option(
|
||||
|
||||
Reference in New Issue
Block a user