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.
Files changed (244) hide show
  1. gobby/__init__.py +1 -1
  2. gobby/adapters/__init__.py +2 -1
  3. gobby/adapters/claude_code.py +13 -4
  4. gobby/adapters/codex_impl/__init__.py +28 -0
  5. gobby/adapters/codex_impl/adapter.py +722 -0
  6. gobby/adapters/codex_impl/client.py +679 -0
  7. gobby/adapters/codex_impl/protocol.py +20 -0
  8. gobby/adapters/codex_impl/types.py +68 -0
  9. gobby/agents/definitions.py +11 -1
  10. gobby/agents/isolation.py +395 -0
  11. gobby/agents/runner.py +8 -0
  12. gobby/agents/sandbox.py +261 -0
  13. gobby/agents/spawn.py +42 -287
  14. gobby/agents/spawn_executor.py +385 -0
  15. gobby/agents/spawners/__init__.py +24 -0
  16. gobby/agents/spawners/command_builder.py +189 -0
  17. gobby/agents/spawners/embedded.py +21 -2
  18. gobby/agents/spawners/headless.py +21 -2
  19. gobby/agents/spawners/prompt_manager.py +125 -0
  20. gobby/cli/__init__.py +6 -0
  21. gobby/cli/clones.py +419 -0
  22. gobby/cli/conductor.py +266 -0
  23. gobby/cli/install.py +4 -4
  24. gobby/cli/installers/antigravity.py +3 -9
  25. gobby/cli/installers/claude.py +15 -9
  26. gobby/cli/installers/codex.py +2 -8
  27. gobby/cli/installers/gemini.py +8 -8
  28. gobby/cli/installers/shared.py +175 -13
  29. gobby/cli/sessions.py +1 -1
  30. gobby/cli/skills.py +858 -0
  31. gobby/cli/tasks/ai.py +0 -440
  32. gobby/cli/tasks/crud.py +44 -6
  33. gobby/cli/tasks/main.py +0 -4
  34. gobby/cli/tui.py +2 -2
  35. gobby/cli/utils.py +12 -5
  36. gobby/clones/__init__.py +13 -0
  37. gobby/clones/git.py +547 -0
  38. gobby/conductor/__init__.py +16 -0
  39. gobby/conductor/alerts.py +135 -0
  40. gobby/conductor/loop.py +164 -0
  41. gobby/conductor/monitors/__init__.py +11 -0
  42. gobby/conductor/monitors/agents.py +116 -0
  43. gobby/conductor/monitors/tasks.py +155 -0
  44. gobby/conductor/pricing.py +234 -0
  45. gobby/conductor/token_tracker.py +160 -0
  46. gobby/config/__init__.py +12 -97
  47. gobby/config/app.py +69 -91
  48. gobby/config/extensions.py +2 -2
  49. gobby/config/features.py +7 -130
  50. gobby/config/search.py +110 -0
  51. gobby/config/servers.py +1 -1
  52. gobby/config/skills.py +43 -0
  53. gobby/config/tasks.py +9 -41
  54. gobby/hooks/__init__.py +0 -13
  55. gobby/hooks/event_handlers.py +188 -2
  56. gobby/hooks/hook_manager.py +50 -4
  57. gobby/hooks/plugins.py +1 -1
  58. gobby/hooks/skill_manager.py +130 -0
  59. gobby/hooks/webhooks.py +1 -1
  60. gobby/install/claude/hooks/hook_dispatcher.py +4 -4
  61. gobby/install/codex/hooks/hook_dispatcher.py +1 -1
  62. gobby/install/gemini/hooks/hook_dispatcher.py +87 -12
  63. gobby/llm/claude.py +22 -34
  64. gobby/llm/claude_executor.py +46 -256
  65. gobby/llm/codex_executor.py +59 -291
  66. gobby/llm/executor.py +21 -0
  67. gobby/llm/gemini.py +134 -110
  68. gobby/llm/litellm_executor.py +143 -6
  69. gobby/llm/resolver.py +98 -35
  70. gobby/mcp_proxy/importer.py +62 -4
  71. gobby/mcp_proxy/instructions.py +56 -0
  72. gobby/mcp_proxy/models.py +15 -0
  73. gobby/mcp_proxy/registries.py +68 -8
  74. gobby/mcp_proxy/server.py +33 -3
  75. gobby/mcp_proxy/services/recommendation.py +43 -11
  76. gobby/mcp_proxy/services/tool_proxy.py +81 -1
  77. gobby/mcp_proxy/stdio.py +2 -1
  78. gobby/mcp_proxy/tools/__init__.py +0 -2
  79. gobby/mcp_proxy/tools/agent_messaging.py +317 -0
  80. gobby/mcp_proxy/tools/agents.py +31 -731
  81. gobby/mcp_proxy/tools/clones.py +518 -0
  82. gobby/mcp_proxy/tools/memory.py +3 -26
  83. gobby/mcp_proxy/tools/metrics.py +65 -1
  84. gobby/mcp_proxy/tools/orchestration/__init__.py +3 -0
  85. gobby/mcp_proxy/tools/orchestration/cleanup.py +151 -0
  86. gobby/mcp_proxy/tools/orchestration/wait.py +467 -0
  87. gobby/mcp_proxy/tools/sessions/__init__.py +14 -0
  88. gobby/mcp_proxy/tools/sessions/_commits.py +232 -0
  89. gobby/mcp_proxy/tools/sessions/_crud.py +253 -0
  90. gobby/mcp_proxy/tools/sessions/_factory.py +63 -0
  91. gobby/mcp_proxy/tools/sessions/_handoff.py +499 -0
  92. gobby/mcp_proxy/tools/sessions/_messages.py +138 -0
  93. gobby/mcp_proxy/tools/skills/__init__.py +616 -0
  94. gobby/mcp_proxy/tools/spawn_agent.py +417 -0
  95. gobby/mcp_proxy/tools/task_orchestration.py +7 -0
  96. gobby/mcp_proxy/tools/task_readiness.py +14 -0
  97. gobby/mcp_proxy/tools/task_sync.py +1 -1
  98. gobby/mcp_proxy/tools/tasks/_context.py +0 -20
  99. gobby/mcp_proxy/tools/tasks/_crud.py +91 -4
  100. gobby/mcp_proxy/tools/tasks/_expansion.py +348 -0
  101. gobby/mcp_proxy/tools/tasks/_factory.py +6 -16
  102. gobby/mcp_proxy/tools/tasks/_lifecycle.py +110 -45
  103. gobby/mcp_proxy/tools/tasks/_lifecycle_validation.py +18 -29
  104. gobby/mcp_proxy/tools/workflows.py +1 -1
  105. gobby/mcp_proxy/tools/worktrees.py +0 -338
  106. gobby/memory/backends/__init__.py +6 -1
  107. gobby/memory/backends/mem0.py +6 -1
  108. gobby/memory/extractor.py +477 -0
  109. gobby/memory/ingestion/__init__.py +5 -0
  110. gobby/memory/ingestion/multimodal.py +221 -0
  111. gobby/memory/manager.py +73 -285
  112. gobby/memory/search/__init__.py +10 -0
  113. gobby/memory/search/coordinator.py +248 -0
  114. gobby/memory/services/__init__.py +5 -0
  115. gobby/memory/services/crossref.py +142 -0
  116. gobby/prompts/loader.py +5 -2
  117. gobby/runner.py +37 -16
  118. gobby/search/__init__.py +48 -6
  119. gobby/search/backends/__init__.py +159 -0
  120. gobby/search/backends/embedding.py +225 -0
  121. gobby/search/embeddings.py +238 -0
  122. gobby/search/models.py +148 -0
  123. gobby/search/unified.py +496 -0
  124. gobby/servers/http.py +24 -12
  125. gobby/servers/routes/admin.py +294 -0
  126. gobby/servers/routes/mcp/endpoints/__init__.py +61 -0
  127. gobby/servers/routes/mcp/endpoints/discovery.py +405 -0
  128. gobby/servers/routes/mcp/endpoints/execution.py +568 -0
  129. gobby/servers/routes/mcp/endpoints/registry.py +378 -0
  130. gobby/servers/routes/mcp/endpoints/server.py +304 -0
  131. gobby/servers/routes/mcp/hooks.py +1 -1
  132. gobby/servers/routes/mcp/tools.py +48 -1317
  133. gobby/servers/websocket.py +2 -2
  134. gobby/sessions/analyzer.py +2 -0
  135. gobby/sessions/lifecycle.py +1 -1
  136. gobby/sessions/processor.py +10 -0
  137. gobby/sessions/transcripts/base.py +2 -0
  138. gobby/sessions/transcripts/claude.py +79 -10
  139. gobby/skills/__init__.py +91 -0
  140. gobby/skills/loader.py +685 -0
  141. gobby/skills/manager.py +384 -0
  142. gobby/skills/parser.py +286 -0
  143. gobby/skills/search.py +463 -0
  144. gobby/skills/sync.py +119 -0
  145. gobby/skills/updater.py +385 -0
  146. gobby/skills/validator.py +368 -0
  147. gobby/storage/clones.py +378 -0
  148. gobby/storage/database.py +1 -1
  149. gobby/storage/memories.py +43 -13
  150. gobby/storage/migrations.py +162 -201
  151. gobby/storage/sessions.py +116 -7
  152. gobby/storage/skills.py +782 -0
  153. gobby/storage/tasks/_crud.py +4 -4
  154. gobby/storage/tasks/_lifecycle.py +57 -7
  155. gobby/storage/tasks/_manager.py +14 -5
  156. gobby/storage/tasks/_models.py +8 -3
  157. gobby/sync/memories.py +40 -5
  158. gobby/sync/tasks.py +83 -6
  159. gobby/tasks/__init__.py +1 -2
  160. gobby/tasks/external_validator.py +1 -1
  161. gobby/tasks/validation.py +46 -35
  162. gobby/tools/summarizer.py +91 -10
  163. gobby/tui/api_client.py +4 -7
  164. gobby/tui/app.py +5 -3
  165. gobby/tui/screens/orchestrator.py +1 -2
  166. gobby/tui/screens/tasks.py +2 -4
  167. gobby/tui/ws_client.py +1 -1
  168. gobby/utils/daemon_client.py +2 -2
  169. gobby/utils/project_context.py +2 -3
  170. gobby/utils/status.py +13 -0
  171. gobby/workflows/actions.py +221 -1135
  172. gobby/workflows/artifact_actions.py +31 -0
  173. gobby/workflows/autonomous_actions.py +11 -0
  174. gobby/workflows/context_actions.py +93 -1
  175. gobby/workflows/detection_helpers.py +115 -31
  176. gobby/workflows/enforcement/__init__.py +47 -0
  177. gobby/workflows/enforcement/blocking.py +269 -0
  178. gobby/workflows/enforcement/commit_policy.py +283 -0
  179. gobby/workflows/enforcement/handlers.py +269 -0
  180. gobby/workflows/{task_enforcement_actions.py → enforcement/task_policy.py} +29 -388
  181. gobby/workflows/engine.py +13 -2
  182. gobby/workflows/git_utils.py +106 -0
  183. gobby/workflows/lifecycle_evaluator.py +29 -1
  184. gobby/workflows/llm_actions.py +30 -0
  185. gobby/workflows/loader.py +19 -6
  186. gobby/workflows/mcp_actions.py +20 -1
  187. gobby/workflows/memory_actions.py +154 -0
  188. gobby/workflows/safe_evaluator.py +183 -0
  189. gobby/workflows/session_actions.py +44 -0
  190. gobby/workflows/state_actions.py +60 -1
  191. gobby/workflows/stop_signal_actions.py +55 -0
  192. gobby/workflows/summary_actions.py +111 -1
  193. gobby/workflows/task_sync_actions.py +347 -0
  194. gobby/workflows/todo_actions.py +34 -1
  195. gobby/workflows/webhook_actions.py +185 -0
  196. {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/METADATA +87 -21
  197. {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/RECORD +201 -172
  198. {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/WHEEL +1 -1
  199. gobby/adapters/codex.py +0 -1292
  200. gobby/install/claude/commands/gobby/bug.md +0 -51
  201. gobby/install/claude/commands/gobby/chore.md +0 -51
  202. gobby/install/claude/commands/gobby/epic.md +0 -52
  203. gobby/install/claude/commands/gobby/eval.md +0 -235
  204. gobby/install/claude/commands/gobby/feat.md +0 -49
  205. gobby/install/claude/commands/gobby/nit.md +0 -52
  206. gobby/install/claude/commands/gobby/ref.md +0 -52
  207. gobby/install/codex/prompts/forget.md +0 -7
  208. gobby/install/codex/prompts/memories.md +0 -7
  209. gobby/install/codex/prompts/recall.md +0 -7
  210. gobby/install/codex/prompts/remember.md +0 -13
  211. gobby/llm/gemini_executor.py +0 -339
  212. gobby/mcp_proxy/tools/session_messages.py +0 -1056
  213. gobby/mcp_proxy/tools/task_expansion.py +0 -591
  214. gobby/prompts/defaults/expansion/system.md +0 -119
  215. gobby/prompts/defaults/expansion/user.md +0 -48
  216. gobby/prompts/defaults/external_validation/agent.md +0 -72
  217. gobby/prompts/defaults/external_validation/external.md +0 -63
  218. gobby/prompts/defaults/external_validation/spawn.md +0 -83
  219. gobby/prompts/defaults/external_validation/system.md +0 -6
  220. gobby/prompts/defaults/features/import_mcp.md +0 -22
  221. gobby/prompts/defaults/features/import_mcp_github.md +0 -17
  222. gobby/prompts/defaults/features/import_mcp_search.md +0 -16
  223. gobby/prompts/defaults/features/recommend_tools.md +0 -32
  224. gobby/prompts/defaults/features/recommend_tools_hybrid.md +0 -35
  225. gobby/prompts/defaults/features/recommend_tools_llm.md +0 -30
  226. gobby/prompts/defaults/features/server_description.md +0 -20
  227. gobby/prompts/defaults/features/server_description_system.md +0 -6
  228. gobby/prompts/defaults/features/task_description.md +0 -31
  229. gobby/prompts/defaults/features/task_description_system.md +0 -6
  230. gobby/prompts/defaults/features/tool_summary.md +0 -17
  231. gobby/prompts/defaults/features/tool_summary_system.md +0 -6
  232. gobby/prompts/defaults/research/step.md +0 -58
  233. gobby/prompts/defaults/validation/criteria.md +0 -47
  234. gobby/prompts/defaults/validation/validate.md +0 -38
  235. gobby/storage/migrations_legacy.py +0 -1359
  236. gobby/tasks/context.py +0 -747
  237. gobby/tasks/criteria.py +0 -342
  238. gobby/tasks/expansion.py +0 -626
  239. gobby/tasks/prompts/expand.py +0 -327
  240. gobby/tasks/research.py +0 -421
  241. gobby/tasks/tdd.py +0 -352
  242. {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/entry_points.txt +0 -0
  243. {gobby-0.2.5.dist-info → gobby-0.2.7.dist-info}/licenses/LICENSE.md +0 -0
  244. {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
- from gobby.config.extensions import (
19
- HookExtensionsConfig,
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
- MemoryConfig,
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.tasks import (
52
- CompactHandoffConfig,
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
- # From gobby.config.extensions
63
- "HookExtensionsConfig",
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=8765,
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:
@@ -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: ["~/.gobby/plugins", ".gobby/plugins"],
141
- description="Directories to scan for plugins (supports ~ expansion)",
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,