feat(05-01): add round and message operations to discussion service
Add create_round, get_current_round, create_message, and get_round_messages functions. All async with proper type hints and eager loading. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
3258c3a596
commit
baf02bb11f
2 changed files with 103 additions and 0 deletions
|
|
@ -7,8 +7,12 @@ providing a clean interface for handlers to use.
|
||||||
from moai.core.services.discussion import (
|
from moai.core.services.discussion import (
|
||||||
complete_discussion,
|
complete_discussion,
|
||||||
create_discussion,
|
create_discussion,
|
||||||
|
create_message,
|
||||||
|
create_round,
|
||||||
get_active_discussion,
|
get_active_discussion,
|
||||||
|
get_current_round,
|
||||||
get_discussion,
|
get_discussion,
|
||||||
|
get_round_messages,
|
||||||
list_discussions,
|
list_discussions,
|
||||||
)
|
)
|
||||||
from moai.core.services.project import create_project, get_project, list_projects
|
from moai.core.services.project import create_project, get_project, list_projects
|
||||||
|
|
@ -16,10 +20,14 @@ from moai.core.services.project import create_project, get_project, list_project
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"complete_discussion",
|
"complete_discussion",
|
||||||
"create_discussion",
|
"create_discussion",
|
||||||
|
"create_message",
|
||||||
"create_project",
|
"create_project",
|
||||||
|
"create_round",
|
||||||
"get_active_discussion",
|
"get_active_discussion",
|
||||||
|
"get_current_round",
|
||||||
"get_discussion",
|
"get_discussion",
|
||||||
"get_project",
|
"get_project",
|
||||||
|
"get_round_messages",
|
||||||
"list_discussions",
|
"list_discussions",
|
||||||
"list_projects",
|
"list_projects",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,9 @@ from moai.core.models import (
|
||||||
Discussion,
|
Discussion,
|
||||||
DiscussionStatus,
|
DiscussionStatus,
|
||||||
DiscussionType,
|
DiscussionType,
|
||||||
|
Message,
|
||||||
Round,
|
Round,
|
||||||
|
RoundType,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -122,3 +124,96 @@ async def complete_discussion(discussion_id: str) -> Discussion | None:
|
||||||
await session.flush()
|
await session.flush()
|
||||||
await session.refresh(discussion)
|
await session.refresh(discussion)
|
||||||
return discussion
|
return discussion
|
||||||
|
|
||||||
|
|
||||||
|
async def create_round(
|
||||||
|
discussion_id: str,
|
||||||
|
round_number: int,
|
||||||
|
round_type: RoundType,
|
||||||
|
) -> Round:
|
||||||
|
"""Create a new round within a discussion.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
discussion_id: The parent discussion's UUID.
|
||||||
|
round_number: Sequential round number within the discussion.
|
||||||
|
round_type: Whether this round is PARALLEL or SEQUENTIAL.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The created Round object.
|
||||||
|
"""
|
||||||
|
async with get_session() as session:
|
||||||
|
round_ = Round(
|
||||||
|
discussion_id=discussion_id,
|
||||||
|
round_number=round_number,
|
||||||
|
type=round_type,
|
||||||
|
)
|
||||||
|
session.add(round_)
|
||||||
|
await session.flush()
|
||||||
|
await session.refresh(round_)
|
||||||
|
return round_
|
||||||
|
|
||||||
|
|
||||||
|
async def get_current_round(discussion_id: str) -> Round | None:
|
||||||
|
"""Get the current (most recent) round for a discussion.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
discussion_id: The discussion's UUID.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The most recent Round object if found, None otherwise.
|
||||||
|
"""
|
||||||
|
async with get_session() as session:
|
||||||
|
result = await session.execute(
|
||||||
|
select(Round)
|
||||||
|
.where(Round.discussion_id == discussion_id)
|
||||||
|
.order_by(Round.round_number.desc())
|
||||||
|
.limit(1)
|
||||||
|
.options(selectinload(Round.messages))
|
||||||
|
)
|
||||||
|
return result.scalar_one_or_none()
|
||||||
|
|
||||||
|
|
||||||
|
async def create_message(
|
||||||
|
round_id: str,
|
||||||
|
model: str,
|
||||||
|
content: str,
|
||||||
|
is_direct: bool = False,
|
||||||
|
) -> Message:
|
||||||
|
"""Create a new message within a round.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
round_id: The parent round's UUID.
|
||||||
|
model: AI model identifier (e.g., "claude", "gpt", "gemini").
|
||||||
|
content: The message content.
|
||||||
|
is_direct: True if this was a direct @mention to this model.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The created Message object.
|
||||||
|
"""
|
||||||
|
async with get_session() as session:
|
||||||
|
message = Message(
|
||||||
|
round_id=round_id,
|
||||||
|
model=model,
|
||||||
|
content=content,
|
||||||
|
is_direct=is_direct,
|
||||||
|
)
|
||||||
|
session.add(message)
|
||||||
|
await session.flush()
|
||||||
|
await session.refresh(message)
|
||||||
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
async def get_round_messages(round_id: str) -> list[Message]:
|
||||||
|
"""Get all messages for a round ordered by timestamp.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
round_id: The round's UUID.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of Message objects ordered by timestamp.
|
||||||
|
"""
|
||||||
|
async with get_session() as session:
|
||||||
|
result = await session.execute(
|
||||||
|
select(Message).where(Message.round_id == round_id).order_by(Message.timestamp)
|
||||||
|
)
|
||||||
|
return list(result.scalars().all())
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue