Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions python/valuecell/core/conversation/conversation_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ async def _ensure_initialized(self):
conversation_id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
title TEXT,
agent_name TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'active'
Expand All @@ -149,6 +150,7 @@ def _row_to_conversation(row: sqlite3.Row) -> Conversation:
conversation_id=row["conversation_id"],
user_id=row["user_id"],
title=row["title"],
agent_name=row["agent_name"],
created_at=datetime.fromisoformat(row["created_at"]),
updated_at=datetime.fromisoformat(row["updated_at"]),
status=row["status"],
Expand All @@ -161,13 +163,14 @@ async def save_conversation(self, conversation: Conversation) -> None:
await db.execute(
"""
INSERT OR REPLACE INTO conversations (
conversation_id, user_id, title, created_at, updated_at, status
) VALUES (?, ?, ?, ?, ?, ?)
conversation_id, user_id, title, agent_name, created_at, updated_at, status
) VALUES (?, ?, ?, ?, ?, ?, ?)
""",
(
conversation.conversation_id,
conversation.user_id,
conversation.title,
conversation.agent_name,
conversation.created_at.isoformat(),
conversation.updated_at.isoformat(),
conversation.status.value
Expand Down
2 changes: 2 additions & 0 deletions python/valuecell/core/conversation/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ async def create_conversation(
user_id: str,
title: Optional[str] = None,
conversation_id: Optional[str] = None,
agent_name: Optional[str] = None,
) -> Conversation:
"""Create new conversation"""
conversation = Conversation(
conversation_id=conversation_id or generate_conversation_id(),
user_id=user_id,
title=title,
agent_name=agent_name,
)
await self.conversation_store.save_conversation(conversation)
return conversation
Expand Down
1 change: 1 addition & 0 deletions python/valuecell/core/conversation/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Conversation(BaseModel):
conversation_id: str = Field(..., description="Unique conversation identifier")
user_id: str = Field(..., description="User ID")
title: Optional[str] = Field(None, description="Conversation title")
agent_name: Optional[str] = Field(None, description="Agent name")
created_at: datetime = Field(
default_factory=datetime.now, description="Creation time"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ def __getitem__(self, key):
"conversation_id": "conv-123",
"user_id": "user-123",
"title": "Test Title",
"agent_name": "Agent-1",
"created_at": now.isoformat(),
"updated_at": now.isoformat(),
"status": "active",
Expand All @@ -571,6 +572,7 @@ def __getitem__(self, key):

assert conversation.conversation_id == "conv-123"
assert conversation.user_id == "user-123"
assert conversation.agent_name == "Agent-1"
assert conversation.title == "Test Title"
assert conversation.status == "active"

Expand Down
7 changes: 5 additions & 2 deletions python/valuecell/core/coordinate/orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ async def process_user_input(
"""
conversation_id = user_input.meta.conversation_id
user_id = user_input.meta.user_id
agent_name = user_input.target_agent_name

try:
# Ensure conversation exists
Expand All @@ -207,7 +208,7 @@ async def process_user_input(
)
if not conversation:
await self.conversation_manager.create_conversation(
user_id, conversation_id=conversation_id
user_id, conversation_id=conversation_id, agent_name=agent_name
)
conversation = await self.conversation_manager.get_conversation(
conversation_id
Expand Down Expand Up @@ -663,7 +664,9 @@ async def _execute_plan_with_input_support(
"phase": SubagentConversationPhase.START.value,
}
await self.conversation_manager.create_conversation(
plan.user_id, conversation_id=task.conversation_id
plan.user_id,
conversation_id=task.conversation_id,
agent_name=task.agent_name,
)
if task.handoff_from_super_agent:
subagent_conv_start_component = (
Expand Down
1 change: 1 addition & 0 deletions python/valuecell/server/api/schemas/conversation.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class MessageData(BaseModel):
payload: Optional[Dict[str, Any]] = Field(None, description="Message payload")
role: Optional[str] = Field(None, description="Role for simple event format")
item_id: Optional[str] = Field(None, description="Item ID for simple event format")
agent_name: Optional[str] = Field(None, description="Name of the agent")


class MessageEvent(BaseModel):
Expand Down
46 changes: 46 additions & 0 deletions python/valuecell/server/db/init_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,52 @@ def create_tables(self) -> bool:
try:
logger.info("Creating database tables...")
Base.metadata.create_all(bind=self.engine)

# Create conversation-related tables that are not in SQLAlchemy models
logger.info("Creating conversation-related tables...")
with self.engine.connect() as conn:
# Create conversations table
conn.execute(
text("""
CREATE TABLE IF NOT EXISTS conversations (
conversation_id TEXT PRIMARY KEY,
user_id TEXT,
title TEXT,
agent_name TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
status TEXT DEFAULT 'active'
)
""")
)

# Create conversation_items table
conn.execute(
text("""
CREATE TABLE IF NOT EXISTS conversation_items (
item_id TEXT PRIMARY KEY,
role TEXT NOT NULL,
event TEXT NOT NULL,
conversation_id TEXT NOT NULL,
thread_id TEXT,
task_id TEXT,
payload TEXT,
agent_name TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
)

# Create index for conversation_items
conn.execute(
text("""
CREATE INDEX IF NOT EXISTS idx_item_conv_time
ON conversation_items(conversation_id, created_at)
""")
)

conn.commit()

logger.info("Database tables created successfully")
return True

Expand Down
25 changes: 2 additions & 23 deletions python/valuecell/server/services/conversation_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,35 +44,14 @@ async def get_conversation_list(

# Apply pagination
total = len(conversations)
paginated_conversations = conversations[offset : offset + limit]

# Convert to response format
conversation_items = []
for conv in paginated_conversations:
# Get the latest item to extract agent_name
latest_items = await self.item_store.get_items(
conversation_id=conv.conversation_id, limit=1
)

agent_name = "unknown"
if latest_items:
# Try to extract agent_name from the latest item's metadata
latest_item = latest_items[0]
if hasattr(latest_item, "metadata") and latest_item.metadata:
extracted_name = latest_item.metadata.get("agent_name")
if extracted_name:
agent_name = extracted_name
elif hasattr(latest_item, "agent_name") and latest_item.agent_name:
agent_name = latest_item.agent_name

# Ensure agent_name is never None or empty
if not agent_name or agent_name is None:
agent_name = "unknown"

for conv in conversations:
conversation_item = ConversationListItem(
conversation_id=conv.conversation_id,
title=conv.title or f"Conversation {conv.conversation_id}",
agent_name=agent_name,
agent_name=conv.agent_name,
update_time=conv.updated_at.isoformat()
if conv.updated_at
else conv.created_at.isoformat(),
Expand Down