empathy-framework 4.9.0__py3-none-any.whl → 5.0.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.
- {empathy_framework-4.9.0.dist-info → empathy_framework-5.0.0.dist-info}/METADATA +64 -25
- {empathy_framework-4.9.0.dist-info → empathy_framework-5.0.0.dist-info}/RECORD +47 -26
- empathy_os/__init__.py +2 -2
- empathy_os/cache/hash_only.py +6 -3
- empathy_os/cache/hybrid.py +6 -3
- empathy_os/cli_legacy.py +27 -1
- empathy_os/cli_minimal.py +512 -15
- empathy_os/cli_router.py +145 -113
- empathy_os/cli_unified.py +25 -0
- empathy_os/dashboard/__init__.py +42 -0
- empathy_os/dashboard/app.py +512 -0
- empathy_os/dashboard/simple_server.py +403 -0
- empathy_os/dashboard/standalone_server.py +536 -0
- empathy_os/memory/__init__.py +19 -5
- empathy_os/memory/short_term.py +4 -70
- empathy_os/memory/types.py +2 -2
- empathy_os/models/__init__.py +3 -0
- empathy_os/models/adaptive_routing.py +437 -0
- empathy_os/models/registry.py +4 -4
- empathy_os/socratic/ab_testing.py +1 -1
- empathy_os/telemetry/__init__.py +29 -1
- empathy_os/telemetry/agent_coordination.py +478 -0
- empathy_os/telemetry/agent_tracking.py +350 -0
- empathy_os/telemetry/approval_gates.py +563 -0
- empathy_os/telemetry/event_streaming.py +405 -0
- empathy_os/telemetry/feedback_loop.py +557 -0
- empathy_os/vscode_bridge 2.py +173 -0
- empathy_os/workflows/__init__.py +4 -4
- empathy_os/workflows/base.py +495 -43
- empathy_os/workflows/history.py +3 -5
- empathy_os/workflows/output.py +410 -0
- empathy_os/workflows/progress.py +324 -22
- empathy_os/workflows/progressive/README 2.md +454 -0
- empathy_os/workflows/progressive/__init__ 2.py +92 -0
- empathy_os/workflows/progressive/cli 2.py +242 -0
- empathy_os/workflows/progressive/core 2.py +488 -0
- empathy_os/workflows/progressive/orchestrator 2.py +701 -0
- empathy_os/workflows/progressive/reports 2.py +528 -0
- empathy_os/workflows/progressive/telemetry 2.py +280 -0
- empathy_os/workflows/progressive/test_gen 2.py +514 -0
- empathy_os/workflows/progressive/workflow 2.py +628 -0
- empathy_os/workflows/routing.py +5 -0
- empathy_os/workflows/security_audit.py +189 -0
- {empathy_framework-4.9.0.dist-info → empathy_framework-5.0.0.dist-info}/WHEEL +0 -0
- {empathy_framework-4.9.0.dist-info → empathy_framework-5.0.0.dist-info}/entry_points.txt +0 -0
- {empathy_framework-4.9.0.dist-info → empathy_framework-5.0.0.dist-info}/licenses/LICENSE +0 -0
- {empathy_framework-4.9.0.dist-info → empathy_framework-5.0.0.dist-info}/top_level.txt +0 -0
empathy_os/cli_router.py
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
"""Hybrid CLI Router -
|
|
1
|
+
"""Hybrid CLI Router - Skills + Natural Language
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
-
|
|
5
|
-
-
|
|
6
|
-
-
|
|
3
|
+
Routes keywords and natural language to Claude Code skill invocations:
|
|
4
|
+
- Skills: /dev, /testing, /workflows (Claude Code Skill tool)
|
|
5
|
+
- Keywords: commit, test, security (maps to skills)
|
|
6
|
+
- Natural language: "commit my changes" (SmartRouter classification)
|
|
7
7
|
|
|
8
8
|
Copyright 2025 Smart-AI-Memory
|
|
9
9
|
Licensed under Fair Source License 0.9
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
|
-
import os
|
|
13
|
-
import re
|
|
14
12
|
from dataclasses import dataclass
|
|
15
13
|
from pathlib import Path
|
|
16
14
|
from typing import Any
|
|
@@ -25,33 +23,34 @@ class RoutingPreference:
|
|
|
25
23
|
"""User's learned routing preferences."""
|
|
26
24
|
|
|
27
25
|
keyword: str
|
|
28
|
-
|
|
26
|
+
skill: str
|
|
27
|
+
args: str = ""
|
|
29
28
|
usage_count: int = 0
|
|
30
29
|
confidence: float = 1.0
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
class HybridRouter:
|
|
34
|
-
"""Routes user input to
|
|
33
|
+
"""Routes user input to Claude Code skill invocations.
|
|
35
34
|
|
|
36
35
|
Supports three input modes:
|
|
37
|
-
1.
|
|
38
|
-
2.
|
|
36
|
+
1. Skills: /dev, /testing (returns skill invocation metadata)
|
|
37
|
+
2. Keywords: commit, test (maps to skill invocations)
|
|
39
38
|
3. Natural language: "I need to commit" (uses SmartRouter)
|
|
40
39
|
|
|
41
40
|
Example:
|
|
42
41
|
router = HybridRouter()
|
|
43
42
|
|
|
44
|
-
#
|
|
45
|
-
result = await router.route("/dev
|
|
46
|
-
# → {type: "
|
|
43
|
+
# Skill invocation
|
|
44
|
+
result = await router.route("/dev")
|
|
45
|
+
# → {type: "skill", skill: "dev", args: "", instruction: "Use Skill tool..."}
|
|
47
46
|
|
|
48
|
-
#
|
|
47
|
+
# Keyword to skill
|
|
49
48
|
result = await router.route("commit")
|
|
50
|
-
# → {type: "
|
|
49
|
+
# → {type: "skill", skill: "dev", args: "commit", instruction: "Use Skill tool..."}
|
|
51
50
|
|
|
52
51
|
# Natural language
|
|
53
52
|
result = await router.route("I want to commit my changes")
|
|
54
|
-
# → {type: "
|
|
53
|
+
# → {type: "skill", skill: "dev", args: "commit", reasoning: "..."}
|
|
55
54
|
"""
|
|
56
55
|
|
|
57
56
|
def __init__(self, preferences_path: str | None = None):
|
|
@@ -67,38 +66,47 @@ class HybridRouter:
|
|
|
67
66
|
self.smart_router = SmartRouter()
|
|
68
67
|
self.preferences: dict[str, RoutingPreference] = {}
|
|
69
68
|
|
|
70
|
-
#
|
|
71
|
-
self.
|
|
72
|
-
# Dev commands
|
|
73
|
-
"commit": "
|
|
74
|
-
"review": "
|
|
75
|
-
"review-pr": "
|
|
76
|
-
"refactor": "
|
|
77
|
-
"perf": "
|
|
78
|
-
"perf-audit": "
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
|
|
86
|
-
"
|
|
87
|
-
|
|
88
|
-
"
|
|
89
|
-
|
|
90
|
-
"
|
|
91
|
-
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
"
|
|
100
|
-
"
|
|
101
|
-
|
|
69
|
+
# Keyword to skill mapping: keyword → (skill_name, args)
|
|
70
|
+
self._keyword_to_skill = {
|
|
71
|
+
# Dev commands → /dev skill
|
|
72
|
+
"commit": ("dev", "commit"),
|
|
73
|
+
"review": ("dev", "review"),
|
|
74
|
+
"review-pr": ("dev", "review"),
|
|
75
|
+
"refactor": ("dev", "refactor"),
|
|
76
|
+
"perf": ("dev", "perf-audit"),
|
|
77
|
+
"perf-audit": ("dev", "perf-audit"),
|
|
78
|
+
"debug": ("dev", "debug"),
|
|
79
|
+
# Testing commands → /testing skill
|
|
80
|
+
"test": ("testing", "run"),
|
|
81
|
+
"tests": ("testing", "run"),
|
|
82
|
+
"coverage": ("testing", "coverage"),
|
|
83
|
+
"generate-tests": ("testing", "gen"),
|
|
84
|
+
"test-gen": ("testing", "gen"),
|
|
85
|
+
"benchmark": ("testing", "benchmark"),
|
|
86
|
+
# Learning commands → /learning skill
|
|
87
|
+
"evaluate": ("learning", "evaluate"),
|
|
88
|
+
"patterns": ("learning", "patterns"),
|
|
89
|
+
"improve": ("learning", "improve"),
|
|
90
|
+
# Workflow commands → /workflows skill
|
|
91
|
+
"security": ("workflows", "run security-audit"),
|
|
92
|
+
"security-audit": ("workflows", "run security-audit"),
|
|
93
|
+
"bug-predict": ("workflows", "run bug-predict"),
|
|
94
|
+
"bugs": ("workflows", "run bug-predict"),
|
|
95
|
+
"perf-workflow": ("workflows", "run perf-audit"),
|
|
96
|
+
# Context commands → /context skill
|
|
97
|
+
"status": ("context", "status"),
|
|
98
|
+
"memory": ("context", "memory"),
|
|
99
|
+
"state": ("context", "state"),
|
|
100
|
+
# Doc commands → /docs skill
|
|
101
|
+
"explain": ("docs", "explain"),
|
|
102
|
+
"document": ("docs", "generate"),
|
|
103
|
+
"overview": ("docs", "overview"),
|
|
104
|
+
# Plan commands → /plan skill
|
|
105
|
+
"plan": ("plan", ""),
|
|
106
|
+
"tdd": ("plan", "tdd"),
|
|
107
|
+
# Release commands → /release skill
|
|
108
|
+
"release": ("release", "prep"),
|
|
109
|
+
"ship": ("release", "prep"),
|
|
102
110
|
}
|
|
103
111
|
|
|
104
112
|
# Hub descriptions for disambiguation
|
|
@@ -126,9 +134,22 @@ class HybridRouter:
|
|
|
126
134
|
data = yaml.safe_load(f) or {}
|
|
127
135
|
|
|
128
136
|
for keyword, pref_data in data.get("preferences", {}).items():
|
|
137
|
+
# Handle backward compatibility: old format had "slash_command"
|
|
138
|
+
if "slash_command" in pref_data:
|
|
139
|
+
# Migrate old format: "/dev commit" → skill="dev", args="commit"
|
|
140
|
+
slash_cmd = pref_data["slash_command"].lstrip("/")
|
|
141
|
+
parts = slash_cmd.split(maxsplit=1)
|
|
142
|
+
skill = parts[0] if parts else "help"
|
|
143
|
+
args = parts[1] if len(parts) > 1 else ""
|
|
144
|
+
else:
|
|
145
|
+
# New format
|
|
146
|
+
skill = pref_data["skill"]
|
|
147
|
+
args = pref_data.get("args", "")
|
|
148
|
+
|
|
129
149
|
self.preferences[keyword] = RoutingPreference(
|
|
130
150
|
keyword=keyword,
|
|
131
|
-
|
|
151
|
+
skill=skill,
|
|
152
|
+
args=args,
|
|
132
153
|
usage_count=pref_data.get("usage_count", 0),
|
|
133
154
|
confidence=pref_data.get("confidence", 1.0),
|
|
134
155
|
)
|
|
@@ -142,7 +163,8 @@ class HybridRouter:
|
|
|
142
163
|
data = {
|
|
143
164
|
"preferences": {
|
|
144
165
|
pref.keyword: {
|
|
145
|
-
"
|
|
166
|
+
"skill": pref.skill,
|
|
167
|
+
"args": pref.args,
|
|
146
168
|
"usage_count": pref.usage_count,
|
|
147
169
|
"confidence": pref.confidence,
|
|
148
170
|
}
|
|
@@ -182,82 +204,83 @@ class HybridRouter:
|
|
|
182
204
|
return await self._route_natural_language(user_input, context)
|
|
183
205
|
|
|
184
206
|
def _route_slash_command(self, command: str) -> dict[str, Any]:
|
|
185
|
-
"""Route slash command
|
|
207
|
+
"""Route slash command to skill invocation.
|
|
186
208
|
|
|
187
209
|
Args:
|
|
188
|
-
command: Slash command like "/dev commit"
|
|
210
|
+
command: Slash command like "/dev" or "/dev commit"
|
|
189
211
|
|
|
190
212
|
Returns:
|
|
191
|
-
|
|
213
|
+
Skill invocation instructions
|
|
192
214
|
"""
|
|
193
215
|
parts = command[1:].split(maxsplit=1) # Remove leading /
|
|
194
|
-
|
|
195
|
-
|
|
216
|
+
skill = parts[0] if parts else "help"
|
|
217
|
+
args = parts[1] if len(parts) > 1 else ""
|
|
196
218
|
|
|
197
219
|
return {
|
|
198
|
-
"type": "
|
|
199
|
-
"
|
|
200
|
-
"
|
|
220
|
+
"type": "skill",
|
|
221
|
+
"skill": skill,
|
|
222
|
+
"args": args,
|
|
201
223
|
"original": command,
|
|
202
224
|
"confidence": 1.0,
|
|
225
|
+
"instruction": f"Use Skill tool with skill='{skill}'" + (f", args='{args}'" if args else ""),
|
|
203
226
|
}
|
|
204
227
|
|
|
205
228
|
def _infer_command(self, keyword: str) -> dict[str, Any] | None:
|
|
206
|
-
"""Infer
|
|
229
|
+
"""Infer skill invocation from keyword or short phrase.
|
|
207
230
|
|
|
208
231
|
Args:
|
|
209
232
|
keyword: Single word or short phrase
|
|
210
233
|
|
|
211
234
|
Returns:
|
|
212
|
-
|
|
235
|
+
Skill invocation instructions if inference successful, None otherwise
|
|
213
236
|
"""
|
|
214
237
|
keyword_lower = keyword.lower().strip()
|
|
215
238
|
|
|
216
239
|
# Check learned preferences first
|
|
217
240
|
if keyword_lower in self.preferences:
|
|
218
241
|
pref = self.preferences[keyword_lower]
|
|
219
|
-
slash_cmd = pref.slash_command
|
|
220
242
|
|
|
221
243
|
# Update usage count
|
|
222
244
|
pref.usage_count += 1
|
|
223
245
|
self._save_preferences()
|
|
224
246
|
|
|
225
|
-
return
|
|
247
|
+
return {
|
|
248
|
+
"type": "skill",
|
|
249
|
+
"skill": pref.skill,
|
|
250
|
+
"args": pref.args,
|
|
251
|
+
"original": keyword,
|
|
252
|
+
"confidence": pref.confidence,
|
|
253
|
+
"source": "learned",
|
|
254
|
+
"instruction": f"Use Skill tool with skill='{pref.skill}'" + (f", args='{pref.args}'" if pref.args else ""),
|
|
255
|
+
}
|
|
226
256
|
|
|
227
|
-
# Check built-in
|
|
228
|
-
if keyword_lower in self.
|
|
229
|
-
|
|
230
|
-
return
|
|
257
|
+
# Check built-in keyword map
|
|
258
|
+
if keyword_lower in self._keyword_to_skill:
|
|
259
|
+
skill, args = self._keyword_to_skill[keyword_lower]
|
|
260
|
+
return {
|
|
261
|
+
"type": "skill",
|
|
262
|
+
"skill": skill,
|
|
263
|
+
"args": args,
|
|
264
|
+
"original": keyword,
|
|
265
|
+
"confidence": 0.9,
|
|
266
|
+
"source": "builtin",
|
|
267
|
+
"instruction": f"Use Skill tool with skill='{skill}'" + (f", args='{args}'" if args else ""),
|
|
268
|
+
}
|
|
231
269
|
|
|
232
270
|
# Check for hub names (show hub menu)
|
|
233
271
|
if keyword_lower in self._hub_descriptions:
|
|
234
272
|
return {
|
|
235
|
-
"type": "
|
|
236
|
-
"
|
|
273
|
+
"type": "skill",
|
|
274
|
+
"skill": keyword_lower,
|
|
275
|
+
"args": "",
|
|
237
276
|
"original": keyword,
|
|
238
277
|
"confidence": 1.0,
|
|
278
|
+
"source": "hub",
|
|
279
|
+
"instruction": f"Use Skill tool with skill='{keyword_lower}'",
|
|
239
280
|
}
|
|
240
281
|
|
|
241
282
|
return None
|
|
242
283
|
|
|
243
|
-
def _parse_inferred(
|
|
244
|
-
self, slash_cmd: str, original: str, confidence: float, source: str
|
|
245
|
-
) -> dict[str, Any]:
|
|
246
|
-
"""Parse inferred slash command."""
|
|
247
|
-
parts = slash_cmd[1:].split(maxsplit=1) # Remove leading /
|
|
248
|
-
hub = parts[0] if parts else "help"
|
|
249
|
-
subcommand = parts[1] if len(parts) > 1 else None
|
|
250
|
-
|
|
251
|
-
return {
|
|
252
|
-
"type": "inferred",
|
|
253
|
-
"hub": hub,
|
|
254
|
-
"command": subcommand,
|
|
255
|
-
"original": original,
|
|
256
|
-
"slash_equivalent": slash_cmd,
|
|
257
|
-
"confidence": confidence,
|
|
258
|
-
"source": source, # learned, builtin
|
|
259
|
-
}
|
|
260
|
-
|
|
261
284
|
async def _route_natural_language(
|
|
262
285
|
self, text: str, context: dict[str, Any] | None = None
|
|
263
286
|
) -> dict[str, Any]:
|
|
@@ -268,52 +291,59 @@ class HybridRouter:
|
|
|
268
291
|
context: Optional context
|
|
269
292
|
|
|
270
293
|
Returns:
|
|
271
|
-
|
|
294
|
+
Skill invocation instructions based on SmartRouter decision
|
|
272
295
|
"""
|
|
273
296
|
# Use SmartRouter for classification
|
|
274
297
|
decision = await self.smart_router.route(text, context)
|
|
275
298
|
|
|
276
|
-
# Map workflow to
|
|
277
|
-
|
|
299
|
+
# Map workflow to skill invocation
|
|
300
|
+
skill, args = self._workflow_to_skill(decision.primary_workflow)
|
|
278
301
|
|
|
279
302
|
return {
|
|
280
|
-
"type": "
|
|
303
|
+
"type": "skill",
|
|
304
|
+
"skill": skill,
|
|
305
|
+
"args": args,
|
|
281
306
|
"workflow": decision.primary_workflow,
|
|
282
307
|
"secondary_workflows": decision.secondary_workflows,
|
|
283
|
-
"slash_equivalent": slash_equivalent,
|
|
284
308
|
"confidence": decision.confidence,
|
|
285
309
|
"reasoning": decision.reasoning,
|
|
286
310
|
"original": text,
|
|
311
|
+
"source": "natural_language",
|
|
312
|
+
"instruction": f"Use Skill tool with skill='{skill}'" + (f", args='{args}'" if args else ""),
|
|
287
313
|
}
|
|
288
314
|
|
|
289
|
-
def
|
|
290
|
-
"""Map workflow name to
|
|
315
|
+
def _workflow_to_skill(self, workflow: str) -> tuple[str, str]:
|
|
316
|
+
"""Map workflow name to skill invocation.
|
|
291
317
|
|
|
292
318
|
Args:
|
|
293
319
|
workflow: Workflow name (e.g., "security-audit")
|
|
294
320
|
|
|
295
321
|
Returns:
|
|
296
|
-
|
|
322
|
+
Tuple of (skill_name, args)
|
|
297
323
|
"""
|
|
298
|
-
# Workflow to
|
|
324
|
+
# Workflow to skill mapping
|
|
299
325
|
workflow_map = {
|
|
300
|
-
"security-audit": "
|
|
301
|
-
"bug-predict": "
|
|
302
|
-
"code-review": "
|
|
303
|
-
"test-gen": "
|
|
304
|
-
"perf-audit": "
|
|
305
|
-
"commit": "
|
|
306
|
-
"refactor": "
|
|
326
|
+
"security-audit": ("workflows", "run security-audit"),
|
|
327
|
+
"bug-predict": ("workflows", "run bug-predict"),
|
|
328
|
+
"code-review": ("dev", "review"),
|
|
329
|
+
"test-gen": ("testing", "gen"),
|
|
330
|
+
"perf-audit": ("workflows", "run perf-audit"),
|
|
331
|
+
"commit": ("dev", "commit"),
|
|
332
|
+
"refactor": ("dev", "refactor"),
|
|
333
|
+
"debug": ("dev", "debug"),
|
|
334
|
+
"explain": ("docs", "explain"),
|
|
335
|
+
"plan": ("plan", ""),
|
|
307
336
|
}
|
|
308
337
|
|
|
309
|
-
return workflow_map.get(workflow,
|
|
338
|
+
return workflow_map.get(workflow, ("workflows", f"run {workflow}"))
|
|
310
339
|
|
|
311
|
-
def learn_preference(self, keyword: str,
|
|
340
|
+
def learn_preference(self, keyword: str, skill: str, args: str = "") -> None:
|
|
312
341
|
"""Learn user's routing preference.
|
|
313
342
|
|
|
314
343
|
Args:
|
|
315
344
|
keyword: Keyword user typed
|
|
316
|
-
|
|
345
|
+
skill: Skill name that was invoked
|
|
346
|
+
args: Arguments passed to skill
|
|
317
347
|
"""
|
|
318
348
|
if keyword in self.preferences:
|
|
319
349
|
pref = self.preferences[keyword]
|
|
@@ -323,7 +353,8 @@ class HybridRouter:
|
|
|
323
353
|
else:
|
|
324
354
|
self.preferences[keyword] = RoutingPreference(
|
|
325
355
|
keyword=keyword,
|
|
326
|
-
|
|
356
|
+
skill=skill,
|
|
357
|
+
args=args,
|
|
327
358
|
usage_count=1,
|
|
328
359
|
confidence=0.8,
|
|
329
360
|
)
|
|
@@ -337,20 +368,21 @@ class HybridRouter:
|
|
|
337
368
|
partial: Partial command input
|
|
338
369
|
|
|
339
370
|
Returns:
|
|
340
|
-
List of suggested
|
|
371
|
+
List of suggested keywords and skills
|
|
341
372
|
"""
|
|
342
373
|
suggestions = []
|
|
343
374
|
partial_lower = partial.lower()
|
|
344
375
|
|
|
345
|
-
# Suggest
|
|
346
|
-
for
|
|
347
|
-
if partial_lower in
|
|
348
|
-
|
|
376
|
+
# Suggest keywords
|
|
377
|
+
for keyword in self._keyword_to_skill.keys():
|
|
378
|
+
if partial_lower in keyword:
|
|
379
|
+
skill, args = self._keyword_to_skill[keyword]
|
|
380
|
+
suggestions.append(f"{keyword} → /{skill} {args}".strip())
|
|
349
381
|
|
|
350
382
|
# Suggest learned preferences
|
|
351
383
|
for pref in self.preferences.values():
|
|
352
384
|
if partial_lower in pref.keyword.lower():
|
|
353
|
-
suggestions.append(f"{pref.keyword} → {pref.
|
|
385
|
+
suggestions.append(f"{pref.keyword} → /{pref.skill} {pref.args}".strip())
|
|
354
386
|
|
|
355
387
|
return suggestions[:5] # Top 5 suggestions
|
|
356
388
|
|
empathy_os/cli_unified.py
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
"""Unified CLI for Empathy Framework
|
|
2
2
|
|
|
3
|
+
DEPRECATED: This module is deprecated as of v5.0.0.
|
|
4
|
+
Use the minimal CLI instead: `empathy` (empathy_os.cli_minimal)
|
|
5
|
+
|
|
6
|
+
The minimal CLI provides:
|
|
7
|
+
- `empathy workflow list|info|run` - Workflow management
|
|
8
|
+
- `empathy telemetry show|savings|export` - Usage tracking
|
|
9
|
+
- `empathy provider show|set` - Provider configuration
|
|
10
|
+
- `empathy validate` - Configuration validation
|
|
11
|
+
|
|
12
|
+
For interactive features, use Claude Code slash commands:
|
|
13
|
+
- /dev, /testing, /docs, /release, /help
|
|
14
|
+
|
|
15
|
+
Migration guide: https://smartaimemory.com/framework-docs/migration/cli/
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
3
19
|
A simplified, intelligent CLI using Socratic questioning.
|
|
4
20
|
|
|
5
21
|
Usage:
|
|
@@ -14,6 +30,15 @@ Copyright 2025 Smart-AI-Memory
|
|
|
14
30
|
Licensed under Fair Source License 0.9
|
|
15
31
|
"""
|
|
16
32
|
|
|
33
|
+
import warnings
|
|
34
|
+
|
|
35
|
+
warnings.warn(
|
|
36
|
+
"empathy-unified CLI is deprecated. Use 'empathy' (cli_minimal) instead. "
|
|
37
|
+
"See: https://smartaimemory.com/framework-docs/reference/cli-reference/",
|
|
38
|
+
DeprecationWarning,
|
|
39
|
+
stacklevel=2,
|
|
40
|
+
)
|
|
41
|
+
|
|
17
42
|
import json
|
|
18
43
|
import subprocess
|
|
19
44
|
import sys
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Agent Coordination Dashboard.
|
|
2
|
+
|
|
3
|
+
Web-based monitoring dashboard for all 6 agent coordination patterns.
|
|
4
|
+
|
|
5
|
+
Usage (Standalone - Direct Redis Access):
|
|
6
|
+
>>> from empathy_os.dashboard import run_standalone_dashboard
|
|
7
|
+
>>> run_standalone_dashboard(host="0.0.0.0", port=8080)
|
|
8
|
+
|
|
9
|
+
Usage (Simple Server - Uses Telemetry API):
|
|
10
|
+
>>> from empathy_os.dashboard import run_simple_dashboard
|
|
11
|
+
>>> run_simple_dashboard(host="0.0.0.0", port=8080)
|
|
12
|
+
|
|
13
|
+
Usage (FastAPI - Requires fastapi and uvicorn):
|
|
14
|
+
>>> from empathy_os.dashboard import run_dashboard
|
|
15
|
+
>>> run_dashboard(host="0.0.0.0", port=8080)
|
|
16
|
+
|
|
17
|
+
Features:
|
|
18
|
+
- Real-time agent status monitoring (Pattern 1)
|
|
19
|
+
- Coordination signal viewer (Pattern 2)
|
|
20
|
+
- Event stream monitor (Pattern 4)
|
|
21
|
+
- Approval request manager (Pattern 5)
|
|
22
|
+
- Quality feedback analytics (Pattern 6)
|
|
23
|
+
- Auto-refresh every 5 seconds
|
|
24
|
+
|
|
25
|
+
Copyright 2025 Smart-AI-Memory
|
|
26
|
+
Licensed under Fair Source License 0.9
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
# Standalone server - reads directly from Redis
|
|
30
|
+
from .standalone_server import run_standalone_dashboard
|
|
31
|
+
|
|
32
|
+
# Simple server - uses telemetry API classes
|
|
33
|
+
from .simple_server import run_simple_dashboard
|
|
34
|
+
|
|
35
|
+
# Optional FastAPI version (requires dependencies)
|
|
36
|
+
try:
|
|
37
|
+
from .app import app, run_dashboard
|
|
38
|
+
|
|
39
|
+
__all__ = ["app", "run_dashboard", "run_simple_dashboard", "run_standalone_dashboard"]
|
|
40
|
+
except ImportError:
|
|
41
|
+
# FastAPI not installed
|
|
42
|
+
__all__ = ["run_simple_dashboard", "run_standalone_dashboard"]
|