htmlgraph 0.20.1__py3-none-any.whl → 0.27.5__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.
- htmlgraph/.htmlgraph/.session-warning-state.json +6 -0
- htmlgraph/.htmlgraph/agents.json +72 -0
- htmlgraph/.htmlgraph/htmlgraph.db +0 -0
- htmlgraph/__init__.py +51 -1
- htmlgraph/__init__.pyi +123 -0
- htmlgraph/agent_detection.py +26 -10
- htmlgraph/agent_registry.py +2 -1
- htmlgraph/analytics/__init__.py +8 -1
- htmlgraph/analytics/cli.py +86 -20
- htmlgraph/analytics/cost_analyzer.py +391 -0
- htmlgraph/analytics/cost_monitor.py +664 -0
- htmlgraph/analytics/cost_reporter.py +675 -0
- htmlgraph/analytics/cross_session.py +617 -0
- htmlgraph/analytics/dependency.py +10 -6
- htmlgraph/analytics/pattern_learning.py +771 -0
- htmlgraph/analytics/session_graph.py +707 -0
- htmlgraph/analytics/strategic/__init__.py +80 -0
- htmlgraph/analytics/strategic/cost_optimizer.py +611 -0
- htmlgraph/analytics/strategic/pattern_detector.py +876 -0
- htmlgraph/analytics/strategic/preference_manager.py +709 -0
- htmlgraph/analytics/strategic/suggestion_engine.py +747 -0
- htmlgraph/analytics/work_type.py +67 -27
- htmlgraph/analytics_index.py +53 -20
- htmlgraph/api/__init__.py +3 -0
- htmlgraph/api/cost_alerts_websocket.py +416 -0
- htmlgraph/api/main.py +2498 -0
- htmlgraph/api/static/htmx.min.js +1 -0
- htmlgraph/api/static/style-redesign.css +1344 -0
- htmlgraph/api/static/style.css +1079 -0
- htmlgraph/api/templates/dashboard-redesign.html +1366 -0
- htmlgraph/api/templates/dashboard.html +794 -0
- htmlgraph/api/templates/partials/activity-feed-hierarchical.html +326 -0
- htmlgraph/api/templates/partials/activity-feed.html +1100 -0
- htmlgraph/api/templates/partials/agents-redesign.html +317 -0
- htmlgraph/api/templates/partials/agents.html +317 -0
- htmlgraph/api/templates/partials/event-traces.html +373 -0
- htmlgraph/api/templates/partials/features-kanban-redesign.html +509 -0
- htmlgraph/api/templates/partials/features.html +578 -0
- htmlgraph/api/templates/partials/metrics-redesign.html +346 -0
- htmlgraph/api/templates/partials/metrics.html +346 -0
- htmlgraph/api/templates/partials/orchestration-redesign.html +443 -0
- htmlgraph/api/templates/partials/orchestration.html +198 -0
- htmlgraph/api/templates/partials/spawners.html +375 -0
- htmlgraph/api/templates/partials/work-items.html +613 -0
- htmlgraph/api/websocket.py +538 -0
- htmlgraph/archive/__init__.py +24 -0
- htmlgraph/archive/bloom.py +234 -0
- htmlgraph/archive/fts.py +297 -0
- htmlgraph/archive/manager.py +583 -0
- htmlgraph/archive/search.py +244 -0
- htmlgraph/atomic_ops.py +560 -0
- htmlgraph/attribute_index.py +2 -1
- htmlgraph/bounded_paths.py +539 -0
- htmlgraph/builders/base.py +57 -2
- htmlgraph/builders/bug.py +19 -3
- htmlgraph/builders/chore.py +19 -3
- htmlgraph/builders/epic.py +19 -3
- htmlgraph/builders/feature.py +27 -3
- htmlgraph/builders/insight.py +2 -1
- htmlgraph/builders/metric.py +2 -1
- htmlgraph/builders/pattern.py +2 -1
- htmlgraph/builders/phase.py +19 -3
- htmlgraph/builders/spike.py +29 -3
- htmlgraph/builders/track.py +42 -1
- htmlgraph/cigs/__init__.py +81 -0
- htmlgraph/cigs/autonomy.py +385 -0
- htmlgraph/cigs/cost.py +475 -0
- htmlgraph/cigs/messages_basic.py +472 -0
- htmlgraph/cigs/messaging.py +365 -0
- htmlgraph/cigs/models.py +771 -0
- htmlgraph/cigs/pattern_storage.py +427 -0
- htmlgraph/cigs/patterns.py +503 -0
- htmlgraph/cigs/posttool_analyzer.py +234 -0
- htmlgraph/cigs/reporter.py +818 -0
- htmlgraph/cigs/tracker.py +317 -0
- htmlgraph/cli/.htmlgraph/.session-warning-state.json +6 -0
- htmlgraph/cli/.htmlgraph/agents.json +72 -0
- htmlgraph/cli/.htmlgraph/htmlgraph.db +0 -0
- htmlgraph/cli/__init__.py +42 -0
- htmlgraph/cli/__main__.py +6 -0
- htmlgraph/cli/analytics.py +1424 -0
- htmlgraph/cli/base.py +685 -0
- htmlgraph/cli/constants.py +206 -0
- htmlgraph/cli/core.py +954 -0
- htmlgraph/cli/main.py +147 -0
- htmlgraph/cli/models.py +475 -0
- htmlgraph/cli/templates/__init__.py +1 -0
- htmlgraph/cli/templates/cost_dashboard.py +399 -0
- htmlgraph/cli/work/__init__.py +239 -0
- htmlgraph/cli/work/browse.py +115 -0
- htmlgraph/cli/work/features.py +568 -0
- htmlgraph/cli/work/orchestration.py +676 -0
- htmlgraph/cli/work/report.py +728 -0
- htmlgraph/cli/work/sessions.py +466 -0
- htmlgraph/cli/work/snapshot.py +559 -0
- htmlgraph/cli/work/tracks.py +486 -0
- htmlgraph/cli_commands/__init__.py +1 -0
- htmlgraph/cli_commands/feature.py +195 -0
- htmlgraph/cli_framework.py +115 -0
- htmlgraph/collections/__init__.py +2 -0
- htmlgraph/collections/base.py +197 -14
- htmlgraph/collections/bug.py +2 -1
- htmlgraph/collections/chore.py +2 -1
- htmlgraph/collections/epic.py +2 -1
- htmlgraph/collections/feature.py +2 -1
- htmlgraph/collections/insight.py +2 -1
- htmlgraph/collections/metric.py +2 -1
- htmlgraph/collections/pattern.py +2 -1
- htmlgraph/collections/phase.py +2 -1
- htmlgraph/collections/session.py +194 -0
- htmlgraph/collections/spike.py +13 -2
- htmlgraph/collections/task_delegation.py +241 -0
- htmlgraph/collections/todo.py +14 -1
- htmlgraph/collections/traces.py +487 -0
- htmlgraph/config/cost_models.json +56 -0
- htmlgraph/config.py +190 -0
- htmlgraph/context_analytics.py +2 -1
- htmlgraph/converter.py +116 -7
- htmlgraph/cost_analysis/__init__.py +5 -0
- htmlgraph/cost_analysis/analyzer.py +438 -0
- htmlgraph/dashboard.html +2246 -248
- htmlgraph/dashboard.html.backup +6592 -0
- htmlgraph/dashboard.html.bak +7181 -0
- htmlgraph/dashboard.html.bak2 +7231 -0
- htmlgraph/dashboard.html.bak3 +7232 -0
- htmlgraph/db/__init__.py +38 -0
- htmlgraph/db/queries.py +790 -0
- htmlgraph/db/schema.py +1788 -0
- htmlgraph/decorators.py +317 -0
- htmlgraph/dependency_models.py +2 -1
- htmlgraph/deploy.py +26 -27
- htmlgraph/docs/API_REFERENCE.md +841 -0
- htmlgraph/docs/HTTP_API.md +750 -0
- htmlgraph/docs/INTEGRATION_GUIDE.md +752 -0
- htmlgraph/docs/ORCHESTRATION_PATTERNS.md +717 -0
- htmlgraph/docs/README.md +532 -0
- htmlgraph/docs/__init__.py +77 -0
- htmlgraph/docs/docs_version.py +55 -0
- htmlgraph/docs/metadata.py +93 -0
- htmlgraph/docs/migrations.py +232 -0
- htmlgraph/docs/template_engine.py +143 -0
- htmlgraph/docs/templates/_sections/cli_reference.md.j2 +52 -0
- htmlgraph/docs/templates/_sections/core_concepts.md.j2 +29 -0
- htmlgraph/docs/templates/_sections/sdk_basics.md.j2 +69 -0
- htmlgraph/docs/templates/base_agents.md.j2 +78 -0
- htmlgraph/docs/templates/example_user_override.md.j2 +47 -0
- htmlgraph/docs/version_check.py +163 -0
- htmlgraph/edge_index.py +2 -1
- htmlgraph/error_handler.py +544 -0
- htmlgraph/event_log.py +86 -37
- htmlgraph/event_migration.py +2 -1
- htmlgraph/file_watcher.py +12 -8
- htmlgraph/find_api.py +2 -1
- htmlgraph/git_events.py +67 -9
- htmlgraph/hooks/.htmlgraph/.session-warning-state.json +6 -0
- htmlgraph/hooks/.htmlgraph/agents.json +72 -0
- htmlgraph/hooks/.htmlgraph/index.sqlite +0 -0
- htmlgraph/hooks/__init__.py +8 -0
- htmlgraph/hooks/bootstrap.py +169 -0
- htmlgraph/hooks/cigs_pretool_enforcer.py +354 -0
- htmlgraph/hooks/concurrent_sessions.py +208 -0
- htmlgraph/hooks/context.py +350 -0
- htmlgraph/hooks/drift_handler.py +525 -0
- htmlgraph/hooks/event_tracker.py +790 -99
- htmlgraph/hooks/git_commands.py +175 -0
- htmlgraph/hooks/installer.py +5 -1
- htmlgraph/hooks/orchestrator.py +327 -76
- htmlgraph/hooks/orchestrator_reflector.py +31 -4
- htmlgraph/hooks/post_tool_use_failure.py +32 -7
- htmlgraph/hooks/post_tool_use_handler.py +257 -0
- htmlgraph/hooks/posttooluse.py +92 -19
- htmlgraph/hooks/pretooluse.py +527 -7
- htmlgraph/hooks/prompt_analyzer.py +637 -0
- htmlgraph/hooks/session_handler.py +668 -0
- htmlgraph/hooks/session_summary.py +395 -0
- htmlgraph/hooks/state_manager.py +504 -0
- htmlgraph/hooks/subagent_detection.py +202 -0
- htmlgraph/hooks/subagent_stop.py +369 -0
- htmlgraph/hooks/task_enforcer.py +99 -4
- htmlgraph/hooks/validator.py +212 -91
- htmlgraph/ids.py +2 -1
- htmlgraph/learning.py +125 -100
- htmlgraph/mcp_server.py +2 -1
- htmlgraph/models.py +217 -18
- htmlgraph/operations/README.md +62 -0
- htmlgraph/operations/__init__.py +79 -0
- htmlgraph/operations/analytics.py +339 -0
- htmlgraph/operations/bootstrap.py +289 -0
- htmlgraph/operations/events.py +244 -0
- htmlgraph/operations/fastapi_server.py +231 -0
- htmlgraph/operations/hooks.py +350 -0
- htmlgraph/operations/initialization.py +597 -0
- htmlgraph/operations/initialization.py.backup +228 -0
- htmlgraph/operations/server.py +303 -0
- htmlgraph/orchestration/__init__.py +58 -0
- htmlgraph/orchestration/claude_launcher.py +179 -0
- htmlgraph/orchestration/command_builder.py +72 -0
- htmlgraph/orchestration/headless_spawner.py +281 -0
- htmlgraph/orchestration/live_events.py +377 -0
- htmlgraph/orchestration/model_selection.py +327 -0
- htmlgraph/orchestration/plugin_manager.py +140 -0
- htmlgraph/orchestration/prompts.py +137 -0
- htmlgraph/orchestration/spawner_event_tracker.py +383 -0
- htmlgraph/orchestration/spawners/__init__.py +16 -0
- htmlgraph/orchestration/spawners/base.py +194 -0
- htmlgraph/orchestration/spawners/claude.py +173 -0
- htmlgraph/orchestration/spawners/codex.py +435 -0
- htmlgraph/orchestration/spawners/copilot.py +294 -0
- htmlgraph/orchestration/spawners/gemini.py +471 -0
- htmlgraph/orchestration/subprocess_runner.py +36 -0
- htmlgraph/{orchestration.py → orchestration/task_coordination.py} +16 -8
- htmlgraph/orchestration.md +563 -0
- htmlgraph/orchestrator-system-prompt-optimized.txt +863 -0
- htmlgraph/orchestrator.py +2 -1
- htmlgraph/orchestrator_config.py +357 -0
- htmlgraph/orchestrator_mode.py +115 -4
- htmlgraph/parallel.py +2 -1
- htmlgraph/parser.py +86 -6
- htmlgraph/path_query.py +608 -0
- htmlgraph/pattern_matcher.py +636 -0
- htmlgraph/pydantic_models.py +476 -0
- htmlgraph/quality_gates.py +350 -0
- htmlgraph/query_builder.py +2 -1
- htmlgraph/query_composer.py +509 -0
- htmlgraph/reflection.py +443 -0
- htmlgraph/refs.py +344 -0
- htmlgraph/repo_hash.py +512 -0
- htmlgraph/repositories/__init__.py +292 -0
- htmlgraph/repositories/analytics_repository.py +455 -0
- htmlgraph/repositories/analytics_repository_standard.py +628 -0
- htmlgraph/repositories/feature_repository.py +581 -0
- htmlgraph/repositories/feature_repository_htmlfile.py +668 -0
- htmlgraph/repositories/feature_repository_memory.py +607 -0
- htmlgraph/repositories/feature_repository_sqlite.py +858 -0
- htmlgraph/repositories/filter_service.py +620 -0
- htmlgraph/repositories/filter_service_standard.py +445 -0
- htmlgraph/repositories/shared_cache.py +621 -0
- htmlgraph/repositories/shared_cache_memory.py +395 -0
- htmlgraph/repositories/track_repository.py +552 -0
- htmlgraph/repositories/track_repository_htmlfile.py +619 -0
- htmlgraph/repositories/track_repository_memory.py +508 -0
- htmlgraph/repositories/track_repository_sqlite.py +711 -0
- htmlgraph/sdk/__init__.py +398 -0
- htmlgraph/sdk/__init__.pyi +14 -0
- htmlgraph/sdk/analytics/__init__.py +19 -0
- htmlgraph/sdk/analytics/engine.py +155 -0
- htmlgraph/sdk/analytics/helpers.py +178 -0
- htmlgraph/sdk/analytics/registry.py +109 -0
- htmlgraph/sdk/base.py +484 -0
- htmlgraph/sdk/constants.py +216 -0
- htmlgraph/sdk/core.pyi +308 -0
- htmlgraph/sdk/discovery.py +120 -0
- htmlgraph/sdk/help/__init__.py +12 -0
- htmlgraph/sdk/help/mixin.py +699 -0
- htmlgraph/sdk/mixins/__init__.py +15 -0
- htmlgraph/sdk/mixins/attribution.py +113 -0
- htmlgraph/sdk/mixins/mixin.py +410 -0
- htmlgraph/sdk/operations/__init__.py +12 -0
- htmlgraph/sdk/operations/mixin.py +427 -0
- htmlgraph/sdk/orchestration/__init__.py +17 -0
- htmlgraph/sdk/orchestration/coordinator.py +203 -0
- htmlgraph/sdk/orchestration/spawner.py +204 -0
- htmlgraph/sdk/planning/__init__.py +19 -0
- htmlgraph/sdk/planning/bottlenecks.py +93 -0
- htmlgraph/sdk/planning/mixin.py +211 -0
- htmlgraph/sdk/planning/parallel.py +186 -0
- htmlgraph/sdk/planning/queue.py +210 -0
- htmlgraph/sdk/planning/recommendations.py +87 -0
- htmlgraph/sdk/planning/smart_planning.py +319 -0
- htmlgraph/sdk/session/__init__.py +19 -0
- htmlgraph/sdk/session/continuity.py +57 -0
- htmlgraph/sdk/session/handoff.py +110 -0
- htmlgraph/sdk/session/info.py +309 -0
- htmlgraph/sdk/session/manager.py +103 -0
- htmlgraph/sdk/strategic/__init__.py +26 -0
- htmlgraph/sdk/strategic/mixin.py +563 -0
- htmlgraph/server.py +295 -107
- htmlgraph/session_hooks.py +300 -0
- htmlgraph/session_manager.py +285 -3
- htmlgraph/session_registry.py +587 -0
- htmlgraph/session_state.py +436 -0
- htmlgraph/session_warning.py +2 -1
- htmlgraph/sessions/__init__.py +23 -0
- htmlgraph/sessions/handoff.py +756 -0
- htmlgraph/system_prompts.py +450 -0
- htmlgraph/templates/orchestration-view.html +350 -0
- htmlgraph/track_builder.py +33 -1
- htmlgraph/track_manager.py +38 -0
- htmlgraph/transcript.py +18 -5
- htmlgraph/validation.py +115 -0
- htmlgraph/watch.py +2 -1
- htmlgraph/work_type_utils.py +2 -1
- {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/dashboard.html +2246 -248
- {htmlgraph-0.20.1.dist-info → htmlgraph-0.27.5.dist-info}/METADATA +95 -64
- htmlgraph-0.27.5.dist-info/RECORD +337 -0
- {htmlgraph-0.20.1.dist-info → htmlgraph-0.27.5.dist-info}/entry_points.txt +1 -1
- htmlgraph/cli.py +0 -4839
- htmlgraph/sdk.py +0 -2359
- htmlgraph-0.20.1.dist-info/RECORD +0 -118
- {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/styles.css +0 -0
- {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/templates/AGENTS.md.template +0 -0
- {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/templates/CLAUDE.md.template +0 -0
- {htmlgraph-0.20.1.data → htmlgraph-0.27.5.data}/data/htmlgraph/templates/GEMINI.md.template +0 -0
- {htmlgraph-0.20.1.dist-info → htmlgraph-0.27.5.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AutonomyRecommender - Adaptive autonomy level management for CIGS.
|
|
3
|
+
|
|
4
|
+
Recommends appropriate autonomy levels based on:
|
|
5
|
+
- Average compliance from last 5 sessions
|
|
6
|
+
- Anti-pattern count
|
|
7
|
+
- Circuit breaker triggers
|
|
8
|
+
|
|
9
|
+
Reference: .htmlgraph/spikes/computational-imperative-guidance-system-design.md (Part 5, Section 5.4)
|
|
10
|
+
|
|
11
|
+
Decision Matrix:
|
|
12
|
+
- Observer (>90% compliance): Minimal guidance, trust developer
|
|
13
|
+
- Consultant (70-90% compliance): Moderate guidance, gentle nudges
|
|
14
|
+
- Collaborator (50-70% compliance): High guidance, active collaboration
|
|
15
|
+
- Operator (<50% compliance): Strict enforcement, mandatory acknowledgment
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from dataclasses import dataclass, field
|
|
19
|
+
|
|
20
|
+
from htmlgraph.cigs.models import (
|
|
21
|
+
AutonomyLevel,
|
|
22
|
+
PatternRecord,
|
|
23
|
+
SessionViolationSummary,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class AutonomyRecommender:
|
|
29
|
+
"""
|
|
30
|
+
Recommend autonomy level based on compliance history and patterns.
|
|
31
|
+
|
|
32
|
+
Implements a four-level decision matrix that adapts guidance intensity
|
|
33
|
+
based on demonstrated delegation compliance and detected anti-patterns.
|
|
34
|
+
|
|
35
|
+
Attributes:
|
|
36
|
+
compliance_history: List of compliance rates from recent sessions (0.0-1.0)
|
|
37
|
+
anti_pattern_count: Number of distinct anti-patterns detected
|
|
38
|
+
circuit_breaker_active: Whether circuit breaker was triggered in recent sessions
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
compliance_history: list[float] = field(default_factory=list)
|
|
42
|
+
anti_pattern_count: int = 0
|
|
43
|
+
circuit_breaker_active: bool = False
|
|
44
|
+
|
|
45
|
+
# Decision matrix thresholds
|
|
46
|
+
OBSERVER_THRESHOLD = 0.90
|
|
47
|
+
CONSULTANT_THRESHOLD = 0.70
|
|
48
|
+
COLLABORATOR_THRESHOLD = 0.50
|
|
49
|
+
|
|
50
|
+
def recommend(
|
|
51
|
+
self,
|
|
52
|
+
violations: SessionViolationSummary,
|
|
53
|
+
patterns: list[PatternRecord] | None = None,
|
|
54
|
+
compliance_history: list[float] | None = None,
|
|
55
|
+
) -> AutonomyLevel:
|
|
56
|
+
"""
|
|
57
|
+
Recommend autonomy level for next session.
|
|
58
|
+
|
|
59
|
+
Implements decision matrix:
|
|
60
|
+
- Observer (>90% compliance, no anti-patterns)
|
|
61
|
+
- Consultant (70-90% compliance OR 1-2 anti-patterns)
|
|
62
|
+
- Collaborator (50-70% compliance OR 3+ anti-patterns)
|
|
63
|
+
- Operator (<50% compliance OR circuit breaker triggered)
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
violations: Summary of violations from current/recent session
|
|
67
|
+
patterns: Detected behavioral patterns (if any)
|
|
68
|
+
compliance_history: Optional list of compliance rates from last 5 sessions
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
AutonomyLevel recommendation with messaging intensity and enforcement mode
|
|
72
|
+
"""
|
|
73
|
+
# Calculate average compliance
|
|
74
|
+
if compliance_history:
|
|
75
|
+
avg_compliance = sum(compliance_history) / len(compliance_history)
|
|
76
|
+
else:
|
|
77
|
+
avg_compliance = violations.compliance_rate
|
|
78
|
+
|
|
79
|
+
# Count anti-patterns
|
|
80
|
+
anti_pattern_count = 0
|
|
81
|
+
if patterns:
|
|
82
|
+
anti_pattern_count = len(
|
|
83
|
+
[p for p in patterns if p.pattern_type == "anti-pattern"]
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# Check circuit breaker status
|
|
87
|
+
circuit_breaker_active = violations.circuit_breaker_triggered
|
|
88
|
+
|
|
89
|
+
# Apply decision matrix
|
|
90
|
+
return self._apply_decision_matrix(
|
|
91
|
+
avg_compliance=avg_compliance,
|
|
92
|
+
anti_pattern_count=anti_pattern_count,
|
|
93
|
+
circuit_breaker_active=circuit_breaker_active,
|
|
94
|
+
violations_count=violations.total_violations,
|
|
95
|
+
patterns=patterns or [],
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
def _apply_decision_matrix(
|
|
99
|
+
self,
|
|
100
|
+
avg_compliance: float,
|
|
101
|
+
anti_pattern_count: int,
|
|
102
|
+
circuit_breaker_active: bool,
|
|
103
|
+
violations_count: int,
|
|
104
|
+
patterns: list[PatternRecord],
|
|
105
|
+
) -> AutonomyLevel:
|
|
106
|
+
"""
|
|
107
|
+
Apply the decision matrix to determine autonomy level.
|
|
108
|
+
|
|
109
|
+
Decision Logic:
|
|
110
|
+
1. If circuit breaker active -> OPERATOR (strict)
|
|
111
|
+
2. If avg_compliance > 90% AND no anti-patterns -> OBSERVER (minimal)
|
|
112
|
+
3. If avg_compliance > 70% OR anti_pattern_count <= 2 -> CONSULTANT (moderate)
|
|
113
|
+
4. If avg_compliance > 50% OR anti_pattern_count <= 4 -> COLLABORATOR (high)
|
|
114
|
+
5. Otherwise -> OPERATOR (strict)
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
avg_compliance: Average compliance rate (0.0-1.0)
|
|
118
|
+
anti_pattern_count: Number of anti-patterns detected
|
|
119
|
+
circuit_breaker_active: Whether circuit breaker is active
|
|
120
|
+
violations_count: Total violation count
|
|
121
|
+
patterns: List of detected patterns
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
AutonomyLevel recommendation
|
|
125
|
+
"""
|
|
126
|
+
# Circuit breaker takes precedence
|
|
127
|
+
if circuit_breaker_active:
|
|
128
|
+
return AutonomyLevel(
|
|
129
|
+
level="operator",
|
|
130
|
+
messaging_intensity="maximal",
|
|
131
|
+
enforcement_mode="strict",
|
|
132
|
+
reason=f"Circuit breaker triggered ({violations_count} violations). Strict enforcement required.",
|
|
133
|
+
based_on_violations=violations_count,
|
|
134
|
+
based_on_patterns=[
|
|
135
|
+
p.name for p in patterns if p.pattern_type == "anti-pattern"
|
|
136
|
+
],
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
# Observer: Excellent compliance, no patterns
|
|
140
|
+
if avg_compliance >= self.OBSERVER_THRESHOLD and anti_pattern_count == 0:
|
|
141
|
+
return AutonomyLevel(
|
|
142
|
+
level="observer",
|
|
143
|
+
messaging_intensity="minimal",
|
|
144
|
+
enforcement_mode="guidance",
|
|
145
|
+
reason=f"Excellent compliance ({avg_compliance:.0%}). Minimal guidance needed.",
|
|
146
|
+
based_on_violations=violations_count,
|
|
147
|
+
based_on_patterns=[
|
|
148
|
+
p.name for p in patterns if p.pattern_type == "anti-pattern"
|
|
149
|
+
],
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
# Consultant: Good compliance (70-90%) AND few anti-patterns (<=2)
|
|
153
|
+
if (
|
|
154
|
+
self.CONSULTANT_THRESHOLD <= avg_compliance < self.OBSERVER_THRESHOLD
|
|
155
|
+
) and anti_pattern_count <= 2:
|
|
156
|
+
anti_pattern_list = [
|
|
157
|
+
p.name for p in patterns if p.pattern_type == "anti-pattern"
|
|
158
|
+
]
|
|
159
|
+
pattern_note = (
|
|
160
|
+
f", {anti_pattern_count} anti-pattern(s)"
|
|
161
|
+
if anti_pattern_count > 0
|
|
162
|
+
else ""
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
return AutonomyLevel(
|
|
166
|
+
level="consultant",
|
|
167
|
+
messaging_intensity="moderate",
|
|
168
|
+
enforcement_mode="guidance",
|
|
169
|
+
reason=f"Good compliance ({avg_compliance:.0%}){pattern_note}. Moderate guidance recommended.",
|
|
170
|
+
based_on_violations=violations_count,
|
|
171
|
+
based_on_patterns=anti_pattern_list,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Collaborator: Moderate compliance (50-70%) AND moderate anti-patterns (3-4)
|
|
175
|
+
if (
|
|
176
|
+
self.COLLABORATOR_THRESHOLD <= avg_compliance < self.CONSULTANT_THRESHOLD
|
|
177
|
+
) and (2 < anti_pattern_count <= 4):
|
|
178
|
+
anti_pattern_list = [
|
|
179
|
+
p.name for p in patterns if p.pattern_type == "anti-pattern"
|
|
180
|
+
]
|
|
181
|
+
return AutonomyLevel(
|
|
182
|
+
level="collaborator",
|
|
183
|
+
messaging_intensity="high",
|
|
184
|
+
enforcement_mode="strict",
|
|
185
|
+
reason=f"Moderate compliance ({avg_compliance:.0%}), {anti_pattern_count} anti-pattern(s). Active guidance needed.",
|
|
186
|
+
based_on_violations=violations_count,
|
|
187
|
+
based_on_patterns=anti_pattern_list,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
# Operator: Low compliance (<50%) OR many anti-patterns (5+)
|
|
191
|
+
anti_pattern_list = [
|
|
192
|
+
p.name for p in patterns if p.pattern_type == "anti-pattern"
|
|
193
|
+
]
|
|
194
|
+
return AutonomyLevel(
|
|
195
|
+
level="operator",
|
|
196
|
+
messaging_intensity="maximal",
|
|
197
|
+
enforcement_mode="strict",
|
|
198
|
+
reason=f"Low compliance ({avg_compliance:.0%}), {anti_pattern_count} anti-pattern(s). Strict enforcement required.",
|
|
199
|
+
based_on_violations=violations_count,
|
|
200
|
+
based_on_patterns=anti_pattern_list,
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def recommend_from_compliance_history(
|
|
204
|
+
self,
|
|
205
|
+
compliance_history: list[float],
|
|
206
|
+
anti_pattern_count: int = 0,
|
|
207
|
+
circuit_breaker_active: bool = False,
|
|
208
|
+
) -> AutonomyLevel:
|
|
209
|
+
"""
|
|
210
|
+
Recommend autonomy level from compliance history alone.
|
|
211
|
+
|
|
212
|
+
Convenience method for cross-session recommendations when
|
|
213
|
+
only compliance history is available.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
compliance_history: List of compliance rates from last 5 sessions
|
|
217
|
+
anti_pattern_count: Number of anti-patterns detected
|
|
218
|
+
circuit_breaker_active: Whether circuit breaker was triggered
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
AutonomyLevel recommendation
|
|
222
|
+
"""
|
|
223
|
+
if not compliance_history:
|
|
224
|
+
# Default to Consultant if no history
|
|
225
|
+
return AutonomyLevel(
|
|
226
|
+
level="consultant",
|
|
227
|
+
messaging_intensity="moderate",
|
|
228
|
+
enforcement_mode="guidance",
|
|
229
|
+
reason="No compliance history. Defaulting to moderate guidance.",
|
|
230
|
+
based_on_violations=0,
|
|
231
|
+
based_on_patterns=[],
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
avg_compliance = sum(compliance_history) / len(compliance_history)
|
|
235
|
+
|
|
236
|
+
# Create minimal summary for decision matrix
|
|
237
|
+
violations = SessionViolationSummary(
|
|
238
|
+
session_id="unknown",
|
|
239
|
+
total_violations=0,
|
|
240
|
+
violations_by_type={},
|
|
241
|
+
total_waste_tokens=0,
|
|
242
|
+
circuit_breaker_triggered=circuit_breaker_active,
|
|
243
|
+
compliance_rate=avg_compliance,
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
return self.recommend(
|
|
247
|
+
violations=violations,
|
|
248
|
+
patterns=None,
|
|
249
|
+
compliance_history=compliance_history,
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
def evaluate_autonomy_transition(
|
|
253
|
+
self,
|
|
254
|
+
current_level: str,
|
|
255
|
+
new_level: str,
|
|
256
|
+
) -> dict[str, str | int]:
|
|
257
|
+
"""
|
|
258
|
+
Evaluate transition between autonomy levels.
|
|
259
|
+
|
|
260
|
+
Returns metadata about the transition for logging/reporting.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
current_level: Current autonomy level ("observer", "consultant", etc.)
|
|
264
|
+
new_level: New autonomy level
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
Dictionary with transition details
|
|
268
|
+
"""
|
|
269
|
+
level_order = ["observer", "consultant", "collaborator", "operator"]
|
|
270
|
+
|
|
271
|
+
current_idx = (
|
|
272
|
+
level_order.index(current_level) if current_level in level_order else -1
|
|
273
|
+
)
|
|
274
|
+
new_idx = level_order.index(new_level) if new_level in level_order else -1
|
|
275
|
+
|
|
276
|
+
if new_idx < 0 or current_idx < 0:
|
|
277
|
+
return {
|
|
278
|
+
"transition": "unknown",
|
|
279
|
+
"direction": "unknown",
|
|
280
|
+
"severity": "unknown",
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if new_idx > current_idx:
|
|
284
|
+
direction = "escalated"
|
|
285
|
+
severity = "high" if new_idx - current_idx > 1 else "moderate"
|
|
286
|
+
elif new_idx < current_idx:
|
|
287
|
+
direction = "relaxed"
|
|
288
|
+
severity = "high" if current_idx - new_idx > 1 else "moderate"
|
|
289
|
+
else:
|
|
290
|
+
direction = "unchanged"
|
|
291
|
+
severity = "none"
|
|
292
|
+
|
|
293
|
+
return {
|
|
294
|
+
"transition": f"{current_level} → {new_level}",
|
|
295
|
+
"direction": direction,
|
|
296
|
+
"severity": severity,
|
|
297
|
+
"escalation_level": new_idx,
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
def get_messaging_config(self, level: str) -> dict[str, str | bool | int]:
|
|
301
|
+
"""
|
|
302
|
+
Get messaging configuration for an autonomy level.
|
|
303
|
+
|
|
304
|
+
Returns imperative message configuration based on autonomy level.
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
level: Autonomy level ("observer", "consultant", "collaborator", "operator")
|
|
308
|
+
|
|
309
|
+
Returns:
|
|
310
|
+
Dictionary with messaging configuration
|
|
311
|
+
"""
|
|
312
|
+
config: dict[str, dict[str, str | bool | int]] = {
|
|
313
|
+
"observer": {
|
|
314
|
+
"prefix": "💡 GUIDANCE",
|
|
315
|
+
"tone": "informative",
|
|
316
|
+
"includes_cost": False,
|
|
317
|
+
"includes_suggestion": True,
|
|
318
|
+
"requires_acknowledgment": False,
|
|
319
|
+
"escalation_level": 0,
|
|
320
|
+
},
|
|
321
|
+
"consultant": {
|
|
322
|
+
"prefix": "🔴 IMPERATIVE",
|
|
323
|
+
"tone": "commanding",
|
|
324
|
+
"includes_cost": True,
|
|
325
|
+
"includes_suggestion": True,
|
|
326
|
+
"requires_acknowledgment": False,
|
|
327
|
+
"escalation_level": 1,
|
|
328
|
+
},
|
|
329
|
+
"collaborator": {
|
|
330
|
+
"prefix": "⚠️ FINAL WARNING",
|
|
331
|
+
"tone": "urgent",
|
|
332
|
+
"includes_cost": True,
|
|
333
|
+
"includes_suggestion": True,
|
|
334
|
+
"includes_consequences": True,
|
|
335
|
+
"requires_acknowledgment": False,
|
|
336
|
+
"escalation_level": 2,
|
|
337
|
+
},
|
|
338
|
+
"operator": {
|
|
339
|
+
"prefix": "🚨 CIRCUIT BREAKER",
|
|
340
|
+
"tone": "blocking",
|
|
341
|
+
"includes_cost": True,
|
|
342
|
+
"includes_suggestion": True,
|
|
343
|
+
"includes_consequences": True,
|
|
344
|
+
"requires_acknowledgment": True,
|
|
345
|
+
"escalation_level": 3,
|
|
346
|
+
},
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return config.get(level, config["consultant"])
|
|
350
|
+
|
|
351
|
+
def estimate_next_level(
|
|
352
|
+
self,
|
|
353
|
+
current_compliance: float,
|
|
354
|
+
projected_violations: int = 0,
|
|
355
|
+
) -> str:
|
|
356
|
+
"""
|
|
357
|
+
Estimate the autonomy level for next session.
|
|
358
|
+
|
|
359
|
+
Projects autonomy level based on current trajectory.
|
|
360
|
+
|
|
361
|
+
Args:
|
|
362
|
+
current_compliance: Current session's compliance rate
|
|
363
|
+
projected_violations: Projected violations for next session (0 = assume improvement)
|
|
364
|
+
|
|
365
|
+
Returns:
|
|
366
|
+
Estimated next autonomy level
|
|
367
|
+
"""
|
|
368
|
+
# If violations decrease, estimate improvement
|
|
369
|
+
if projected_violations == 0:
|
|
370
|
+
estimated_compliance = min(1.0, current_compliance + 0.05)
|
|
371
|
+
else:
|
|
372
|
+
# Assume violations stay constant or worsen
|
|
373
|
+
estimated_compliance = max(0.0, current_compliance - 0.05)
|
|
374
|
+
|
|
375
|
+
violations = SessionViolationSummary(
|
|
376
|
+
session_id="projected",
|
|
377
|
+
total_violations=0,
|
|
378
|
+
violations_by_type={},
|
|
379
|
+
total_waste_tokens=0,
|
|
380
|
+
circuit_breaker_triggered=False,
|
|
381
|
+
compliance_rate=estimated_compliance,
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
recommendation = self.recommend(violations)
|
|
385
|
+
return recommendation.level
|