empathy-framework 4.6.6__py3-none-any.whl → 4.7.1__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.7.1.dist-info/METADATA +690 -0
- empathy_framework-4.7.1.dist-info/RECORD +379 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/top_level.txt +1 -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 2.py +173 -0
- 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/README 2.md +454 -0
- empathy_os/workflows/progressive/__init__ 2.py +92 -0
- empathy_os/workflows/progressive/__init__.py +2 -12
- empathy_os/workflows/progressive/cli 2.py +242 -0
- empathy_os/workflows/progressive/cli.py +14 -37
- empathy_os/workflows/progressive/core 2.py +488 -0
- empathy_os/workflows/progressive/core.py +12 -12
- empathy_os/workflows/progressive/orchestrator 2.py +701 -0
- empathy_os/workflows/progressive/orchestrator.py +166 -144
- empathy_os/workflows/progressive/reports 2.py +528 -0
- empathy_os/workflows/progressive/reports.py +22 -31
- empathy_os/workflows/progressive/telemetry 2.py +280 -0
- empathy_os/workflows/progressive/telemetry.py +8 -14
- empathy_os/workflows/progressive/test_gen 2.py +514 -0
- empathy_os/workflows/progressive/test_gen.py +29 -48
- empathy_os/workflows/progressive/workflow 2.py +628 -0
- 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
- patterns/README.md +119 -0
- patterns/__init__.py +95 -0
- patterns/behavior.py +298 -0
- patterns/code_review_memory.json +441 -0
- patterns/core.py +97 -0
- patterns/debugging.json +3763 -0
- patterns/empathy.py +268 -0
- patterns/health_check_memory.json +505 -0
- patterns/input.py +161 -0
- patterns/memory_graph.json +8 -0
- patterns/refactoring_memory.json +1113 -0
- patterns/registry.py +663 -0
- patterns/security_memory.json +8 -0
- patterns/structural.py +415 -0
- patterns/validation.py +194 -0
- 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/METADATA +0 -1597
- 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.1.dist-info}/WHEEL +0 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/entry_points.txt +0 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/licenses/LICENSE +0 -0
empathy_os/scaffolding/cli.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"""CLI for
|
|
1
|
+
"""CLI for workflow scaffolding.
|
|
2
2
|
|
|
3
3
|
Usage:
|
|
4
|
-
python -m scaffolding create
|
|
5
|
-
python -m scaffolding create
|
|
6
|
-
python -m scaffolding create
|
|
4
|
+
python -m scaffolding create my_workflow --domain healthcare
|
|
5
|
+
python -m scaffolding create my_workflow --methodology tdd --domain finance
|
|
6
|
+
python -m scaffolding create my_workflow --interactive
|
|
7
7
|
|
|
8
8
|
Copyright 2025 Smart AI Memory, LLC
|
|
9
9
|
Licensed under Fair Source 0.9
|
|
@@ -26,29 +26,29 @@ logger = logging.getLogger(__name__)
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def cmd_create(args):
|
|
29
|
-
"""Create a new
|
|
29
|
+
"""Create a new workflow using specified methodology.
|
|
30
30
|
|
|
31
31
|
Args:
|
|
32
32
|
args: Command line arguments
|
|
33
33
|
|
|
34
34
|
"""
|
|
35
|
-
|
|
35
|
+
workflow_name = args.name
|
|
36
36
|
domain = args.domain or "general"
|
|
37
|
-
|
|
37
|
+
workflow_type = args.type or "domain"
|
|
38
38
|
methodology = args.methodology or "pattern"
|
|
39
39
|
|
|
40
40
|
print(f"\n{'=' * 60}")
|
|
41
|
-
print(f"Creating
|
|
41
|
+
print(f"Creating Workflow: {workflow_name}")
|
|
42
42
|
print(f"{'=' * 60}\n")
|
|
43
43
|
print(f"Domain: {domain}")
|
|
44
|
-
print(f"Type: {
|
|
44
|
+
print(f"Type: {workflow_type}")
|
|
45
45
|
print(f"Methodology: {methodology}")
|
|
46
46
|
print()
|
|
47
47
|
|
|
48
48
|
# Get pattern recommendations
|
|
49
49
|
registry = get_pattern_registry()
|
|
50
|
-
recommended = registry.
|
|
51
|
-
|
|
50
|
+
recommended = registry.recommend_for_workflow(
|
|
51
|
+
workflow_type=workflow_type,
|
|
52
52
|
domain=domain,
|
|
53
53
|
)
|
|
54
54
|
|
|
@@ -82,23 +82,23 @@ def cmd_create(args):
|
|
|
82
82
|
for pid in selected_patterns:
|
|
83
83
|
print(f" - {pid}")
|
|
84
84
|
|
|
85
|
-
# Create
|
|
86
|
-
print(f"\nCreating
|
|
85
|
+
# Create workflow using selected methodology
|
|
86
|
+
print(f"\nCreating workflow with {methodology} methodology...")
|
|
87
87
|
|
|
88
88
|
if methodology == "pattern":
|
|
89
89
|
method = PatternCompose()
|
|
90
|
-
result = method.
|
|
91
|
-
name=
|
|
90
|
+
result = method.create_workflow(
|
|
91
|
+
name=workflow_name,
|
|
92
92
|
domain=domain,
|
|
93
|
-
|
|
93
|
+
workflow_type=workflow_type,
|
|
94
94
|
selected_patterns=selected_patterns,
|
|
95
95
|
)
|
|
96
96
|
elif methodology == "tdd":
|
|
97
97
|
method = TDDFirst()
|
|
98
|
-
result = method.
|
|
99
|
-
name=
|
|
98
|
+
result = method.create_workflow(
|
|
99
|
+
name=workflow_name,
|
|
100
100
|
domain=domain,
|
|
101
|
-
|
|
101
|
+
workflow_type=workflow_type,
|
|
102
102
|
pattern_ids=selected_patterns,
|
|
103
103
|
)
|
|
104
104
|
else:
|
|
@@ -107,7 +107,7 @@ def cmd_create(args):
|
|
|
107
107
|
|
|
108
108
|
# Display results
|
|
109
109
|
print(f"\n{'=' * 60}")
|
|
110
|
-
print("✅
|
|
110
|
+
print("✅ Workflow Created Successfully!")
|
|
111
111
|
print(f"{'=' * 60}\n")
|
|
112
112
|
|
|
113
113
|
print("Generated Files:")
|
|
@@ -162,21 +162,21 @@ def cmd_list_patterns(args):
|
|
|
162
162
|
def main():
|
|
163
163
|
"""Main CLI entry point."""
|
|
164
164
|
parser = argparse.ArgumentParser(
|
|
165
|
-
description="
|
|
165
|
+
description="Workflow Scaffolding for Empathy Framework",
|
|
166
166
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
167
167
|
epilog="""
|
|
168
168
|
Examples:
|
|
169
|
-
# Create healthcare
|
|
169
|
+
# Create healthcare workflow (recommended approach)
|
|
170
170
|
%(prog)s create patient_intake --domain healthcare
|
|
171
171
|
|
|
172
172
|
# Create with TDD methodology
|
|
173
|
-
%(prog)s create
|
|
173
|
+
%(prog)s create my_workflow --methodology tdd --domain finance
|
|
174
174
|
|
|
175
175
|
# Interactive pattern selection
|
|
176
|
-
%(prog)s create
|
|
176
|
+
%(prog)s create my_workflow --interactive --domain legal
|
|
177
177
|
|
|
178
178
|
# Specify patterns manually
|
|
179
|
-
%(prog)s create
|
|
179
|
+
%(prog)s create my_workflow --patterns linear_flow,approval,structured_fields
|
|
180
180
|
|
|
181
181
|
# List available patterns
|
|
182
182
|
%(prog)s list-patterns
|
|
@@ -186,8 +186,8 @@ Examples:
|
|
|
186
186
|
subparsers = parser.add_subparsers(dest="command", help="Command to run")
|
|
187
187
|
|
|
188
188
|
# Create command
|
|
189
|
-
create_parser = subparsers.add_parser("create", help="Create a new
|
|
190
|
-
create_parser.add_argument("name", help="
|
|
189
|
+
create_parser = subparsers.add_parser("create", help="Create a new workflow")
|
|
190
|
+
create_parser.add_argument("name", help="Workflow name (e.g., patient_intake)")
|
|
191
191
|
create_parser.add_argument(
|
|
192
192
|
"--domain",
|
|
193
193
|
"-d",
|
|
@@ -197,7 +197,7 @@ Examples:
|
|
|
197
197
|
"--type",
|
|
198
198
|
"-t",
|
|
199
199
|
choices=["domain", "coach", "ai"],
|
|
200
|
-
help="
|
|
200
|
+
help="Workflow type (default: domain)",
|
|
201
201
|
)
|
|
202
202
|
create_parser.add_argument(
|
|
203
203
|
"--methodology",
|
empathy_os/socratic/__init__.py
CHANGED
|
@@ -43,12 +43,7 @@ from .ab_testing import (
|
|
|
43
43
|
Variant,
|
|
44
44
|
WorkflowABTester,
|
|
45
45
|
)
|
|
46
|
-
from .blueprint import
|
|
47
|
-
AgentBlueprint,
|
|
48
|
-
AgentSpec,
|
|
49
|
-
ToolSpec,
|
|
50
|
-
WorkflowBlueprint,
|
|
51
|
-
)
|
|
46
|
+
from .blueprint import AgentBlueprint, AgentSpec, ToolSpec, WorkflowBlueprint
|
|
52
47
|
|
|
53
48
|
# CLI interface
|
|
54
49
|
from .cli import Console
|
|
@@ -110,13 +105,7 @@ from .feedback import (
|
|
|
110
105
|
FeedbackLoop,
|
|
111
106
|
WorkflowPattern,
|
|
112
107
|
)
|
|
113
|
-
from .forms import
|
|
114
|
-
FieldType,
|
|
115
|
-
Form,
|
|
116
|
-
FormField,
|
|
117
|
-
FormResponse,
|
|
118
|
-
ValidationResult,
|
|
119
|
-
)
|
|
108
|
+
from .forms import FieldType, Form, FormField, FormResponse, ValidationResult
|
|
120
109
|
from .generator import AgentGenerator
|
|
121
110
|
|
|
122
111
|
# LLM-powered analysis
|
|
@@ -133,12 +122,7 @@ from .mcp_server import SOCRATIC_TOOLS, SocraticMCPServer
|
|
|
133
122
|
from .session import SessionState, SocraticSession
|
|
134
123
|
|
|
135
124
|
# Persistent storage
|
|
136
|
-
from .storage import
|
|
137
|
-
JSONFileStorage,
|
|
138
|
-
SQLiteStorage,
|
|
139
|
-
StorageBackend,
|
|
140
|
-
StorageManager,
|
|
141
|
-
)
|
|
125
|
+
from .storage import JSONFileStorage, SQLiteStorage, StorageBackend, StorageManager
|
|
142
126
|
from .success import MetricType, SuccessCriteria, SuccessMetric
|
|
143
127
|
|
|
144
128
|
# Visual editor
|
|
@@ -166,24 +166,16 @@ class Experiment:
|
|
|
166
166
|
variants=[Variant.from_dict(v) for v in data["variants"]],
|
|
167
167
|
domain_filter=data.get("domain_filter"),
|
|
168
168
|
goal_filter=data.get("goal_filter"),
|
|
169
|
-
allocation_strategy=AllocationStrategy(
|
|
170
|
-
data.get("allocation_strategy", "fixed")
|
|
171
|
-
),
|
|
169
|
+
allocation_strategy=AllocationStrategy(data.get("allocation_strategy", "fixed")),
|
|
172
170
|
min_sample_size=data.get("min_sample_size", 100),
|
|
173
171
|
max_duration_days=data.get("max_duration_days", 30),
|
|
174
172
|
confidence_level=data.get("confidence_level", 0.95),
|
|
175
173
|
status=ExperimentStatus(data.get("status", "draft")),
|
|
176
174
|
created_at=datetime.fromisoformat(data["created_at"]),
|
|
177
175
|
started_at=(
|
|
178
|
-
datetime.fromisoformat(data["started_at"])
|
|
179
|
-
if data.get("started_at")
|
|
180
|
-
else None
|
|
181
|
-
),
|
|
182
|
-
ended_at=(
|
|
183
|
-
datetime.fromisoformat(data["ended_at"])
|
|
184
|
-
if data.get("ended_at")
|
|
185
|
-
else None
|
|
176
|
+
datetime.fromisoformat(data["started_at"]) if data.get("started_at") else None
|
|
186
177
|
),
|
|
178
|
+
ended_at=(datetime.fromisoformat(data["ended_at"]) if data.get("ended_at") else None),
|
|
187
179
|
)
|
|
188
180
|
|
|
189
181
|
@property
|
|
@@ -360,7 +352,7 @@ class StatisticalAnalyzer:
|
|
|
360
352
|
# Continued fraction approximation (simplified)
|
|
361
353
|
result = 0.0
|
|
362
354
|
for k in range(100):
|
|
363
|
-
term = (x
|
|
355
|
+
term = (x**k) * math.gamma(a + k) / (math.gamma(k + 1) * math.gamma(a))
|
|
364
356
|
result += term * ((1 - x) ** b) / (a + k)
|
|
365
357
|
if abs(term) < 1e-10:
|
|
366
358
|
break
|
|
@@ -421,10 +413,12 @@ class TrafficAllocator:
|
|
|
421
413
|
def _fixed_allocation(self, user_id: str) -> Variant:
|
|
422
414
|
"""Deterministic allocation based on user ID hash."""
|
|
423
415
|
# Hash user ID for consistent assignment (not for security)
|
|
424
|
-
hash_val = int(
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
416
|
+
hash_val = int(
|
|
417
|
+
hashlib.md5(
|
|
418
|
+
f"{self.experiment.experiment_id}:{user_id}".encode(), usedforsecurity=False
|
|
419
|
+
).hexdigest(),
|
|
420
|
+
16,
|
|
421
|
+
)
|
|
428
422
|
bucket = hash_val % 100
|
|
429
423
|
|
|
430
424
|
cumulative = 0.0
|
|
@@ -471,12 +465,10 @@ class TrafficAllocator:
|
|
|
471
465
|
for variant in self.experiment.variants:
|
|
472
466
|
if variant.impressions == 0:
|
|
473
467
|
# Give unvisited variants high priority
|
|
474
|
-
ucb_scores.append((float(
|
|
468
|
+
ucb_scores.append((float("inf"), variant))
|
|
475
469
|
else:
|
|
476
470
|
mean = variant.avg_success_score
|
|
477
|
-
exploration = math.sqrt(
|
|
478
|
-
2 * math.log(total_impressions) / variant.impressions
|
|
479
|
-
)
|
|
471
|
+
exploration = math.sqrt(2 * math.log(total_impressions) / variant.impressions)
|
|
480
472
|
ucb = mean + exploration
|
|
481
473
|
ucb_scores.append((ucb, variant))
|
|
482
474
|
|
|
@@ -532,9 +524,7 @@ class ExperimentManager:
|
|
|
532
524
|
Returns:
|
|
533
525
|
Created experiment
|
|
534
526
|
"""
|
|
535
|
-
experiment_id = hashlib.sha256(
|
|
536
|
-
f"{name}:{time.time()}".encode()
|
|
537
|
-
).hexdigest()[:12]
|
|
527
|
+
experiment_id = hashlib.sha256(f"{name}:{time.time()}".encode()).hexdigest()[:12]
|
|
538
528
|
|
|
539
529
|
# Create variants
|
|
540
530
|
num_variants = 1 + len(treatment_configs)
|
|
@@ -552,14 +542,16 @@ class ExperimentManager:
|
|
|
552
542
|
]
|
|
553
543
|
|
|
554
544
|
for i, config in enumerate(treatment_configs):
|
|
555
|
-
variants.append(
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
545
|
+
variants.append(
|
|
546
|
+
Variant(
|
|
547
|
+
variant_id=f"{experiment_id}_treatment_{i}",
|
|
548
|
+
name=config.get("name", f"Treatment {i + 1}"),
|
|
549
|
+
description=config.get("description", ""),
|
|
550
|
+
config=config.get("config", config),
|
|
551
|
+
is_control=False,
|
|
552
|
+
traffic_percentage=traffic_each,
|
|
553
|
+
)
|
|
554
|
+
)
|
|
563
555
|
|
|
564
556
|
experiment = Experiment(
|
|
565
557
|
experiment_id=experiment_id,
|
|
@@ -724,8 +716,7 @@ class ExperimentManager:
|
|
|
724
716
|
# Calculate lift
|
|
725
717
|
if control.conversion_rate > 0:
|
|
726
718
|
lift = (
|
|
727
|
-
(best_treatment.conversion_rate - control.conversion_rate)
|
|
728
|
-
/ control.conversion_rate
|
|
719
|
+
(best_treatment.conversion_rate - control.conversion_rate) / control.conversion_rate
|
|
729
720
|
) * 100
|
|
730
721
|
else:
|
|
731
722
|
lift = 0.0
|
|
@@ -750,9 +741,7 @@ class ExperimentManager:
|
|
|
750
741
|
)
|
|
751
742
|
else:
|
|
752
743
|
winner = control
|
|
753
|
-
recommendation =
|
|
754
|
-
"Keep control. Treatment did not show improvement."
|
|
755
|
-
)
|
|
744
|
+
recommendation = "Keep control. Treatment did not show improvement."
|
|
756
745
|
else:
|
|
757
746
|
recommendation = (
|
|
758
747
|
f"No significant difference detected (p={p_value:.4f}). "
|
empathy_os/socratic/blueprint.py
CHANGED
|
@@ -404,27 +404,21 @@ class WorkflowBlueprint:
|
|
|
404
404
|
# Validate all agents
|
|
405
405
|
for agent in self.agents:
|
|
406
406
|
if not agent.validate():
|
|
407
|
-
errors.extend(
|
|
408
|
-
f"Agent '{agent.spec.id}': {e}" for e in agent.validation_errors
|
|
409
|
-
)
|
|
407
|
+
errors.extend(f"Agent '{agent.spec.id}': {e}" for e in agent.validation_errors)
|
|
410
408
|
|
|
411
409
|
# Validate stages reference valid agents
|
|
412
410
|
agent_ids = {a.spec.id for a in self.agents}
|
|
413
411
|
for stage in self.stages:
|
|
414
412
|
for agent_id in stage.agent_ids:
|
|
415
413
|
if agent_id not in agent_ids:
|
|
416
|
-
errors.append(
|
|
417
|
-
f"Stage '{stage.id}' references unknown agent '{agent_id}'"
|
|
418
|
-
)
|
|
414
|
+
errors.append(f"Stage '{stage.id}' references unknown agent '{agent_id}'")
|
|
419
415
|
|
|
420
416
|
# Validate stage dependencies
|
|
421
417
|
stage_ids = {s.id for s in self.stages}
|
|
422
418
|
for stage in self.stages:
|
|
423
419
|
for dep in stage.depends_on:
|
|
424
420
|
if dep not in stage_ids:
|
|
425
|
-
errors.append(
|
|
426
|
-
f"Stage '{stage.id}' depends on unknown stage '{dep}'"
|
|
427
|
-
)
|
|
421
|
+
errors.append(f"Stage '{stage.id}' depends on unknown stage '{dep}'")
|
|
428
422
|
|
|
429
423
|
return len(errors) == 0, errors
|
|
430
424
|
|
|
@@ -497,37 +491,43 @@ class WorkflowBlueprint:
|
|
|
497
491
|
|
|
498
492
|
# Parse tools
|
|
499
493
|
for tool_data in spec_data.get("tools", []):
|
|
500
|
-
spec.tools.append(
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
494
|
+
spec.tools.append(
|
|
495
|
+
ToolSpec(
|
|
496
|
+
id=tool_data.get("id", ""),
|
|
497
|
+
name=tool_data.get("name", ""),
|
|
498
|
+
category=ToolCategory(tool_data.get("category", "code_analysis")),
|
|
499
|
+
description=tool_data.get("description", ""),
|
|
500
|
+
parameters=tool_data.get("parameters", {}),
|
|
501
|
+
requires_confirmation=tool_data.get("requires_confirmation", False),
|
|
502
|
+
is_mutating=tool_data.get("is_mutating", False),
|
|
503
|
+
cost_tier=tool_data.get("cost_tier", "cheap"),
|
|
504
|
+
)
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
blueprint.agents.append(
|
|
508
|
+
AgentBlueprint(
|
|
509
|
+
spec=spec,
|
|
510
|
+
generated_from=agent_data.get("generated_from", "socratic"),
|
|
511
|
+
template_id=agent_data.get("template_id"),
|
|
512
|
+
customizations=agent_data.get("customizations", {}),
|
|
513
|
+
)
|
|
514
|
+
)
|
|
517
515
|
|
|
518
516
|
# Parse stages
|
|
519
517
|
for stage_data in data.get("stages", []):
|
|
520
|
-
blueprint.stages.append(
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
518
|
+
blueprint.stages.append(
|
|
519
|
+
StageSpec(
|
|
520
|
+
id=stage_data.get("id", ""),
|
|
521
|
+
name=stage_data.get("name", ""),
|
|
522
|
+
description=stage_data.get("description", ""),
|
|
523
|
+
agent_ids=stage_data.get("agent_ids", []),
|
|
524
|
+
parallel=stage_data.get("parallel", False),
|
|
525
|
+
run_when=stage_data.get("run_when"),
|
|
526
|
+
depends_on=stage_data.get("depends_on", []),
|
|
527
|
+
input_mapping=stage_data.get("input_mapping", {}),
|
|
528
|
+
output_aggregation=stage_data.get("output_aggregation", "merge"),
|
|
529
|
+
timeout=stage_data.get("timeout", 300),
|
|
530
|
+
)
|
|
531
|
+
)
|
|
532
532
|
|
|
533
533
|
return blueprint
|
empathy_os/socratic/cli.py
CHANGED
|
@@ -109,17 +109,13 @@ class Console:
|
|
|
109
109
|
widths[i] = max(widths[i], len(str(cell)))
|
|
110
110
|
|
|
111
111
|
# Print header
|
|
112
|
-
header_line = " | ".join(
|
|
113
|
-
self._c("bold", h.ljust(widths[i])) for i, h in enumerate(headers)
|
|
114
|
-
)
|
|
112
|
+
header_line = " | ".join(self._c("bold", h.ljust(widths[i])) for i, h in enumerate(headers))
|
|
115
113
|
print(header_line)
|
|
116
114
|
print("-" * (sum(widths) + len(widths) * 3 - 1))
|
|
117
115
|
|
|
118
116
|
# Print rows
|
|
119
117
|
for row in rows:
|
|
120
|
-
row_line = " | ".join(
|
|
121
|
-
str(cell).ljust(widths[i]) for i, cell in enumerate(row)
|
|
122
|
-
)
|
|
118
|
+
row_line = " | ".join(str(cell).ljust(widths[i]) for i, cell in enumerate(row))
|
|
123
119
|
print(row_line)
|
|
124
120
|
|
|
125
121
|
|
|
@@ -469,12 +465,18 @@ def cmd_list(args: argparse.Namespace) -> int:
|
|
|
469
465
|
headers = ["ID", "State", "Goal", "Updated"]
|
|
470
466
|
rows = []
|
|
471
467
|
for s in sessions:
|
|
472
|
-
rows.append(
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
468
|
+
rows.append(
|
|
469
|
+
[
|
|
470
|
+
s["session_id"][:8],
|
|
471
|
+
s["state"],
|
|
472
|
+
(
|
|
473
|
+
(s.get("goal") or "")[:40] + "..."
|
|
474
|
+
if len(s.get("goal") or "") > 40
|
|
475
|
+
else s.get("goal") or ""
|
|
476
|
+
),
|
|
477
|
+
s.get("updated_at", "")[:16],
|
|
478
|
+
]
|
|
479
|
+
)
|
|
478
480
|
|
|
479
481
|
console.table(headers, rows)
|
|
480
482
|
return 0
|
|
@@ -495,13 +497,15 @@ def cmd_blueprints(args: argparse.Namespace) -> int:
|
|
|
495
497
|
headers = ["ID", "Name", "Domain", "Agents", "Generated"]
|
|
496
498
|
rows = []
|
|
497
499
|
for b in blueprints:
|
|
498
|
-
rows.append(
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
500
|
+
rows.append(
|
|
501
|
+
[
|
|
502
|
+
b["id"][:8] if b.get("id") else "?",
|
|
503
|
+
b.get("name", "")[:30],
|
|
504
|
+
b.get("domain", ""),
|
|
505
|
+
str(b.get("agents_count", 0)),
|
|
506
|
+
(b.get("generated_at") or "")[:16],
|
|
507
|
+
]
|
|
508
|
+
)
|
|
505
509
|
|
|
506
510
|
console.table(headers, rows)
|
|
507
511
|
return 0
|
|
@@ -625,7 +629,17 @@ def create_parser() -> argparse.ArgumentParser:
|
|
|
625
629
|
|
|
626
630
|
# list
|
|
627
631
|
list_parser = subparsers.add_parser("list", help="List sessions")
|
|
628
|
-
list_parser.add_argument(
|
|
632
|
+
list_parser.add_argument(
|
|
633
|
+
"--state",
|
|
634
|
+
"-s",
|
|
635
|
+
choices=[
|
|
636
|
+
"awaiting_goal",
|
|
637
|
+
"awaiting_answers",
|
|
638
|
+
"ready_to_generate",
|
|
639
|
+
"completed",
|
|
640
|
+
"cancelled",
|
|
641
|
+
],
|
|
642
|
+
)
|
|
629
643
|
list_parser.add_argument("--limit", "-n", type=int, default=20)
|
|
630
644
|
|
|
631
645
|
# blueprints
|
|
@@ -348,9 +348,7 @@ class CollaborationManager:
|
|
|
348
348
|
Returns:
|
|
349
349
|
The created session
|
|
350
350
|
"""
|
|
351
|
-
session_id = hashlib.sha256(
|
|
352
|
-
f"{base_session_id}:{time.time()}".encode()
|
|
353
|
-
).hexdigest()[:12]
|
|
351
|
+
session_id = hashlib.sha256(f"{base_session_id}:{time.time()}".encode()).hexdigest()[:12]
|
|
354
352
|
|
|
355
353
|
owner = Participant(
|
|
356
354
|
user_id=owner_id,
|
|
@@ -485,9 +483,9 @@ class CollaborationManager:
|
|
|
485
483
|
if not author:
|
|
486
484
|
return None
|
|
487
485
|
|
|
488
|
-
comment_id = hashlib.sha256(
|
|
489
|
-
|
|
490
|
-
|
|
486
|
+
comment_id = hashlib.sha256(f"{session_id}:{author_id}:{time.time()}".encode()).hexdigest()[
|
|
487
|
+
:12
|
|
488
|
+
]
|
|
491
489
|
|
|
492
490
|
comment = Comment(
|
|
493
491
|
comment_id=comment_id,
|
|
@@ -614,9 +612,14 @@ class CollaborationManager:
|
|
|
614
612
|
|
|
615
613
|
# Check if already voted
|
|
616
614
|
existing = next(
|
|
617
|
-
(
|
|
618
|
-
|
|
619
|
-
|
|
615
|
+
(
|
|
616
|
+
v
|
|
617
|
+
for v in session.votes
|
|
618
|
+
if v.voter_id == voter_id
|
|
619
|
+
and v.target_type == target_type
|
|
620
|
+
and v.target_id == target_id
|
|
621
|
+
),
|
|
622
|
+
None,
|
|
620
623
|
)
|
|
621
624
|
if existing:
|
|
622
625
|
# Update existing vote
|
|
@@ -676,8 +679,7 @@ class CollaborationManager:
|
|
|
676
679
|
|
|
677
680
|
# Get votes for this target
|
|
678
681
|
votes = [
|
|
679
|
-
v for v in session.votes
|
|
680
|
-
if v.target_type == target_type and v.target_id == target_id
|
|
682
|
+
v for v in session.votes if v.target_type == target_type and v.target_id == target_id
|
|
681
683
|
]
|
|
682
684
|
|
|
683
685
|
# Count by type
|
|
@@ -686,10 +688,7 @@ class CollaborationManager:
|
|
|
686
688
|
abstentions = sum(1 for v in votes if v.vote_type == VoteType.ABSTAIN)
|
|
687
689
|
|
|
688
690
|
# Calculate quorum
|
|
689
|
-
eligible_voters = [
|
|
690
|
-
p for p in session.participants
|
|
691
|
-
if p.role != ParticipantRole.VIEWER
|
|
692
|
-
]
|
|
691
|
+
eligible_voters = [p for p in session.participants if p.role != ParticipantRole.VIEWER]
|
|
693
692
|
participation_rate = len(votes) / len(eligible_voters) if eligible_voters else 0
|
|
694
693
|
quorum_reached = participation_rate >= session.quorum
|
|
695
694
|
|
|
@@ -731,8 +730,7 @@ class CollaborationManager:
|
|
|
731
730
|
return []
|
|
732
731
|
|
|
733
732
|
comments = [
|
|
734
|
-
c for c in session.comments
|
|
735
|
-
if c.target_type == target_type and c.target_id == target_id
|
|
733
|
+
c for c in session.comments if c.target_type == target_type and c.target_id == target_id
|
|
736
734
|
]
|
|
737
735
|
|
|
738
736
|
if not include_resolved:
|
|
@@ -786,8 +784,7 @@ class CollaborationManager:
|
|
|
786
784
|
session = self._sessions.get(session_id)
|
|
787
785
|
if session:
|
|
788
786
|
self._track_change(
|
|
789
|
-
session, change_type, author_id, description,
|
|
790
|
-
before_value, after_value
|
|
787
|
+
session, change_type, author_id, description, before_value, after_value
|
|
791
788
|
)
|
|
792
789
|
self._save_session(session)
|
|
793
790
|
|
|
@@ -818,9 +815,7 @@ class CollaborationManager:
|
|
|
818
815
|
after_value: Any = None,
|
|
819
816
|
):
|
|
820
817
|
"""Internal method to track a change."""
|
|
821
|
-
change_id = hashlib.sha256(
|
|
822
|
-
f"{session.session_id}:{time.time()}".encode()
|
|
823
|
-
).hexdigest()[:12]
|
|
818
|
+
change_id = hashlib.sha256(f"{session.session_id}:{time.time()}".encode()).hexdigest()[:12]
|
|
824
819
|
|
|
825
820
|
change = Change(
|
|
826
821
|
change_id=change_id,
|
|
@@ -836,7 +831,9 @@ class CollaborationManager:
|
|
|
836
831
|
for listener in self._change_listeners:
|
|
837
832
|
try:
|
|
838
833
|
listener(change)
|
|
839
|
-
except Exception:
|
|
834
|
+
except Exception: # noqa: BLE001
|
|
835
|
+
# INTENTIONAL: Listener failure should not break change tracking.
|
|
836
|
+
# One bad listener shouldn't prevent others from executing.
|
|
840
837
|
pass
|
|
841
838
|
|
|
842
839
|
def _save_session(self, session: CollaborativeSession):
|
|
@@ -853,7 +850,9 @@ class CollaborationManager:
|
|
|
853
850
|
data = json.load(f)
|
|
854
851
|
session = CollaborativeSession.from_dict(data)
|
|
855
852
|
self._sessions[session.session_id] = session
|
|
856
|
-
except Exception:
|
|
853
|
+
except Exception: # noqa: BLE001
|
|
854
|
+
# INTENTIONAL: Skip corrupted session files gracefully.
|
|
855
|
+
# Loading should not fail due to one malformed file.
|
|
857
856
|
pass
|
|
858
857
|
|
|
859
858
|
def list_sessions(self) -> list[CollaborativeSession]:
|
|
@@ -874,8 +873,7 @@ class CollaborationManager:
|
|
|
874
873
|
List of sessions the user participates in
|
|
875
874
|
"""
|
|
876
875
|
return [
|
|
877
|
-
s for s in self._sessions.values()
|
|
878
|
-
if any(p.user_id == user_id for p in s.participants)
|
|
876
|
+
s for s in self._sessions.values() if any(p.user_id == user_id for p in s.participants)
|
|
879
877
|
]
|
|
880
878
|
|
|
881
879
|
|
|
@@ -930,7 +928,9 @@ class SyncAdapter:
|
|
|
930
928
|
for handler in self._event_handlers:
|
|
931
929
|
try:
|
|
932
930
|
handler(event)
|
|
933
|
-
except Exception:
|
|
931
|
+
except Exception: # noqa: BLE001
|
|
932
|
+
# INTENTIONAL: Handler failure should not prevent other handlers.
|
|
933
|
+
# Event propagation must continue for sync reliability.
|
|
934
934
|
pass
|
|
935
935
|
|
|
936
936
|
def on_event(self, handler: Callable[[SyncEvent], None]):
|
|
@@ -1038,6 +1038,7 @@ class InvitationManager:
|
|
|
1038
1038
|
).hexdigest()[:16]
|
|
1039
1039
|
|
|
1040
1040
|
from datetime import timedelta
|
|
1041
|
+
|
|
1041
1042
|
expires = datetime.now() + timedelta(hours=expires_hours)
|
|
1042
1043
|
|
|
1043
1044
|
invitation = Invitation(
|
|
@@ -1105,7 +1106,8 @@ class InvitationManager:
|
|
|
1105
1106
|
"""
|
|
1106
1107
|
now = datetime.now()
|
|
1107
1108
|
return [
|
|
1108
|
-
inv
|
|
1109
|
+
inv
|
|
1110
|
+
for inv in self._invitations.values()
|
|
1109
1111
|
if inv.session_id == session_id
|
|
1110
1112
|
and not inv.accepted
|
|
1111
1113
|
and (inv.expires_at is None or inv.expires_at > now)
|
|
@@ -777,7 +777,15 @@ class DomainTemplateRegistry:
|
|
|
777
777
|
agents=[SECURITY_SCANNER, COMPLIANCE_AUDITOR, RESULT_SYNTHESIZER],
|
|
778
778
|
workflows=[SECURITY_AUDIT_WORKFLOW],
|
|
779
779
|
default_workflow="security_audit_comprehensive",
|
|
780
|
-
keywords=[
|
|
780
|
+
keywords=[
|
|
781
|
+
"security",
|
|
782
|
+
"vulnerability",
|
|
783
|
+
"audit",
|
|
784
|
+
"compliance",
|
|
785
|
+
"penetration",
|
|
786
|
+
"CVE",
|
|
787
|
+
"OWASP",
|
|
788
|
+
],
|
|
781
789
|
required_tools=["read_file", "security_scan"],
|
|
782
790
|
optional_tools=["grep_code", "analyze_ast"],
|
|
783
791
|
)
|