gobby 0.2.5__py3-none-any.whl → 0.2.7__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.
- gobby/__init__.py +1 -1
- gobby/adapters/__init__.py +2 -1
- gobby/adapters/claude_code.py +13 -4
- gobby/adapters/codex_impl/__init__.py +28 -0
- gobby/adapters/codex_impl/adapter.py +722 -0
- gobby/adapters/codex_impl/client.py +679 -0
- gobby/adapters/codex_impl/protocol.py +20 -0
- gobby/adapters/codex_impl/types.py +68 -0
- gobby/agents/definitions.py +11 -1
- gobby/agents/isolation.py +395 -0
- gobby/agents/runner.py +8 -0
- gobby/agents/sandbox.py +261 -0
- gobby/agents/spawn.py +42 -287
- gobby/agents/spawn_executor.py +385 -0
- gobby/agents/spawners/__init__.py +24 -0
- gobby/agents/spawners/command_builder.py +189 -0
- gobby/agents/spawners/embedded.py +21 -2
- gobby/agents/spawners/headless.py +21 -2
- gobby/agents/spawners/prompt_manager.py +125 -0
- gobby/cli/__init__.py +6 -0
- gobby/cli/clones.py +419 -0
- gobby/cli/conductor.py +266 -0
- gobby/cli/install.py +4 -4
- gobby/cli/installers/antigravity.py +3 -9
- gobby/cli/installers/claude.py +15 -9
- gobby/cli/installers/codex.py +2 -8
- gobby/cli/installers/gemini.py +8 -8
- gobby/cli/installers/shared.py +175 -13
- gobby/cli/sessions.py +1 -1
- gobby/cli/skills.py +858 -0
- gobby/cli/tasks/ai.py +0 -440
- gobby/cli/tasks/crud.py +44 -6
- gobby/cli/tasks/main.py +0 -4
- gobby/cli/tui.py +2 -2
- gobby/cli/utils.py +12 -5
- gobby/clones/__init__.py +13 -0
- gobby/clones/git.py +547 -0
- gobby/conductor/__init__.py +16 -0
- gobby/conductor/alerts.py +135 -0
- gobby/conductor/loop.py +164 -0
- gobby/conductor/monitors/__init__.py +11 -0
- gobby/conductor/monitors/agents.py +116 -0
- gobby/conductor/monitors/tasks.py +155 -0
- gobby/conductor/pricing.py +234 -0
- gobby/conductor/token_tracker.py +160 -0
- gobby/config/__init__.py +12 -97
- gobby/config/app.py +69 -91
- gobby/config/extensions.py +2 -2
- gobby/config/features.py +7 -130
- gobby/config/search.py +110 -0
- gobby/config/servers.py +1 -1
- gobby/config/skills.py +43 -0
- gobby/config/tasks.py +9 -41
- gobby/hooks/__init__.py +0 -13
- gobby/hooks/event_handlers.py +188 -2
- gobby/hooks/hook_manager.py +50 -4
- gobby/hooks/plugins.py +1 -1
- gobby/hooks/skill_manager.py +130 -0
- gobby/hooks/webhooks.py +1 -1
- gobby/install/claude/hooks/hook_dispatcher.py +4 -4
- gobby/install/codex/hooks/hook_dispatcher.py +1 -1
- gobby/install/gemini/hooks/hook_dispatcher.py +87 -12
- gobby/llm/claude.py +22 -34
- gobby/llm/claude_executor.py +46 -256
- gobby/llm/codex_executor.py +59 -291
- gobby/llm/executor.py +21 -0
- gobby/llm/gemini.py +134 -110
- gobby/llm/litellm_executor.py +143 -6
- gobby/llm/resolver.py +98 -35
- gobby/mcp_proxy/importer.py +62 -4
- gobby/mcp_proxy/instructions.py +56 -0
- gobby/mcp_proxy/models.py +15 -0
- gobby/mcp_proxy/registries.py +68 -8
- gobby/mcp_proxy/server.py +33 -3
- gobby/mcp_proxy/services/recommendation.py +43 -11
- gobby/mcp_proxy/services/tool_proxy.py +81 -1
- gobby/mcp_proxy/stdio.py +2 -1
- gobby/mcp_proxy/tools/__init__.py +0 -2
- gobby/mcp_proxy/tools/agent_messaging.py +317 -0
- gobby/mcp_proxy/tools/agents.py +31 -731
- gobby/mcp_proxy/tools/clones.py +518 -0
- gobby/mcp_proxy/tools/memory.py +3 -26
- gobby/mcp_proxy/tools/metrics.py +65 -1
- gobby/mcp_proxy/tools/orchestration/__init__.py +3 -0
- gobby/mcp_proxy/tools/orchestration/cleanup.py +151 -0
- gobby/mcp_proxy/tools/orchestration/wait.py +467 -0
- gobby/mcp_proxy/tools/sessions/__init__.py +14 -0
- gobby/mcp_proxy/tools/sessions/_commits.py +232 -0
- gobby/mcp_proxy/tools/sessions/_crud.py +253 -0
- gobby/mcp_proxy/tools/sessions/_factory.py +63 -0
- gobby/mcp_proxy/tools/sessions/_handoff.py +499 -0
- gobby/mcp_proxy/tools/sessions/_messages.py +138 -0
- gobby/mcp_proxy/tools/skills/__init__.py +616 -0
- gobby/mcp_proxy/tools/spawn_agent.py +417 -0
- gobby/mcp_proxy/tools/task_orchestration.py +7 -0
- gobby/mcp_proxy/tools/task_readiness.py +14 -0
- gobby/mcp_proxy/tools/task_sync.py +1 -1
- gobby/mcp_proxy/tools/tasks/_context.py +0 -20
- gobby/mcp_proxy/tools/tasks/_crud.py +91 -4
- gobby/mcp_proxy/tools/tasks/_expansion.py +348 -0
- gobby/mcp_proxy/tools/tasks/_factory.py +6 -16
- gobby/mcp_proxy/tools/tasks/_lifecycle.py +110 -45
- gobby/mcp_proxy/tools/tasks/_lifecycle_validation.py +18 -29
- gobby/mcp_proxy/tools/workflows.py +1 -1
- gobby/mcp_proxy/tools/worktrees.py +0 -338
- gobby/memory/backends/__init__.py +6 -1
- gobby/memory/backends/mem0.py +6 -1
- gobby/memory/extractor.py +477 -0
- gobby/memory/ingestion/__init__.py +5 -0
- gobby/memory/ingestion/multimodal.py +221 -0
- gobby/memory/manager.py +73 -285
- gobby/memory/search/__init__.py +10 -0
- gobby/memory/search/coordinator.py +248 -0
- gobby/memory/services/__init__.py +5 -0
- gobby/memory/services/crossref.py +142 -0
- gobby/prompts/loader.py +5 -2
- gobby/runner.py +37 -16
- gobby/search/__init__.py +48 -6
- gobby/search/backends/__init__.py +159 -0
- gobby/search/backends/embedding.py +225 -0
- gobby/search/embeddings.py +238 -0
- gobby/search/models.py +148 -0
- gobby/search/unified.py +496 -0
- gobby/servers/http.py +24 -12
- gobby/servers/routes/admin.py +294 -0
- gobby/servers/routes/mcp/endpoints/__init__.py +61 -0
- gobby/servers/routes/mcp/endpoints/discovery.py +405 -0
- gobby/servers/routes/mcp/endpoints/execution.py +568 -0
- gobby/servers/routes/mcp/endpoints/registry.py +378 -0
- gobby/servers/routes/mcp/endpoints/server.py +304 -0
- gobby/servers/routes/mcp/hooks.py +1 -1
- gobby/servers/routes/mcp/tools.py +48 -1317
- gobby/servers/websocket.py +2 -2
- gobby/sessions/analyzer.py +2 -0
- gobby/sessions/lifecycle.py +1 -1
- gobby/sessions/processor.py +10 -0
- gobby/sessions/transcripts/base.py +2 -0
- gobby/sessions/transcripts/claude.py +79 -10
- gobby/skills/__init__.py +91 -0
- gobby/skills/loader.py +685 -0
- gobby/skills/manager.py +384 -0
- gobby/skills/parser.py +286 -0
- gobby/skills/search.py +463 -0
- gobby/skills/sync.py +119 -0
- gobby/skills/updater.py +385 -0
- gobby/skills/validator.py +368 -0
- gobby/storage/clones.py +378 -0
- gobby/storage/database.py +1 -1
- gobby/storage/memories.py +43 -13
- gobby/storage/migrations.py +162 -201
- gobby/storage/sessions.py +116 -7
- gobby/storage/skills.py +782 -0
- gobby/storage/tasks/_crud.py +4 -4
- gobby/storage/tasks/_lifecycle.py +57 -7
- gobby/storage/tasks/_manager.py +14 -5
- gobby/storage/tasks/_models.py +8 -3
- gobby/sync/memories.py +40 -5
- gobby/sync/tasks.py +83 -6
- gobby/tasks/__init__.py +1 -2
- gobby/tasks/external_validator.py +1 -1
- gobby/tasks/validation.py +46 -35
- gobby/tools/summarizer.py +91 -10
- gobby/tui/api_client.py +4 -7
- gobby/tui/app.py +5 -3
- gobby/tui/screens/orchestrator.py +1 -2
- gobby/tui/screens/tasks.py +2 -4
- gobby/tui/ws_client.py +1 -1
- gobby/utils/daemon_client.py +2 -2
- gobby/utils/project_context.py +2 -3
- gobby/utils/status.py +13 -0
- gobby/workflows/actions.py +221 -1135
- gobby/workflows/artifact_actions.py +31 -0
- gobby/workflows/autonomous_actions.py +11 -0
- gobby/workflows/context_actions.py +93 -1
- gobby/workflows/detection_helpers.py +115 -31
- gobby/workflows/enforcement/__init__.py +47 -0
- gobby/workflows/enforcement/blocking.py +269 -0
- gobby/workflows/enforcement/commit_policy.py +283 -0
- gobby/workflows/enforcement/handlers.py +269 -0
- gobby/workflows/{task_enforcement_actions.py → enforcement/task_policy.py} +29 -388
- gobby/workflows/engine.py +13 -2
- gobby/workflows/git_utils.py +106 -0
- gobby/workflows/lifecycle_evaluator.py +29 -1
- gobby/workflows/llm_actions.py +30 -0
- gobby/workflows/loader.py +19 -6
- gobby/workflows/mcp_actions.py +20 -1
- gobby/workflows/memory_actions.py +154 -0
- gobby/workflows/safe_evaluator.py +183 -0
- gobby/workflows/session_actions.py +44 -0
- gobby/workflows/state_actions.py +60 -1
- gobby/workflows/stop_signal_actions.py +55 -0
- gobby/workflows/summary_actions.py +111 -1
- gobby/workflows/task_sync_actions.py +347 -0
- gobby/workflows/todo_actions.py +34 -1
- gobby/workflows/webhook_actions.py +185 -0
- {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/METADATA +87 -21
- {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/RECORD +201 -172
- {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/WHEEL +1 -1
- gobby/adapters/codex.py +0 -1292
- gobby/install/claude/commands/gobby/bug.md +0 -51
- gobby/install/claude/commands/gobby/chore.md +0 -51
- gobby/install/claude/commands/gobby/epic.md +0 -52
- gobby/install/claude/commands/gobby/eval.md +0 -235
- gobby/install/claude/commands/gobby/feat.md +0 -49
- gobby/install/claude/commands/gobby/nit.md +0 -52
- gobby/install/claude/commands/gobby/ref.md +0 -52
- gobby/install/codex/prompts/forget.md +0 -7
- gobby/install/codex/prompts/memories.md +0 -7
- gobby/install/codex/prompts/recall.md +0 -7
- gobby/install/codex/prompts/remember.md +0 -13
- gobby/llm/gemini_executor.py +0 -339
- gobby/mcp_proxy/tools/session_messages.py +0 -1056
- gobby/mcp_proxy/tools/task_expansion.py +0 -591
- gobby/prompts/defaults/expansion/system.md +0 -119
- gobby/prompts/defaults/expansion/user.md +0 -48
- gobby/prompts/defaults/external_validation/agent.md +0 -72
- gobby/prompts/defaults/external_validation/external.md +0 -63
- gobby/prompts/defaults/external_validation/spawn.md +0 -83
- gobby/prompts/defaults/external_validation/system.md +0 -6
- gobby/prompts/defaults/features/import_mcp.md +0 -22
- gobby/prompts/defaults/features/import_mcp_github.md +0 -17
- gobby/prompts/defaults/features/import_mcp_search.md +0 -16
- gobby/prompts/defaults/features/recommend_tools.md +0 -32
- gobby/prompts/defaults/features/recommend_tools_hybrid.md +0 -35
- gobby/prompts/defaults/features/recommend_tools_llm.md +0 -30
- gobby/prompts/defaults/features/server_description.md +0 -20
- gobby/prompts/defaults/features/server_description_system.md +0 -6
- gobby/prompts/defaults/features/task_description.md +0 -31
- gobby/prompts/defaults/features/task_description_system.md +0 -6
- gobby/prompts/defaults/features/tool_summary.md +0 -17
- gobby/prompts/defaults/features/tool_summary_system.md +0 -6
- gobby/prompts/defaults/research/step.md +0 -58
- gobby/prompts/defaults/validation/criteria.md +0 -47
- gobby/prompts/defaults/validation/validate.md +0 -38
- gobby/storage/migrations_legacy.py +0 -1359
- gobby/tasks/context.py +0 -747
- gobby/tasks/criteria.py +0 -342
- gobby/tasks/expansion.py +0 -626
- gobby/tasks/prompts/expand.py +0 -327
- gobby/tasks/research.py +0 -421
- gobby/tasks/tdd.py +0 -352
- {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/entry_points.txt +0 -0
- {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/licenses/LICENSE.md +0 -0
- {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""Session-based token tracking for budget management.
|
|
2
|
+
|
|
3
|
+
This module provides SessionTokenTracker which aggregates usage from sessions
|
|
4
|
+
over time and enables budget tracking for agent spawning decisions.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from datetime import UTC, datetime, timedelta
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class SessionTokenTracker:
|
|
19
|
+
"""Track token usage from sessions for budget management.
|
|
20
|
+
|
|
21
|
+
This class aggregates usage data from sessions over time and provides
|
|
22
|
+
budget checking for agent spawning decisions.
|
|
23
|
+
|
|
24
|
+
Example:
|
|
25
|
+
tracker = SessionTokenTracker(
|
|
26
|
+
session_storage=session_manager,
|
|
27
|
+
daily_budget_usd=10.0,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Get usage summary for last 7 days
|
|
31
|
+
summary = tracker.get_usage_summary(days=7)
|
|
32
|
+
|
|
33
|
+
# Check if we can spawn an agent
|
|
34
|
+
can_spawn, reason = tracker.can_spawn_agent()
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
session_storage: Any # LocalSessionManager
|
|
38
|
+
daily_budget_usd: float = 50.0 # Default daily budget in USD
|
|
39
|
+
|
|
40
|
+
# Cached data
|
|
41
|
+
_usage_cache: dict[str, Any] = field(default_factory=dict)
|
|
42
|
+
_cache_time: datetime | None = field(default=None)
|
|
43
|
+
_cache_ttl_seconds: int = 60 # Cache for 60 seconds
|
|
44
|
+
|
|
45
|
+
def get_usage_summary(self, days: int = 1) -> dict[str, Any]:
|
|
46
|
+
"""Get usage summary for the specified number of days.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
days: Number of days to look back (default: 1 = today)
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Dict with total cost, tokens, session count, and model breakdown
|
|
53
|
+
"""
|
|
54
|
+
since = datetime.now(UTC) - timedelta(days=days)
|
|
55
|
+
sessions = self.session_storage.get_sessions_since(since)
|
|
56
|
+
|
|
57
|
+
total_cost = 0.0
|
|
58
|
+
total_input_tokens = 0
|
|
59
|
+
total_output_tokens = 0
|
|
60
|
+
total_cache_creation_tokens = 0
|
|
61
|
+
total_cache_read_tokens = 0
|
|
62
|
+
usage_by_model: dict[str, dict[str, Any]] = {}
|
|
63
|
+
|
|
64
|
+
for session in sessions:
|
|
65
|
+
# Safely handle None values by defaulting to 0
|
|
66
|
+
total_cost += session.usage_total_cost_usd or 0
|
|
67
|
+
total_input_tokens += session.usage_input_tokens or 0
|
|
68
|
+
total_output_tokens += session.usage_output_tokens or 0
|
|
69
|
+
total_cache_creation_tokens += session.usage_cache_creation_tokens or 0
|
|
70
|
+
total_cache_read_tokens += session.usage_cache_read_tokens or 0
|
|
71
|
+
|
|
72
|
+
# Aggregate by model
|
|
73
|
+
model = session.model or "unknown"
|
|
74
|
+
if model not in usage_by_model:
|
|
75
|
+
usage_by_model[model] = {
|
|
76
|
+
"cost": 0.0,
|
|
77
|
+
"input_tokens": 0,
|
|
78
|
+
"output_tokens": 0,
|
|
79
|
+
"sessions": 0,
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
usage_by_model[model]["cost"] += session.usage_total_cost_usd or 0
|
|
83
|
+
usage_by_model[model]["input_tokens"] += session.usage_input_tokens or 0
|
|
84
|
+
usage_by_model[model]["output_tokens"] += session.usage_output_tokens or 0
|
|
85
|
+
usage_by_model[model]["sessions"] += 1
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
"total_cost_usd": total_cost,
|
|
89
|
+
"total_input_tokens": total_input_tokens,
|
|
90
|
+
"total_output_tokens": total_output_tokens,
|
|
91
|
+
"total_cache_creation_tokens": total_cache_creation_tokens,
|
|
92
|
+
"total_cache_read_tokens": total_cache_read_tokens,
|
|
93
|
+
"session_count": len(sessions),
|
|
94
|
+
"usage_by_model": usage_by_model,
|
|
95
|
+
"period_days": days,
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
def get_budget_status(self) -> dict[str, Any]:
|
|
99
|
+
"""Get current budget status for today.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
Dict with budget info: daily_budget_usd, used_today_usd,
|
|
103
|
+
remaining_usd, percentage_used, over_budget
|
|
104
|
+
"""
|
|
105
|
+
summary = self.get_usage_summary(days=1)
|
|
106
|
+
used_today = summary["total_cost_usd"]
|
|
107
|
+
|
|
108
|
+
# Handle unlimited budget (daily_budget_usd <= 0)
|
|
109
|
+
if self.daily_budget_usd <= 0:
|
|
110
|
+
return {
|
|
111
|
+
"daily_budget_usd": self.daily_budget_usd,
|
|
112
|
+
"used_today_usd": used_today,
|
|
113
|
+
"remaining_usd": float("inf"),
|
|
114
|
+
"percentage_used": 0.0,
|
|
115
|
+
"over_budget": False,
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
remaining = self.daily_budget_usd - used_today
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
"daily_budget_usd": self.daily_budget_usd,
|
|
122
|
+
"used_today_usd": used_today,
|
|
123
|
+
"remaining_usd": remaining,
|
|
124
|
+
"percentage_used": (used_today / self.daily_budget_usd * 100),
|
|
125
|
+
"over_budget": used_today > self.daily_budget_usd,
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
def can_spawn_agent(self, estimated_cost: float | None = None) -> tuple[bool, str | None]:
|
|
129
|
+
"""Check if we can spawn an agent based on budget.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
estimated_cost: Optional estimated cost for the agent run
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
Tuple of (can_spawn, reason if not)
|
|
136
|
+
"""
|
|
137
|
+
# Unlimited budget (0 or negative means no limit)
|
|
138
|
+
if self.daily_budget_usd <= 0.0:
|
|
139
|
+
return True, None
|
|
140
|
+
|
|
141
|
+
status = self.get_budget_status()
|
|
142
|
+
|
|
143
|
+
# Already over budget
|
|
144
|
+
if status["over_budget"]:
|
|
145
|
+
return (
|
|
146
|
+
False,
|
|
147
|
+
f"Daily budget exceeded: ${status['used_today_usd']:.2f} used "
|
|
148
|
+
f"of ${self.daily_budget_usd:.2f}",
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# Check if estimated cost would exceed budget
|
|
152
|
+
if estimated_cost is not None:
|
|
153
|
+
if status["used_today_usd"] + estimated_cost > self.daily_budget_usd:
|
|
154
|
+
return (
|
|
155
|
+
False,
|
|
156
|
+
f"Estimated cost ${estimated_cost:.2f} would exceed budget. "
|
|
157
|
+
f"Remaining: ${status['remaining_usd']:.2f}",
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
return True, None
|
gobby/config/__init__.py
CHANGED
|
@@ -14,116 +14,31 @@ Module structure:
|
|
|
14
14
|
- extensions.py: Hook extension configs (webhooks, plugins)
|
|
15
15
|
- sessions.py: Session lifecycle and tracking configs
|
|
16
16
|
- features.py: MCP proxy feature configs (code execution, tool recommendation)
|
|
17
|
+
|
|
18
|
+
Import from submodules directly for specific configs:
|
|
19
|
+
from gobby.config.tasks import TaskValidationConfig
|
|
20
|
+
from gobby.config.extensions import WebhooksConfig
|
|
21
|
+
|
|
22
|
+
Import from this package for app-level items:
|
|
23
|
+
from gobby.config import DaemonConfig, load_config
|
|
17
24
|
"""
|
|
18
25
|
|
|
19
26
|
# Core configuration and utilities from app.py
|
|
20
27
|
from gobby.config.app import (
|
|
21
28
|
DaemonConfig,
|
|
22
29
|
expand_env_vars,
|
|
30
|
+
generate_default_config,
|
|
23
31
|
load_config,
|
|
32
|
+
load_yaml,
|
|
24
33
|
save_config,
|
|
25
34
|
)
|
|
26
35
|
|
|
27
|
-
# Extension configs
|
|
28
|
-
from gobby.config.extensions import (
|
|
29
|
-
HookExtensionsConfig,
|
|
30
|
-
PluginItemConfig,
|
|
31
|
-
PluginsConfig,
|
|
32
|
-
WebhookEndpointConfig,
|
|
33
|
-
WebhooksConfig,
|
|
34
|
-
WebSocketBroadcastConfig,
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
# Feature configs
|
|
38
|
-
from gobby.config.features import (
|
|
39
|
-
ImportMCPServerConfig,
|
|
40
|
-
MetricsConfig,
|
|
41
|
-
ProjectVerificationConfig,
|
|
42
|
-
RecommendToolsConfig,
|
|
43
|
-
ToolSummarizerConfig,
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
# LLM provider configs
|
|
47
|
-
from gobby.config.llm_providers import (
|
|
48
|
-
LLMProviderConfig,
|
|
49
|
-
LLMProvidersConfig,
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
# Logging configs
|
|
53
|
-
from gobby.config.logging import LoggingSettings
|
|
54
|
-
|
|
55
|
-
# Persistence configs
|
|
56
|
-
from gobby.config.persistence import (
|
|
57
|
-
MemoryConfig,
|
|
58
|
-
MemorySyncConfig,
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
# Server configs
|
|
62
|
-
from gobby.config.servers import (
|
|
63
|
-
MCPClientProxyConfig,
|
|
64
|
-
WebSocketSettings,
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
# Session configs
|
|
68
|
-
from gobby.config.sessions import (
|
|
69
|
-
ContextInjectionConfig,
|
|
70
|
-
MessageTrackingConfig,
|
|
71
|
-
SessionLifecycleConfig,
|
|
72
|
-
SessionSummaryConfig,
|
|
73
|
-
TitleSynthesisConfig,
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
# Task configs
|
|
77
|
-
from gobby.config.tasks import (
|
|
78
|
-
CompactHandoffConfig,
|
|
79
|
-
GobbyTasksConfig,
|
|
80
|
-
PatternCriteriaConfig,
|
|
81
|
-
TaskExpansionConfig,
|
|
82
|
-
TaskValidationConfig,
|
|
83
|
-
WorkflowConfig,
|
|
84
|
-
)
|
|
85
|
-
|
|
86
36
|
__all__ = [
|
|
87
|
-
# Core
|
|
37
|
+
# Core app-level exports only
|
|
88
38
|
"DaemonConfig",
|
|
89
39
|
"expand_env_vars",
|
|
40
|
+
"generate_default_config",
|
|
90
41
|
"load_config",
|
|
42
|
+
"load_yaml",
|
|
91
43
|
"save_config",
|
|
92
|
-
# Extension configs
|
|
93
|
-
"HookExtensionsConfig",
|
|
94
|
-
"PluginItemConfig",
|
|
95
|
-
"PluginsConfig",
|
|
96
|
-
"WebhookEndpointConfig",
|
|
97
|
-
"WebhooksConfig",
|
|
98
|
-
"WebSocketBroadcastConfig",
|
|
99
|
-
# Feature configs
|
|
100
|
-
"ImportMCPServerConfig",
|
|
101
|
-
"MetricsConfig",
|
|
102
|
-
"ProjectVerificationConfig",
|
|
103
|
-
"RecommendToolsConfig",
|
|
104
|
-
"ToolSummarizerConfig",
|
|
105
|
-
# LLM provider configs
|
|
106
|
-
"LLMProviderConfig",
|
|
107
|
-
"LLMProvidersConfig",
|
|
108
|
-
# Logging configs
|
|
109
|
-
"LoggingSettings",
|
|
110
|
-
# Persistence configs
|
|
111
|
-
"MemoryConfig",
|
|
112
|
-
"MemorySyncConfig",
|
|
113
|
-
# Server configs
|
|
114
|
-
"MCPClientProxyConfig",
|
|
115
|
-
"WebSocketSettings",
|
|
116
|
-
# Session configs
|
|
117
|
-
"ContextInjectionConfig",
|
|
118
|
-
"MessageTrackingConfig",
|
|
119
|
-
"SessionLifecycleConfig",
|
|
120
|
-
"SessionSummaryConfig",
|
|
121
|
-
"TitleSynthesisConfig",
|
|
122
|
-
# Task configs
|
|
123
|
-
"CompactHandoffConfig",
|
|
124
|
-
"GobbyTasksConfig",
|
|
125
|
-
"PatternCriteriaConfig",
|
|
126
|
-
"TaskExpansionConfig",
|
|
127
|
-
"TaskValidationConfig",
|
|
128
|
-
"WorkflowConfig",
|
|
129
44
|
]
|
gobby/config/app.py
CHANGED
|
@@ -15,14 +15,8 @@ from typing import Any
|
|
|
15
15
|
import yaml
|
|
16
16
|
from pydantic import BaseModel, Field, field_validator
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
PluginItemConfig,
|
|
21
|
-
PluginsConfig,
|
|
22
|
-
WebhookEndpointConfig,
|
|
23
|
-
WebhooksConfig,
|
|
24
|
-
WebSocketBroadcastConfig,
|
|
25
|
-
)
|
|
18
|
+
# Internal imports for DaemonConfig fields - NOT re-exported
|
|
19
|
+
from gobby.config.extensions import HookExtensionsConfig
|
|
26
20
|
from gobby.config.features import (
|
|
27
21
|
ImportMCPServerConfig,
|
|
28
22
|
MetricsConfig,
|
|
@@ -31,14 +25,10 @@ from gobby.config.features import (
|
|
|
31
25
|
TaskDescriptionConfig,
|
|
32
26
|
ToolSummarizerConfig,
|
|
33
27
|
)
|
|
34
|
-
|
|
35
|
-
# Re-export from extracted modules (Strangler Fig pattern for backwards compatibility)
|
|
36
|
-
from gobby.config.llm_providers import LLMProviderConfig, LLMProvidersConfig
|
|
28
|
+
from gobby.config.llm_providers import LLMProvidersConfig
|
|
37
29
|
from gobby.config.logging import LoggingSettings
|
|
38
|
-
from gobby.config.persistence import
|
|
39
|
-
|
|
40
|
-
MemorySyncConfig,
|
|
41
|
-
)
|
|
30
|
+
from gobby.config.persistence import MemoryConfig, MemorySyncConfig
|
|
31
|
+
from gobby.config.search import SearchConfig
|
|
42
32
|
from gobby.config.servers import MCPClientProxyConfig, WebSocketSettings
|
|
43
33
|
from gobby.config.sessions import (
|
|
44
34
|
ArtifactHandoffConfig,
|
|
@@ -48,57 +38,12 @@ from gobby.config.sessions import (
|
|
|
48
38
|
SessionSummaryConfig,
|
|
49
39
|
TitleSynthesisConfig,
|
|
50
40
|
)
|
|
51
|
-
from gobby.config.
|
|
52
|
-
|
|
53
|
-
GobbyTasksConfig,
|
|
54
|
-
PatternCriteriaConfig,
|
|
55
|
-
TaskExpansionConfig,
|
|
56
|
-
TaskValidationConfig,
|
|
57
|
-
WorkflowConfig,
|
|
58
|
-
)
|
|
41
|
+
from gobby.config.skills import SkillsConfig
|
|
42
|
+
from gobby.config.tasks import CompactHandoffConfig, GobbyTasksConfig, WorkflowConfig
|
|
59
43
|
|
|
60
|
-
# Explicit exports for mypy (re-exported symbols from submodules)
|
|
61
44
|
__all__ = [
|
|
62
|
-
#
|
|
63
|
-
"
|
|
64
|
-
"PluginItemConfig",
|
|
65
|
-
"PluginsConfig",
|
|
66
|
-
"WebhookEndpointConfig",
|
|
67
|
-
"WebhooksConfig",
|
|
68
|
-
"WebSocketBroadcastConfig",
|
|
69
|
-
# From gobby.config.features
|
|
70
|
-
"ImportMCPServerConfig",
|
|
71
|
-
"MetricsConfig",
|
|
72
|
-
"ProjectVerificationConfig",
|
|
73
|
-
"RecommendToolsConfig",
|
|
74
|
-
"TaskDescriptionConfig",
|
|
75
|
-
"ToolSummarizerConfig",
|
|
76
|
-
# From gobby.config.llm_providers
|
|
77
|
-
"LLMProviderConfig",
|
|
78
|
-
"LLMProvidersConfig",
|
|
79
|
-
# From gobby.config.logging
|
|
80
|
-
"LoggingSettings",
|
|
81
|
-
# From gobby.config.persistence
|
|
82
|
-
"MemoryConfig",
|
|
83
|
-
"MemorySyncConfig",
|
|
84
|
-
# From gobby.config.servers
|
|
85
|
-
"MCPClientProxyConfig",
|
|
86
|
-
"WebSocketSettings",
|
|
87
|
-
# From gobby.config.sessions
|
|
88
|
-
"ArtifactHandoffConfig",
|
|
89
|
-
"ContextInjectionConfig",
|
|
90
|
-
"MessageTrackingConfig",
|
|
91
|
-
"SessionLifecycleConfig",
|
|
92
|
-
"SessionSummaryConfig",
|
|
93
|
-
"TitleSynthesisConfig",
|
|
94
|
-
# From gobby.config.tasks
|
|
95
|
-
"CompactHandoffConfig",
|
|
96
|
-
"GobbyTasksConfig",
|
|
97
|
-
"PatternCriteriaConfig",
|
|
98
|
-
"TaskExpansionConfig",
|
|
99
|
-
"TaskValidationConfig",
|
|
100
|
-
"WorkflowConfig",
|
|
101
|
-
# Local definitions
|
|
45
|
+
# Local definitions only - no re-exports
|
|
46
|
+
"ConductorConfig",
|
|
102
47
|
"DaemonConfig",
|
|
103
48
|
"expand_env_vars",
|
|
104
49
|
"load_yaml",
|
|
@@ -114,6 +59,37 @@ __all__ = [
|
|
|
114
59
|
ENV_VAR_PATTERN = re.compile(r"\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}")
|
|
115
60
|
|
|
116
61
|
|
|
62
|
+
class ConductorConfig(BaseModel):
|
|
63
|
+
"""
|
|
64
|
+
Configuration for the Conductor orchestration system.
|
|
65
|
+
|
|
66
|
+
Controls token budget management and agent spawning throttling.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
daily_budget_usd: float = Field(
|
|
70
|
+
default=50.0,
|
|
71
|
+
ge=0.0,
|
|
72
|
+
description="Daily budget limit in USD. Set to 0 for unlimited.",
|
|
73
|
+
)
|
|
74
|
+
warning_threshold: float = Field(
|
|
75
|
+
default=0.8,
|
|
76
|
+
ge=0.0,
|
|
77
|
+
le=1.0,
|
|
78
|
+
description="Budget percentage at which to issue warnings (0.0-1.0).",
|
|
79
|
+
)
|
|
80
|
+
throttle_threshold: float = Field(
|
|
81
|
+
default=0.9,
|
|
82
|
+
ge=0.0,
|
|
83
|
+
le=1.0,
|
|
84
|
+
description="Budget percentage at which to throttle agent spawning (0.0-1.0).",
|
|
85
|
+
)
|
|
86
|
+
tracking_window_days: int = Field(
|
|
87
|
+
default=7,
|
|
88
|
+
gt=0,
|
|
89
|
+
description="Number of days to track usage for reporting.",
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
117
93
|
def expand_env_vars(content: str) -> str:
|
|
118
94
|
"""
|
|
119
95
|
Expand environment variables in configuration content.
|
|
@@ -146,32 +122,6 @@ def expand_env_vars(content: str) -> str:
|
|
|
146
122
|
return ENV_VAR_PATTERN.sub(replace_match, content)
|
|
147
123
|
|
|
148
124
|
|
|
149
|
-
# WebSocketSettings moved to gobby.config.servers (re-exported above)
|
|
150
|
-
# LoggingSettings moved to gobby.config.logging (re-exported above)
|
|
151
|
-
# CompactHandoffConfig moved to gobby.config.tasks (re-exported above)
|
|
152
|
-
|
|
153
|
-
# ContextInjectionConfig, SessionSummaryConfig, TitleSynthesisConfig,
|
|
154
|
-
# MessageTrackingConfig, SessionLifecycleConfig
|
|
155
|
-
# moved to gobby.config.sessions (re-exported above)
|
|
156
|
-
|
|
157
|
-
# ToolSummarizerConfig, RecommendToolsConfig, ImportMCPServerConfig,
|
|
158
|
-
# MetricsConfig, ProjectVerificationConfig
|
|
159
|
-
# moved to gobby.config.features (re-exported above)
|
|
160
|
-
|
|
161
|
-
# WebSocketBroadcastConfig, WebhookEndpointConfig, WebhooksConfig,
|
|
162
|
-
# PluginItemConfig, PluginsConfig, HookExtensionsConfig
|
|
163
|
-
# moved to gobby.config.extensions (re-exported above)
|
|
164
|
-
|
|
165
|
-
# PatternCriteriaConfig, TaskExpansionConfig, TaskValidationConfig, WorkflowConfig,
|
|
166
|
-
# GobbyTasksConfig, CompactHandoffConfig
|
|
167
|
-
# moved to gobby.config.tasks (re-exported above)
|
|
168
|
-
|
|
169
|
-
# MCPClientProxyConfig moved to gobby.config.servers (re-exported above)
|
|
170
|
-
# LLMProviderConfig and LLMProvidersConfig moved to gobby.config.llm_providers (re-exported above)
|
|
171
|
-
# MemoryConfig, MemorySyncConfig
|
|
172
|
-
# moved to gobby.config.persistence (re-exported above)
|
|
173
|
-
|
|
174
|
-
|
|
175
125
|
class DaemonConfig(BaseModel):
|
|
176
126
|
"""
|
|
177
127
|
Main configuration for Gobby daemon.
|
|
@@ -188,19 +138,27 @@ class DaemonConfig(BaseModel):
|
|
|
188
138
|
|
|
189
139
|
# Daemon settings
|
|
190
140
|
daemon_port: int = Field(
|
|
191
|
-
default=
|
|
141
|
+
default=60887,
|
|
192
142
|
description="Port for daemon to listen on",
|
|
193
143
|
)
|
|
194
144
|
daemon_health_check_interval: float = Field(
|
|
195
145
|
default=10.0,
|
|
196
146
|
description="Daemon health check interval in seconds",
|
|
197
147
|
)
|
|
148
|
+
test_mode: bool = Field(
|
|
149
|
+
default=False,
|
|
150
|
+
description="Run daemon in test mode (enables test endpoints)",
|
|
151
|
+
)
|
|
198
152
|
|
|
199
153
|
# Local storage
|
|
200
154
|
database_path: str = Field(
|
|
201
155
|
default="~/.gobby/gobby-hub.db",
|
|
202
156
|
description="Path to hub database for cross-project queries.",
|
|
203
157
|
)
|
|
158
|
+
use_flattened_baseline: bool = Field(
|
|
159
|
+
default=True,
|
|
160
|
+
description="Use flattened V2 baseline schema (v75) for new databases instead of legacy migrations.",
|
|
161
|
+
)
|
|
204
162
|
|
|
205
163
|
# Sub-configs
|
|
206
164
|
websocket: WebSocketSettings = Field(
|
|
@@ -279,6 +237,10 @@ class DaemonConfig(BaseModel):
|
|
|
279
237
|
default_factory=MemorySyncConfig,
|
|
280
238
|
description="Memory synchronization configuration",
|
|
281
239
|
)
|
|
240
|
+
skills: SkillsConfig = Field(
|
|
241
|
+
default_factory=SkillsConfig,
|
|
242
|
+
description="Skills injection configuration",
|
|
243
|
+
)
|
|
282
244
|
message_tracking: MessageTrackingConfig = Field(
|
|
283
245
|
default_factory=MessageTrackingConfig,
|
|
284
246
|
description="Session message tracking configuration",
|
|
@@ -295,6 +257,14 @@ class DaemonConfig(BaseModel):
|
|
|
295
257
|
default_factory=ProjectVerificationConfig,
|
|
296
258
|
description="Default verification commands for projects without auto-detected config",
|
|
297
259
|
)
|
|
260
|
+
conductor: ConductorConfig = Field(
|
|
261
|
+
default_factory=ConductorConfig,
|
|
262
|
+
description="Conductor orchestration system configuration",
|
|
263
|
+
)
|
|
264
|
+
search: SearchConfig = Field(
|
|
265
|
+
default_factory=SearchConfig,
|
|
266
|
+
description="Unified search configuration with embedding fallback",
|
|
267
|
+
)
|
|
298
268
|
|
|
299
269
|
def get_recommend_tools_config(self) -> RecommendToolsConfig:
|
|
300
270
|
"""Get recommend_tools configuration."""
|
|
@@ -324,6 +294,10 @@ class DaemonConfig(BaseModel):
|
|
|
324
294
|
"""Get memory sync configuration."""
|
|
325
295
|
return self.memory_sync
|
|
326
296
|
|
|
297
|
+
def get_skills_config(self) -> SkillsConfig:
|
|
298
|
+
"""Get skills configuration."""
|
|
299
|
+
return self.skills
|
|
300
|
+
|
|
327
301
|
def get_gobby_tasks_config(self) -> GobbyTasksConfig:
|
|
328
302
|
"""Get gobby-tasks configuration."""
|
|
329
303
|
return self.gobby_tasks
|
|
@@ -336,6 +310,10 @@ class DaemonConfig(BaseModel):
|
|
|
336
310
|
"""Get default verification commands configuration."""
|
|
337
311
|
return self.verification_defaults
|
|
338
312
|
|
|
313
|
+
def get_search_config(self) -> SearchConfig:
|
|
314
|
+
"""Get search configuration."""
|
|
315
|
+
return self.search
|
|
316
|
+
|
|
339
317
|
@field_validator("daemon_port")
|
|
340
318
|
@classmethod
|
|
341
319
|
def validate_port(cls, v: int) -> int:
|
gobby/config/extensions.py
CHANGED
|
@@ -137,8 +137,8 @@ class PluginsConfig(BaseModel):
|
|
|
137
137
|
description="Enable plugin system (disabled by default for security)",
|
|
138
138
|
)
|
|
139
139
|
plugin_dirs: list[str] = Field(
|
|
140
|
-
default_factory=lambda: ["
|
|
141
|
-
description="Directories to scan for plugins (
|
|
140
|
+
default_factory=lambda: [".gobby/plugins"],
|
|
141
|
+
description="Directories to scan for plugins (project-scoped)",
|
|
142
142
|
)
|
|
143
143
|
auto_discover: bool = Field(
|
|
144
144
|
default=True,
|