empathy-framework 5.2.1__py3-none-any.whl → 5.4.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 (480) hide show
  1. empathy_framework-5.4.0.dist-info/METADATA +47 -0
  2. empathy_framework-5.4.0.dist-info/RECORD +8 -0
  3. {empathy_framework-5.2.1.dist-info → empathy_framework-5.4.0.dist-info}/top_level.txt +0 -1
  4. empathy_healthcare_plugin/__init__.py +12 -11
  5. empathy_llm_toolkit/__init__.py +12 -26
  6. empathy_os/__init__.py +12 -356
  7. empathy_software_plugin/__init__.py +12 -11
  8. empathy_framework-5.2.1.dist-info/METADATA +0 -1002
  9. empathy_framework-5.2.1.dist-info/RECORD +0 -478
  10. empathy_framework-5.2.1.dist-info/entry_points.txt +0 -26
  11. empathy_framework-5.2.1.dist-info/licenses/LICENSE +0 -201
  12. empathy_framework-5.2.1.dist-info/licenses/LICENSE_CHANGE_ANNOUNCEMENT.md +0 -101
  13. empathy_healthcare_plugin/monitors/__init__.py +0 -9
  14. empathy_healthcare_plugin/monitors/clinical_protocol_monitor.py +0 -315
  15. empathy_healthcare_plugin/monitors/monitoring/__init__.py +0 -44
  16. empathy_healthcare_plugin/monitors/monitoring/protocol_checker.py +0 -300
  17. empathy_healthcare_plugin/monitors/monitoring/protocol_loader.py +0 -214
  18. empathy_healthcare_plugin/monitors/monitoring/sensor_parsers.py +0 -306
  19. empathy_healthcare_plugin/monitors/monitoring/trajectory_analyzer.py +0 -389
  20. empathy_healthcare_plugin/protocols/cardiac.json +0 -93
  21. empathy_healthcare_plugin/protocols/post_operative.json +0 -92
  22. empathy_healthcare_plugin/protocols/respiratory.json +0 -92
  23. empathy_healthcare_plugin/protocols/sepsis.json +0 -141
  24. empathy_llm_toolkit/README.md +0 -553
  25. empathy_llm_toolkit/agent_factory/__init__.py +0 -53
  26. empathy_llm_toolkit/agent_factory/adapters/__init__.py +0 -85
  27. empathy_llm_toolkit/agent_factory/adapters/autogen_adapter.py +0 -312
  28. empathy_llm_toolkit/agent_factory/adapters/crewai_adapter.py +0 -483
  29. empathy_llm_toolkit/agent_factory/adapters/haystack_adapter.py +0 -298
  30. empathy_llm_toolkit/agent_factory/adapters/langchain_adapter.py +0 -362
  31. empathy_llm_toolkit/agent_factory/adapters/langgraph_adapter.py +0 -333
  32. empathy_llm_toolkit/agent_factory/adapters/native.py +0 -228
  33. empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +0 -423
  34. empathy_llm_toolkit/agent_factory/base.py +0 -305
  35. empathy_llm_toolkit/agent_factory/crews/__init__.py +0 -67
  36. empathy_llm_toolkit/agent_factory/crews/code_review.py +0 -1113
  37. empathy_llm_toolkit/agent_factory/crews/health_check.py +0 -1262
  38. empathy_llm_toolkit/agent_factory/crews/refactoring.py +0 -1128
  39. empathy_llm_toolkit/agent_factory/crews/security_audit.py +0 -1018
  40. empathy_llm_toolkit/agent_factory/decorators.py +0 -287
  41. empathy_llm_toolkit/agent_factory/factory.py +0 -558
  42. empathy_llm_toolkit/agent_factory/framework.py +0 -193
  43. empathy_llm_toolkit/agent_factory/memory_integration.py +0 -328
  44. empathy_llm_toolkit/agent_factory/resilient.py +0 -320
  45. empathy_llm_toolkit/agents_md/__init__.py +0 -22
  46. empathy_llm_toolkit/agents_md/loader.py +0 -218
  47. empathy_llm_toolkit/agents_md/parser.py +0 -271
  48. empathy_llm_toolkit/agents_md/registry.py +0 -307
  49. empathy_llm_toolkit/claude_memory.py +0 -466
  50. empathy_llm_toolkit/cli/__init__.py +0 -8
  51. empathy_llm_toolkit/cli/sync_claude.py +0 -487
  52. empathy_llm_toolkit/code_health.py +0 -1313
  53. empathy_llm_toolkit/commands/__init__.py +0 -51
  54. empathy_llm_toolkit/commands/context.py +0 -375
  55. empathy_llm_toolkit/commands/loader.py +0 -301
  56. empathy_llm_toolkit/commands/models.py +0 -231
  57. empathy_llm_toolkit/commands/parser.py +0 -371
  58. empathy_llm_toolkit/commands/registry.py +0 -429
  59. empathy_llm_toolkit/config/__init__.py +0 -29
  60. empathy_llm_toolkit/config/unified.py +0 -291
  61. empathy_llm_toolkit/context/__init__.py +0 -22
  62. empathy_llm_toolkit/context/compaction.py +0 -455
  63. empathy_llm_toolkit/context/manager.py +0 -434
  64. empathy_llm_toolkit/contextual_patterns.py +0 -361
  65. empathy_llm_toolkit/core.py +0 -907
  66. empathy_llm_toolkit/git_pattern_extractor.py +0 -435
  67. empathy_llm_toolkit/hooks/__init__.py +0 -24
  68. empathy_llm_toolkit/hooks/config.py +0 -306
  69. empathy_llm_toolkit/hooks/executor.py +0 -289
  70. empathy_llm_toolkit/hooks/registry.py +0 -302
  71. empathy_llm_toolkit/hooks/scripts/__init__.py +0 -39
  72. empathy_llm_toolkit/hooks/scripts/evaluate_session.py +0 -201
  73. empathy_llm_toolkit/hooks/scripts/first_time_init.py +0 -285
  74. empathy_llm_toolkit/hooks/scripts/pre_compact.py +0 -207
  75. empathy_llm_toolkit/hooks/scripts/session_end.py +0 -183
  76. empathy_llm_toolkit/hooks/scripts/session_start.py +0 -163
  77. empathy_llm_toolkit/hooks/scripts/suggest_compact.py +0 -225
  78. empathy_llm_toolkit/learning/__init__.py +0 -30
  79. empathy_llm_toolkit/learning/evaluator.py +0 -438
  80. empathy_llm_toolkit/learning/extractor.py +0 -514
  81. empathy_llm_toolkit/learning/storage.py +0 -560
  82. empathy_llm_toolkit/levels.py +0 -227
  83. empathy_llm_toolkit/pattern_confidence.py +0 -414
  84. empathy_llm_toolkit/pattern_resolver.py +0 -272
  85. empathy_llm_toolkit/pattern_summary.py +0 -350
  86. empathy_llm_toolkit/providers.py +0 -967
  87. empathy_llm_toolkit/routing/__init__.py +0 -32
  88. empathy_llm_toolkit/routing/model_router.py +0 -362
  89. empathy_llm_toolkit/security/IMPLEMENTATION_SUMMARY.md +0 -413
  90. empathy_llm_toolkit/security/PHASE2_COMPLETE.md +0 -384
  91. empathy_llm_toolkit/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +0 -271
  92. empathy_llm_toolkit/security/QUICK_REFERENCE.md +0 -316
  93. empathy_llm_toolkit/security/README.md +0 -262
  94. empathy_llm_toolkit/security/__init__.py +0 -62
  95. empathy_llm_toolkit/security/audit_logger.py +0 -929
  96. empathy_llm_toolkit/security/audit_logger_example.py +0 -152
  97. empathy_llm_toolkit/security/pii_scrubber.py +0 -640
  98. empathy_llm_toolkit/security/secrets_detector.py +0 -678
  99. empathy_llm_toolkit/security/secrets_detector_example.py +0 -304
  100. empathy_llm_toolkit/security/secure_memdocs.py +0 -1192
  101. empathy_llm_toolkit/security/secure_memdocs_example.py +0 -278
  102. empathy_llm_toolkit/session_status.py +0 -745
  103. empathy_llm_toolkit/state.py +0 -246
  104. empathy_llm_toolkit/utils/__init__.py +0 -5
  105. empathy_llm_toolkit/utils/tokens.py +0 -349
  106. empathy_os/adaptive/__init__.py +0 -13
  107. empathy_os/adaptive/task_complexity.py +0 -127
  108. empathy_os/agent_monitoring.py +0 -414
  109. empathy_os/cache/__init__.py +0 -117
  110. empathy_os/cache/base.py +0 -166
  111. empathy_os/cache/dependency_manager.py +0 -256
  112. empathy_os/cache/hash_only.py +0 -251
  113. empathy_os/cache/hybrid.py +0 -453
  114. empathy_os/cache/storage.py +0 -285
  115. empathy_os/cache_monitor.py +0 -356
  116. empathy_os/cache_stats.py +0 -298
  117. empathy_os/cli/__init__.py +0 -152
  118. empathy_os/cli/__main__.py +0 -12
  119. empathy_os/cli/commands/__init__.py +0 -1
  120. empathy_os/cli/commands/batch.py +0 -256
  121. empathy_os/cli/commands/cache.py +0 -248
  122. empathy_os/cli/commands/help.py +0 -331
  123. empathy_os/cli/commands/info.py +0 -140
  124. empathy_os/cli/commands/inspect.py +0 -436
  125. empathy_os/cli/commands/inspection.py +0 -57
  126. empathy_os/cli/commands/memory.py +0 -48
  127. empathy_os/cli/commands/metrics.py +0 -92
  128. empathy_os/cli/commands/orchestrate.py +0 -184
  129. empathy_os/cli/commands/patterns.py +0 -207
  130. empathy_os/cli/commands/profiling.py +0 -198
  131. empathy_os/cli/commands/provider.py +0 -98
  132. empathy_os/cli/commands/routing.py +0 -285
  133. empathy_os/cli/commands/setup.py +0 -96
  134. empathy_os/cli/commands/status.py +0 -235
  135. empathy_os/cli/commands/sync.py +0 -166
  136. empathy_os/cli/commands/tier.py +0 -121
  137. empathy_os/cli/commands/utilities.py +0 -114
  138. empathy_os/cli/commands/workflow.py +0 -575
  139. empathy_os/cli/core.py +0 -32
  140. empathy_os/cli/parsers/__init__.py +0 -68
  141. empathy_os/cli/parsers/batch.py +0 -118
  142. empathy_os/cli/parsers/cache 2.py +0 -65
  143. empathy_os/cli/parsers/cache.py +0 -65
  144. empathy_os/cli/parsers/help.py +0 -41
  145. empathy_os/cli/parsers/info.py +0 -26
  146. empathy_os/cli/parsers/inspect.py +0 -66
  147. empathy_os/cli/parsers/metrics.py +0 -42
  148. empathy_os/cli/parsers/orchestrate.py +0 -61
  149. empathy_os/cli/parsers/patterns.py +0 -54
  150. empathy_os/cli/parsers/provider.py +0 -40
  151. empathy_os/cli/parsers/routing.py +0 -110
  152. empathy_os/cli/parsers/setup.py +0 -42
  153. empathy_os/cli/parsers/status.py +0 -47
  154. empathy_os/cli/parsers/sync.py +0 -31
  155. empathy_os/cli/parsers/tier.py +0 -33
  156. empathy_os/cli/parsers/workflow.py +0 -77
  157. empathy_os/cli/utils/__init__.py +0 -1
  158. empathy_os/cli/utils/data.py +0 -242
  159. empathy_os/cli/utils/helpers.py +0 -68
  160. empathy_os/cli_legacy.py +0 -3957
  161. empathy_os/cli_minimal.py +0 -1159
  162. empathy_os/cli_router 2.py +0 -416
  163. empathy_os/cli_router.py +0 -437
  164. empathy_os/cli_unified.py +0 -814
  165. empathy_os/config/__init__.py +0 -66
  166. empathy_os/config/xml_config.py +0 -286
  167. empathy_os/config.py +0 -532
  168. empathy_os/coordination.py +0 -870
  169. empathy_os/core.py +0 -1511
  170. empathy_os/core_modules/__init__.py +0 -15
  171. empathy_os/cost_tracker.py +0 -626
  172. empathy_os/dashboard/__init__.py +0 -41
  173. empathy_os/dashboard/app 2.py +0 -512
  174. empathy_os/dashboard/app.py +0 -512
  175. empathy_os/dashboard/simple_server 2.py +0 -403
  176. empathy_os/dashboard/simple_server.py +0 -403
  177. empathy_os/dashboard/standalone_server 2.py +0 -536
  178. empathy_os/dashboard/standalone_server.py +0 -547
  179. empathy_os/discovery.py +0 -306
  180. empathy_os/emergence.py +0 -306
  181. empathy_os/exceptions.py +0 -123
  182. empathy_os/feedback_loops.py +0 -373
  183. empathy_os/hot_reload/README.md +0 -473
  184. empathy_os/hot_reload/__init__.py +0 -62
  185. empathy_os/hot_reload/config.py +0 -83
  186. empathy_os/hot_reload/integration.py +0 -229
  187. empathy_os/hot_reload/reloader.py +0 -298
  188. empathy_os/hot_reload/watcher.py +0 -183
  189. empathy_os/hot_reload/websocket.py +0 -177
  190. empathy_os/levels.py +0 -577
  191. empathy_os/leverage_points.py +0 -441
  192. empathy_os/logging_config.py +0 -261
  193. empathy_os/mcp/__init__.py +0 -10
  194. empathy_os/mcp/server.py +0 -506
  195. empathy_os/memory/__init__.py +0 -237
  196. empathy_os/memory/claude_memory.py +0 -469
  197. empathy_os/memory/config.py +0 -224
  198. empathy_os/memory/control_panel.py +0 -1290
  199. empathy_os/memory/control_panel_support.py +0 -145
  200. empathy_os/memory/cross_session.py +0 -845
  201. empathy_os/memory/edges.py +0 -179
  202. empathy_os/memory/encryption.py +0 -159
  203. empathy_os/memory/file_session.py +0 -770
  204. empathy_os/memory/graph.py +0 -570
  205. empathy_os/memory/long_term.py +0 -913
  206. empathy_os/memory/long_term_types.py +0 -99
  207. empathy_os/memory/mixins/__init__.py +0 -25
  208. empathy_os/memory/mixins/backend_init_mixin.py +0 -244
  209. empathy_os/memory/mixins/capabilities_mixin.py +0 -199
  210. empathy_os/memory/mixins/handoff_mixin.py +0 -208
  211. empathy_os/memory/mixins/lifecycle_mixin.py +0 -49
  212. empathy_os/memory/mixins/long_term_mixin.py +0 -352
  213. empathy_os/memory/mixins/promotion_mixin.py +0 -109
  214. empathy_os/memory/mixins/short_term_mixin.py +0 -182
  215. empathy_os/memory/nodes.py +0 -179
  216. empathy_os/memory/redis_bootstrap.py +0 -540
  217. empathy_os/memory/security/__init__.py +0 -31
  218. empathy_os/memory/security/audit_logger.py +0 -932
  219. empathy_os/memory/security/pii_scrubber.py +0 -640
  220. empathy_os/memory/security/secrets_detector.py +0 -678
  221. empathy_os/memory/short_term.py +0 -2150
  222. empathy_os/memory/simple_storage.py +0 -302
  223. empathy_os/memory/storage/__init__.py +0 -15
  224. empathy_os/memory/storage_backend.py +0 -167
  225. empathy_os/memory/summary_index.py +0 -583
  226. empathy_os/memory/types.py +0 -441
  227. empathy_os/memory/unified.py +0 -182
  228. empathy_os/meta_workflows/__init__.py +0 -74
  229. empathy_os/meta_workflows/agent_creator.py +0 -248
  230. empathy_os/meta_workflows/builtin_templates.py +0 -567
  231. empathy_os/meta_workflows/cli_commands/__init__.py +0 -56
  232. empathy_os/meta_workflows/cli_commands/agent_commands.py +0 -321
  233. empathy_os/meta_workflows/cli_commands/analytics_commands.py +0 -442
  234. empathy_os/meta_workflows/cli_commands/config_commands.py +0 -232
  235. empathy_os/meta_workflows/cli_commands/memory_commands.py +0 -182
  236. empathy_os/meta_workflows/cli_commands/template_commands.py +0 -354
  237. empathy_os/meta_workflows/cli_commands/workflow_commands.py +0 -382
  238. empathy_os/meta_workflows/cli_meta_workflows.py +0 -59
  239. empathy_os/meta_workflows/form_engine.py +0 -292
  240. empathy_os/meta_workflows/intent_detector.py +0 -409
  241. empathy_os/meta_workflows/models.py +0 -569
  242. empathy_os/meta_workflows/pattern_learner.py +0 -738
  243. empathy_os/meta_workflows/plan_generator.py +0 -384
  244. empathy_os/meta_workflows/session_context.py +0 -397
  245. empathy_os/meta_workflows/template_registry.py +0 -229
  246. empathy_os/meta_workflows/workflow.py +0 -984
  247. empathy_os/metrics/__init__.py +0 -12
  248. empathy_os/metrics/collector.py +0 -31
  249. empathy_os/metrics/prompt_metrics.py +0 -194
  250. empathy_os/models/__init__.py +0 -172
  251. empathy_os/models/__main__.py +0 -13
  252. empathy_os/models/adaptive_routing 2.py +0 -437
  253. empathy_os/models/adaptive_routing.py +0 -437
  254. empathy_os/models/auth_cli.py +0 -444
  255. empathy_os/models/auth_strategy.py +0 -450
  256. empathy_os/models/cli.py +0 -655
  257. empathy_os/models/empathy_executor.py +0 -354
  258. empathy_os/models/executor.py +0 -257
  259. empathy_os/models/fallback.py +0 -762
  260. empathy_os/models/provider_config.py +0 -282
  261. empathy_os/models/registry.py +0 -472
  262. empathy_os/models/tasks.py +0 -359
  263. empathy_os/models/telemetry/__init__.py +0 -71
  264. empathy_os/models/telemetry/analytics.py +0 -594
  265. empathy_os/models/telemetry/backend.py +0 -196
  266. empathy_os/models/telemetry/data_models.py +0 -431
  267. empathy_os/models/telemetry/storage.py +0 -489
  268. empathy_os/models/token_estimator.py +0 -420
  269. empathy_os/models/validation.py +0 -280
  270. empathy_os/monitoring/__init__.py +0 -52
  271. empathy_os/monitoring/alerts.py +0 -946
  272. empathy_os/monitoring/alerts_cli.py +0 -448
  273. empathy_os/monitoring/multi_backend.py +0 -271
  274. empathy_os/monitoring/otel_backend.py +0 -362
  275. empathy_os/optimization/__init__.py +0 -19
  276. empathy_os/optimization/context_optimizer.py +0 -272
  277. empathy_os/orchestration/__init__.py +0 -67
  278. empathy_os/orchestration/agent_templates.py +0 -707
  279. empathy_os/orchestration/config_store.py +0 -499
  280. empathy_os/orchestration/execution_strategies.py +0 -2111
  281. empathy_os/orchestration/meta_orchestrator.py +0 -1168
  282. empathy_os/orchestration/pattern_learner.py +0 -696
  283. empathy_os/orchestration/real_tools.py +0 -931
  284. empathy_os/pattern_cache.py +0 -187
  285. empathy_os/pattern_library.py +0 -542
  286. empathy_os/patterns/debugging/all_patterns.json +0 -81
  287. empathy_os/patterns/debugging/workflow_20260107_1770825e.json +0 -77
  288. empathy_os/patterns/refactoring_memory.json +0 -89
  289. empathy_os/persistence.py +0 -564
  290. empathy_os/platform_utils.py +0 -265
  291. empathy_os/plugins/__init__.py +0 -28
  292. empathy_os/plugins/base.py +0 -361
  293. empathy_os/plugins/registry.py +0 -268
  294. empathy_os/project_index/__init__.py +0 -32
  295. empathy_os/project_index/cli.py +0 -335
  296. empathy_os/project_index/index.py +0 -667
  297. empathy_os/project_index/models.py +0 -504
  298. empathy_os/project_index/reports.py +0 -474
  299. empathy_os/project_index/scanner.py +0 -777
  300. empathy_os/project_index/scanner_parallel 2.py +0 -291
  301. empathy_os/project_index/scanner_parallel.py +0 -291
  302. empathy_os/prompts/__init__.py +0 -61
  303. empathy_os/prompts/config.py +0 -77
  304. empathy_os/prompts/context.py +0 -177
  305. empathy_os/prompts/parser.py +0 -285
  306. empathy_os/prompts/registry.py +0 -313
  307. empathy_os/prompts/templates.py +0 -208
  308. empathy_os/redis_config.py +0 -302
  309. empathy_os/redis_memory.py +0 -799
  310. empathy_os/resilience/__init__.py +0 -56
  311. empathy_os/resilience/circuit_breaker.py +0 -256
  312. empathy_os/resilience/fallback.py +0 -179
  313. empathy_os/resilience/health.py +0 -300
  314. empathy_os/resilience/retry.py +0 -209
  315. empathy_os/resilience/timeout.py +0 -135
  316. empathy_os/routing/__init__.py +0 -43
  317. empathy_os/routing/chain_executor.py +0 -433
  318. empathy_os/routing/classifier.py +0 -217
  319. empathy_os/routing/smart_router.py +0 -234
  320. empathy_os/routing/workflow_registry.py +0 -343
  321. empathy_os/scaffolding/README.md +0 -589
  322. empathy_os/scaffolding/__init__.py +0 -35
  323. empathy_os/scaffolding/__main__.py +0 -14
  324. empathy_os/scaffolding/cli.py +0 -240
  325. empathy_os/socratic/__init__.py +0 -256
  326. empathy_os/socratic/ab_testing.py +0 -958
  327. empathy_os/socratic/blueprint.py +0 -533
  328. empathy_os/socratic/cli.py +0 -703
  329. empathy_os/socratic/collaboration.py +0 -1114
  330. empathy_os/socratic/domain_templates.py +0 -924
  331. empathy_os/socratic/embeddings.py +0 -738
  332. empathy_os/socratic/engine.py +0 -794
  333. empathy_os/socratic/explainer.py +0 -682
  334. empathy_os/socratic/feedback.py +0 -772
  335. empathy_os/socratic/forms.py +0 -629
  336. empathy_os/socratic/generator.py +0 -732
  337. empathy_os/socratic/llm_analyzer.py +0 -637
  338. empathy_os/socratic/mcp_server.py +0 -702
  339. empathy_os/socratic/session.py +0 -312
  340. empathy_os/socratic/storage.py +0 -667
  341. empathy_os/socratic/success.py +0 -730
  342. empathy_os/socratic/visual_editor.py +0 -860
  343. empathy_os/socratic/web_ui.py +0 -958
  344. empathy_os/telemetry/__init__.py +0 -39
  345. empathy_os/telemetry/agent_coordination 2.py +0 -478
  346. empathy_os/telemetry/agent_coordination.py +0 -476
  347. empathy_os/telemetry/agent_tracking 2.py +0 -350
  348. empathy_os/telemetry/agent_tracking.py +0 -348
  349. empathy_os/telemetry/approval_gates 2.py +0 -563
  350. empathy_os/telemetry/approval_gates.py +0 -551
  351. empathy_os/telemetry/cli.py +0 -1231
  352. empathy_os/telemetry/commands/__init__.py +0 -14
  353. empathy_os/telemetry/commands/dashboard_commands.py +0 -696
  354. empathy_os/telemetry/event_streaming 2.py +0 -405
  355. empathy_os/telemetry/event_streaming.py +0 -405
  356. empathy_os/telemetry/feedback_loop 2.py +0 -557
  357. empathy_os/telemetry/feedback_loop.py +0 -554
  358. empathy_os/telemetry/usage_tracker.py +0 -591
  359. empathy_os/templates.py +0 -754
  360. empathy_os/test_generator/__init__.py +0 -38
  361. empathy_os/test_generator/__main__.py +0 -14
  362. empathy_os/test_generator/cli.py +0 -234
  363. empathy_os/test_generator/generator.py +0 -355
  364. empathy_os/test_generator/risk_analyzer.py +0 -216
  365. empathy_os/tier_recommender.py +0 -384
  366. empathy_os/tools.py +0 -183
  367. empathy_os/trust/__init__.py +0 -28
  368. empathy_os/trust/circuit_breaker.py +0 -579
  369. empathy_os/trust_building.py +0 -527
  370. empathy_os/validation/__init__.py +0 -19
  371. empathy_os/validation/xml_validator.py +0 -281
  372. empathy_os/vscode_bridge 2.py +0 -173
  373. empathy_os/vscode_bridge.py +0 -173
  374. empathy_os/workflow_commands.py +0 -780
  375. empathy_os/workflow_patterns/__init__.py +0 -33
  376. empathy_os/workflow_patterns/behavior.py +0 -249
  377. empathy_os/workflow_patterns/core.py +0 -76
  378. empathy_os/workflow_patterns/output.py +0 -99
  379. empathy_os/workflow_patterns/registry.py +0 -255
  380. empathy_os/workflow_patterns/structural.py +0 -288
  381. empathy_os/workflows/__init__.py +0 -539
  382. empathy_os/workflows/autonomous_test_gen.py +0 -1268
  383. empathy_os/workflows/base.py +0 -2667
  384. empathy_os/workflows/batch_processing.py +0 -342
  385. empathy_os/workflows/bug_predict.py +0 -1084
  386. empathy_os/workflows/builder.py +0 -273
  387. empathy_os/workflows/caching.py +0 -253
  388. empathy_os/workflows/code_review.py +0 -1048
  389. empathy_os/workflows/code_review_adapters.py +0 -312
  390. empathy_os/workflows/code_review_pipeline.py +0 -722
  391. empathy_os/workflows/config.py +0 -645
  392. empathy_os/workflows/dependency_check.py +0 -644
  393. empathy_os/workflows/document_gen/__init__.py +0 -25
  394. empathy_os/workflows/document_gen/config.py +0 -30
  395. empathy_os/workflows/document_gen/report_formatter.py +0 -162
  396. empathy_os/workflows/document_gen/workflow.py +0 -1426
  397. empathy_os/workflows/document_gen.py +0 -29
  398. empathy_os/workflows/document_manager.py +0 -216
  399. empathy_os/workflows/document_manager_README.md +0 -134
  400. empathy_os/workflows/documentation_orchestrator.py +0 -1205
  401. empathy_os/workflows/history.py +0 -510
  402. empathy_os/workflows/keyboard_shortcuts/__init__.py +0 -39
  403. empathy_os/workflows/keyboard_shortcuts/generators.py +0 -391
  404. empathy_os/workflows/keyboard_shortcuts/parsers.py +0 -416
  405. empathy_os/workflows/keyboard_shortcuts/prompts.py +0 -295
  406. empathy_os/workflows/keyboard_shortcuts/schema.py +0 -193
  407. empathy_os/workflows/keyboard_shortcuts/workflow.py +0 -509
  408. empathy_os/workflows/llm_base.py +0 -363
  409. empathy_os/workflows/manage_docs.py +0 -87
  410. empathy_os/workflows/manage_docs_README.md +0 -134
  411. empathy_os/workflows/manage_documentation.py +0 -821
  412. empathy_os/workflows/new_sample_workflow1.py +0 -149
  413. empathy_os/workflows/new_sample_workflow1_README.md +0 -150
  414. empathy_os/workflows/orchestrated_health_check.py +0 -849
  415. empathy_os/workflows/orchestrated_release_prep.py +0 -600
  416. empathy_os/workflows/output.py +0 -410
  417. empathy_os/workflows/perf_audit.py +0 -863
  418. empathy_os/workflows/pr_review.py +0 -762
  419. empathy_os/workflows/progress.py +0 -779
  420. empathy_os/workflows/progress_server.py +0 -322
  421. empathy_os/workflows/progressive/README 2.md +0 -454
  422. empathy_os/workflows/progressive/README.md +0 -454
  423. empathy_os/workflows/progressive/__init__ 2.py +0 -92
  424. empathy_os/workflows/progressive/__init__.py +0 -82
  425. empathy_os/workflows/progressive/cli 2.py +0 -242
  426. empathy_os/workflows/progressive/cli.py +0 -219
  427. empathy_os/workflows/progressive/core 2.py +0 -488
  428. empathy_os/workflows/progressive/core.py +0 -488
  429. empathy_os/workflows/progressive/orchestrator 2.py +0 -701
  430. empathy_os/workflows/progressive/orchestrator.py +0 -723
  431. empathy_os/workflows/progressive/reports 2.py +0 -528
  432. empathy_os/workflows/progressive/reports.py +0 -520
  433. empathy_os/workflows/progressive/telemetry 2.py +0 -280
  434. empathy_os/workflows/progressive/telemetry.py +0 -274
  435. empathy_os/workflows/progressive/test_gen 2.py +0 -514
  436. empathy_os/workflows/progressive/test_gen.py +0 -495
  437. empathy_os/workflows/progressive/workflow 2.py +0 -628
  438. empathy_os/workflows/progressive/workflow.py +0 -589
  439. empathy_os/workflows/refactor_plan.py +0 -694
  440. empathy_os/workflows/release_prep.py +0 -895
  441. empathy_os/workflows/release_prep_crew.py +0 -969
  442. empathy_os/workflows/research_synthesis.py +0 -404
  443. empathy_os/workflows/routing.py +0 -168
  444. empathy_os/workflows/secure_release.py +0 -593
  445. empathy_os/workflows/security_adapters.py +0 -297
  446. empathy_os/workflows/security_audit.py +0 -1329
  447. empathy_os/workflows/security_audit_phase3.py +0 -355
  448. empathy_os/workflows/seo_optimization.py +0 -633
  449. empathy_os/workflows/step_config.py +0 -234
  450. empathy_os/workflows/telemetry_mixin.py +0 -269
  451. empathy_os/workflows/test5.py +0 -125
  452. empathy_os/workflows/test5_README.md +0 -158
  453. empathy_os/workflows/test_coverage_boost_crew.py +0 -849
  454. empathy_os/workflows/test_gen/__init__.py +0 -52
  455. empathy_os/workflows/test_gen/ast_analyzer.py +0 -249
  456. empathy_os/workflows/test_gen/config.py +0 -88
  457. empathy_os/workflows/test_gen/data_models.py +0 -38
  458. empathy_os/workflows/test_gen/report_formatter.py +0 -289
  459. empathy_os/workflows/test_gen/test_templates.py +0 -381
  460. empathy_os/workflows/test_gen/workflow.py +0 -655
  461. empathy_os/workflows/test_gen.py +0 -54
  462. empathy_os/workflows/test_gen_behavioral.py +0 -477
  463. empathy_os/workflows/test_gen_parallel.py +0 -341
  464. empathy_os/workflows/test_lifecycle.py +0 -526
  465. empathy_os/workflows/test_maintenance.py +0 -627
  466. empathy_os/workflows/test_maintenance_cli.py +0 -590
  467. empathy_os/workflows/test_maintenance_crew.py +0 -840
  468. empathy_os/workflows/test_runner.py +0 -622
  469. empathy_os/workflows/tier_tracking.py +0 -531
  470. empathy_os/workflows/xml_enhanced_crew.py +0 -285
  471. empathy_software_plugin/SOFTWARE_PLUGIN_README.md +0 -57
  472. empathy_software_plugin/cli/__init__.py +0 -120
  473. empathy_software_plugin/cli/inspect.py +0 -362
  474. empathy_software_plugin/cli.py +0 -574
  475. empathy_software_plugin/plugin.py +0 -188
  476. workflow_scaffolding/__init__.py +0 -11
  477. workflow_scaffolding/__main__.py +0 -12
  478. workflow_scaffolding/cli.py +0 -206
  479. workflow_scaffolding/generator.py +0 -265
  480. {empathy_framework-5.2.1.dist-info → empathy_framework-5.4.0.dist-info}/WHEEL +0 -0
@@ -1,15 +0,0 @@
1
- """Core EmpathyOS Modules.
2
-
3
- Modular implementation of EmpathyOS functionality.
4
-
5
- Copyright 2025 Smart AI Memory, LLC
6
- Licensed under Fair Source 0.9
7
- """
8
-
9
- # Core classes
10
- from ..core import CollaborationState, EmpathyOS
11
-
12
- __all__ = [
13
- "EmpathyOS",
14
- "CollaborationState",
15
- ]
@@ -1,626 +0,0 @@
1
- """Cost Tracking for Empathy Framework
2
-
3
- Tracks API costs across model tiers and calculates savings from
4
- smart model routing (Haiku/Sonnet/Opus selection).
5
-
6
- Features:
7
- - Log each API request with model, tokens, and task type
8
- - Calculate actual cost vs baseline (if all requests used premium model)
9
- - Generate weekly/monthly reports
10
- - Integrate with `empathy costs` and `empathy morning` commands
11
- - **Performance optimized**: Batch writes (50 requests) + JSONL format
12
-
13
- Model pricing is sourced from empathy_os.models.MODEL_REGISTRY.
14
-
15
- Copyright 2025 Smart-AI-Memory
16
- Licensed under Fair Source License 0.9
17
- """
18
-
19
- import atexit
20
- import heapq
21
- import json
22
- from datetime import datetime, timedelta
23
- from pathlib import Path
24
- from typing import Any
25
-
26
- # Import pricing from unified registry
27
- from empathy_os.config import _validate_file_path
28
- from empathy_os.models import MODEL_REGISTRY
29
- from empathy_os.models.registry import TIER_PRICING
30
-
31
-
32
- def _build_model_pricing() -> dict[str, dict[str, float]]:
33
- """Build MODEL_PRICING from unified registry."""
34
- pricing: dict[str, dict[str, float]] = {}
35
-
36
- # Add all models from registry
37
- for provider_models in MODEL_REGISTRY.values():
38
- for model_info in provider_models.values():
39
- pricing[model_info.id] = {
40
- "input": model_info.input_cost_per_million,
41
- "output": model_info.output_cost_per_million,
42
- }
43
-
44
- # Add tier aliases from registry
45
- pricing.update(TIER_PRICING)
46
-
47
- # Add legacy model names for backward compatibility
48
- legacy_models = {
49
- "claude-3-haiku-20240307": {"input": 0.25, "output": 1.25},
50
- "claude-3-5-sonnet-20241022": {"input": 3.00, "output": 15.00},
51
- "claude-opus-4-20250514": {"input": 15.00, "output": 75.00},
52
- "gpt-4-turbo": {"input": 10.00, "output": 30.00},
53
- }
54
- pricing.update(legacy_models)
55
-
56
- return pricing
57
-
58
-
59
- # Pricing per million tokens - sourced from unified registry
60
- MODEL_PRICING = _build_model_pricing()
61
-
62
- # Default premium model for baseline comparison
63
- BASELINE_MODEL = "claude-opus-4-5-20251101"
64
-
65
-
66
- class CostTracker:
67
- """Tracks API costs and calculates savings from model routing.
68
-
69
- **Performance Optimized:**
70
- - Batch writes (flush every 50 requests)
71
- - JSONL append-only format for new data
72
- - Backward compatible with JSON format
73
- - Zero data loss (atexit handler)
74
- - Lazy loading: Full request history only loaded when accessed
75
- - Separate summary file: Fast init (80-90% faster for large histories)
76
-
77
- Usage:
78
- tracker = CostTracker()
79
- tracker.log_request("claude-3-haiku-20240307", 1000, 500, "summarize")
80
- report = tracker.get_report()
81
- """
82
-
83
- @property
84
- def requests(self) -> list[dict]:
85
- """Access request history (lazy-loaded for performance).
86
-
87
- Returns:
88
- List of request records. Triggers lazy loading on first access.
89
- """
90
- self._load_requests()
91
- return self.data.get("requests", [])
92
-
93
- def __init__(self, storage_dir: str = ".empathy", batch_size: int = 50):
94
- """Initialize cost tracker.
95
-
96
- Args:
97
- storage_dir: Directory for cost data storage
98
- batch_size: Number of requests to buffer before flushing (default: 50)
99
-
100
- Performance optimizations:
101
- - Lazy loading: Only load summary data on init, defer full request history
102
- - Separate summary file: Fast access to daily_totals without parsing JSONL
103
- - Init time reduced by 80-90% for large history files
104
- """
105
- self.storage_dir = Path(storage_dir)
106
- self.storage_dir.mkdir(parents=True, exist_ok=True)
107
- self.costs_file = self.storage_dir / "costs.json"
108
- self.costs_jsonl = self.storage_dir / "costs.jsonl"
109
- self.costs_summary = self.storage_dir / "costs_summary.json"
110
- self.batch_size = batch_size
111
- self._buffer: list[dict] = [] # Buffered requests not yet flushed
112
- self._requests_loaded = False # Track if full history is loaded
113
- self._load_summary() # Only load summary on init (fast)
114
-
115
- # Register cleanup handler to flush on exit
116
- atexit.register(self._cleanup)
117
-
118
- def _cleanup(self) -> None:
119
- """Cleanup handler - flush buffer on exit."""
120
- try:
121
- if self._buffer:
122
- self.flush()
123
- except Exception: # noqa: BLE001
124
- # INTENTIONAL: Best-effort flush, don't break shutdown
125
- pass
126
-
127
- def _load_summary(self) -> None:
128
- """Load only summary data on init (fast path).
129
-
130
- This loads daily_totals from the summary file without parsing
131
- the full request history. Full history is lazy-loaded only when needed.
132
-
133
- Performance: 80-90% faster init for large history files.
134
- """
135
- # Initialize with default structure (no requests loaded yet)
136
- self.data = self._default_data()
137
- self.data["requests"] = [] # Start empty, lazy-load later
138
-
139
- # Try loading pre-computed summary first (fastest)
140
- if self.costs_summary.exists():
141
- try:
142
- with open(self.costs_summary) as f:
143
- summary_data = json.load(f)
144
- self.data["daily_totals"] = summary_data.get("daily_totals", {})
145
- self.data["created_at"] = summary_data.get(
146
- "created_at", self.data["created_at"]
147
- )
148
- self.data["last_updated"] = summary_data.get(
149
- "last_updated", self.data["last_updated"]
150
- )
151
- return # Summary loaded, done
152
- except (OSError, json.JSONDecodeError):
153
- pass # Fall through to JSON fallback
154
-
155
- # Fallback: Load daily_totals from costs.json (backward compatibility)
156
- if self.costs_file.exists():
157
- try:
158
- with open(self.costs_file) as f:
159
- json_data = json.load(f)
160
- self.data["daily_totals"] = json_data.get("daily_totals", {})
161
- self.data["created_at"] = json_data.get("created_at", self.data["created_at"])
162
- self.data["last_updated"] = json_data.get(
163
- "last_updated", self.data["last_updated"]
164
- )
165
- # Don't load requests here - they'll be lazy-loaded
166
- except (OSError, json.JSONDecodeError):
167
- pass # Use defaults
168
-
169
- def _load_requests(self) -> None:
170
- """Lazy-load full request history (only when needed).
171
-
172
- Called automatically when request history is accessed.
173
- Most operations use daily_totals and don't need this.
174
- """
175
- if self._requests_loaded:
176
- return # Already loaded
177
-
178
- # Load from JSON first
179
- if self.costs_file.exists():
180
- try:
181
- with open(self.costs_file) as f:
182
- json_data = json.load(f)
183
- self.data["requests"] = json_data.get("requests", [])
184
- except (OSError, json.JSONDecodeError):
185
- self.data["requests"] = []
186
-
187
- # Append from JSONL if it exists
188
- if self.costs_jsonl.exists():
189
- try:
190
- with open(self.costs_jsonl) as f:
191
- for line in f:
192
- if line.strip():
193
- request = json.loads(line)
194
- self.data["requests"].append(request)
195
- except (OSError, json.JSONDecodeError):
196
- pass # Ignore errors, use what we have
197
-
198
- self._requests_loaded = True
199
-
200
- def _load(self) -> None:
201
- """Load cost data from storage (supports both JSON and JSONL).
202
-
203
- Deprecated: Use _load_summary() for fast init, _load_requests() for full history.
204
- Kept for backward compatibility.
205
- """
206
- self._load_summary()
207
- self._load_requests()
208
-
209
- def _default_data(self) -> dict:
210
- """Return default data structure."""
211
- return {
212
- "requests": [],
213
- "daily_totals": {},
214
- "created_at": datetime.now().isoformat(),
215
- "last_updated": datetime.now().isoformat(),
216
- }
217
-
218
- def _update_daily_totals(self, request: dict) -> None:
219
- """Update daily totals from a request.
220
-
221
- Args:
222
- request: Request record with cost information
223
-
224
- """
225
- timestamp = request.get("timestamp", datetime.now().isoformat())
226
- date = timestamp[:10] # Extract YYYY-MM-DD
227
-
228
- if date not in self.data["daily_totals"]:
229
- self.data["daily_totals"][date] = {
230
- "requests": 0,
231
- "input_tokens": 0,
232
- "output_tokens": 0,
233
- "actual_cost": 0,
234
- "baseline_cost": 0,
235
- "savings": 0,
236
- }
237
-
238
- daily = self.data["daily_totals"][date]
239
- daily["requests"] += 1
240
- daily["input_tokens"] += request["input_tokens"]
241
- daily["output_tokens"] += request["output_tokens"]
242
- daily["actual_cost"] = round(daily["actual_cost"] + request["actual_cost"], 6)
243
- daily["baseline_cost"] = round(daily["baseline_cost"] + request["baseline_cost"], 6)
244
- daily["savings"] = round(daily["savings"] + request["savings"], 6)
245
-
246
- def _save(self) -> None:
247
- """Save cost data to storage (legacy JSON format).
248
-
249
- **Note:** This is only used for backward compatibility.
250
- New data is written to JSONL format via flush().
251
- """
252
- self.data["last_updated"] = datetime.now().isoformat()
253
- validated_path = _validate_file_path(str(self.costs_file))
254
- with open(validated_path, "w") as f:
255
- json.dump(self.data, f, indent=2)
256
-
257
- def _save_summary(self) -> None:
258
- """Save summary data (daily_totals) to separate file for fast loading.
259
-
260
- This enables 80-90% faster init by avoiding full JSONL parsing on startup.
261
- """
262
- summary_data = {
263
- "daily_totals": self.data.get("daily_totals", {}),
264
- "created_at": self.data.get("created_at", datetime.now().isoformat()),
265
- "last_updated": datetime.now().isoformat(),
266
- }
267
- try:
268
- validated_path = _validate_file_path(str(self.costs_summary))
269
- with open(validated_path, "w") as f:
270
- json.dump(summary_data, f, indent=2)
271
- except (OSError, ValueError):
272
- pass # Best effort - summary is an optimization, not critical
273
-
274
- def flush(self) -> None:
275
- """Flush buffered requests to disk (JSONL format).
276
-
277
- This is called automatically:
278
- - Every `batch_size` requests
279
- - On process exit (atexit handler)
280
- - Manually by calling tracker.flush()
281
- """
282
- if not self._buffer:
283
- return
284
-
285
- # Append buffered requests to JSONL file
286
- try:
287
- with open(self.costs_jsonl, "a") as f:
288
- for request in self._buffer:
289
- f.write(json.dumps(request) + "\n")
290
-
291
- # Update daily totals (always in memory)
292
- for request in self._buffer:
293
- self._update_daily_totals(request)
294
-
295
- # Load requests if needed before extending (maintains backward compat)
296
- # This defers the expensive load from init to first flush
297
- if not self._requests_loaded:
298
- self._load_requests()
299
-
300
- self.data["requests"].extend(self._buffer)
301
- # Keep only last 1000 requests in memory
302
- if len(self.data["requests"]) > 1000:
303
- self.data["requests"] = self.data["requests"][-1000:]
304
-
305
- # Save summary file (fast path for future loads)
306
- self._save_summary()
307
-
308
- # Update JSON file periodically (every 10 flushes = 500 requests)
309
- # This maintains backward compatibility without killing performance
310
- if len(self._buffer) >= 500 or not self.costs_jsonl.exists():
311
- self._save()
312
-
313
- # Clear buffer
314
- self._buffer.clear()
315
-
316
- except OSError:
317
- # If JSONL write fails, fallback to immediate JSON save
318
- for request in self._buffer:
319
- self._update_daily_totals(request)
320
- if not self._requests_loaded:
321
- self._load_requests()
322
- self.data["requests"].extend(self._buffer)
323
- self._buffer.clear()
324
- self._save()
325
- self._save_summary()
326
-
327
- def _calculate_cost(self, model: str, input_tokens: int, output_tokens: int) -> float:
328
- """Calculate cost for a request.
329
-
330
- Args:
331
- model: Model name or tier
332
- input_tokens: Number of input tokens
333
- output_tokens: Number of output tokens
334
-
335
- Returns:
336
- Cost in USD
337
-
338
- """
339
- pricing = MODEL_PRICING.get(model) or MODEL_PRICING["capable"]
340
- input_cost = (input_tokens / 1_000_000) * pricing["input"]
341
- output_cost = (output_tokens / 1_000_000) * pricing["output"]
342
- return input_cost + output_cost
343
-
344
- def log_request(
345
- self,
346
- model: str,
347
- input_tokens: int,
348
- output_tokens: int,
349
- task_type: str = "unknown",
350
- tier: str | None = None,
351
- ) -> dict:
352
- """Log an API request with cost tracking (batched writes).
353
-
354
- **Performance optimized**: Requests are buffered and flushed every
355
- `batch_size` requests (default: 50) instead of writing to disk
356
- immediately. This provides a 60x+ performance improvement.
357
-
358
- Args:
359
- model: Model name used
360
- input_tokens: Number of input tokens
361
- output_tokens: Number of output tokens
362
- task_type: Type of task (summarize, generate_code, etc.)
363
- tier: Optional tier override (cheap, capable, premium)
364
-
365
- Returns:
366
- Request record with cost information
367
-
368
- """
369
- actual_cost = self._calculate_cost(model, input_tokens, output_tokens)
370
- baseline_cost = self._calculate_cost(BASELINE_MODEL, input_tokens, output_tokens)
371
- savings = baseline_cost - actual_cost
372
-
373
- request = {
374
- "timestamp": datetime.now().isoformat(),
375
- "model": model,
376
- "tier": tier or self._get_tier(model),
377
- "task_type": task_type,
378
- "input_tokens": input_tokens,
379
- "output_tokens": output_tokens,
380
- "actual_cost": round(actual_cost, 6),
381
- "baseline_cost": round(baseline_cost, 6),
382
- "savings": round(savings, 6),
383
- }
384
-
385
- # Add to buffer instead of immediate save
386
- self._buffer.append(request)
387
-
388
- # Flush when buffer reaches batch size
389
- if len(self._buffer) >= self.batch_size:
390
- self.flush()
391
-
392
- return request
393
-
394
- def _get_tier(self, model: str) -> str:
395
- """Determine tier from model name."""
396
- if "haiku" in model.lower():
397
- return "cheap"
398
- if "opus" in model.lower():
399
- return "premium"
400
- return "capable"
401
-
402
- def get_summary(self, days: int = 7, include_breakdown: bool = True) -> dict:
403
- """Get cost summary for recent period (includes buffered requests).
404
-
405
- **Real-time data**: Includes buffered requests that haven't been
406
- flushed to disk yet, ensuring accurate real-time reporting.
407
-
408
- **Performance optimized**: Main totals computed from pre-aggregated
409
- daily_totals. Full request history only loaded if include_breakdown=True.
410
-
411
- Args:
412
- days: Number of days to include
413
- include_breakdown: If True, include by_tier and by_task breakdown
414
- (requires loading full request history). Default: True.
415
-
416
- Returns:
417
- Summary with totals and savings percentage
418
-
419
- """
420
- cutoff = datetime.now() - timedelta(days=days)
421
- cutoff_str = cutoff.strftime("%Y-%m-%d")
422
-
423
- totals: dict[str, Any] = {
424
- "days": days,
425
- "requests": 0,
426
- "input_tokens": 0,
427
- "output_tokens": 0,
428
- "actual_cost": 0,
429
- "baseline_cost": 0,
430
- "savings": 0,
431
- "by_tier": {"cheap": 0, "capable": 0, "premium": 0},
432
- "by_task": {},
433
- }
434
-
435
- # Include daily totals from flushed data (fast - always in memory)
436
- for date, daily in self.data.get("daily_totals", {}).items():
437
- if date >= cutoff_str:
438
- totals["requests"] += daily["requests"]
439
- totals["input_tokens"] += daily["input_tokens"]
440
- totals["output_tokens"] += daily["output_tokens"]
441
- totals["actual_cost"] += daily["actual_cost"]
442
- totals["baseline_cost"] += daily["baseline_cost"]
443
- totals["savings"] += daily["savings"]
444
-
445
- # Add buffered request costs to totals (always in memory)
446
- cutoff_iso = cutoff.isoformat()
447
- for req in self._buffer:
448
- if req["timestamp"] >= cutoff_iso:
449
- totals["requests"] += 1
450
- totals["input_tokens"] += req["input_tokens"]
451
- totals["output_tokens"] += req["output_tokens"]
452
- totals["actual_cost"] += req["actual_cost"]
453
- totals["baseline_cost"] += req["baseline_cost"]
454
- totals["savings"] += req["savings"]
455
-
456
- # Include breakdown by tier/task (requires loading full history)
457
- if include_breakdown:
458
- # Lazy-load full request history only when needed
459
- self._load_requests()
460
- all_requests = list(self.data.get("requests", [])) + self._buffer
461
-
462
- for req in all_requests:
463
- if req["timestamp"] >= cutoff_iso:
464
- tier = req.get("tier", "capable")
465
- task = req.get("task_type", "unknown")
466
- totals["by_tier"][tier] = totals["by_tier"].get(tier, 0) + 1
467
- totals["by_task"][task] = totals["by_task"].get(task, 0) + 1
468
-
469
- # Calculate savings percentage
470
- if totals["baseline_cost"] > 0:
471
- totals["savings_percent"] = round(
472
- (totals["savings"] / totals["baseline_cost"]) * 100,
473
- 1,
474
- )
475
- else:
476
- totals["savings_percent"] = 0
477
-
478
- return totals
479
-
480
- def get_report(self, days: int = 7) -> str:
481
- """Generate a formatted cost report.
482
-
483
- Args:
484
- days: Number of days to include
485
-
486
- Returns:
487
- Formatted report string
488
-
489
- """
490
- summary = self.get_summary(days)
491
-
492
- lines = [
493
- "",
494
- "=" * 60,
495
- " COST TRACKING REPORT",
496
- f" Last {days} days",
497
- "=" * 60,
498
- "",
499
- "SUMMARY",
500
- "-" * 40,
501
- f" Total requests: {summary['requests']:,}",
502
- f" Input tokens: {summary['input_tokens']:,}",
503
- f" Output tokens: {summary['output_tokens']:,}",
504
- "",
505
- "COSTS",
506
- "-" * 40,
507
- f" Actual cost: ${summary['actual_cost']:.4f}",
508
- f" Baseline (Opus): ${summary['baseline_cost']:.4f}",
509
- f" You saved: ${summary['savings']:.4f} ({summary['savings_percent']}%)",
510
- "",
511
- ]
512
-
513
- # Tier breakdown
514
- if sum(summary["by_tier"].values()) > 0:
515
- lines.extend(
516
- [
517
- "BY MODEL TIER",
518
- "-" * 40,
519
- ],
520
- )
521
- for tier, count in sorted(summary["by_tier"].items(), key=lambda x: -x[1]):
522
- if count > 0:
523
- pct = (count / summary["requests"]) * 100 if summary["requests"] else 0
524
- lines.append(f" {tier:12} {count:6,} requests ({pct:.1f}%)")
525
- lines.append("")
526
-
527
- # Task breakdown (top 5)
528
- if summary["by_task"]:
529
- lines.extend(
530
- [
531
- "BY TASK TYPE (Top 5)",
532
- "-" * 40,
533
- ],
534
- )
535
- top_tasks = heapq.nlargest(5, summary["by_task"].items(), key=lambda x: x[1])
536
- for task, count in top_tasks:
537
- lines.append(f" {task:20} {count:,}")
538
- lines.append("")
539
-
540
- lines.extend(
541
- [
542
- "=" * 60,
543
- " Model routing saves money by using cheaper models",
544
- " for simple tasks and Opus only when needed.",
545
- "=" * 60,
546
- "",
547
- ],
548
- )
549
-
550
- return "\n".join(lines)
551
-
552
- def get_today(self) -> dict[str, int | float]:
553
- """Get today's cost summary (includes buffered requests)."""
554
- today = datetime.now().strftime("%Y-%m-%d")
555
- daily_totals = self.data.get("daily_totals", {})
556
- default: dict[str, int | float] = {
557
- "requests": 0,
558
- "input_tokens": 0,
559
- "output_tokens": 0,
560
- "actual_cost": 0,
561
- "baseline_cost": 0,
562
- "savings": 0,
563
- }
564
-
565
- # Start with flushed daily totals
566
- if isinstance(daily_totals, dict) and today in daily_totals:
567
- result = daily_totals[today]
568
- totals = result.copy() if isinstance(result, dict) else default.copy()
569
- else:
570
- totals = default.copy()
571
-
572
- # Add buffered requests for today (real-time data)
573
- for req in self._buffer:
574
- req_date = req["timestamp"][:10] # Extract YYYY-MM-DD
575
- if req_date == today:
576
- totals["requests"] += 1
577
- totals["input_tokens"] += req["input_tokens"]
578
- totals["output_tokens"] += req["output_tokens"]
579
- totals["actual_cost"] = round(totals["actual_cost"] + req["actual_cost"], 6)
580
- totals["baseline_cost"] = round(totals["baseline_cost"] + req["baseline_cost"], 6)
581
- totals["savings"] = round(totals["savings"] + req["savings"], 6)
582
-
583
- return totals
584
-
585
-
586
- def cmd_costs(args):
587
- """CLI command handler for costs."""
588
- tracker = CostTracker(storage_dir=getattr(args, "empathy_dir", ".empathy"))
589
- days = getattr(args, "days", 7)
590
-
591
- if getattr(args, "json", False):
592
- import json as json_mod
593
-
594
- print(json_mod.dumps(tracker.get_summary(days), indent=2))
595
- else:
596
- print(tracker.get_report(days))
597
-
598
- return 0
599
-
600
-
601
- # Singleton for global tracking
602
- _tracker: CostTracker | None = None
603
-
604
-
605
- def get_tracker(storage_dir: str = ".empathy") -> CostTracker:
606
- """Get or create the global cost tracker."""
607
- global _tracker
608
- if _tracker is None:
609
- _tracker = CostTracker(storage_dir)
610
- return _tracker
611
-
612
-
613
- def log_request(
614
- model: str,
615
- input_tokens: int,
616
- output_tokens: int,
617
- task_type: str = "unknown",
618
- tier: str | None = None,
619
- ) -> dict:
620
- """Convenience function to log a request to the global tracker.
621
-
622
- Usage:
623
- from empathy_os.cost_tracker import log_request
624
- log_request("claude-3-haiku-20240307", 1000, 500, "summarize")
625
- """
626
- return get_tracker().log_request(model, input_tokens, output_tokens, task_type, tier)
@@ -1,41 +0,0 @@
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
- # Simple server - uses telemetry API classes
31
- from .simple_server import run_simple_dashboard
32
- from .standalone_server import run_standalone_dashboard
33
-
34
- # Optional FastAPI version (requires dependencies)
35
- try:
36
- from .app import app, run_dashboard
37
-
38
- __all__ = ["app", "run_dashboard", "run_simple_dashboard", "run_standalone_dashboard"]
39
- except ImportError:
40
- # FastAPI not installed
41
- __all__ = ["run_simple_dashboard", "run_standalone_dashboard"]