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.
- uacs/__init__.py +12 -0
- uacs/adapters/__init__.py +19 -0
- uacs/adapters/agent_skill_adapter.py +202 -0
- uacs/adapters/agents_md_adapter.py +330 -0
- uacs/adapters/base.py +261 -0
- uacs/adapters/clinerules_adapter.py +39 -0
- uacs/adapters/cursorrules_adapter.py +39 -0
- uacs/api.py +262 -0
- uacs/cli/__init__.py +6 -0
- uacs/cli/context.py +349 -0
- uacs/cli/main.py +195 -0
- uacs/cli/mcp.py +115 -0
- uacs/cli/memory.py +142 -0
- uacs/cli/packages.py +309 -0
- uacs/cli/skills.py +144 -0
- uacs/cli/utils.py +24 -0
- uacs/config/repositories.yaml +26 -0
- uacs/context/__init__.py +0 -0
- uacs/context/agent_context.py +406 -0
- uacs/context/shared_context.py +661 -0
- uacs/context/unified_context.py +332 -0
- uacs/mcp_server_entry.py +80 -0
- uacs/memory/__init__.py +5 -0
- uacs/memory/simple_memory.py +255 -0
- uacs/packages/__init__.py +26 -0
- uacs/packages/manager.py +413 -0
- uacs/packages/models.py +60 -0
- uacs/packages/sources.py +270 -0
- uacs/protocols/__init__.py +5 -0
- uacs/protocols/mcp/__init__.py +8 -0
- uacs/protocols/mcp/manager.py +77 -0
- uacs/protocols/mcp/skills_server.py +700 -0
- uacs/skills_validator.py +367 -0
- uacs/utils/__init__.py +5 -0
- uacs/utils/paths.py +24 -0
- uacs/visualization/README.md +132 -0
- uacs/visualization/__init__.py +36 -0
- uacs/visualization/models.py +195 -0
- uacs/visualization/static/index.html +857 -0
- uacs/visualization/storage.py +402 -0
- uacs/visualization/visualization.py +328 -0
- uacs/visualization/web_server.py +364 -0
- universal_agent_context-0.2.0.dist-info/METADATA +873 -0
- universal_agent_context-0.2.0.dist-info/RECORD +47 -0
- universal_agent_context-0.2.0.dist-info/WHEEL +4 -0
- universal_agent_context-0.2.0.dist-info/entry_points.txt +2 -0
- 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
|