universal-agent-context 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. uacs/__init__.py +12 -0
  2. uacs/adapters/__init__.py +19 -0
  3. uacs/adapters/agent_skill_adapter.py +202 -0
  4. uacs/adapters/agents_md_adapter.py +330 -0
  5. uacs/adapters/base.py +261 -0
  6. uacs/adapters/clinerules_adapter.py +39 -0
  7. uacs/adapters/cursorrules_adapter.py +39 -0
  8. uacs/api.py +262 -0
  9. uacs/cli/__init__.py +6 -0
  10. uacs/cli/context.py +349 -0
  11. uacs/cli/main.py +195 -0
  12. uacs/cli/mcp.py +115 -0
  13. uacs/cli/memory.py +142 -0
  14. uacs/cli/packages.py +309 -0
  15. uacs/cli/skills.py +144 -0
  16. uacs/cli/utils.py +24 -0
  17. uacs/config/repositories.yaml +26 -0
  18. uacs/context/__init__.py +0 -0
  19. uacs/context/agent_context.py +406 -0
  20. uacs/context/shared_context.py +661 -0
  21. uacs/context/unified_context.py +332 -0
  22. uacs/mcp_server_entry.py +80 -0
  23. uacs/memory/__init__.py +5 -0
  24. uacs/memory/simple_memory.py +255 -0
  25. uacs/packages/__init__.py +26 -0
  26. uacs/packages/manager.py +413 -0
  27. uacs/packages/models.py +60 -0
  28. uacs/packages/sources.py +270 -0
  29. uacs/protocols/__init__.py +5 -0
  30. uacs/protocols/mcp/__init__.py +8 -0
  31. uacs/protocols/mcp/manager.py +77 -0
  32. uacs/protocols/mcp/skills_server.py +700 -0
  33. uacs/skills_validator.py +367 -0
  34. uacs/utils/__init__.py +5 -0
  35. uacs/utils/paths.py +24 -0
  36. uacs/visualization/README.md +132 -0
  37. uacs/visualization/__init__.py +36 -0
  38. uacs/visualization/models.py +195 -0
  39. uacs/visualization/static/index.html +857 -0
  40. uacs/visualization/storage.py +402 -0
  41. uacs/visualization/visualization.py +328 -0
  42. uacs/visualization/web_server.py +364 -0
  43. universal_agent_context-0.2.0.dist-info/METADATA +873 -0
  44. universal_agent_context-0.2.0.dist-info/RECORD +47 -0
  45. universal_agent_context-0.2.0.dist-info/WHEEL +4 -0
  46. universal_agent_context-0.2.0.dist-info/entry_points.txt +2 -0
  47. universal_agent_context-0.2.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,195 @@
1
+ """Data models for trace visualization.
2
+
3
+ Provides Session and Event models for LangSmith-style trace visualization.
4
+ """
5
+
6
+ from datetime import datetime
7
+ from enum import Enum
8
+ from typing import Any
9
+ from pydantic import BaseModel, Field
10
+
11
+
12
+ class EventType(str, Enum):
13
+ """Types of events in a session."""
14
+
15
+ USER_PROMPT = "user_prompt"
16
+ ASSISTANT_RESPONSE = "assistant_response"
17
+ TOOL_USE = "tool_use"
18
+ COMPRESSION = "compression"
19
+ ERROR = "error"
20
+
21
+
22
+ class CompressionTrigger(str, Enum):
23
+ """Types of compression triggers."""
24
+
25
+ EARLY_COMPRESSION = "early_compression" # Proactive at 50%
26
+ PRECOMPACT = "precompact" # Emergency before Claude compacts
27
+ SESSIONEND = "sessionend" # Final compression
28
+
29
+
30
+ class Event(BaseModel):
31
+ """Single event in a session (tool use, prompt, compression, etc.)."""
32
+
33
+ event_id: str
34
+ session_id: str
35
+ type: EventType
36
+ timestamp: str # ISO format
37
+
38
+ # Tool use fields
39
+ tool_name: str | None = None
40
+ tool_input: dict[str, Any] | None = None
41
+ tool_response: str | None = None
42
+ latency_ms: int | None = None
43
+
44
+ # Content fields
45
+ content: str | None = None # For prompts/responses
46
+
47
+ # Compression fields
48
+ compression_trigger: CompressionTrigger | None = None
49
+ compression_usage: str | None = None # e.g., "52.3%"
50
+ tokens_before: int | None = None
51
+ tokens_after: int | None = None
52
+ tokens_saved: int | None = None
53
+ compression_ratio: str | None = None
54
+ turns_archived: int | None = None
55
+
56
+ # Common fields
57
+ topics: list[str] = Field(default_factory=list)
58
+ tokens_in: int = 0
59
+ tokens_out: int = 0
60
+ tokens_cumulative: int = 0
61
+ quality: float = 0.8
62
+ metadata: dict[str, Any] = Field(default_factory=dict)
63
+
64
+
65
+ class Session(BaseModel):
66
+ """Claude Code session with full trace."""
67
+
68
+ session_id: str
69
+ started_at: str # ISO format
70
+ ended_at: str | None = None
71
+ duration_seconds: int | None = None
72
+
73
+ # Counts
74
+ turn_count: int = 0
75
+ event_count: int = 0
76
+
77
+ # Topics
78
+ topics: list[str] = Field(default_factory=list)
79
+
80
+ # Tokens
81
+ total_tokens: int = 0
82
+ compressed_tokens: int = 0
83
+ compression_savings: int = 0
84
+ compression_percentage: str = "0%"
85
+
86
+ # Quality
87
+ quality_avg: float = 0.8
88
+
89
+ # Source
90
+ source: str = "claude-code" # claude-code-posttooluse, claude-code-sessionend
91
+
92
+ # Metadata
93
+ metadata: dict[str, Any] = Field(default_factory=dict)
94
+
95
+ # Events (optional, loaded on demand)
96
+ events: list[Event] = Field(default_factory=list)
97
+
98
+
99
+ class SessionList(BaseModel):
100
+ """Paginated list of sessions."""
101
+
102
+ sessions: list[Session]
103
+ total: int
104
+ skip: int
105
+ limit: int
106
+
107
+
108
+ class EventList(BaseModel):
109
+ """Paginated list of events."""
110
+
111
+ events: list[Event]
112
+ total: int
113
+ skip: int
114
+ limit: int
115
+
116
+
117
+ class TokenAnalytics(BaseModel):
118
+ """Token usage analytics."""
119
+
120
+ total_tokens: int
121
+ compressed_tokens: int
122
+ savings: int
123
+ savings_percentage: str
124
+ avg_per_session: int
125
+ sessions_count: int
126
+
127
+ # Breakdown by type
128
+ user_prompt_tokens: int = 0
129
+ assistant_response_tokens: int = 0
130
+ tool_use_tokens: int = 0
131
+
132
+ # Trend data (list of daily totals)
133
+ trend_dates: list[str] = Field(default_factory=list)
134
+ trend_values: list[int] = Field(default_factory=list)
135
+
136
+
137
+ class CompressionAnalytics(BaseModel):
138
+ """Compression events analytics."""
139
+
140
+ early_compression_count: int = 0
141
+ early_compression_avg_savings: int = 0
142
+ precompact_count: int = 0
143
+ precompact_avg_savings: int = 0
144
+ sessionend_count: int = 0
145
+ sessionend_avg_savings: int = 0
146
+
147
+ compaction_prevention_rate: str = "0%"
148
+ compaction_prevention_count: int = 0
149
+ compaction_prevention_total: int = 0
150
+
151
+
152
+ class TopicCluster(BaseModel):
153
+ """Topic cluster with session references."""
154
+
155
+ topic: str
156
+ count: int
157
+ session_ids: list[str] = Field(default_factory=list)
158
+ total_tokens: int = 0
159
+ avg_quality: float = 0.8
160
+
161
+
162
+ class TopicAnalytics(BaseModel):
163
+ """Topic distribution analytics."""
164
+
165
+ clusters: list[TopicCluster]
166
+ total_topics: int
167
+
168
+
169
+ class QualityAnalytics(BaseModel):
170
+ """Quality distribution analytics."""
171
+
172
+ average: float
173
+ high_quality_count: int # >= 0.8
174
+ medium_quality_count: int # 0.5-0.8
175
+ low_quality_count: int # < 0.5
176
+
177
+ distribution: list[dict[str, Any]] = Field(default_factory=list)
178
+
179
+
180
+ class SearchRequest(BaseModel):
181
+ """Search request with filters."""
182
+
183
+ query: str
184
+ filters: dict[str, Any] = Field(default_factory=dict)
185
+ skip: int = 0
186
+ limit: int = 50
187
+
188
+
189
+ class SearchResults(BaseModel):
190
+ """Search results with sessions and events."""
191
+
192
+ query: str
193
+ sessions: list[Session] = Field(default_factory=list)
194
+ events: list[Event] = Field(default_factory=list)
195
+ total_results: int