feat: add tool scoping and orchestration markers to agent tool registry

Introduce `mark_orchestration_tools`, `set_tool_scope`, and `reset_tool_scope` in `agents/agent.py` to allow runtime filtering of tool payloads by scope and orchestration flag. Refactor `get_tool_payloads` to respect the active scope and exclude orchestration-only tools. Update `agents/core/__init__.py` with `worker_tool_names` helper that returns read/reasoning tools plus conditional write/verify tools per mode, replacing the old `payloads_for` exclusion logic. Modify `agents/maestro.py` to call `mark_orchestration_tools` and wire per-agent result recording via `on_result` callback in `run_fleet`. Extend `agents/orchestrator.py` `run_fleet` signature to accept an optional `on_result` callable and invoke it after each agent run. Revise `agents/style.py` em-dash rule to distinguish prose from data occurrences, and add repository layout guidance to `agents/base.py` MAINT_HEADER.
This commit is contained in:
2026-06-12 04:30:08 +00:00
parent 31841fece4
commit 5e6b1c09df
38 changed files with 679 additions and 86 deletions
+8 -4
View File
@@ -11,7 +11,9 @@ from devplacepy.constants import DEVII_GUEST_COOKIE
from devplacepy.database import get_int_setting
from devplacepy.seo import base_seo_context, site_url
from devplacepy.services.manager import service_manager
from devplacepy.templating import templates
from devplacepy.responses import respond
from devplacepy.schemas import DeviiPageOut
from devplacepy.utils import (
_user_from_api_key,
_user_from_session,
@@ -78,7 +80,7 @@ async def devii_page(request: Request):
description="Your personal AI development assistant on DevPlace.",
robots="noindex,nofollow",
)
response = templates.TemplateResponse(
response = respond(
request,
"devii.html",
{
@@ -86,6 +88,7 @@ async def devii_page(request: Request):
"request": request,
"user": user,
},
model=DeviiPageOut,
)
if not user and not request.cookies.get(GUEST_COOKIE):
response.set_cookie(
@@ -121,7 +124,7 @@ async def devii_session(request: Request):
return response
def _safe_next(value: str) -> str:
def _validate_target(value: str) -> str:
if value.startswith("/") and not value.startswith("//"):
return value
return "/"
@@ -131,7 +134,7 @@ def _safe_next(value: str) -> str:
async def devii_adopt(request: Request):
# The terminal's agent logged in; adopt the real session it minted into the browser so both
# share one session, then return to where the user was.
target = _safe_next(request.query_params.get("next", "/"))
target = _validate_target(request.query_params.get("next", "/"))
response = RedirectResponse(target, status_code=303)
svc = _service()
if svc is None:
@@ -170,6 +173,7 @@ async def devii_usage(request: Request):
@router.post("/clippy/ai/chat")
async def clippy_proxy(request: Request):
user = require_user(request)
svc = _service()
if svc is None or not svc.is_enabled():
return JSONResponse({"error": "Devii is unavailable"}, status_code=503)