mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
feat(sessions): Session-Task linking with scoped context management
Major feature: Sessions are now linked to tasks with smart routing and context loading, ensuring agents have proper discussion context.
## Session-Task Relationship (Many-to-Many)
- Added SessionTaskTable junction table linking sessions to tasks
- Sessions can link to multiple tasks, tasks can have multiple sessions
- is_primary flag marks the main discussion session for a task
- relationship_type: discussion, planning, review, retrospective
- Subtasks auto-inherit parent task's session
## BACKLOG Status + Activation Flow
- Tasks now created with BACKLOG status (not PENDING)
- PMs must create session BEFORE activating task
- roboco_task_activate() transitions BACKLOG → PENDING
- Prevents race condition where dev starts before session exists
- Flow: CREATE (backlog) → SESSION → ACTIVATE (pending) → spawn
## Session Scopes
- SessionScope enum: initiative, cell, task
- initiative: Cross-cell coordination (Main PM, #dev-all)
- cell: Cell-specific work (Cell PM default)
- task: Individual task execution (dev level)
- Enables future smart context loading by scope
## Message Routing to Task Sessions
- When task_id provided in roboco_message_send(), routes to task's primary session instead of channel's active session
- New API endpoint: GET /sessions/for-task/{task_id}
- TaskResponse now includes linked sessions array
## Dev Session Access
- New tool: roboco_session_history_for_task(task_id)
- Devs can now see their task's discussion history
- Messages tagged with task_id for filtering
## Communication Guidelines
- Added "When to Post / When NOT to Post" to all 9 agent blueprints
- Devs/QA/Doc should use task tools for status, journal for reasoning
- Sessions reserved for coordination that needs response
- Reduces noise: no "Starting work" or "Made progress" chat messages
Files changed:
- DB: SessionTaskTable, SessionScope column
- Services: messaging.py (linking), task.py (activation)
- MCP: 5 new session tools, message routing update
- API: session-task endpoints, TaskResponse sessions
- Blueprints: All 13 updated with session/activation workflow
This commit is contained in:
@@ -3,9 +3,15 @@ Session Model
|
||||
|
||||
Sessions group messages within boundaries (time, count, content length).
|
||||
They are automatically created and closed based on configuration.
|
||||
|
||||
Session-Task Relationships:
|
||||
PMs can create work sessions as discussion contexts for tasks.
|
||||
A session can discuss multiple related tasks.
|
||||
A task can have multiple sessions (planning, review, retrospective).
|
||||
"""
|
||||
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from enum import StrEnum
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
from pydantic import Field
|
||||
@@ -16,6 +22,44 @@ from roboco.models.base import (
|
||||
TimestampMixin,
|
||||
)
|
||||
|
||||
# =============================================================================
|
||||
# SESSION SCOPE (Context Level)
|
||||
# =============================================================================
|
||||
|
||||
|
||||
class SessionScope(StrEnum):
|
||||
"""
|
||||
Scope level for sessions - determines context loading strategy.
|
||||
|
||||
Sessions at different scopes serve different purposes:
|
||||
- INITIATIVE: Cross-cell coordination (Main PM, #dev-all)
|
||||
- CELL: Cell-specific work (Cell PM, #backend-cell)
|
||||
- TASK: Individual task execution (Developer level)
|
||||
|
||||
When loading context for an agent:
|
||||
- Load their scope's sessions fully
|
||||
- Load parent scope sessions as summaries/references
|
||||
"""
|
||||
|
||||
INITIATIVE = "initiative" # Cross-cell, Main PM level
|
||||
CELL = "cell" # Cell-specific, Cell PM level
|
||||
TASK = "task" # Individual task execution
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# SESSION-TASK RELATIONSHIP TYPES
|
||||
# =============================================================================
|
||||
|
||||
|
||||
class SessionTaskRelationshipType(StrEnum):
|
||||
"""Type of relationship between a session and a task."""
|
||||
|
||||
DISCUSSION = "discussion" # General discussion about the task
|
||||
PLANNING = "planning" # Planning session for the task
|
||||
REVIEW = "review" # Review/retrospective session
|
||||
RETROSPECTIVE = "retrospective" # Post-completion reflection
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# SUPPORTING MODELS
|
||||
# =============================================================================
|
||||
@@ -72,6 +116,12 @@ class Session(TimestampMixin):
|
||||
# State
|
||||
status: SessionStatus = Field(default=SessionStatus.ACTIVE)
|
||||
|
||||
# Scope (for smart context loading)
|
||||
scope: SessionScope = Field(
|
||||
default=SessionScope.TASK,
|
||||
description="Session scope level - initiative, cell, or task",
|
||||
)
|
||||
|
||||
# Timestamps
|
||||
started_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
|
||||
last_activity_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
|
||||
@@ -97,3 +147,65 @@ class SessionCreate(RobocoBase):
|
||||
|
||||
group_id: UUID
|
||||
config: SessionConfig | None = None
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# SESSION-TASK LINK MODELS
|
||||
# =============================================================================
|
||||
|
||||
|
||||
class SessionTaskLink(TimestampMixin):
|
||||
"""
|
||||
Represents a link between a session and a task.
|
||||
|
||||
Used for reading/displaying session-task relationships.
|
||||
"""
|
||||
|
||||
id: UUID = Field(default_factory=uuid4, description="Link ID")
|
||||
session_id: UUID = Field(..., description="Session ID")
|
||||
task_id: UUID = Field(..., description="Task ID")
|
||||
|
||||
# Relationship metadata
|
||||
is_primary: bool = Field(
|
||||
default=False, description="Is this the primary discussion session for the task"
|
||||
)
|
||||
relationship_type: SessionTaskRelationshipType = Field(
|
||||
default=SessionTaskRelationshipType.DISCUSSION,
|
||||
description="Type of session-task relationship",
|
||||
)
|
||||
|
||||
# Audit
|
||||
added_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
|
||||
added_by: UUID | None = Field(default=None, description="PM who created the link")
|
||||
|
||||
|
||||
class SessionTaskLinkCreate(RobocoBase):
|
||||
"""Schema for creating a session-task link."""
|
||||
|
||||
session_id: UUID = Field(..., description="Session to link")
|
||||
task_id: UUID = Field(..., description="Task to link")
|
||||
is_primary: bool = Field(
|
||||
default=False, description="Mark as primary session for this task"
|
||||
)
|
||||
relationship_type: SessionTaskRelationshipType = Field(
|
||||
default=SessionTaskRelationshipType.DISCUSSION,
|
||||
description="Type of relationship",
|
||||
)
|
||||
|
||||
|
||||
class SessionForTasksCreate(RobocoBase):
|
||||
"""Schema for PM creating a session linked to multiple tasks."""
|
||||
|
||||
task_ids: list[UUID] = Field(..., min_length=1, description="Tasks to link")
|
||||
channel_slug: str = Field(..., description="Channel where session is created")
|
||||
scope: SessionScope = Field(
|
||||
default=SessionScope.CELL,
|
||||
description="Session scope level for context loading strategy",
|
||||
)
|
||||
config: SessionConfig | None = Field(
|
||||
default=None, description="Session boundary configuration"
|
||||
)
|
||||
relationship_type: SessionTaskRelationshipType = Field(
|
||||
default=SessionTaskRelationshipType.DISCUSSION,
|
||||
description="Relationship type for all links",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user