mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
Smoke run 2026-05-11 showed five regressions stemming from the gateway consolidating multiple typed endpoints into thin verbs with collapsed signatures. The choreography is fine; the verb signatures lost the structured shape that pre-gateway forced agents to fill. Each fix restores a structured surface so the LLM's tool schema again carries the constraints that prevent the observed bugs. A) do_server: list valid channel slugs in say()/dm() docstrings. Stops invented channels (`backend`, `backend-dev`) — the LLM now sees the closed set in the tool schema. B) choreographer: add _delegate_sibling_dedup_guard. Rejects a delegate that would create a non-terminal sibling with the same assigned_to + task_type under the same parent — the dupe shape observed on smoke (Main PM creating two planning tasks for be-pm; Cell PM creating two code tasks for be-dev-1). C) choreographer: extend _validate_assignee_task_type to all roles. Devs may only get code|documentation|research (not planning/design/ administrative). QA gets code only. Documenters get documentation only. Catches the misroute observed on smoke (Cell PM gave be-dev-2 a 'research' coordination task that should have stayed with the PM). D) i_will_plan: thread approach / technical_considerations / risks / open_questions from MCP through to TaskService.set_plan as a TaskPlan-shaped dict. Empty default keeps back-compat. Panel's Plan tab now renders Approach / Sub-Tasks / Technical Considerations / Risks / Open Questions instead of an empty pane. E) note(): scope-specific structured fields restored. For 'decision' scope: context, options[], chosen, rationale, consequences. For 'reflect' scope: what_done, what_learned, what_struggled, next_steps. Rendered as markdown sections into the journal entry content so the Decisions and Reflections views show named blocks instead of a one-line phrase. Pre-gateway parity. Files changed: - roboco/mcp/do_server.py (A, E) - roboco/mcp/flow_server.py (D) - roboco/services/gateway/choreographer/_impl.py (B, C, D) - roboco/services/gateway/content_actions.py (E) - roboco/api/schemas/v2/flow.py (D) - roboco/api/schemas/v2/do.py (E) - roboco/api/routes/v2/flow_main_pm.py (D) - roboco/api/routes/v2/flow_cell_pm.py (D) - roboco/api/routes/v2/do.py (E) Quality: ruff + mypy clean. 89 unit tests pass on the touched surfaces.
68 lines
1.8 KiB
Python
68 lines
1.8 KiB
Python
"""Request schemas for /api/v2/do/* content tools."""
|
|
|
|
from uuid import UUID
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class CommitRequest(BaseModel):
|
|
message: str = Field(..., min_length=1)
|
|
files: list[str] | None = None
|
|
|
|
|
|
class NoteRequest(BaseModel):
|
|
"""Journal entry. ``text`` is always the short summary line.
|
|
|
|
Scope-specific fields are optional but pre-gateway parity expected
|
|
them filled for `decision` and `reflect`:
|
|
|
|
- decision: ``context``, ``options``, ``chosen``, ``rationale``,
|
|
``consequences``
|
|
- reflect: ``what_done``, ``what_learned``, ``what_struggled``,
|
|
``next_steps``
|
|
|
|
When provided, these are formatted into the journal entry's content
|
|
as structured markdown — the panel UI's decision/reflect views show
|
|
them as named sections instead of a one-line phrase.
|
|
"""
|
|
|
|
text: str = Field(..., min_length=1)
|
|
scope: str = "note"
|
|
task_id: UUID | None = None
|
|
title: str | None = None
|
|
# decision scope
|
|
context: str | None = None
|
|
options: list[str] | None = None
|
|
chosen: str | None = None
|
|
rationale: str | None = None
|
|
consequences: str | None = None
|
|
# reflect scope
|
|
what_done: str | None = None
|
|
what_learned: str | None = None
|
|
what_struggled: str | None = None
|
|
next_steps: str | None = None
|
|
|
|
|
|
class SayRequest(BaseModel):
|
|
channel: str
|
|
text: str = Field(..., min_length=1)
|
|
task_id: UUID | None = None
|
|
|
|
|
|
class DmRequest(BaseModel):
|
|
recipient: str # agent slug
|
|
text: str = Field(..., min_length=1)
|
|
task_id: UUID | None = None
|
|
skill: str | None = None
|
|
|
|
|
|
class NotifyRequest(BaseModel):
|
|
target: str # agent slug
|
|
text: str = Field(..., min_length=1)
|
|
priority: str = "normal" # normal | high | urgent
|
|
task_id: UUID | None = None
|
|
|
|
|
|
class EvidenceRequest(BaseModel):
|
|
task_id: UUID
|