返回 ViMax
models.py
根目录 / agent_runtime / models.py
1 from __future__ import annotations
2
3 from dataclasses import dataclass, field
4 from threading import Event
5 from time import time
6 from typing import Any, Literal
7 from uuid import uuid4
8
9
10 @dataclass(slots=True)
11 class ToolCall:
12 name: str
13 arguments: dict[str, Any] = field(default_factory=dict)
14 id: str = field(default_factory=lambda: f"tool-{uuid4().hex[:12]}")
15
16 def as_dict(self) -> dict[str, Any]:
17 return {"id": self.id, "name": self.name, "arguments": self.arguments}
18
19
20 @dataclass(slots=True)
21 class ToolResult:
22 name: str
23 ok: bool
24 content: str
25 metadata: dict[str, Any] = field(default_factory=dict)
26 # Transient multimodal blocks for the next LLM turn. Deliberately omitted
27 # from as_dict() so image bytes never enter JSONL logs or session history.
28 model_content: list[dict[str, Any]] | None = field(default=None, repr=False)
29
30 def as_dict(self) -> dict[str, Any]:
31 return {"name": self.name, "ok": self.ok, "content": self.content, "metadata": dict(self.metadata)}
32
33
34 @dataclass(slots=True)
35 class TurnControl:
36 turn_id: str = field(default_factory=lambda: f"turn-{uuid4().hex[:12]}")
37 cancel_event: Event = field(default_factory=Event)
38 cancel_reason: str = ""
39
40 def cancel(self, reason: str = "") -> None:
41 self.cancel_reason = reason.strip()
42 self.cancel_event.set()
43
44
45 @dataclass(slots=True)
46 class SessionRecord:
47 session_id: str
48 working_dir: str
49 idea: str = ""
50 user_requirement: str = ""
51 style: str = ""
52 stage: str = "created"
53 summary: str = ""
54 stale: dict[str, bool] = field(default_factory=dict)
55 created_at: str = ""
56 updated_at: str = ""
57
58
59 StreamEventType = Literal["turn", "status", "token", "tool_start", "tool_progress", "tool_result", "terminal", "done", "session", "error", "prompt_trace"]
60
61
62 def now_ts() -> float:
63 return time()
64
64 lines PYTHON