feat(routers): add API endpoints for agents and skills
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -6,6 +6,7 @@ from sqlalchemy import select
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from app.database import get_db
|
from app.database import get_db
|
||||||
|
from app.agents.learning.store import LearningArtifactStore, SessionRetrospectiveStore
|
||||||
from app.agents.registry import load_builtin_registry_indexes
|
from app.agents.registry import load_builtin_registry_indexes
|
||||||
from app.agents.runtime_metrics import coerce_cost_thresholds, estimate_token_cost, is_cost_budget_warning
|
from app.agents.runtime_metrics import coerce_cost_thresholds, estimate_token_cost, is_cost_budget_warning
|
||||||
from app.models.agent import Agent
|
from app.models.agent import Agent
|
||||||
@@ -37,6 +38,7 @@ from app.schemas.agent import (
|
|||||||
AgentVisibilityVerifierOut,
|
AgentVisibilityVerifierOut,
|
||||||
)
|
)
|
||||||
from app.services.agent_service import _extract_continuity_snapshot
|
from app.services.agent_service import _extract_continuity_snapshot
|
||||||
|
from app.services.runtime_observability import build_runtime_observability_report
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/agents", tags=["Agent"])
|
router = APIRouter(prefix="/api/agents", tags=["Agent"])
|
||||||
|
|
||||||
@@ -662,6 +664,59 @@ async def get_visibility_tools(
|
|||||||
return _build_tool_governance(state, conversation_id=conversation_id)
|
return _build_tool_governance(state, conversation_id=conversation_id)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/visibility/debug")
|
||||||
|
async def get_visibility_debug(
|
||||||
|
conversation_id: str,
|
||||||
|
current_user: User = Depends(get_current_user),
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
):
|
||||||
|
state = await _get_visibility_state(conversation_id, current_user=current_user, db=db)
|
||||||
|
observability = build_runtime_observability_report(
|
||||||
|
state=state,
|
||||||
|
feature_flags=dict(state.get("feature_flags") or {}),
|
||||||
|
)
|
||||||
|
retrospective_store = SessionRetrospectiveStore(db)
|
||||||
|
artifact_store = LearningArtifactStore(db)
|
||||||
|
recent_retrospectives = await retrospective_store.list_recent(
|
||||||
|
user_id=current_user.id,
|
||||||
|
limit=5,
|
||||||
|
)
|
||||||
|
recent_artifacts = await artifact_store.list_recent(
|
||||||
|
user_id=current_user.id,
|
||||||
|
limit=10,
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"conversation_id": conversation_id,
|
||||||
|
"observability": observability,
|
||||||
|
"skill_shortlist": list(state.get("skill_shortlist") or []),
|
||||||
|
"retrospective_shortlist": list(state.get("retrospective_shortlist") or []),
|
||||||
|
"merge_report": state.get("merge_report"),
|
||||||
|
"verification_report": state.get("verification_report"),
|
||||||
|
"recent_retrospectives": [
|
||||||
|
{
|
||||||
|
"id": item.id,
|
||||||
|
"task_type": item.task_type,
|
||||||
|
"summary": item.summary_text,
|
||||||
|
"execution_mode": item.execution_mode,
|
||||||
|
"verification_status": item.verification_status,
|
||||||
|
"recorded_at": item.recorded_at.isoformat() if item.recorded_at else None,
|
||||||
|
}
|
||||||
|
for item in recent_retrospectives
|
||||||
|
],
|
||||||
|
"recent_learning_artifacts": [
|
||||||
|
{
|
||||||
|
"id": item.id,
|
||||||
|
"artifact_type": item.artifact_type,
|
||||||
|
"artifact_key": item.artifact_key,
|
||||||
|
"summary": item.summary_text,
|
||||||
|
"recorded_at": item.recorded_at.isoformat() if item.recorded_at else None,
|
||||||
|
}
|
||||||
|
for item in recent_artifacts
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.post("", response_model=AgentOut, status_code=201)
|
@router.post("", response_model=AgentOut, status_code=201)
|
||||||
async def create_agent(
|
async def create_agent(
|
||||||
data: AgentCreate,
|
data: AgentCreate,
|
||||||
|
|||||||
@@ -145,6 +145,9 @@ async def chat_stream(
|
|||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
yield f"event: error\ndata: {json.dumps({'error': str(exc)}, ensure_ascii=False)}\n\n"
|
yield f"event: error\ndata: {json.dumps({'error': str(exc)}, ensure_ascii=False)}\n\n"
|
||||||
return
|
return
|
||||||
|
except Exception as exc:
|
||||||
|
yield f"event: error\ndata: {json.dumps({'error': str(exc)}, ensure_ascii=False)}\n\n"
|
||||||
|
return
|
||||||
|
|
||||||
yield f"event: metadata\ndata: {json.dumps({'conversation_id': conv_id, 'message_id': msg_id})}\n\n"
|
yield f"event: metadata\ndata: {json.dumps({'conversation_id': conv_id, 'message_id': msg_id})}\n\n"
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ async def create_skill(
|
|||||||
visibility=data.visibility,
|
visibility=data.visibility,
|
||||||
team_id=data.team_id,
|
team_id=data.team_id,
|
||||||
is_active=data.is_active,
|
is_active=data.is_active,
|
||||||
|
status=data.status,
|
||||||
|
scope=data.scope,
|
||||||
|
effectiveness=data.effectiveness,
|
||||||
|
review_after=data.review_after,
|
||||||
owner_id=current_user.id,
|
owner_id=current_user.id,
|
||||||
)
|
)
|
||||||
db.add(skill)
|
db.add(skill)
|
||||||
@@ -103,6 +107,14 @@ async def update_skill(
|
|||||||
skill.team_id = data.team_id
|
skill.team_id = data.team_id
|
||||||
if data.is_active is not None:
|
if data.is_active is not None:
|
||||||
skill.is_active = data.is_active
|
skill.is_active = data.is_active
|
||||||
|
if data.status is not None:
|
||||||
|
skill.status = data.status
|
||||||
|
if data.scope is not None:
|
||||||
|
skill.scope = data.scope
|
||||||
|
if data.effectiveness is not None:
|
||||||
|
skill.effectiveness = data.effectiveness
|
||||||
|
if data.review_after is not None:
|
||||||
|
skill.review_after = data.review_after
|
||||||
|
|
||||||
await db.commit()
|
await db.commit()
|
||||||
await db.refresh(skill)
|
await db.refresh(skill)
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ async def get_system_status():
|
|||||||
@router.get('/config')
|
@router.get('/config')
|
||||||
async def get_system_config():
|
async def get_system_config():
|
||||||
"""Get public system configuration."""
|
"""Get public system configuration."""
|
||||||
return SystemService().get_config()
|
return await SystemService().get_config()
|
||||||
|
|||||||
Reference in New Issue
Block a user