shotgun-sh 0.1.0.dev12__py3-none-any.whl → 0.1.0.dev13__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.

Potentially problematic release.


This version of shotgun-sh might be problematic. Click here for more details.

Files changed (49) hide show
  1. shotgun/agents/common.py +94 -79
  2. shotgun/agents/config/constants.py +18 -0
  3. shotgun/agents/config/manager.py +68 -16
  4. shotgun/agents/config/provider.py +11 -6
  5. shotgun/agents/models.py +6 -0
  6. shotgun/agents/plan.py +15 -37
  7. shotgun/agents/research.py +10 -45
  8. shotgun/agents/specify.py +97 -0
  9. shotgun/agents/tasks.py +7 -36
  10. shotgun/agents/tools/artifact_management.py +450 -0
  11. shotgun/agents/tools/file_management.py +2 -2
  12. shotgun/artifacts/__init__.py +17 -0
  13. shotgun/artifacts/exceptions.py +89 -0
  14. shotgun/artifacts/manager.py +529 -0
  15. shotgun/artifacts/models.py +332 -0
  16. shotgun/artifacts/service.py +463 -0
  17. shotgun/artifacts/templates/__init__.py +10 -0
  18. shotgun/artifacts/templates/loader.py +252 -0
  19. shotgun/artifacts/templates/models.py +136 -0
  20. shotgun/artifacts/templates/plan/delivery_and_release_plan.yaml +66 -0
  21. shotgun/artifacts/templates/research/market_research.yaml +585 -0
  22. shotgun/artifacts/templates/research/sdk_comparison.yaml +257 -0
  23. shotgun/artifacts/templates/specify/prd.yaml +331 -0
  24. shotgun/artifacts/templates/specify/product_spec.yaml +301 -0
  25. shotgun/artifacts/utils.py +76 -0
  26. shotgun/cli/plan.py +1 -4
  27. shotgun/cli/specify.py +69 -0
  28. shotgun/cli/tasks.py +0 -4
  29. shotgun/logging_config.py +23 -7
  30. shotgun/main.py +7 -6
  31. shotgun/prompts/agents/partials/artifact_system.j2 +32 -0
  32. shotgun/prompts/agents/partials/common_agent_system_prompt.j2 +28 -2
  33. shotgun/prompts/agents/partials/content_formatting.j2 +65 -0
  34. shotgun/prompts/agents/partials/interactive_mode.j2 +10 -2
  35. shotgun/prompts/agents/plan.j2 +31 -32
  36. shotgun/prompts/agents/research.j2 +37 -29
  37. shotgun/prompts/agents/specify.j2 +31 -0
  38. shotgun/prompts/agents/tasks.j2 +27 -12
  39. shotgun/sdk/artifact_models.py +186 -0
  40. shotgun/sdk/artifacts.py +448 -0
  41. shotgun/tui/app.py +26 -7
  42. shotgun/tui/screens/chat.py +28 -3
  43. shotgun/tui/screens/directory_setup.py +113 -0
  44. {shotgun_sh-0.1.0.dev12.dist-info → shotgun_sh-0.1.0.dev13.dist-info}/METADATA +2 -2
  45. {shotgun_sh-0.1.0.dev12.dist-info → shotgun_sh-0.1.0.dev13.dist-info}/RECORD +48 -25
  46. shotgun/prompts/user/research.j2 +0 -5
  47. {shotgun_sh-0.1.0.dev12.dist-info → shotgun_sh-0.1.0.dev13.dist-info}/WHEEL +0 -0
  48. {shotgun_sh-0.1.0.dev12.dist-info → shotgun_sh-0.1.0.dev13.dist-info}/entry_points.txt +0 -0
  49. {shotgun_sh-0.1.0.dev12.dist-info → shotgun_sh-0.1.0.dev13.dist-info}/licenses/LICENSE +0 -0
@@ -1,9 +1,10 @@
1
1
  """Research agent factory and functions using Pydantic AI with file-based memory."""
2
2
 
3
+ from functools import partial
4
+
3
5
  from pydantic_ai import (
4
6
  Agent,
5
7
  DeferredToolRequests,
6
- RunContext,
7
8
  )
8
9
  from pydantic_ai.agent import AgentRunResult
9
10
  from pydantic_ai.messages import (
@@ -12,14 +13,12 @@ from pydantic_ai.messages import (
12
13
 
13
14
  from shotgun.agents.config import ProviderType
14
15
  from shotgun.logging_config import get_logger
15
- from shotgun.prompts import PromptLoader
16
16
 
17
17
  from .common import (
18
18
  add_system_status_message,
19
+ build_agent_system_prompt,
19
20
  create_base_agent,
20
21
  create_usage_limits,
21
- ensure_file_exists,
22
- get_file_history,
23
22
  run_agent,
24
23
  )
25
24
  from .models import AgentDeps, AgentRuntimeOptions
@@ -27,30 +26,11 @@ from .tools import get_available_web_search_tools
27
26
 
28
27
  logger = get_logger(__name__)
29
28
 
30
- # Global prompt loader instance
31
- prompt_loader = PromptLoader()
32
-
33
-
34
- def _build_research_agent_system_prompt(ctx: RunContext[AgentDeps]) -> str:
35
- """Build the system prompt for the research agent.
36
-
37
- Args:
38
- ctx: RunContext containing AgentDeps with interactive_mode and other settings
39
-
40
- Returns:
41
- The complete system prompt string for the research agent
42
- """
43
- return prompt_loader.render(
44
- "agents/research.j2",
45
- interactive_mode=ctx.deps.interactive_mode,
46
- context="research output",
47
- )
48
-
49
29
 
50
30
  def create_research_agent(
51
31
  agent_runtime_options: AgentRuntimeOptions, provider: ProviderType | None = None
52
32
  ) -> tuple[Agent[AgentDeps, str | DeferredToolRequests], AgentDeps]:
53
- """Create a research agent with web search capabilities.
33
+ """Create a research agent with web search and artifact management capabilities.
54
34
 
55
35
  Args:
56
36
  agent_runtime_options: Agent runtime options for the agent
@@ -71,8 +51,11 @@ def create_research_agent(
71
51
  else:
72
52
  logger.warning("Research agent configured without web search tools")
73
53
 
54
+ # Use partial to create system prompt function for research agent
55
+ system_prompt_fn = partial(build_agent_system_prompt, "research")
56
+
74
57
  agent, deps = create_base_agent(
75
- _build_research_agent_system_prompt,
58
+ system_prompt_fn,
76
59
  agent_runtime_options,
77
60
  load_codebase_understanding_tools=True,
78
61
  additional_tools=web_search_tools,
@@ -87,7 +70,7 @@ async def run_research_agent(
87
70
  deps: AgentDeps,
88
71
  message_history: list[ModelMessage] | None = None,
89
72
  ) -> AgentRunResult[str | DeferredToolRequests]:
90
- """Perform research on the given query and update the research file.
73
+ """Perform research on the given query and update research artifacts.
91
74
 
92
75
  Args:
93
76
  agent: The configured research agent
@@ -99,24 +82,15 @@ async def run_research_agent(
99
82
  """
100
83
  logger.debug("🔬 Starting research for query: %s", query)
101
84
 
102
- # Ensure research.md exists
103
- ensure_file_exists("research.md", "# Research")
104
-
105
85
  message_history = await add_system_status_message(deps, message_history)
106
86
 
107
- user_prompt = prompt_loader.render(
108
- "user/research.j2",
109
- user_query=query,
110
- context="research output",
111
- )
112
-
113
87
  try:
114
88
  # Create usage limits for responsible API usage
115
89
  usage_limits = create_usage_limits()
116
90
 
117
91
  result = await run_agent(
118
92
  agent=agent,
119
- prompt=user_prompt,
93
+ prompt=query,
120
94
  deps=deps,
121
95
  message_history=message_history,
122
96
  usage_limits=usage_limits,
@@ -131,12 +105,3 @@ async def run_research_agent(
131
105
  logger.error("Full traceback:\n%s", traceback.format_exc())
132
106
  logger.error("❌ Research failed: %s", str(e))
133
107
  raise
134
-
135
-
136
- def get_research_history() -> str:
137
- """Get the full research history from the file.
138
-
139
- Returns:
140
- Research history content or fallback message
141
- """
142
- return get_file_history("research.md")
@@ -0,0 +1,97 @@
1
+ """Specify agent factory and functions using Pydantic AI with file-based memory."""
2
+
3
+ from functools import partial
4
+
5
+ from pydantic_ai import (
6
+ Agent,
7
+ DeferredToolRequests,
8
+ )
9
+ from pydantic_ai.agent import AgentRunResult
10
+ from pydantic_ai.messages import ModelMessage
11
+
12
+ from shotgun.agents.config import ProviderType
13
+ from shotgun.logging_config import get_logger
14
+
15
+ from .common import (
16
+ add_system_status_message,
17
+ build_agent_system_prompt,
18
+ create_base_agent,
19
+ create_usage_limits,
20
+ run_agent,
21
+ )
22
+ from .models import AgentDeps, AgentRuntimeOptions
23
+
24
+ logger = get_logger(__name__)
25
+
26
+
27
+ def create_specify_agent(
28
+ agent_runtime_options: AgentRuntimeOptions, provider: ProviderType | None = None
29
+ ) -> tuple[Agent[AgentDeps, str | DeferredToolRequests], AgentDeps]:
30
+ """Create a specify agent with artifact management capabilities.
31
+
32
+ Args:
33
+ agent_runtime_options: Agent runtime options for the agent
34
+ provider: Optional provider override. If None, uses configured default
35
+
36
+ Returns:
37
+ Tuple of (Configured Pydantic AI agent for specification tasks, Agent dependencies)
38
+ """
39
+ logger.debug("Initializing specify agent")
40
+ # Use partial to create system prompt function for specify agent
41
+ system_prompt_fn = partial(build_agent_system_prompt, "specify")
42
+
43
+ agent, deps = create_base_agent(
44
+ system_prompt_fn,
45
+ agent_runtime_options,
46
+ load_codebase_understanding_tools=True,
47
+ additional_tools=None,
48
+ provider=provider,
49
+ )
50
+ return agent, deps
51
+
52
+
53
+ async def run_specify_agent(
54
+ agent: Agent[AgentDeps, str | DeferredToolRequests],
55
+ requirement: str,
56
+ deps: AgentDeps,
57
+ message_history: list[ModelMessage] | None = None,
58
+ ) -> AgentRunResult[str | DeferredToolRequests]:
59
+ """Create or update specifications based on the given requirement.
60
+
61
+ Args:
62
+ agent: The configured specify agent
63
+ requirement: The specification requirement or instruction
64
+ deps: Agent dependencies
65
+ message_history: Optional message history for conversation continuity
66
+
67
+ Returns:
68
+ AgentRunResult containing the specification process output
69
+ """
70
+ logger.debug("📋 Starting specification for requirement: %s", requirement)
71
+
72
+ # Simple prompt - the agent system prompt has all the artifact instructions
73
+ full_prompt = f"Create a comprehensive specification for: {requirement}"
74
+
75
+ try:
76
+ # Create usage limits for responsible API usage
77
+ usage_limits = create_usage_limits()
78
+
79
+ message_history = await add_system_status_message(deps, message_history)
80
+
81
+ result = await run_agent(
82
+ agent=agent,
83
+ prompt=full_prompt,
84
+ deps=deps,
85
+ message_history=message_history,
86
+ usage_limits=usage_limits,
87
+ )
88
+
89
+ logger.debug("✅ Specification completed successfully")
90
+ return result
91
+
92
+ except Exception as e:
93
+ import traceback
94
+
95
+ logger.error("Full traceback:\n%s", traceback.format_exc())
96
+ logger.error("❌ Specification failed: %s", str(e))
97
+ raise
shotgun/agents/tasks.py CHANGED
@@ -1,48 +1,28 @@
1
1
  """Tasks agent factory and functions using Pydantic AI with file-based memory."""
2
2
 
3
+ from functools import partial
4
+
3
5
  from pydantic_ai import (
4
6
  Agent,
5
7
  DeferredToolRequests,
6
- RunContext,
7
8
  )
8
9
  from pydantic_ai.agent import AgentRunResult
9
10
  from pydantic_ai.messages import ModelMessage
10
11
 
11
12
  from shotgun.agents.config import ProviderType
12
13
  from shotgun.logging_config import get_logger
13
- from shotgun.prompts import PromptLoader
14
14
 
15
15
  from .common import (
16
16
  add_system_status_message,
17
+ build_agent_system_prompt,
17
18
  create_base_agent,
18
19
  create_usage_limits,
19
- ensure_file_exists,
20
- get_file_history,
21
20
  run_agent,
22
21
  )
23
22
  from .models import AgentDeps, AgentRuntimeOptions
24
23
 
25
24
  logger = get_logger(__name__)
26
25
 
27
- # Global prompt loader instance
28
- prompt_loader = PromptLoader()
29
-
30
-
31
- def _build_tasks_agent_system_prompt(ctx: RunContext[AgentDeps]) -> str:
32
- """Build the system prompt for the tasks agent.
33
-
34
- Args:
35
- ctx: RunContext containing AgentDeps with interactive_mode and other settings
36
-
37
- Returns:
38
- The complete system prompt string for the tasks agent
39
- """
40
- return prompt_loader.render(
41
- "agents/tasks.j2",
42
- interactive_mode=ctx.deps.interactive_mode,
43
- context="task lists",
44
- )
45
-
46
26
 
47
27
  def create_tasks_agent(
48
28
  agent_runtime_options: AgentRuntimeOptions, provider: ProviderType | None = None
@@ -57,8 +37,11 @@ def create_tasks_agent(
57
37
  Tuple of (Configured Pydantic AI agent for task management, Agent dependencies)
58
38
  """
59
39
  logger.debug("Initializing tasks agent")
40
+ # Use partial to create system prompt function for tasks agent
41
+ system_prompt_fn = partial(build_agent_system_prompt, "tasks")
42
+
60
43
  agent, deps = create_base_agent(
61
- _build_tasks_agent_system_prompt, agent_runtime_options, provider=provider
44
+ system_prompt_fn, agent_runtime_options, provider=provider
62
45
  )
63
46
  return agent, deps
64
47
 
@@ -82,9 +65,6 @@ async def run_tasks_agent(
82
65
  """
83
66
  logger.debug("📋 Starting task creation for instruction: %s", instruction)
84
67
 
85
- # Ensure tasks.md exists
86
- ensure_file_exists("tasks.md", "# Tasks")
87
-
88
68
  message_history = await add_system_status_message(deps, message_history)
89
69
 
90
70
  # Let the agent use its tools to read existing tasks, plan, and research
@@ -111,12 +91,3 @@ async def run_tasks_agent(
111
91
  logger.error("Full traceback:\n%s", traceback.format_exc())
112
92
  logger.error("❌ Task creation failed: %s", str(e))
113
93
  raise
114
-
115
-
116
- def get_tasks_history() -> str:
117
- """Get the full tasks history from the file.
118
-
119
- Returns:
120
- Tasks history content or fallback message
121
- """
122
- return get_file_history("tasks.md")