empathy-framework 4.6.6__py3-none-any.whl → 4.7.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.6.6.dist-info → empathy_framework-4.7.0.dist-info}/METADATA +7 -6
- empathy_framework-4.7.0.dist-info/RECORD +354 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/top_level.txt +0 -2
- empathy_healthcare_plugin/monitors/monitoring/__init__.py +9 -9
- empathy_llm_toolkit/agent_factory/__init__.py +6 -6
- empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +7 -10
- empathy_llm_toolkit/agents_md/__init__.py +22 -0
- empathy_llm_toolkit/agents_md/loader.py +218 -0
- empathy_llm_toolkit/agents_md/parser.py +271 -0
- empathy_llm_toolkit/agents_md/registry.py +307 -0
- empathy_llm_toolkit/commands/__init__.py +51 -0
- empathy_llm_toolkit/commands/context.py +375 -0
- empathy_llm_toolkit/commands/loader.py +301 -0
- empathy_llm_toolkit/commands/models.py +231 -0
- empathy_llm_toolkit/commands/parser.py +371 -0
- empathy_llm_toolkit/commands/registry.py +429 -0
- empathy_llm_toolkit/config/__init__.py +8 -8
- empathy_llm_toolkit/config/unified.py +3 -7
- empathy_llm_toolkit/context/__init__.py +22 -0
- empathy_llm_toolkit/context/compaction.py +455 -0
- empathy_llm_toolkit/context/manager.py +434 -0
- empathy_llm_toolkit/hooks/__init__.py +24 -0
- empathy_llm_toolkit/hooks/config.py +306 -0
- empathy_llm_toolkit/hooks/executor.py +289 -0
- empathy_llm_toolkit/hooks/registry.py +302 -0
- empathy_llm_toolkit/hooks/scripts/__init__.py +39 -0
- empathy_llm_toolkit/hooks/scripts/evaluate_session.py +201 -0
- empathy_llm_toolkit/hooks/scripts/first_time_init.py +285 -0
- empathy_llm_toolkit/hooks/scripts/pre_compact.py +207 -0
- empathy_llm_toolkit/hooks/scripts/session_end.py +183 -0
- empathy_llm_toolkit/hooks/scripts/session_start.py +163 -0
- empathy_llm_toolkit/hooks/scripts/suggest_compact.py +225 -0
- empathy_llm_toolkit/learning/__init__.py +30 -0
- empathy_llm_toolkit/learning/evaluator.py +438 -0
- empathy_llm_toolkit/learning/extractor.py +514 -0
- empathy_llm_toolkit/learning/storage.py +560 -0
- empathy_llm_toolkit/providers.py +4 -11
- empathy_llm_toolkit/security/__init__.py +17 -17
- empathy_llm_toolkit/utils/tokens.py +2 -5
- empathy_os/__init__.py +202 -70
- empathy_os/cache_monitor.py +5 -3
- empathy_os/cli/__init__.py +11 -55
- empathy_os/cli/__main__.py +29 -15
- empathy_os/cli/commands/inspection.py +21 -12
- empathy_os/cli/commands/memory.py +4 -12
- empathy_os/cli/commands/profiling.py +198 -0
- empathy_os/cli/commands/utilities.py +27 -7
- empathy_os/cli.py +28 -57
- empathy_os/cli_unified.py +525 -1164
- empathy_os/cost_tracker.py +9 -3
- empathy_os/dashboard/server.py +200 -2
- empathy_os/hot_reload/__init__.py +7 -7
- empathy_os/hot_reload/config.py +6 -7
- empathy_os/hot_reload/integration.py +35 -35
- empathy_os/hot_reload/reloader.py +57 -57
- empathy_os/hot_reload/watcher.py +28 -28
- empathy_os/hot_reload/websocket.py +2 -2
- empathy_os/memory/__init__.py +11 -4
- empathy_os/memory/claude_memory.py +1 -1
- empathy_os/memory/cross_session.py +8 -12
- empathy_os/memory/edges.py +6 -6
- empathy_os/memory/file_session.py +770 -0
- empathy_os/memory/graph.py +30 -30
- empathy_os/memory/nodes.py +6 -6
- empathy_os/memory/short_term.py +15 -9
- empathy_os/memory/unified.py +606 -140
- empathy_os/meta_workflows/agent_creator.py +3 -9
- empathy_os/meta_workflows/cli_meta_workflows.py +113 -53
- empathy_os/meta_workflows/form_engine.py +6 -18
- empathy_os/meta_workflows/intent_detector.py +64 -24
- empathy_os/meta_workflows/models.py +3 -1
- empathy_os/meta_workflows/pattern_learner.py +13 -31
- empathy_os/meta_workflows/plan_generator.py +55 -47
- empathy_os/meta_workflows/session_context.py +2 -3
- empathy_os/meta_workflows/workflow.py +20 -51
- empathy_os/models/cli.py +2 -2
- empathy_os/models/tasks.py +1 -2
- empathy_os/models/telemetry.py +4 -1
- empathy_os/models/token_estimator.py +3 -1
- empathy_os/monitoring/alerts.py +938 -9
- empathy_os/monitoring/alerts_cli.py +346 -183
- empathy_os/orchestration/execution_strategies.py +12 -29
- empathy_os/orchestration/pattern_learner.py +20 -26
- empathy_os/orchestration/real_tools.py +6 -15
- empathy_os/platform_utils.py +2 -1
- empathy_os/plugins/__init__.py +2 -2
- empathy_os/plugins/base.py +64 -64
- empathy_os/plugins/registry.py +32 -32
- empathy_os/project_index/index.py +49 -15
- empathy_os/project_index/models.py +1 -2
- empathy_os/project_index/reports.py +1 -1
- empathy_os/project_index/scanner.py +1 -0
- empathy_os/redis_memory.py +10 -7
- empathy_os/resilience/__init__.py +1 -1
- empathy_os/resilience/health.py +10 -10
- empathy_os/routing/__init__.py +7 -7
- empathy_os/routing/chain_executor.py +37 -37
- empathy_os/routing/classifier.py +36 -36
- empathy_os/routing/smart_router.py +40 -40
- empathy_os/routing/{wizard_registry.py → workflow_registry.py} +47 -47
- empathy_os/scaffolding/__init__.py +8 -8
- empathy_os/scaffolding/__main__.py +1 -1
- empathy_os/scaffolding/cli.py +28 -28
- empathy_os/socratic/__init__.py +3 -19
- empathy_os/socratic/ab_testing.py +25 -36
- empathy_os/socratic/blueprint.py +38 -38
- empathy_os/socratic/cli.py +34 -20
- empathy_os/socratic/collaboration.py +30 -28
- empathy_os/socratic/domain_templates.py +9 -1
- empathy_os/socratic/embeddings.py +17 -13
- empathy_os/socratic/engine.py +135 -70
- empathy_os/socratic/explainer.py +70 -60
- empathy_os/socratic/feedback.py +24 -19
- empathy_os/socratic/forms.py +15 -10
- empathy_os/socratic/generator.py +51 -35
- empathy_os/socratic/llm_analyzer.py +25 -23
- empathy_os/socratic/mcp_server.py +99 -159
- empathy_os/socratic/session.py +19 -13
- empathy_os/socratic/storage.py +98 -67
- empathy_os/socratic/success.py +38 -27
- empathy_os/socratic/visual_editor.py +51 -39
- empathy_os/socratic/web_ui.py +99 -66
- empathy_os/telemetry/cli.py +3 -1
- empathy_os/telemetry/usage_tracker.py +1 -3
- empathy_os/test_generator/__init__.py +3 -3
- empathy_os/test_generator/cli.py +28 -28
- empathy_os/test_generator/generator.py +64 -66
- empathy_os/test_generator/risk_analyzer.py +11 -11
- empathy_os/vscode_bridge.py +173 -0
- empathy_os/workflows/__init__.py +212 -120
- empathy_os/workflows/batch_processing.py +8 -24
- empathy_os/workflows/bug_predict.py +1 -1
- empathy_os/workflows/code_review.py +20 -5
- empathy_os/workflows/code_review_pipeline.py +13 -8
- empathy_os/workflows/keyboard_shortcuts/workflow.py +6 -2
- empathy_os/workflows/manage_documentation.py +1 -0
- empathy_os/workflows/orchestrated_health_check.py +6 -11
- empathy_os/workflows/orchestrated_release_prep.py +3 -3
- empathy_os/workflows/pr_review.py +18 -10
- empathy_os/workflows/progressive/__init__.py +2 -12
- empathy_os/workflows/progressive/cli.py +14 -37
- empathy_os/workflows/progressive/core.py +12 -12
- empathy_os/workflows/progressive/orchestrator.py +166 -144
- empathy_os/workflows/progressive/reports.py +22 -31
- empathy_os/workflows/progressive/telemetry.py +8 -14
- empathy_os/workflows/progressive/test_gen.py +29 -48
- empathy_os/workflows/progressive/workflow.py +31 -70
- empathy_os/workflows/release_prep.py +21 -6
- empathy_os/workflows/release_prep_crew.py +1 -0
- empathy_os/workflows/secure_release.py +13 -6
- empathy_os/workflows/security_audit.py +8 -3
- empathy_os/workflows/test_coverage_boost_crew.py +3 -2
- empathy_os/workflows/test_maintenance_crew.py +1 -0
- empathy_os/workflows/test_runner.py +16 -12
- empathy_software_plugin/SOFTWARE_PLUGIN_README.md +25 -703
- empathy_software_plugin/cli.py +0 -122
- coach_wizards/__init__.py +0 -45
- coach_wizards/accessibility_wizard.py +0 -91
- coach_wizards/api_wizard.py +0 -91
- coach_wizards/base_wizard.py +0 -209
- coach_wizards/cicd_wizard.py +0 -91
- coach_wizards/code_reviewer_README.md +0 -60
- coach_wizards/code_reviewer_wizard.py +0 -180
- coach_wizards/compliance_wizard.py +0 -91
- coach_wizards/database_wizard.py +0 -91
- coach_wizards/debugging_wizard.py +0 -91
- coach_wizards/documentation_wizard.py +0 -91
- coach_wizards/generate_wizards.py +0 -347
- coach_wizards/localization_wizard.py +0 -173
- coach_wizards/migration_wizard.py +0 -91
- coach_wizards/monitoring_wizard.py +0 -91
- coach_wizards/observability_wizard.py +0 -91
- coach_wizards/performance_wizard.py +0 -91
- coach_wizards/prompt_engineering_wizard.py +0 -661
- coach_wizards/refactoring_wizard.py +0 -91
- coach_wizards/scaling_wizard.py +0 -90
- coach_wizards/security_wizard.py +0 -92
- coach_wizards/testing_wizard.py +0 -91
- empathy_framework-4.6.6.dist-info/RECORD +0 -410
- empathy_llm_toolkit/wizards/__init__.py +0 -43
- empathy_llm_toolkit/wizards/base_wizard.py +0 -364
- empathy_llm_toolkit/wizards/customer_support_wizard.py +0 -190
- empathy_llm_toolkit/wizards/healthcare_wizard.py +0 -378
- empathy_llm_toolkit/wizards/patient_assessment_README.md +0 -64
- empathy_llm_toolkit/wizards/patient_assessment_wizard.py +0 -193
- empathy_llm_toolkit/wizards/technology_wizard.py +0 -209
- empathy_os/wizard_factory_cli.py +0 -170
- empathy_software_plugin/wizards/__init__.py +0 -42
- empathy_software_plugin/wizards/advanced_debugging_wizard.py +0 -395
- empathy_software_plugin/wizards/agent_orchestration_wizard.py +0 -511
- empathy_software_plugin/wizards/ai_collaboration_wizard.py +0 -503
- empathy_software_plugin/wizards/ai_context_wizard.py +0 -441
- empathy_software_plugin/wizards/ai_documentation_wizard.py +0 -503
- empathy_software_plugin/wizards/base_wizard.py +0 -288
- empathy_software_plugin/wizards/book_chapter_wizard.py +0 -519
- empathy_software_plugin/wizards/code_review_wizard.py +0 -604
- empathy_software_plugin/wizards/debugging/__init__.py +0 -50
- empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +0 -414
- empathy_software_plugin/wizards/debugging/config_loaders.py +0 -446
- empathy_software_plugin/wizards/debugging/fix_applier.py +0 -469
- empathy_software_plugin/wizards/debugging/language_patterns.py +0 -385
- empathy_software_plugin/wizards/debugging/linter_parsers.py +0 -470
- empathy_software_plugin/wizards/debugging/verification.py +0 -369
- empathy_software_plugin/wizards/enhanced_testing_wizard.py +0 -537
- empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +0 -816
- empathy_software_plugin/wizards/multi_model_wizard.py +0 -501
- empathy_software_plugin/wizards/pattern_extraction_wizard.py +0 -422
- empathy_software_plugin/wizards/pattern_retriever_wizard.py +0 -400
- empathy_software_plugin/wizards/performance/__init__.py +0 -9
- empathy_software_plugin/wizards/performance/bottleneck_detector.py +0 -221
- empathy_software_plugin/wizards/performance/profiler_parsers.py +0 -278
- empathy_software_plugin/wizards/performance/trajectory_analyzer.py +0 -429
- empathy_software_plugin/wizards/performance_profiling_wizard.py +0 -305
- empathy_software_plugin/wizards/prompt_engineering_wizard.py +0 -425
- empathy_software_plugin/wizards/rag_pattern_wizard.py +0 -461
- empathy_software_plugin/wizards/security/__init__.py +0 -32
- empathy_software_plugin/wizards/security/exploit_analyzer.py +0 -290
- empathy_software_plugin/wizards/security/owasp_patterns.py +0 -241
- empathy_software_plugin/wizards/security/vulnerability_scanner.py +0 -604
- empathy_software_plugin/wizards/security_analysis_wizard.py +0 -322
- empathy_software_plugin/wizards/security_learning_wizard.py +0 -740
- empathy_software_plugin/wizards/tech_debt_wizard.py +0 -726
- empathy_software_plugin/wizards/testing/__init__.py +0 -27
- empathy_software_plugin/wizards/testing/coverage_analyzer.py +0 -459
- empathy_software_plugin/wizards/testing/quality_analyzer.py +0 -525
- empathy_software_plugin/wizards/testing/test_suggester.py +0 -533
- empathy_software_plugin/wizards/testing_wizard.py +0 -274
- wizards/__init__.py +0 -82
- wizards/admission_assessment_wizard.py +0 -644
- wizards/care_plan.py +0 -321
- wizards/clinical_assessment.py +0 -769
- wizards/discharge_planning.py +0 -77
- wizards/discharge_summary_wizard.py +0 -468
- wizards/dosage_calculation.py +0 -497
- wizards/incident_report_wizard.py +0 -454
- wizards/medication_reconciliation.py +0 -85
- wizards/nursing_assessment.py +0 -171
- wizards/patient_education.py +0 -654
- wizards/quality_improvement.py +0 -705
- wizards/sbar_report.py +0 -324
- wizards/sbar_wizard.py +0 -608
- wizards/shift_handoff_wizard.py +0 -535
- wizards/soap_note_wizard.py +0 -679
- wizards/treatment_plan.py +0 -15
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/WHEEL +0 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/entry_points.txt +0 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/licenses/LICENSE +0 -0
empathy_os/socratic/web_ui.py
CHANGED
|
@@ -65,16 +65,20 @@ class ReactFormSchema:
|
|
|
65
65
|
"pattern": f.validation.pattern,
|
|
66
66
|
},
|
|
67
67
|
"showWhen": f.show_when,
|
|
68
|
-
"options":
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
68
|
+
"options": (
|
|
69
|
+
[
|
|
70
|
+
{
|
|
71
|
+
"value": o.value,
|
|
72
|
+
"label": o.label,
|
|
73
|
+
"description": o.description,
|
|
74
|
+
"icon": o.icon,
|
|
75
|
+
"recommended": o.recommended,
|
|
76
|
+
}
|
|
77
|
+
for o in f.options
|
|
78
|
+
]
|
|
79
|
+
if f.options
|
|
80
|
+
else None
|
|
81
|
+
),
|
|
78
82
|
}
|
|
79
83
|
fields.append(field_schema)
|
|
80
84
|
|
|
@@ -165,26 +169,34 @@ class ReactBlueprintSchema:
|
|
|
165
169
|
"""Create schema from a WorkflowBlueprint."""
|
|
166
170
|
agents = []
|
|
167
171
|
for agent in blueprint.agents:
|
|
168
|
-
agents.append(
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
172
|
+
agents.append(
|
|
173
|
+
{
|
|
174
|
+
"id": agent.spec.id,
|
|
175
|
+
"name": agent.spec.name,
|
|
176
|
+
"role": agent.spec.role.value,
|
|
177
|
+
"goal": agent.spec.goal,
|
|
178
|
+
"backstory": (
|
|
179
|
+
agent.spec.backstory[:200] + "..."
|
|
180
|
+
if len(agent.spec.backstory) > 200
|
|
181
|
+
else agent.spec.backstory
|
|
182
|
+
),
|
|
183
|
+
"modelTier": agent.spec.model_tier,
|
|
184
|
+
"tools": [t.name for t in agent.spec.tools],
|
|
185
|
+
}
|
|
186
|
+
)
|
|
177
187
|
|
|
178
188
|
stages = []
|
|
179
189
|
for stage in blueprint.stages:
|
|
180
|
-
stages.append(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
190
|
+
stages.append(
|
|
191
|
+
{
|
|
192
|
+
"id": stage.id,
|
|
193
|
+
"name": stage.name,
|
|
194
|
+
"description": stage.description,
|
|
195
|
+
"agents": stage.agent_ids,
|
|
196
|
+
"parallel": stage.parallel,
|
|
197
|
+
"dependsOn": stage.depends_on,
|
|
198
|
+
}
|
|
199
|
+
)
|
|
188
200
|
|
|
189
201
|
success_criteria = None
|
|
190
202
|
if blueprint.success_criteria:
|
|
@@ -226,13 +238,13 @@ def render_form_html(form: Form, action_url: str = "/api/socratic/submit") -> st
|
|
|
226
238
|
html_parts = [
|
|
227
239
|
f'<form id="{form.id}" action="{action_url}" method="POST" class="socratic-form">',
|
|
228
240
|
' <div class="form-header">',
|
|
229
|
-
f
|
|
241
|
+
f" <h2>{_escape_html(form.title)}</h2>",
|
|
230
242
|
f' <p class="form-description">{_escape_html(form.description)}</p>',
|
|
231
243
|
' <div class="progress-bar">',
|
|
232
244
|
f' <div class="progress-fill" style="width: {form.progress * 100}%"></div>',
|
|
233
245
|
f' <span class="progress-text">{form.progress:.0%}</span>',
|
|
234
|
-
|
|
235
|
-
|
|
246
|
+
" </div>",
|
|
247
|
+
" </div>",
|
|
236
248
|
' <div class="form-fields">',
|
|
237
249
|
]
|
|
238
250
|
|
|
@@ -242,34 +254,36 @@ def render_form_html(form: Form, action_url: str = "/api/socratic/submit") -> st
|
|
|
242
254
|
for category, fields in fields_by_category.items():
|
|
243
255
|
if len(fields_by_category) > 1:
|
|
244
256
|
html_parts.append(f' <fieldset class="field-category" data-category="{category}">')
|
|
245
|
-
html_parts.append(f
|
|
257
|
+
html_parts.append(f" <legend>{category.title()}</legend>")
|
|
246
258
|
|
|
247
259
|
for field in fields:
|
|
248
260
|
html_parts.append(_render_field_html(field))
|
|
249
261
|
|
|
250
262
|
if len(fields_by_category) > 1:
|
|
251
|
-
html_parts.append(
|
|
252
|
-
|
|
253
|
-
html_parts.extend(
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
263
|
+
html_parts.append(" </fieldset>")
|
|
264
|
+
|
|
265
|
+
html_parts.extend(
|
|
266
|
+
[
|
|
267
|
+
" </div>",
|
|
268
|
+
' <div class="form-actions">',
|
|
269
|
+
' <button type="submit" class="btn-primary">Continue</button>',
|
|
270
|
+
" </div>",
|
|
271
|
+
"</form>",
|
|
272
|
+
]
|
|
273
|
+
)
|
|
260
274
|
|
|
261
275
|
return "\n".join(html_parts)
|
|
262
276
|
|
|
263
277
|
|
|
264
278
|
def _render_field_html(field: FormField) -> str:
|
|
265
279
|
"""Render a single field as HTML."""
|
|
266
|
-
required =
|
|
267
|
-
required_indicator = '<span class="required">*</span>' if field.validation.required else
|
|
280
|
+
required = "required" if field.validation.required else ""
|
|
281
|
+
required_indicator = '<span class="required">*</span>' if field.validation.required else ""
|
|
268
282
|
|
|
269
283
|
# Show when data attribute
|
|
270
284
|
show_when = ""
|
|
271
285
|
if field.show_when:
|
|
272
|
-
show_when = f
|
|
286
|
+
show_when = f" data-show-when='{json.dumps(field.show_when)}'"
|
|
273
287
|
|
|
274
288
|
parts = [
|
|
275
289
|
f' <div class="form-field" data-field-id="{field.id}"{show_when}>',
|
|
@@ -283,65 +297,84 @@ def _render_field_html(field: FormField) -> str:
|
|
|
283
297
|
if field.field_type == FieldType.SINGLE_SELECT:
|
|
284
298
|
parts.append(' <div class="radio-group">')
|
|
285
299
|
for opt in field.options:
|
|
286
|
-
rec_class =
|
|
300
|
+
rec_class = " recommended" if opt.recommended else ""
|
|
287
301
|
parts.append(f' <label class="radio-option{rec_class}">')
|
|
288
|
-
parts.append(
|
|
302
|
+
parts.append(
|
|
303
|
+
f' <input type="radio" name="{field.id}" value="{opt.value}" {required}>'
|
|
304
|
+
)
|
|
289
305
|
parts.append(f' <span class="option-label">{_escape_html(opt.label)}</span>')
|
|
290
306
|
if opt.description:
|
|
291
|
-
parts.append(
|
|
292
|
-
|
|
293
|
-
|
|
307
|
+
parts.append(
|
|
308
|
+
f' <span class="option-desc">{_escape_html(opt.description)}</span>'
|
|
309
|
+
)
|
|
310
|
+
parts.append(" </label>")
|
|
311
|
+
parts.append(" </div>")
|
|
294
312
|
|
|
295
313
|
elif field.field_type == FieldType.MULTI_SELECT:
|
|
296
314
|
parts.append(' <div class="checkbox-group">')
|
|
297
315
|
for opt in field.options:
|
|
298
|
-
rec_class =
|
|
316
|
+
rec_class = " recommended" if opt.recommended else ""
|
|
299
317
|
parts.append(f' <label class="checkbox-option{rec_class}">')
|
|
300
318
|
parts.append(f' <input type="checkbox" name="{field.id}" value="{opt.value}">')
|
|
301
319
|
parts.append(f' <span class="option-label">{_escape_html(opt.label)}</span>')
|
|
302
320
|
if opt.description:
|
|
303
|
-
parts.append(
|
|
304
|
-
|
|
305
|
-
|
|
321
|
+
parts.append(
|
|
322
|
+
f' <span class="option-desc">{_escape_html(opt.description)}</span>'
|
|
323
|
+
)
|
|
324
|
+
parts.append(" </label>")
|
|
325
|
+
parts.append(" </div>")
|
|
306
326
|
|
|
307
327
|
elif field.field_type == FieldType.TEXT_AREA:
|
|
308
|
-
max_len =
|
|
309
|
-
|
|
328
|
+
max_len = (
|
|
329
|
+
f' maxlength="{field.validation.max_length}"' if field.validation.max_length else ""
|
|
330
|
+
)
|
|
331
|
+
parts.append(
|
|
332
|
+
f' <textarea id="{field.id}" name="{field.id}" placeholder="{_escape_html(field.placeholder)}"{max_len} {required}></textarea>'
|
|
333
|
+
)
|
|
310
334
|
|
|
311
335
|
elif field.field_type == FieldType.BOOLEAN:
|
|
312
336
|
parts.append(' <div class="switch-container">')
|
|
313
337
|
parts.append(' <label class="switch">')
|
|
314
|
-
parts.append(
|
|
338
|
+
parts.append(
|
|
339
|
+
f' <input type="checkbox" id="{field.id}" name="{field.id}" value="true">'
|
|
340
|
+
)
|
|
315
341
|
parts.append(' <span class="slider"></span>')
|
|
316
|
-
parts.append(
|
|
317
|
-
parts.append(
|
|
342
|
+
parts.append(" </label>")
|
|
343
|
+
parts.append(" </div>")
|
|
318
344
|
|
|
319
345
|
elif field.field_type == FieldType.SLIDER:
|
|
320
346
|
min_val = field.validation.min_value or 0
|
|
321
347
|
max_val = field.validation.max_value or 100
|
|
322
348
|
parts.append(' <div class="slider-container">')
|
|
323
|
-
parts.append(
|
|
349
|
+
parts.append(
|
|
350
|
+
f' <input type="range" id="{field.id}" name="{field.id}" min="{min_val}" max="{max_val}">'
|
|
351
|
+
)
|
|
324
352
|
parts.append(f' <output for="{field.id}"></output>')
|
|
325
|
-
parts.append(
|
|
353
|
+
parts.append(" </div>")
|
|
326
354
|
|
|
327
355
|
else: # TEXT, NUMBER
|
|
328
356
|
input_type = "number" if field.field_type == FieldType.NUMBER else "text"
|
|
329
|
-
max_len =
|
|
330
|
-
|
|
357
|
+
max_len = (
|
|
358
|
+
f' maxlength="{field.validation.max_length}"' if field.validation.max_length else ""
|
|
359
|
+
)
|
|
360
|
+
parts.append(
|
|
361
|
+
f' <input type="{input_type}" id="{field.id}" name="{field.id}" placeholder="{_escape_html(field.placeholder)}"{max_len} {required}>'
|
|
362
|
+
)
|
|
331
363
|
|
|
332
|
-
parts.append(
|
|
364
|
+
parts.append(" </div>")
|
|
333
365
|
|
|
334
366
|
return "\n".join(parts)
|
|
335
367
|
|
|
336
368
|
|
|
337
369
|
def _escape_html(text: str) -> str:
|
|
338
370
|
"""Escape HTML special characters."""
|
|
339
|
-
return (
|
|
340
|
-
.replace("&", "&")
|
|
371
|
+
return (
|
|
372
|
+
text.replace("&", "&")
|
|
341
373
|
.replace("<", "<")
|
|
342
374
|
.replace(">", ">")
|
|
343
375
|
.replace('"', """)
|
|
344
|
-
.replace("'", "'")
|
|
376
|
+
.replace("'", "'")
|
|
377
|
+
)
|
|
345
378
|
|
|
346
379
|
|
|
347
380
|
# =============================================================================
|
|
@@ -908,7 +941,7 @@ def render_complete_page(form: Form, session: SocraticSession) -> str:
|
|
|
908
941
|
<body>
|
|
909
942
|
<div class="container">
|
|
910
943
|
<div class="session-info">
|
|
911
|
-
<span class="domain-badge">{session_data.domain or
|
|
944
|
+
<span class="domain-badge">{session_data.domain or "General"}</span>
|
|
912
945
|
<span class="confidence">Confidence: {session_data.confidence:.0%}</span>
|
|
913
946
|
</div>
|
|
914
947
|
|
empathy_os/telemetry/cli.py
CHANGED
|
@@ -1493,7 +1493,9 @@ def cmd_file_test_status(args: Any) -> int:
|
|
|
1493
1493
|
stale_marker = " [STALE]" if record.is_stale else ""
|
|
1494
1494
|
print(f"\n{record.file_path}")
|
|
1495
1495
|
print(f" Status: {status}{stale_marker}")
|
|
1496
|
-
print(
|
|
1496
|
+
print(
|
|
1497
|
+
f" Tests: {record.test_count} (passed: {record.passed}, failed: {record.failed})"
|
|
1498
|
+
)
|
|
1497
1499
|
if record.duration_seconds:
|
|
1498
1500
|
print(f" Duration: {record.duration_seconds:.1f}s")
|
|
1499
1501
|
print(f" Last Run: {record.timestamp[:19]}")
|
|
@@ -566,9 +566,7 @@ class UsageTracker:
|
|
|
566
566
|
# Calculate hit rates for workflows
|
|
567
567
|
for wf_stats in by_workflow.values():
|
|
568
568
|
wf_requests = wf_stats["requests"]
|
|
569
|
-
wf_stats["hit_rate"] = (
|
|
570
|
-
(wf_stats["hits"] / wf_requests) if wf_requests > 0 else 0.0
|
|
571
|
-
)
|
|
569
|
+
wf_stats["hit_rate"] = (wf_stats["hits"] / wf_requests) if wf_requests > 0 else 0.0
|
|
572
570
|
|
|
573
571
|
return {
|
|
574
572
|
"hit_rate": round(hit_rate, 4),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"""Risk-Driven Test Generator for
|
|
1
|
+
"""Risk-Driven Test Generator for Workflow Factory.
|
|
2
2
|
|
|
3
|
-
Generates comprehensive tests for
|
|
3
|
+
Generates comprehensive tests for workflows based on risk analysis and patterns.
|
|
4
4
|
|
|
5
5
|
Features:
|
|
6
6
|
- Risk-based test prioritization
|
|
@@ -14,7 +14,7 @@ Usage:
|
|
|
14
14
|
|
|
15
15
|
generator = TestGenerator()
|
|
16
16
|
tests = generator.generate_tests(
|
|
17
|
-
|
|
17
|
+
workflow_id="soap_note",
|
|
18
18
|
pattern_ids=["linear_flow", "approval", "structured_fields"]
|
|
19
19
|
)
|
|
20
20
|
|
empathy_os/test_generator/cli.py
CHANGED
|
@@ -28,33 +28,33 @@ logger = logging.getLogger(__name__)
|
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
def cmd_generate(args):
|
|
31
|
-
"""Generate tests for a
|
|
31
|
+
"""Generate tests for a workflow.
|
|
32
32
|
|
|
33
33
|
Args:
|
|
34
34
|
args: Command line arguments
|
|
35
35
|
|
|
36
36
|
"""
|
|
37
|
-
|
|
37
|
+
workflow_id = args.workflow_id
|
|
38
38
|
pattern_ids = args.patterns.split(",") if args.patterns else []
|
|
39
39
|
|
|
40
|
-
logger.info(f"Generating tests for
|
|
40
|
+
logger.info(f"Generating tests for workflow: {workflow_id}")
|
|
41
41
|
logger.info(f"Patterns: {', '.join(pattern_ids)}")
|
|
42
42
|
|
|
43
43
|
# Generate tests
|
|
44
44
|
generator = TestGenerator()
|
|
45
45
|
tests = generator.generate_tests(
|
|
46
|
-
|
|
46
|
+
workflow_id=workflow_id,
|
|
47
47
|
pattern_ids=pattern_ids,
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
workflow_module=args.module,
|
|
49
|
+
workflow_class=args.workflow_class,
|
|
50
50
|
)
|
|
51
51
|
|
|
52
52
|
# Determine output directory
|
|
53
|
-
output_dir = Path(args.output) if args.output else Path("tests/unit/
|
|
53
|
+
output_dir = Path(args.output) if args.output else Path("tests/unit/workflows")
|
|
54
54
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
55
55
|
|
|
56
56
|
# Write unit tests
|
|
57
|
-
unit_test_file = output_dir / f"test_{
|
|
57
|
+
unit_test_file = output_dir / f"test_{workflow_id}_workflow.py"
|
|
58
58
|
validated_unit_test = _validate_file_path(str(unit_test_file))
|
|
59
59
|
with open(validated_unit_test, "w") as f:
|
|
60
60
|
f.write(tests["unit"])
|
|
@@ -63,7 +63,7 @@ def cmd_generate(args):
|
|
|
63
63
|
# Write integration tests (if generated)
|
|
64
64
|
if tests["integration"]:
|
|
65
65
|
integration_test_file = (
|
|
66
|
-
output_dir.parent.parent / "integration" / f"test_{
|
|
66
|
+
output_dir.parent.parent / "integration" / f"test_{workflow_id}_integration.py"
|
|
67
67
|
)
|
|
68
68
|
integration_test_file.parent.mkdir(parents=True, exist_ok=True)
|
|
69
69
|
validated_integration = _validate_file_path(str(integration_test_file))
|
|
@@ -72,7 +72,7 @@ def cmd_generate(args):
|
|
|
72
72
|
logger.info(f"✓ Integration tests written to: {validated_integration}")
|
|
73
73
|
|
|
74
74
|
# Write fixtures
|
|
75
|
-
fixtures_file = output_dir / f"fixtures_{
|
|
75
|
+
fixtures_file = output_dir / f"fixtures_{workflow_id}.py"
|
|
76
76
|
validated_fixtures = _validate_file_path(str(fixtures_file))
|
|
77
77
|
with open(validated_fixtures, "w") as f:
|
|
78
78
|
f.write(tests["fixtures"])
|
|
@@ -92,24 +92,24 @@ def cmd_generate(args):
|
|
|
92
92
|
|
|
93
93
|
|
|
94
94
|
def cmd_analyze(args):
|
|
95
|
-
"""Analyze
|
|
95
|
+
"""Analyze workflow risk and show recommendations.
|
|
96
96
|
|
|
97
97
|
Args:
|
|
98
98
|
args: Command line arguments
|
|
99
99
|
|
|
100
100
|
"""
|
|
101
|
-
|
|
101
|
+
workflow_id = args.workflow_id
|
|
102
102
|
pattern_ids = args.patterns.split(",") if args.patterns else []
|
|
103
103
|
|
|
104
|
-
logger.info(f"Analyzing
|
|
104
|
+
logger.info(f"Analyzing workflow: {workflow_id}")
|
|
105
105
|
|
|
106
106
|
# Perform risk analysis
|
|
107
107
|
analyzer = RiskAnalyzer()
|
|
108
|
-
analysis = analyzer.analyze(
|
|
108
|
+
analysis = analyzer.analyze(workflow_id, pattern_ids)
|
|
109
109
|
|
|
110
110
|
# Display results
|
|
111
111
|
print(f"\n{'=' * 60}")
|
|
112
|
-
print(f"Risk Analysis: {
|
|
112
|
+
print(f"Risk Analysis: {workflow_id}")
|
|
113
113
|
print(f"{'=' * 60}\n")
|
|
114
114
|
|
|
115
115
|
print(f"Patterns Used: {len(analysis.pattern_ids)}")
|
|
@@ -148,7 +148,7 @@ def cmd_analyze(args):
|
|
|
148
148
|
# JSON output if requested
|
|
149
149
|
if args.json:
|
|
150
150
|
json_output = analysis.to_dict()
|
|
151
|
-
json_file = Path(f"{
|
|
151
|
+
json_file = Path(f"{workflow_id}_risk_analysis.json")
|
|
152
152
|
with open(json_file, "w") as f:
|
|
153
153
|
json.dump(json_output, f, indent=2)
|
|
154
154
|
print(f"\n✓ JSON output written to: {json_file}")
|
|
@@ -157,18 +157,18 @@ def cmd_analyze(args):
|
|
|
157
157
|
def main():
|
|
158
158
|
"""Main CLI entry point."""
|
|
159
159
|
parser = argparse.ArgumentParser(
|
|
160
|
-
description="Test Generator for Empathy
|
|
160
|
+
description="Test Generator for Empathy Workflow Factory",
|
|
161
161
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
162
162
|
epilog="""
|
|
163
163
|
Examples:
|
|
164
|
-
# Generate tests for SOAP Note
|
|
164
|
+
# Generate tests for SOAP Note workflow
|
|
165
165
|
%(prog)s generate soap_note --patterns linear_flow,approval,structured_fields
|
|
166
166
|
|
|
167
|
-
# Analyze risk for debugging
|
|
167
|
+
# Analyze risk for debugging workflow
|
|
168
168
|
%(prog)s analyze debugging --patterns code_analysis_input,risk_assessment
|
|
169
169
|
|
|
170
170
|
# Generate with custom module/class
|
|
171
|
-
%(prog)s generate
|
|
171
|
+
%(prog)s generate my_workflow --patterns linear_flow --module workflows.my_workflow --class MyWorkflow
|
|
172
172
|
|
|
173
173
|
# Output to custom directory
|
|
174
174
|
%(prog)s generate soap_note --patterns linear_flow --output tests/custom/
|
|
@@ -178,8 +178,8 @@ Examples:
|
|
|
178
178
|
subparsers = parser.add_subparsers(dest="command", help="Command to run")
|
|
179
179
|
|
|
180
180
|
# Generate command
|
|
181
|
-
gen_parser = subparsers.add_parser("generate", help="Generate tests for a
|
|
182
|
-
gen_parser.add_argument("
|
|
181
|
+
gen_parser = subparsers.add_parser("generate", help="Generate tests for a workflow")
|
|
182
|
+
gen_parser.add_argument("workflow_id", help="Workflow identifier (e.g., soap_note)")
|
|
183
183
|
gen_parser.add_argument(
|
|
184
184
|
"--patterns",
|
|
185
185
|
required=True,
|
|
@@ -187,22 +187,22 @@ Examples:
|
|
|
187
187
|
)
|
|
188
188
|
gen_parser.add_argument(
|
|
189
189
|
"--module",
|
|
190
|
-
help="Python module path (e.g.,
|
|
190
|
+
help="Python module path (e.g., workflows.soap_note)",
|
|
191
191
|
)
|
|
192
192
|
gen_parser.add_argument(
|
|
193
193
|
"--class",
|
|
194
|
-
dest="
|
|
195
|
-
help="
|
|
194
|
+
dest="workflow_class",
|
|
195
|
+
help="Workflow class name (e.g., SOAPNoteWorkflow)",
|
|
196
196
|
)
|
|
197
197
|
gen_parser.add_argument(
|
|
198
198
|
"--output",
|
|
199
199
|
"-o",
|
|
200
|
-
help="Output directory (default: tests/unit/
|
|
200
|
+
help="Output directory (default: tests/unit/workflows/)",
|
|
201
201
|
)
|
|
202
202
|
|
|
203
203
|
# Analyze command
|
|
204
|
-
analyze_parser = subparsers.add_parser("analyze", help="Analyze
|
|
205
|
-
analyze_parser.add_argument("
|
|
204
|
+
analyze_parser = subparsers.add_parser("analyze", help="Analyze workflow risk")
|
|
205
|
+
analyze_parser.add_argument("workflow_id", help="Workflow identifier")
|
|
206
206
|
analyze_parser.add_argument(
|
|
207
207
|
"--patterns",
|
|
208
208
|
required=True,
|