data_juicer_agents.tui.models 源代码
# -*- coding: utf-8 -*-
"""State models for the dj-agents terminal transcript UI."""
from __future__ import annotations
from dataclasses import dataclass
from dataclasses import field
from datetime import datetime
from typing import Dict
from typing import List
from typing import Optional
[文档]
@dataclass
class ChatMessage:
role: str
text: str
markdown: bool = False
timestamp: datetime = field(default_factory=datetime.utcnow)
[文档]
@dataclass
class TimelineItem:
kind: str
title: str
text: str = ""
markdown: bool = False
status: Optional[str] = None
tool: Optional[str] = None
timestamp: datetime = field(default_factory=datetime.utcnow)
[文档]
@dataclass
class TuiState:
messages: List[ChatMessage] = field(default_factory=list)
tool_calls: Dict[str, ToolCallState] = field(default_factory=dict)
tool_call_order: List[str] = field(default_factory=list)
reasoning_notes: List[str] = field(default_factory=list)
timeline: List[TimelineItem] = field(default_factory=list)
status_line: str = "Ready."
model_label: str = "session-agent"
planner_model_label: str = "planner"
llm_base_url: str = ""
permissions_label: str = "Workspace"
cwd: str = "~"
session_workdir: str = "./.djx"
[文档]
def add_timeline(
self,
*,
kind: str,
title: str,
text: str = "",
markdown: bool = False,
status: Optional[str] = None,
tool: Optional[str] = None,
timestamp: Optional[datetime] = None,
limit: int = 300,
) -> None:
if not str(title or "").strip() and not str(text or "").strip():
return
item = TimelineItem(
kind=str(kind or "event").strip() or "event",
title=str(title or "").strip(),
text=str(text or "").strip(),
markdown=bool(markdown),
status=str(status or "").strip() or None,
tool=str(tool or "").strip() or None,
timestamp=timestamp or datetime.utcnow(),
)
self.timeline.append(item)
if limit > 0 and len(self.timeline) > limit:
self.timeline = self.timeline[-limit:]
[文档]
def add_message(self, role: str, text: str, markdown: bool = False) -> None:
content = str(text or "").strip()
if not content:
return
role_text = str(role or "").strip() or "assistant"
self.messages.append(ChatMessage(role=role_text, text=content, markdown=markdown))
self.add_timeline(
kind="user" if role_text.lower() == "you" else "assistant",
title=role_text,
text=content,
markdown=markdown,
)
[文档]
def recent_messages(self, limit: int = 12) -> List[ChatMessage]:
if limit <= 0:
return []
return self.messages[-limit:]
[文档]
def recent_timeline(self, limit: int = 40) -> List[TimelineItem]:
if limit <= 0:
return []
return self.timeline[-limit:]
[文档]
def append_reasoning(self, note: str, *, limit: int = 20) -> None:
text = str(note or "").strip()
if not text:
return
self.reasoning_notes.append(text)
if limit > 0 and len(self.reasoning_notes) > limit:
self.reasoning_notes = self.reasoning_notes[-limit:]
self.add_timeline(kind="reasoning", title="reasoning", text=text)