feat: Add agent workspace system and runtime management

- Add agent core modules (agent_core, factory, registry, skill_loader)
- Add runtime system for agent execution management
- Add REST API for agents, workspaces, and runtime control
- Add process supervisor for agent lifecycle management
- Add workspace template system with agent profiles
- Add frontend RuntimeView and runtime API integration
- Add per-agent skill workspaces for smoke_fullstack run
- Refactor skill system with active/installed separation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-17 16:43:29 +08:00
parent 2daf5717ba
commit 59b44545d0
121 changed files with 8384 additions and 358 deletions

View File

@@ -38,6 +38,7 @@ class Scheduler:
self.running = False
self._task: Optional[asyncio.Task] = None
self._callback: Optional[Callable] = None
def _now_nyse(self) -> datetime:
"""Get current time in NYSE timezone"""
@@ -68,18 +69,69 @@ class Scheduler:
return
self.running = True
if self.mode == "daily":
self._task = asyncio.create_task(self._run_daily(callback))
elif self.mode == "intraday":
self._task = asyncio.create_task(self._run_intraday(callback))
else:
raise ValueError(f"Unknown scheduler mode: {self.mode}")
self._callback = callback
self._schedule_task()
logger.info(
f"Scheduler started: mode={self.mode}, timezone=America/New_York",
)
def _schedule_task(self):
"""Create the active scheduler task for the current mode."""
if not self._callback:
raise ValueError("Scheduler callback is not set")
if self._task:
self._task.cancel()
self._task = None
if self.mode == "daily":
self._task = asyncio.create_task(self._run_daily(self._callback))
elif self.mode == "intraday":
self._task = asyncio.create_task(
self._run_intraday(self._callback),
)
else:
raise ValueError(f"Unknown scheduler mode: {self.mode}")
def reconfigure(
self,
*,
mode: Optional[str] = None,
trigger_time: Optional[str] = None,
interval_minutes: Optional[int] = None,
) -> bool:
"""Update scheduler parameters in-place and restart its timing loop."""
changed = False
if mode and mode != self.mode:
self.mode = mode
changed = True
if trigger_time and trigger_time != self.trigger_time:
self.trigger_time = trigger_time
self.trigger_now = self.trigger_time == "now"
changed = True
if (
interval_minutes is not None
and interval_minutes > 0
and interval_minutes != self.interval_minutes
):
self.interval_minutes = interval_minutes
changed = True
if changed and self.running and self._callback:
self._schedule_task()
logger.info(
"Scheduler reconfigured: mode=%s, trigger_time=%s, interval_minutes=%s",
self.mode,
self.trigger_time,
self.interval_minutes,
)
return changed
async def _run_daily(self, callback: Callable):
"""Run once per trading day at specified time (NYSE timezone)"""
first_run = True