gobby 0.2.6__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/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/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/install.py +4 -4
- gobby/cli/installers/claude.py +6 -0
- gobby/cli/installers/gemini.py +6 -0
- gobby/cli/installers/shared.py +103 -4
- gobby/cli/sessions.py +1 -1
- gobby/cli/utils.py +9 -2
- gobby/config/__init__.py +12 -97
- gobby/config/app.py +10 -94
- gobby/config/extensions.py +2 -2
- gobby/config/features.py +7 -130
- gobby/config/tasks.py +4 -28
- gobby/hooks/__init__.py +0 -13
- gobby/hooks/event_handlers.py +45 -2
- gobby/hooks/hook_manager.py +2 -2
- gobby/hooks/plugins.py +1 -1
- gobby/hooks/webhooks.py +1 -1
- gobby/llm/resolver.py +3 -2
- gobby/mcp_proxy/importer.py +62 -4
- gobby/mcp_proxy/instructions.py +2 -0
- gobby/mcp_proxy/registries.py +1 -4
- gobby/mcp_proxy/services/recommendation.py +43 -11
- gobby/mcp_proxy/tools/agents.py +31 -731
- gobby/mcp_proxy/tools/clones.py +0 -385
- gobby/mcp_proxy/tools/memory.py +2 -2
- 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 +14 -29
- gobby/mcp_proxy/tools/spawn_agent.py +417 -0
- gobby/mcp_proxy/tools/tasks/_lifecycle.py +52 -18
- gobby/mcp_proxy/tools/tasks/_lifecycle_validation.py +1 -1
- gobby/mcp_proxy/tools/worktrees.py +0 -343
- gobby/memory/ingestion/__init__.py +5 -0
- gobby/memory/ingestion/multimodal.py +221 -0
- gobby/memory/manager.py +62 -283
- 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/servers/http.py +1 -4
- gobby/servers/routes/admin.py +14 -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 -1506
- gobby/sessions/lifecycle.py +1 -1
- gobby/sessions/processor.py +10 -0
- gobby/sessions/transcripts/base.py +1 -0
- gobby/sessions/transcripts/claude.py +15 -5
- gobby/skills/parser.py +30 -2
- gobby/storage/migrations.py +159 -372
- gobby/storage/sessions.py +43 -7
- gobby/storage/skills.py +37 -4
- gobby/storage/tasks/_lifecycle.py +18 -3
- gobby/sync/memories.py +1 -1
- gobby/tasks/external_validator.py +1 -1
- gobby/tasks/validation.py +22 -20
- gobby/tools/summarizer.py +91 -10
- gobby/utils/project_context.py +2 -3
- gobby/utils/status.py +13 -0
- gobby/workflows/actions.py +221 -1217
- gobby/workflows/artifact_actions.py +31 -0
- gobby/workflows/autonomous_actions.py +11 -0
- gobby/workflows/context_actions.py +50 -1
- 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/enforcement/task_policy.py +542 -0
- gobby/workflows/git_utils.py +106 -0
- gobby/workflows/llm_actions.py +30 -0
- gobby/workflows/mcp_actions.py +20 -1
- gobby/workflows/memory_actions.py +80 -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 +94 -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.6.dist-info → gobby-0.2.7.dist-info}/METADATA +6 -1
- {gobby-0.2.6.dist-info → gobby-0.2.7.dist-info}/RECORD +111 -111
- {gobby-0.2.6.dist-info → gobby-0.2.7.dist-info}/WHEEL +1 -1
- gobby/adapters/codex.py +0 -1332
- 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/mcp_proxy/tools/session_messages.py +0 -1055
- 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/handoff/compact.md +0 -63
- gobby/prompts/defaults/handoff/session_end.md +0 -57
- gobby/prompts/defaults/memory/extract.md +0 -61
- 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/workflows/task_enforcement_actions.py +0 -1343
- {gobby-0.2.6.dist-info → gobby-0.2.7.dist-info}/entry_points.txt +0 -0
- {gobby-0.2.6.dist-info → gobby-0.2.7.dist-info}/licenses/LICENSE.md +0 -0
- {gobby-0.2.6.dist-info → gobby-0.2.7.dist-info}/top_level.txt +0 -0
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,9 @@ 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
|
|
42
31
|
from gobby.config.search import SearchConfig
|
|
43
32
|
from gobby.config.servers import MCPClientProxyConfig, WebSocketSettings
|
|
44
33
|
from gobby.config.sessions import (
|
|
@@ -50,61 +39,10 @@ from gobby.config.sessions import (
|
|
|
50
39
|
TitleSynthesisConfig,
|
|
51
40
|
)
|
|
52
41
|
from gobby.config.skills import SkillsConfig
|
|
53
|
-
from gobby.config.tasks import
|
|
54
|
-
CompactHandoffConfig,
|
|
55
|
-
GobbyTasksConfig,
|
|
56
|
-
PatternCriteriaConfig,
|
|
57
|
-
TaskExpansionConfig,
|
|
58
|
-
TaskValidationConfig,
|
|
59
|
-
WorkflowConfig,
|
|
60
|
-
)
|
|
42
|
+
from gobby.config.tasks import CompactHandoffConfig, GobbyTasksConfig, WorkflowConfig
|
|
61
43
|
|
|
62
|
-
# Explicit exports for mypy (re-exported symbols from submodules)
|
|
63
44
|
__all__ = [
|
|
64
|
-
#
|
|
65
|
-
"HookExtensionsConfig",
|
|
66
|
-
"PluginItemConfig",
|
|
67
|
-
"PluginsConfig",
|
|
68
|
-
"WebhookEndpointConfig",
|
|
69
|
-
"WebhooksConfig",
|
|
70
|
-
"WebSocketBroadcastConfig",
|
|
71
|
-
# From gobby.config.features
|
|
72
|
-
"ImportMCPServerConfig",
|
|
73
|
-
"MetricsConfig",
|
|
74
|
-
"ProjectVerificationConfig",
|
|
75
|
-
"RecommendToolsConfig",
|
|
76
|
-
"TaskDescriptionConfig",
|
|
77
|
-
"ToolSummarizerConfig",
|
|
78
|
-
# From gobby.config.llm_providers
|
|
79
|
-
"LLMProviderConfig",
|
|
80
|
-
"LLMProvidersConfig",
|
|
81
|
-
# From gobby.config.logging
|
|
82
|
-
"LoggingSettings",
|
|
83
|
-
# From gobby.config.persistence
|
|
84
|
-
"MemoryConfig",
|
|
85
|
-
"MemorySyncConfig",
|
|
86
|
-
# From gobby.config.search
|
|
87
|
-
"SearchConfig",
|
|
88
|
-
# From gobby.config.servers
|
|
89
|
-
"MCPClientProxyConfig",
|
|
90
|
-
"WebSocketSettings",
|
|
91
|
-
# From gobby.config.skills
|
|
92
|
-
"SkillsConfig",
|
|
93
|
-
# From gobby.config.sessions
|
|
94
|
-
"ArtifactHandoffConfig",
|
|
95
|
-
"ContextInjectionConfig",
|
|
96
|
-
"MessageTrackingConfig",
|
|
97
|
-
"SessionLifecycleConfig",
|
|
98
|
-
"SessionSummaryConfig",
|
|
99
|
-
"TitleSynthesisConfig",
|
|
100
|
-
# From gobby.config.tasks
|
|
101
|
-
"CompactHandoffConfig",
|
|
102
|
-
"GobbyTasksConfig",
|
|
103
|
-
"PatternCriteriaConfig",
|
|
104
|
-
"TaskExpansionConfig",
|
|
105
|
-
"TaskValidationConfig",
|
|
106
|
-
"WorkflowConfig",
|
|
107
|
-
# Local definitions
|
|
45
|
+
# Local definitions only - no re-exports
|
|
108
46
|
"ConductorConfig",
|
|
109
47
|
"DaemonConfig",
|
|
110
48
|
"expand_env_vars",
|
|
@@ -184,32 +122,6 @@ def expand_env_vars(content: str) -> str:
|
|
|
184
122
|
return ENV_VAR_PATTERN.sub(replace_match, content)
|
|
185
123
|
|
|
186
124
|
|
|
187
|
-
# WebSocketSettings moved to gobby.config.servers (re-exported above)
|
|
188
|
-
# LoggingSettings moved to gobby.config.logging (re-exported above)
|
|
189
|
-
# CompactHandoffConfig moved to gobby.config.tasks (re-exported above)
|
|
190
|
-
|
|
191
|
-
# ContextInjectionConfig, SessionSummaryConfig, TitleSynthesisConfig,
|
|
192
|
-
# MessageTrackingConfig, SessionLifecycleConfig
|
|
193
|
-
# moved to gobby.config.sessions (re-exported above)
|
|
194
|
-
|
|
195
|
-
# ToolSummarizerConfig, RecommendToolsConfig, ImportMCPServerConfig,
|
|
196
|
-
# MetricsConfig, ProjectVerificationConfig
|
|
197
|
-
# moved to gobby.config.features (re-exported above)
|
|
198
|
-
|
|
199
|
-
# WebSocketBroadcastConfig, WebhookEndpointConfig, WebhooksConfig,
|
|
200
|
-
# PluginItemConfig, PluginsConfig, HookExtensionsConfig
|
|
201
|
-
# moved to gobby.config.extensions (re-exported above)
|
|
202
|
-
|
|
203
|
-
# PatternCriteriaConfig, TaskExpansionConfig, TaskValidationConfig, WorkflowConfig,
|
|
204
|
-
# GobbyTasksConfig, CompactHandoffConfig
|
|
205
|
-
# moved to gobby.config.tasks (re-exported above)
|
|
206
|
-
|
|
207
|
-
# MCPClientProxyConfig moved to gobby.config.servers (re-exported above)
|
|
208
|
-
# LLMProviderConfig and LLMProvidersConfig moved to gobby.config.llm_providers (re-exported above)
|
|
209
|
-
# MemoryConfig, MemorySyncConfig
|
|
210
|
-
# moved to gobby.config.persistence (re-exported above)
|
|
211
|
-
|
|
212
|
-
|
|
213
125
|
class DaemonConfig(BaseModel):
|
|
214
126
|
"""
|
|
215
127
|
Main configuration for Gobby daemon.
|
|
@@ -243,6 +155,10 @@ class DaemonConfig(BaseModel):
|
|
|
243
155
|
default="~/.gobby/gobby-hub.db",
|
|
244
156
|
description="Path to hub database for cross-project queries.",
|
|
245
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
|
+
)
|
|
246
162
|
|
|
247
163
|
# Sub-configs
|
|
248
164
|
websocket: WebSocketSettings = Field(
|
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,
|
gobby/config/features.py
CHANGED
|
@@ -42,45 +42,22 @@ class ToolSummarizerConfig(BaseModel):
|
|
|
42
42
|
default="claude-haiku-4-5",
|
|
43
43
|
description="Model to use for summarization (fast/cheap recommended)",
|
|
44
44
|
)
|
|
45
|
-
prompt: str = Field(
|
|
46
|
-
default="""Summarize this MCP tool description in 180 characters or less.
|
|
47
|
-
Keep it to three sentences or less. Be concise and preserve the key functionality.
|
|
48
|
-
Do not add quotes, extra formatting, or code examples.
|
|
49
45
|
|
|
50
|
-
Description: {description}
|
|
51
|
-
|
|
52
|
-
Summary:""",
|
|
53
|
-
description="DEPRECATED: Use prompt_path instead. Prompt template for tool description summarization",
|
|
54
|
-
)
|
|
55
46
|
prompt_path: str | None = Field(
|
|
56
47
|
default=None,
|
|
57
48
|
description="Path to custom tool summary prompt template (e.g., 'features/tool_summary')",
|
|
58
49
|
)
|
|
59
|
-
|
|
60
|
-
default="You are a technical summarizer. Create concise tool descriptions.",
|
|
61
|
-
description="DEPRECATED: Use system_prompt_path instead. System prompt for tool description summarization",
|
|
62
|
-
)
|
|
50
|
+
|
|
63
51
|
system_prompt_path: str | None = Field(
|
|
64
52
|
default=None,
|
|
65
53
|
description="Path to custom tool summary system prompt (e.g., 'features/tool_summary_system')",
|
|
66
54
|
)
|
|
67
|
-
server_description_prompt: str = Field(
|
|
68
|
-
default="""Write a single concise sentence describing what the '{server_name}' MCP server does based on its tools.
|
|
69
55
|
|
|
70
|
-
Tools:
|
|
71
|
-
{tools_list}
|
|
72
|
-
|
|
73
|
-
Description (1 sentence, try to keep under 100 characters):""",
|
|
74
|
-
description="DEPRECATED: Use server_description_prompt_path instead. Prompt template for server description generation",
|
|
75
|
-
)
|
|
76
56
|
server_description_prompt_path: str | None = Field(
|
|
77
57
|
default=None,
|
|
78
58
|
description="Path to custom server description prompt (e.g., 'features/server_description')",
|
|
79
59
|
)
|
|
80
|
-
|
|
81
|
-
default="You write concise technical descriptions.",
|
|
82
|
-
description="DEPRECATED: Use server_description_system_prompt_path instead. System prompt for server description generation",
|
|
83
|
-
)
|
|
60
|
+
|
|
84
61
|
server_description_system_prompt_path: str | None = Field(
|
|
85
62
|
default=None,
|
|
86
63
|
description="Path to custom server description system prompt (e.g., 'features/server_description_system')",
|
|
@@ -110,26 +87,12 @@ class TaskDescriptionConfig(BaseModel):
|
|
|
110
87
|
default=50,
|
|
111
88
|
description="Minimum length of structured extraction before LLM fallback triggers",
|
|
112
89
|
)
|
|
113
|
-
prompt: str = Field(
|
|
114
|
-
default="""Generate a concise task description for this task from a spec document.
|
|
115
|
-
|
|
116
|
-
Task title: {task_title}
|
|
117
|
-
Section: {section_title}
|
|
118
|
-
Section content: {section_content}
|
|
119
|
-
Existing context: {existing_context}
|
|
120
90
|
|
|
121
|
-
Write a 1-2 sentence description focusing on the goal and deliverable.
|
|
122
|
-
Do not add quotes, extra formatting, or implementation details.""",
|
|
123
|
-
description="DEPRECATED: Use prompt_path instead. Prompt template for task description generation",
|
|
124
|
-
)
|
|
125
91
|
prompt_path: str | None = Field(
|
|
126
92
|
default=None,
|
|
127
93
|
description="Path to custom task description prompt (e.g., 'features/task_description')",
|
|
128
94
|
)
|
|
129
|
-
|
|
130
|
-
default="You are a technical writer creating concise task descriptions for developers.",
|
|
131
|
-
description="DEPRECATED: Use system_prompt_path instead. System prompt for task description generation",
|
|
132
|
-
)
|
|
95
|
+
|
|
133
96
|
system_prompt_path: str | None = Field(
|
|
134
97
|
default=None,
|
|
135
98
|
description="Path to custom task description system prompt (e.g., 'features/task_description_system')",
|
|
@@ -159,83 +122,17 @@ class RecommendToolsConfig(BaseModel):
|
|
|
159
122
|
default="claude-sonnet-4-5",
|
|
160
123
|
description="Model to use for tool recommendations",
|
|
161
124
|
)
|
|
162
|
-
|
|
163
|
-
default="""You are a tool recommendation assistant for Claude Code with access to MCP servers.
|
|
164
|
-
|
|
165
|
-
CRITICAL PRIORITIZATION RULES:
|
|
166
|
-
1. Analyze the task type (code navigation, docs lookup, database query, planning, data processing, etc.)
|
|
167
|
-
2. Check available MCP server DESCRIPTIONS for capability matches
|
|
168
|
-
3. If ANY MCP server's description matches the task type -> recommend those tools FIRST
|
|
169
|
-
4. Only recommend built-in Claude Code tools (Grep, Read, Bash, WebSearch) if NO suitable MCP server exists
|
|
170
|
-
|
|
171
|
-
TASK TYPE MATCHING GUIDELINES:
|
|
172
|
-
- Task needs library/framework documentation -> Look for MCP servers describing "documentation", "library docs", "API reference"
|
|
173
|
-
- Task needs code navigation/architecture understanding -> Look for MCP servers describing "code analysis", "symbols", "semantic search"
|
|
174
|
-
- Task needs database operations -> Look for MCP servers describing "database", "PostgreSQL", "SQL"
|
|
175
|
-
- Task needs complex reasoning/planning -> Look for MCP servers describing "problem-solving", "thinking", "reasoning"
|
|
176
|
-
- Task needs data processing/large datasets -> Look for MCP servers describing "code execution", "data processing", "token optimization"
|
|
177
|
-
|
|
178
|
-
ANTI-PATTERNS (What NOT to recommend):
|
|
179
|
-
- Don't recommend WebSearch when an MCP server provides library/framework documentation
|
|
180
|
-
- Don't recommend Grep/Read for code architecture questions when an MCP server does semantic code analysis
|
|
181
|
-
- Don't recommend Bash for database queries when an MCP server provides database tools
|
|
182
|
-
- Don't recommend direct implementation when an MCP server provides structured reasoning
|
|
183
|
-
|
|
184
|
-
OUTPUT FORMAT:
|
|
185
|
-
Be concise and specific. Recommend 1-3 tools maximum with:
|
|
186
|
-
1. Which MCP server and tools to use (if applicable)
|
|
187
|
-
2. Brief rationale based on server description matching task type
|
|
188
|
-
3. Suggested workflow (e.g., "First call X, then use result with Y")
|
|
189
|
-
4. Only mention built-in tools if no MCP server is suitable""",
|
|
190
|
-
description="DEPRECATED: Use prompt_path instead. System prompt for recommend_tools() MCP tool.",
|
|
191
|
-
)
|
|
125
|
+
|
|
192
126
|
prompt_path: str | None = Field(
|
|
193
127
|
default=None,
|
|
194
128
|
description="Path to custom recommend tools system prompt (e.g., 'features/recommend_tools')",
|
|
195
129
|
)
|
|
196
|
-
|
|
197
|
-
default="""You are an expert at selecting tools for tasks.
|
|
198
|
-
Task: {task_description}
|
|
199
|
-
|
|
200
|
-
Candidate tools (ranked by semantic similarity):
|
|
201
|
-
{candidate_list}
|
|
202
|
-
|
|
203
|
-
Re-rank these tools by relevance to the task and provide reasoning.
|
|
204
|
-
Return the top {top_k} most relevant as JSON:
|
|
205
|
-
{{
|
|
206
|
-
"recommendations": [
|
|
207
|
-
{{
|
|
208
|
-
"server": "server_name",
|
|
209
|
-
"tool": "tool_name",
|
|
210
|
-
"reason": "Why this tool is the best choice"
|
|
211
|
-
}}
|
|
212
|
-
]
|
|
213
|
-
}}""",
|
|
214
|
-
description="DEPRECATED: Use hybrid_rerank_prompt_path instead. Prompt template for hybrid mode re-ranking",
|
|
215
|
-
)
|
|
130
|
+
|
|
216
131
|
hybrid_rerank_prompt_path: str | None = Field(
|
|
217
132
|
default=None,
|
|
218
133
|
description="Path to custom hybrid re-rank prompt (e.g., 'features/recommend_tools_hybrid')",
|
|
219
134
|
)
|
|
220
|
-
|
|
221
|
-
default="""You are an expert at selecting the right tools for a given task.
|
|
222
|
-
Task: {task_description}
|
|
223
|
-
|
|
224
|
-
Available Servers: {available_servers}
|
|
225
|
-
|
|
226
|
-
Please recommend which tools from these servers would be most useful for this task.
|
|
227
|
-
Return a JSON object with this structure:
|
|
228
|
-
{{
|
|
229
|
-
"recommendations": [
|
|
230
|
-
{{
|
|
231
|
-
"server": "server_name",
|
|
232
|
-
"tool": "tool_name",
|
|
233
|
-
"reason": "Why this tool is useful"
|
|
234
|
-
}}
|
|
235
|
-
]
|
|
236
|
-
}}""",
|
|
237
|
-
description="DEPRECATED: Use llm_prompt_path instead. Prompt template for LLM mode recommendations",
|
|
238
|
-
)
|
|
135
|
+
|
|
239
136
|
llm_prompt_path: str | None = Field(
|
|
240
137
|
default=None,
|
|
241
138
|
description="Path to custom LLM recommendation prompt (e.g., 'features/recommend_tools_llm')",
|
|
@@ -276,37 +173,17 @@ class ImportMCPServerConfig(BaseModel):
|
|
|
276
173
|
default="claude-haiku-4-5",
|
|
277
174
|
description="Model to use for config extraction",
|
|
278
175
|
)
|
|
279
|
-
|
|
280
|
-
default=DEFAULT_IMPORT_MCP_SERVER_PROMPT,
|
|
281
|
-
description="DEPRECATED: Use prompt_path instead. System prompt for MCP server config extraction",
|
|
282
|
-
)
|
|
176
|
+
|
|
283
177
|
prompt_path: str | None = Field(
|
|
284
178
|
default=None,
|
|
285
179
|
description="Path to custom import MCP system prompt (e.g., 'features/import_mcp')",
|
|
286
180
|
)
|
|
287
|
-
github_fetch_prompt: str = Field(
|
|
288
|
-
default="""Fetch the README from this GitHub repository and extract MCP server configuration:
|
|
289
|
-
|
|
290
|
-
{github_url}
|
|
291
|
-
|
|
292
|
-
If the URL doesn't point directly to a README, try to find and fetch the README.md file.
|
|
293
181
|
|
|
294
|
-
After reading the documentation, extract the MCP server configuration as a JSON object.""",
|
|
295
|
-
description="DEPRECATED: Use github_fetch_prompt_path instead. User prompt template for GitHub import",
|
|
296
|
-
)
|
|
297
182
|
github_fetch_prompt_path: str | None = Field(
|
|
298
183
|
default=None,
|
|
299
184
|
description="Path to custom GitHub fetch prompt (e.g., 'features/import_mcp_github')",
|
|
300
185
|
)
|
|
301
|
-
search_fetch_prompt: str = Field(
|
|
302
|
-
default="""Search for MCP server: {search_query}
|
|
303
|
-
|
|
304
|
-
Find the official documentation or GitHub repository for this MCP server.
|
|
305
|
-
Then fetch and read the README or installation docs.
|
|
306
186
|
|
|
307
|
-
After reading the documentation, extract the MCP server configuration as a JSON object.""",
|
|
308
|
-
description="DEPRECATED: Use search_fetch_prompt_path instead. User prompt template for search-based import",
|
|
309
|
-
)
|
|
310
187
|
search_fetch_prompt_path: str | None = Field(
|
|
311
188
|
default=None,
|
|
312
189
|
description="Path to custom search fetch prompt (e.g., 'features/import_mcp_search')",
|
gobby/config/tasks.py
CHANGED
|
@@ -38,14 +38,6 @@ class CompactHandoffConfig(BaseModel):
|
|
|
38
38
|
default=True,
|
|
39
39
|
description="Enable compact handoff context extraction and injection",
|
|
40
40
|
)
|
|
41
|
-
# DEPRECATED: prompt field is no longer used.
|
|
42
|
-
# Template is now defined in session-handoff.yaml workflow file.
|
|
43
|
-
# Kept for backwards compatibility but will be removed in a future version.
|
|
44
|
-
prompt: str | None = Field(
|
|
45
|
-
default=None,
|
|
46
|
-
description="DEPRECATED: Template moved to session-handoff.yaml workflow. "
|
|
47
|
-
"This field is ignored.",
|
|
48
|
-
)
|
|
49
41
|
|
|
50
42
|
|
|
51
43
|
class PatternCriteriaConfig(BaseModel):
|
|
@@ -147,10 +139,7 @@ class TaskExpansionConfig(BaseModel):
|
|
|
147
139
|
default="claude-opus-4-5",
|
|
148
140
|
description="Model to use for expansion",
|
|
149
141
|
)
|
|
150
|
-
|
|
151
|
-
default=None,
|
|
152
|
-
description="DEPRECATED: Use prompt_path instead. Custom prompt template for task expansion",
|
|
153
|
-
)
|
|
142
|
+
|
|
154
143
|
prompt_path: str | None = Field(
|
|
155
144
|
default=None,
|
|
156
145
|
description="Path to custom user prompt template (e.g., 'expansion/user')",
|
|
@@ -175,14 +164,7 @@ class TaskExpansionConfig(BaseModel):
|
|
|
175
164
|
default="You are a senior developer researching a codebase. Use tools to find relevant code.",
|
|
176
165
|
description="System prompt for the research agent",
|
|
177
166
|
)
|
|
178
|
-
|
|
179
|
-
default=None,
|
|
180
|
-
description="DEPRECATED: Use system_prompt_path instead. Custom system prompt for task expansion",
|
|
181
|
-
)
|
|
182
|
-
tdd_prompt: str | None = Field(
|
|
183
|
-
default=None,
|
|
184
|
-
description="DEPRECATED: TDD instructions are now embedded in task descriptions for code/config categories",
|
|
185
|
-
)
|
|
167
|
+
|
|
186
168
|
web_research_enabled: bool = Field(
|
|
187
169
|
default=True,
|
|
188
170
|
description="Enable web research for task expansion using MCP tools",
|
|
@@ -228,10 +210,7 @@ class TaskValidationConfig(BaseModel):
|
|
|
228
210
|
default="You are a QA validator. Output ONLY valid JSON. No markdown, no explanation, no code blocks. Just the raw JSON object.",
|
|
229
211
|
description="System prompt for task validation",
|
|
230
212
|
)
|
|
231
|
-
|
|
232
|
-
default=None,
|
|
233
|
-
description="DEPRECATED: Use prompt_path instead. Custom prompt template for task validation",
|
|
234
|
-
)
|
|
213
|
+
|
|
235
214
|
prompt_path: str | None = Field(
|
|
236
215
|
default=None,
|
|
237
216
|
description="Path to custom validation prompt template (e.g., 'validation/validate')",
|
|
@@ -260,10 +239,7 @@ class TaskValidationConfig(BaseModel):
|
|
|
260
239
|
default="You are a QA engineer writing acceptance criteria. CRITICAL: Only include requirements explicitly stated in the task. Do NOT invent specific values, thresholds, timeouts, or edge cases that aren't mentioned. Vague tasks get vague criteria. Use markdown checkboxes.",
|
|
261
240
|
description="System prompt for generating validation criteria",
|
|
262
241
|
)
|
|
263
|
-
|
|
264
|
-
default=None,
|
|
265
|
-
description="DEPRECATED: Use criteria_prompt_path instead. Custom prompt template for generating validation criteria",
|
|
266
|
-
)
|
|
242
|
+
|
|
267
243
|
# Validation loop control
|
|
268
244
|
max_iterations: int = Field(
|
|
269
245
|
default=10,
|
gobby/hooks/__init__.py
CHANGED
|
@@ -65,14 +65,6 @@ from gobby.hooks.plugins import (
|
|
|
65
65
|
from gobby.hooks.session_coordinator import SessionCoordinator
|
|
66
66
|
from gobby.hooks.webhooks import WebhookDispatcher
|
|
67
67
|
|
|
68
|
-
# Legacy imports for backward compatibility
|
|
69
|
-
from gobby.sessions.manager import SessionManager
|
|
70
|
-
from gobby.sessions.summary import SummaryFileGenerator
|
|
71
|
-
from gobby.sessions.transcripts.claude import ClaudeTranscriptParser
|
|
72
|
-
|
|
73
|
-
# Backward-compatible alias
|
|
74
|
-
TranscriptProcessor = ClaudeTranscriptParser
|
|
75
|
-
|
|
76
68
|
__all__ = [
|
|
77
69
|
# Core coordinator
|
|
78
70
|
"HookManager",
|
|
@@ -96,9 +88,4 @@ __all__ = [
|
|
|
96
88
|
"RegisteredHandler",
|
|
97
89
|
"hook_handler",
|
|
98
90
|
"run_plugin_handlers",
|
|
99
|
-
# Legacy exports (backward compatibility)
|
|
100
|
-
"SessionManager",
|
|
101
|
-
"SummaryFileGenerator",
|
|
102
|
-
"TranscriptProcessor",
|
|
103
|
-
"ClaudeTranscriptParser",
|
|
104
91
|
]
|
gobby/hooks/event_handlers.py
CHANGED
|
@@ -29,6 +29,16 @@ if TYPE_CHECKING:
|
|
|
29
29
|
from gobby.workflows.hooks import WorkflowHookHandler
|
|
30
30
|
|
|
31
31
|
|
|
32
|
+
EDIT_TOOLS = {
|
|
33
|
+
"write_file",
|
|
34
|
+
"replace",
|
|
35
|
+
"edit_file",
|
|
36
|
+
"notebook_edit",
|
|
37
|
+
"edit",
|
|
38
|
+
"write",
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
32
42
|
class EventHandlers:
|
|
33
43
|
"""
|
|
34
44
|
Manages event handler registration and dispatch.
|
|
@@ -221,7 +231,12 @@ class EventHandlers:
|
|
|
221
231
|
self.logger.warning(f"Workflow error: {e}")
|
|
222
232
|
|
|
223
233
|
# Build system message (terminal display only)
|
|
224
|
-
|
|
234
|
+
# Display #N format if seq_num available, fallback to UUID
|
|
235
|
+
session_ref = (
|
|
236
|
+
f"#{existing_session.seq_num}" if existing_session.seq_num else session_id
|
|
237
|
+
)
|
|
238
|
+
system_message = f"\nGobby Session Ref: {session_ref}"
|
|
239
|
+
system_message += f"\nGobby Session ID: {session_id}"
|
|
225
240
|
system_message += f"\nExternal ID: {external_id}"
|
|
226
241
|
if parent_session_id:
|
|
227
242
|
context_parts.append(f"Parent session: {parent_session_id}")
|
|
@@ -333,7 +348,14 @@ class EventHandlers:
|
|
|
333
348
|
context_parts.append(f"Parent session: {parent_session_id}")
|
|
334
349
|
|
|
335
350
|
# Build system message (terminal display only)
|
|
336
|
-
|
|
351
|
+
# Fetch session to get seq_num for #N display
|
|
352
|
+
session_ref = session_id # fallback
|
|
353
|
+
if session_id and self._session_storage:
|
|
354
|
+
session_obj = self._session_storage.get(session_id)
|
|
355
|
+
if session_obj and session_obj.seq_num:
|
|
356
|
+
session_ref = f"#{session_obj.seq_num}"
|
|
357
|
+
system_message = f"\nGobby Session Ref: {session_ref}"
|
|
358
|
+
system_message += f"\nGobby Session ID: {session_id}"
|
|
337
359
|
system_message += f"\nExternal ID: {external_id}"
|
|
338
360
|
|
|
339
361
|
# Add active lifecycle workflows
|
|
@@ -691,6 +713,27 @@ class EventHandlers:
|
|
|
691
713
|
status = "FAIL" if is_failure else "OK"
|
|
692
714
|
if session_id:
|
|
693
715
|
self.logger.debug(f"AFTER_TOOL [{status}]: {tool_name}, session {session_id}")
|
|
716
|
+
|
|
717
|
+
# Track edits for session high-water mark
|
|
718
|
+
# Only if tool succeeded, matches edit tools, and session has claimed a task
|
|
719
|
+
if (
|
|
720
|
+
not is_failure
|
|
721
|
+
and tool_name
|
|
722
|
+
and tool_name.lower() in EDIT_TOOLS
|
|
723
|
+
and self._session_storage
|
|
724
|
+
and self._task_manager
|
|
725
|
+
):
|
|
726
|
+
try:
|
|
727
|
+
# Check if session has any claimed tasks in progress
|
|
728
|
+
claimed_tasks = self._task_manager.list_tasks(
|
|
729
|
+
assignee=session_id, status="in_progress", limit=1
|
|
730
|
+
)
|
|
731
|
+
if claimed_tasks:
|
|
732
|
+
self._session_storage.mark_had_edits(session_id)
|
|
733
|
+
self.logger.debug(f"Marked session {session_id} as had_edits")
|
|
734
|
+
except Exception as e:
|
|
735
|
+
self.logger.warning(f"Failed to track edit history: {e}")
|
|
736
|
+
|
|
694
737
|
else:
|
|
695
738
|
self.logger.debug(f"AFTER_TOOL [{status}]: {tool_name}")
|
|
696
739
|
|
gobby/hooks/hook_manager.py
CHANGED
|
@@ -228,7 +228,7 @@ class HookManager:
|
|
|
228
228
|
)
|
|
229
229
|
|
|
230
230
|
if not memory_config:
|
|
231
|
-
from gobby.config.
|
|
231
|
+
from gobby.config.persistence import MemoryConfig
|
|
232
232
|
|
|
233
233
|
memory_config = MemoryConfig()
|
|
234
234
|
|
|
@@ -316,7 +316,7 @@ class HookManager:
|
|
|
316
316
|
if self._config and hasattr(self._config, "hook_extensions"):
|
|
317
317
|
webhooks_config = self._config.hook_extensions.webhooks
|
|
318
318
|
if not webhooks_config:
|
|
319
|
-
from gobby.config.
|
|
319
|
+
from gobby.config.extensions import WebhooksConfig
|
|
320
320
|
|
|
321
321
|
webhooks_config = WebhooksConfig()
|
|
322
322
|
self._webhook_dispatcher = WebhookDispatcher(webhooks_config)
|
gobby/hooks/plugins.py
CHANGED
|
@@ -23,7 +23,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
23
23
|
from gobby.hooks.events import HookEvent, HookEventType, HookResponse
|
|
24
24
|
|
|
25
25
|
if TYPE_CHECKING:
|
|
26
|
-
from gobby.config.
|
|
26
|
+
from gobby.config.extensions import PluginsConfig
|
|
27
27
|
|
|
28
28
|
logger = logging.getLogger(__name__)
|
|
29
29
|
|
gobby/hooks/webhooks.py
CHANGED
|
@@ -20,7 +20,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
20
20
|
import httpx
|
|
21
21
|
|
|
22
22
|
if TYPE_CHECKING:
|
|
23
|
-
from gobby.config.
|
|
23
|
+
from gobby.config.extensions import WebhookEndpointConfig, WebhooksConfig
|
|
24
24
|
from gobby.hooks.events import HookEvent
|
|
25
25
|
|
|
26
26
|
logger = logging.getLogger(__name__)
|
gobby/llm/resolver.py
CHANGED
|
@@ -18,7 +18,8 @@ from typing import TYPE_CHECKING, Literal
|
|
|
18
18
|
from gobby.llm.executor import AgentExecutor
|
|
19
19
|
|
|
20
20
|
if TYPE_CHECKING:
|
|
21
|
-
from gobby.config.app import DaemonConfig
|
|
21
|
+
from gobby.config.app import DaemonConfig
|
|
22
|
+
from gobby.config.llm_providers import LLMProvidersConfig
|
|
22
23
|
from gobby.workflows.definitions import WorkflowDefinition
|
|
23
24
|
|
|
24
25
|
logger = logging.getLogger(__name__)
|
|
@@ -479,7 +480,7 @@ def _create_codex_executor(
|
|
|
479
480
|
|
|
480
481
|
# Re-export for TYPE_CHECKING
|
|
481
482
|
if TYPE_CHECKING:
|
|
482
|
-
from gobby.config.
|
|
483
|
+
from gobby.config.llm_providers import LLMProviderConfig
|
|
483
484
|
|
|
484
485
|
|
|
485
486
|
class ExecutorRegistry:
|