Deleted Files (7,506 lines removed)

| File                          | Lines  | Purpose                                   |
  |-------------------------------|--------|-------------------------------------------|
  | HOMELAB_TEAM_V0.md            | 3,443  | Original blueprint doc (now in CLAUDE.md) |
  | WORKFLOWS.md                  | 260    | Workflow docs                             |
  | roboco/agents/*.py            | ~5,800 | Entire Python agent framework (14 files)  |
  | roboco/models/organization.py | 157    | Unused org types                          |

  New Files (53 lines added)

  | File                        | Lines | Purpose                                                    |
  |-----------------------------|-------|------------------------------------------------------------|
  | roboco/runtime/streaming.py | 53    | Migrated set_reasoning_stream_callback from deleted agents |

  Modified Files

  Config & Settings:
  - .gitignore - Added .OLD/ directory

  Blueprints (13 files):
  - Fixed roboco_task_plan() signatures: (task_id, plan) → (task_id, approach, steps, risks?, open_questions?)
  - PM blueprints: Fixed channel access (read/write for dev-all, qa-all, doc-all)

  Core Code:
  | File                           | Changes                                   |
  |--------------------------------|-------------------------------------------|
  | roboco/agents_config.py        | Team naming uxui → ux_ui, docstring fixes |
  | roboco/api/routes/tasks.py     | Hardcoded roles → AgentRole enum          |
  | roboco/services/permissions.py | Cell PM → Main PM notification fix        |
  | roboco/services/task.py        | Removed unused imports                    |
  | roboco/bootstrap.py            | Updated import path after agents deletion |
  | roboco/runtime/__init__.py     | Added streaming exports                   |
  | roboco/runtime/orchestrator.py | Various improvements (+229/-10)           |
  | roboco/mcp/task_server.py      | Docstring team fix                        |
  | roboco/mcp/tasks/handlers/*.py | Handler improvements                      |
  | roboco/enforcement/*.py        | Lifecycle enforcement updates             |
  | roboco/db/tables.py            | Table changes (+76 lines)                 |
  | roboco/models/base.py          | Minor enum tweaks                         |
  | roboco/seeds/initial_data.py   | Docstring team fix                        |

  Key Architecture Change:
  Removed the unused Python agent framework (roboco/agents/) - the system uses Docker-based Claude Code spawning via roboco/runtime/orchestrator.py instead.
This commit is contained in:
Renn F
2025-12-25 21:01:12 +01:00
parent 7f13e10bf4
commit 1f6c099d8a
55 changed files with 1397 additions and 10895 deletions
+46 -3
View File
@@ -5,6 +5,11 @@ Real-time communication via WebSocket connections for:
- Channel streams (all messages in a channel)
- Agent streams (individual agent output)
- Session streams (messages in a session)
Security Note:
WebSocket connections validate agent_id via query params and verify
the agent exists in the database. In production, this should be
enhanced with proper token-based authentication (JWT, etc.).
"""
import asyncio
@@ -20,6 +25,8 @@ from roboco.api.schemas.websocket import (
NewMessageBroadcast,
)
from roboco.config import settings
from roboco.db.base import get_db
from roboco.services.repositories import resolve_agent_uuid
router = APIRouter()
@@ -177,6 +184,24 @@ class ConnectionManager:
manager = ConnectionManager()
async def validate_agent_exists(agent_id: UUID | str) -> bool:
"""
Validate that an agent exists in the database.
This provides basic security by ensuring the claimed agent_id
is a valid agent, not just a valid UUID format.
TODO: Enhance with token-based authentication (JWT) for production.
"""
try:
async for db in get_db():
result = await resolve_agent_uuid(db, str(agent_id))
return result is not None
except Exception:
return False
return False
async def validate_channel_access(channel_id: UUID, agent_id: UUID) -> bool:
"""
Validate that an agent has access to a channel.
@@ -286,6 +311,11 @@ async def agent_stream(
await websocket.close(code=status.WS_1008_POLICY_VIOLATION)
return
# Validate viewer agent exists in database
if not await validate_agent_exists(viewer_id):
await websocket.close(code=status.WS_1008_POLICY_VIOLATION)
return
await manager.connect_agent(websocket, agent_id, viewer_id)
try:
@@ -327,6 +357,11 @@ async def session_stream(
await websocket.close(code=status.WS_1008_POLICY_VIOLATION)
return
# Validate agent exists in database
if not await validate_agent_exists(agent_id):
await websocket.close(code=status.WS_1008_POLICY_VIOLATION)
return
await manager.connect_session(websocket, session_id, agent_id)
try:
@@ -356,6 +391,11 @@ async def notification_stream(
Agents receive real-time notifications via this stream.
"""
# Validate agent exists in database
if not await validate_agent_exists(agent_id):
await websocket.close(code=status.WS_1008_POLICY_VIOLATION)
return
await manager.connect_notifications(websocket, agent_id)
try:
@@ -397,16 +437,19 @@ async def broadcast_new_message(msg: NewMessageBroadcast) -> None:
)
async def broadcast_agent_chunk(agent_id: UUID, chunk: str) -> None:
async def broadcast_agent_chunk(
agent_id: str, chunk: str, metadata: dict[str, Any]
) -> None:
"""Broadcast an agent stream chunk to watchers."""
event = {
"type": "agent.stream",
"agent_id": str(agent_id),
"agent_id": agent_id,
"chunk": chunk,
"timestamp": datetime.now(UTC).isoformat(),
**metadata,
}
await manager.broadcast_to_agent_watchers(agent_id, event)
await manager.broadcast_to_agent_watchers(UUID(agent_id), event)
async def broadcast_session_closed(