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

@@ -34,6 +34,7 @@ from textual.widget import Widget
34
34
 
35
35
  from shotgun.agents.common import add_system_prompt_message
36
36
 
37
+ from .export import create_export_agent
37
38
  from .history.compaction import apply_persistent_compaction
38
39
  from .models import AgentDeps, AgentRuntimeOptions, FileOperation
39
40
  from .plan import create_plan_agent
@@ -51,6 +52,7 @@ class AgentType(Enum):
51
52
  PLAN = "plan"
52
53
  TASKS = "tasks"
53
54
  SPECIFY = "specify"
55
+ EXPORT = "export"
54
56
 
55
57
 
56
58
  class MessageHistoryUpdated(Message):
@@ -138,6 +140,9 @@ class AgentManager(Widget):
138
140
  self.specify_agent, self.specify_deps = create_specify_agent(
139
141
  agent_runtime_options=agent_runtime_options
140
142
  )
143
+ self.export_agent, self.export_deps = create_export_agent(
144
+ agent_runtime_options=agent_runtime_options
145
+ )
141
146
 
142
147
  # Track current active agent
143
148
  self._current_agent_type: AgentType = initial_type
@@ -173,6 +178,7 @@ class AgentManager(Widget):
173
178
  AgentType.PLAN: self.plan_agent,
174
179
  AgentType.TASKS: self.tasks_agent,
175
180
  AgentType.SPECIFY: self.specify_agent,
181
+ AgentType.EXPORT: self.export_agent,
176
182
  }
177
183
  return agent_map[agent_type]
178
184
 
@@ -190,6 +196,7 @@ class AgentManager(Widget):
190
196
  AgentType.PLAN: self.plan_deps,
191
197
  AgentType.TASKS: self.tasks_deps,
192
198
  AgentType.SPECIFY: self.specify_deps,
199
+ AgentType.EXPORT: self.export_deps,
193
200
  }
194
201
  return deps_map[agent_type]
195
202
 
shotgun/agents/common.py CHANGED
@@ -160,6 +160,7 @@ def create_base_agent(
160
160
  deps_type=AgentDeps,
161
161
  instrument=True,
162
162
  history_processors=[history_processor],
163
+ retries=3, # Default retry count for tool calls and output validation
163
164
  )
164
165
 
165
166
  # System prompt function is stored in deps and will be called manually in run_agent
@@ -176,9 +177,9 @@ def create_base_agent(
176
177
  logger.debug("📞 Interactive mode enabled - ask_user tool registered")
177
178
 
178
179
  # Register common file management tools (always available)
179
- agent.tool(read_file)
180
180
  agent.tool(write_file)
181
181
  agent.tool(append_file)
182
+ agent.tool(read_file)
182
183
 
183
184
  # Register artifact management tools (always available)
184
185
  agent.tool(create_artifact)
@@ -102,7 +102,7 @@ MODEL_SPECS: dict[str, ModelSpec] = {
102
102
  name="claude-3-5-sonnet-latest",
103
103
  provider=ProviderType.ANTHROPIC,
104
104
  max_input_tokens=200_000,
105
- max_output_tokens=20_000,
105
+ max_output_tokens=8_192,
106
106
  ),
107
107
  "gemini-2.5-pro": ModelSpec(
108
108
  name="gemini-2.5-pro",
@@ -4,12 +4,13 @@ import os
4
4
 
5
5
  from pydantic import SecretStr
6
6
  from pydantic_ai.models import Model
7
- from pydantic_ai.models.anthropic import AnthropicModel
7
+ from pydantic_ai.models.anthropic import AnthropicModel, AnthropicModelSettings
8
8
  from pydantic_ai.models.google import GoogleModel
9
9
  from pydantic_ai.models.openai import OpenAIChatModel
10
10
  from pydantic_ai.providers.anthropic import AnthropicProvider
11
11
  from pydantic_ai.providers.google import GoogleProvider
12
12
  from pydantic_ai.providers.openai import OpenAIProvider
13
+ from pydantic_ai.settings import ModelSettings
13
14
 
14
15
  from shotgun.logging_config import get_logger
15
16
 
@@ -47,18 +48,47 @@ def get_or_create_model(provider: ProviderType, model_name: str, api_key: str) -
47
48
  logger.debug("Creating new %s model instance: %s", provider.value, model_name)
48
49
 
49
50
  if provider == ProviderType.OPENAI:
51
+ # Get max_tokens from MODEL_SPECS to use full capacity
52
+ if model_name in MODEL_SPECS:
53
+ max_tokens = MODEL_SPECS[model_name].max_output_tokens
54
+ else:
55
+ max_tokens = 16_000 # Default for GPT models
56
+
50
57
  openai_provider = OpenAIProvider(api_key=api_key)
51
58
  _model_cache[cache_key] = OpenAIChatModel(
52
- model_name, provider=openai_provider
59
+ model_name,
60
+ provider=openai_provider,
61
+ settings=ModelSettings(max_tokens=max_tokens),
53
62
  )
54
63
  elif provider == ProviderType.ANTHROPIC:
64
+ # Get max_tokens from MODEL_SPECS to use full capacity
65
+ if model_name in MODEL_SPECS:
66
+ max_tokens = MODEL_SPECS[model_name].max_output_tokens
67
+ else:
68
+ max_tokens = 32_000 # Default for Claude models
69
+
55
70
  anthropic_provider = AnthropicProvider(api_key=api_key)
56
71
  _model_cache[cache_key] = AnthropicModel(
57
- model_name, provider=anthropic_provider
72
+ model_name,
73
+ provider=anthropic_provider,
74
+ settings=AnthropicModelSettings(
75
+ max_tokens=max_tokens,
76
+ timeout=600, # 10 minutes timeout for large responses
77
+ ),
58
78
  )
59
79
  elif provider == ProviderType.GOOGLE:
80
+ # Get max_tokens from MODEL_SPECS to use full capacity
81
+ if model_name in MODEL_SPECS:
82
+ max_tokens = MODEL_SPECS[model_name].max_output_tokens
83
+ else:
84
+ max_tokens = 64_000 # Default for Gemini models
85
+
60
86
  google_provider = GoogleProvider(api_key=api_key)
61
- _model_cache[cache_key] = GoogleModel(model_name, provider=google_provider)
87
+ _model_cache[cache_key] = GoogleModel(
88
+ model_name,
89
+ provider=google_provider,
90
+ settings=ModelSettings(max_tokens=max_tokens),
91
+ )
62
92
  else:
63
93
  raise ValueError(f"Unsupported provider: {provider}")
64
94
  else:
@@ -0,0 +1,93 @@
1
+ """Export 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_export_agent(
28
+ agent_runtime_options: AgentRuntimeOptions, provider: ProviderType | None = None
29
+ ) -> tuple[Agent[AgentDeps, str | DeferredToolRequests], AgentDeps]:
30
+ """Create an export agent with file 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 export management, Agent dependencies)
38
+ """
39
+ logger.debug("Initializing export agent")
40
+ # Use partial to create system prompt function for export agent
41
+ system_prompt_fn = partial(build_agent_system_prompt, "export")
42
+
43
+ agent, deps = create_base_agent(
44
+ system_prompt_fn, agent_runtime_options, provider=provider
45
+ )
46
+ return agent, deps
47
+
48
+
49
+ async def run_export_agent(
50
+ agent: Agent[AgentDeps, str | DeferredToolRequests],
51
+ instruction: str,
52
+ deps: AgentDeps,
53
+ message_history: list[ModelMessage] | None = None,
54
+ ) -> AgentRunResult[str | DeferredToolRequests]:
55
+ """Export artifacts based on the given instruction.
56
+
57
+ Args:
58
+ agent: The configured export agent
59
+ instruction: The export instruction
60
+ deps: Agent dependencies
61
+ message_history: Optional message history for conversation continuity
62
+
63
+ Returns:
64
+ AgentRunResult containing the export process output
65
+ """
66
+ logger.debug("📤 Starting export for instruction: %s", instruction)
67
+
68
+ message_history = await add_system_status_message(deps, message_history)
69
+
70
+ # Let the agent use its tools to read existing artifacts and export them
71
+ full_prompt = f"Export artifacts or findings based on: {instruction}"
72
+
73
+ try:
74
+ # Create usage limits for responsible API usage
75
+ usage_limits = create_usage_limits()
76
+
77
+ result = await run_agent(
78
+ agent=agent,
79
+ prompt=full_prompt,
80
+ deps=deps,
81
+ message_history=message_history,
82
+ usage_limits=usage_limits,
83
+ )
84
+
85
+ logger.debug("✅ Export completed successfully")
86
+ return result
87
+
88
+ except Exception as e:
89
+ import traceback
90
+
91
+ logger.error("Full traceback:\n%s", traceback.format_exc())
92
+ logger.error("❌ Export failed: %s", str(e))
93
+ raise
shotgun/cli/export.py ADDED
@@ -0,0 +1,81 @@
1
+ """Export command for shotgun CLI."""
2
+
3
+ import asyncio
4
+ from typing import Annotated
5
+
6
+ import typer
7
+
8
+ from shotgun.agents.config import ProviderType
9
+ from shotgun.agents.export import (
10
+ create_export_agent,
11
+ run_export_agent,
12
+ )
13
+ from shotgun.agents.models import AgentRuntimeOptions
14
+ from shotgun.logging_config import get_logger
15
+
16
+ app = typer.Typer(
17
+ name="export", help="Export artifacts to various formats with agentic approach"
18
+ )
19
+ logger = get_logger(__name__)
20
+
21
+
22
+ @app.callback(invoke_without_command=True)
23
+ def export(
24
+ instruction: Annotated[
25
+ str, typer.Argument(help="Export instruction or format specification")
26
+ ],
27
+ non_interactive: Annotated[
28
+ bool,
29
+ typer.Option(
30
+ "--non-interactive", "-n", help="Disable user interaction (for CI/CD)"
31
+ ),
32
+ ] = False,
33
+ provider: Annotated[
34
+ ProviderType | None,
35
+ typer.Option("--provider", "-p", help="AI provider to use (overrides default)"),
36
+ ] = None,
37
+ ) -> None:
38
+ """Export artifacts and findings to various formats.
39
+
40
+ This command exports research, plans, tasks, and other project artifacts
41
+ to different formats like Markdown, HTML, JSON, CSV, or project management
42
+ tool formats. The AI agent will analyze available content and transform
43
+ it according to your export requirements.
44
+ """
45
+
46
+ logger.info("📤 Export Instruction: %s", instruction)
47
+
48
+ try:
49
+ # Track export command usage
50
+ from shotgun.posthog_telemetry import track_event
51
+
52
+ track_event(
53
+ "export_command",
54
+ {
55
+ "non_interactive": non_interactive,
56
+ "provider": provider.value if provider else "default",
57
+ },
58
+ )
59
+
60
+ # Create agent dependencies
61
+ agent_runtime_options = AgentRuntimeOptions(
62
+ interactive_mode=not non_interactive
63
+ )
64
+
65
+ # Create the export agent with deps and provider
66
+ agent, deps = create_export_agent(agent_runtime_options, provider)
67
+
68
+ # Start export process
69
+ logger.info("🎯 Starting export...")
70
+ result = asyncio.run(run_export_agent(agent, instruction, deps))
71
+
72
+ # Display results
73
+ logger.info("✅ Export Complete!")
74
+ logger.info("📤 Results:")
75
+ logger.info("%s", result.output)
76
+
77
+ except Exception as e:
78
+ logger.error("❌ Error during export: %s", str(e))
79
+ import traceback
80
+
81
+ logger.debug("Full traceback:\n%s", traceback.format_exc())
shotgun/main.py CHANGED
@@ -7,7 +7,7 @@ from dotenv import load_dotenv
7
7
 
8
8
  from shotgun import __version__
9
9
  from shotgun.agents.config import get_config_manager
10
- from shotgun.cli import codebase, config, plan, research, specify, tasks, update
10
+ from shotgun.cli import codebase, config, export, plan, research, specify, tasks, update
11
11
  from shotgun.logging_config import configure_root_logger, get_logger
12
12
  from shotgun.posthog_telemetry import setup_posthog_observability
13
13
  from shotgun.sentry_telemetry import setup_sentry_observability
@@ -66,6 +66,7 @@ app.add_typer(research.app, name="research", help="Perform research with agentic
66
66
  app.add_typer(plan.app, name="plan", help="Generate structured plans")
67
67
  app.add_typer(specify.app, name="specify", help="Generate comprehensive specifications")
68
68
  app.add_typer(tasks.app, name="tasks", help="Generate task lists with agentic approach")
69
+ app.add_typer(export.app, name="export", help="Export artifacts to various formats")
69
70
  app.add_typer(update.app, name="update", help="Check for and install updates")
70
71
 
71
72
 
@@ -0,0 +1,83 @@
1
+ You are an experienced Export Specialist and Data Transformation Expert.
2
+
3
+ Your job is to help export artifacts, research findings, plans, and other project data to various formats and destinations.
4
+
5
+ {% include 'agents/partials/common_agent_system_prompt.j2' %}
6
+
7
+ ## EXPORT WORKFLOW
8
+
9
+ For export tasks:
10
+ 1. **Check existing artifacts**: See the "## Existing Artifacts" section to see what content is available to export.
11
+ 2. **Understand the export requirements**: Understand what the user wants to export, assuming that's everything - but always confirm. For example some research might not be relevant for export. Priority: Tasks, Plan, Specify, Research.
12
+ 3. **Analyze export requirements**: Understand the requested format, destination, and scope
13
+ 4. **Read source content**: Read the content of all the relevant artifacts.
14
+ 5. **Transform and format**: Convert content to the requested format
15
+ 5. **Create export artifacts**: Use write_file with BOTH "filename" AND "content" parameters:
16
+ 6. **Validate output**: Ensure the export meets requirements and is properly formatted using read_file()
17
+
18
+ ## SUPPORTED EXPORT FORMATS
19
+
20
+ - **AGENTS.md**: See below
21
+ - **Markdown (.md)**: Nicely formatted Markdown file with everything the user wants to export
22
+
23
+ ### AGENTS.md
24
+
25
+ Your task: generate an **AGENTS.md** file (in Markdown) for a project based on the provided documentation, specification files, and any context I supply.
26
+
27
+ **Instructions / constraints**:
28
+ - Use clear headings (e.g. “Architecture & Structure”, “Setup / Prerequisites”, “Build & Test”, “Coding Conventions”, etc.).
29
+ - For sections with commands, wrap them in backticks so they can be executed directly.
30
+ - Provide enough detail so that an AI coding agent can understand how to build, test, validate, deploy, and work with the project, without needing to hunt in scattered docs.
31
+ - Link or refer to deeper docs (README, design docs) rather than duplicating large content.
32
+ - If the project is a monorepo or modular, mention whether nested AGENTS.md may override parts.
33
+ - Do **not** include large prose — focus on actionable instructions and bullet lists.
34
+ - Assume the agent must obey programmatic checks listed in the file after generating code.
35
+
36
+
37
+ ## EXPORT PRINCIPLES
38
+
39
+ - Preserve content structure and meaning during transformation
40
+ - Include proper headers, metadata, and formatting for target format
41
+ - Maintain links, references, and cross-references where applicable
42
+ - Create self-contained exports that can be used independently
43
+ - Add appropriate file extensions and format indicators
44
+ - Include export timestamp and source information
45
+ - Validate exported content is properly formatted and complete
46
+ - Handle missing or incomplete source data gracefully
47
+ - Consider target audience and use case for formatting decisions
48
+
49
+ {% if interactive_mode %}
50
+ USER INTERACTION - CLARIFY EXPORT REQUIREMENTS:
51
+
52
+ - ALWAYS ask clarifying questions when export requirements are unclear
53
+ - Use ask_user tool to gather specific details about:
54
+ - Target format and file type preferences
55
+ - Intended use case and audience for the export
56
+ - Specific content sections or artifacts to include/exclude
57
+ - Output structure and organization preferences
58
+ - Destination (where to save the file)
59
+ - Ask follow-up questions to ensure exports meet exact needs
60
+ - Confirm export scope and format before proceeding with large exports
61
+ - Better to ask 2-3 targeted questions than create generic exports
62
+ {% else %}
63
+ NON-INTERACTIVE MODE - MAKE REASONABLE EXPORT DECISIONS:
64
+
65
+ - Make reasonable assumptions about format based on content type
66
+ - Use standard formats and conventions for the target format
67
+ - Include comprehensive content unless scope is clearly limited
68
+ - Apply sensible default formatting and structure
69
+ - Export to commonly used and widely compatible formats
70
+ - Include standard metadata and documentation
71
+ {% endif %}
72
+
73
+ IMPORTANT RULES:
74
+ - Always verify source content exists before attempting export
75
+ - Preserve all critical information during format conversion
76
+ - Include source attribution and export metadata
77
+ - Create well-structured, properly formatted output
78
+ {% if interactive_mode %}
79
+ - When export requirements are ambiguous, ASK before proceeding
80
+ {% else %}
81
+ - When requirements are unclear, use industry standard practices
82
+ {% endif %}
83
+ - Ensure exported content is self-contained and usable
@@ -7,16 +7,20 @@ Your extensive expertise spans, among other things:
7
7
 
8
8
  ## KEY RULES
9
9
 
10
- 0. Above all, prefer using tools to do the work and NEVER respond with text.
11
- 1. **Be Detailed**: Write meticulously detailed documents in artifacts, but when communicating with the users, please respond with a paragraph at most.
12
- 2. **Be Helpful**: Always prioritize user needs and provide actionable assistance
13
- 3. **Be Precise**: Provide specific, detailed responses rather than vague generalities
14
- 4. **Be Collaborative**: Work effectively with other agents when needed
15
- 5. **Be Transparent**: Let the user know what you're going to do before getting to work.
16
- 6. **Be Efficient**: Avoid redundant work - check existing artifacts and agent outputs
17
- 7. **Be Creative**: If the user seems not to know something, always be creative and come up with ideas that fit their thinking.
18
- 8. Greet the user when you're just starting to work.
19
- 9. DO NOT repeat yourself.
10
+ {% if interactive_mode %}
11
+ 0. Always ask for the review and go ahead to move forward after using write_artifact_section().
12
+ {% endif %}
13
+ 1. Above all, prefer using tools to do the work and NEVER respond with text.
14
+ 2. IMPORTANT: Always ask for the review and go ahead to move forward after using write_artifact_section().
15
+ 3. **Be Detailed**: Write meticulously detailed documents in artifacts, but when communicating with the users, please respond with a paragraph at most.
16
+ 4. **Be Helpful**: Always prioritize user needs and provide actionable assistance
17
+ 5. **Be Precise**: Provide specific, detailed responses rather than vague generalities
18
+ 6. **Be Collaborative**: Work effectively with other agents when needed
19
+ 7. **Be Transparent**: Let the user know what you're going to do before getting to work.
20
+ 8. **Be Efficient**: Avoid redundant work - check existing artifacts and agent outputs
21
+ 9. **Be Creative**: If the user seems not to know something, always be creative and come up with ideas that fit their thinking.
22
+ 10. Greet the user when you're just starting to work.
23
+ 11. DO NOT repeat yourself.
20
24
 
21
25
 
22
26
  ## Quality Standards
@@ -8,6 +8,7 @@ IMPORTANT: USER INTERACTION IS ENABLED (interactive mode).
8
8
 
9
9
  - BEFORE GETTING TO WORK, ALWAYS THINK WHAT YOU'RE GOING TO DO AND ask_user() TO ACCEPT WHAT YOU'RE GOING TO DO.
10
10
  - ALWAYS USE ask_user TO REVIEW AND ACCEPT THE ARTIFACT SECTION YOU'VE WORKED ON BEFORE PROCEEDING TO THE NEXT SECTION.
11
+ - AFTER USING write_artifact_section(), ALWAYS USE ask_user() TO REVIEW AND ACCEPT THE ARTIFACT SECTION YOU'VE WORKED ON BEFORE PROCEEDING TO THE NEXT SECTION.
11
12
  - Don't assume - ask for confirmation of your understanding
12
13
  - When in doubt about any aspect of the goal, ASK before proceeding
13
14
 
@@ -62,8 +62,10 @@ class CommandHandler:
62
62
 
63
63
  **Agent Modes:**
64
64
  • **Research** - Research topics with web search and synthesize findings
65
+ • **Specify** - Create detailed specifications and requirements documents
65
66
  • **Planning** - Create comprehensive, actionable plans with milestones
66
67
  • **Tasks** - Generate specific, actionable tasks from research and plans
68
+ • **Export** - Export artifacts and findings to various formats
67
69
 
68
70
  **Usage:**
69
71
  Type your message and press Enter to chat with the AI. The AI will respond based on the current mode."""
@@ -124,12 +124,14 @@ class ModeIndicator(Widget):
124
124
  AgentType.PLAN: "Planning",
125
125
  AgentType.TASKS: "Tasks",
126
126
  AgentType.SPECIFY: "Specify",
127
+ AgentType.EXPORT: "Export",
127
128
  }
128
129
  mode_description = {
129
130
  AgentType.RESEARCH: "Research topics with web search and synthesize findings",
130
131
  AgentType.PLAN: "Create comprehensive, actionable plans with milestones",
131
132
  AgentType.TASKS: "Generate specific, actionable tasks from research and plans",
132
133
  AgentType.SPECIFY: "Create detailed specifications and requirements documents",
134
+ AgentType.EXPORT: "Export artifacts and findings to various formats",
133
135
  }
134
136
 
135
137
  mode_title = mode_display.get(self.mode, self.mode.value.title())
@@ -317,6 +319,9 @@ class ChatScreen(Screen[None]):
317
319
  AgentType.SPECIFY: (
318
320
  "Request detailed specifications, e.g. create a comprehensive spec for user authentication system"
319
321
  ),
322
+ AgentType.EXPORT: (
323
+ "Request export tasks, e.g. export research findings to Markdown or convert tasks to CSV"
324
+ ),
320
325
  }
321
326
 
322
327
  value = reactive("")
@@ -430,7 +435,13 @@ class ChatScreen(Screen[None]):
430
435
  question_display.display = False
431
436
 
432
437
  def action_toggle_mode(self) -> None:
433
- modes = [AgentType.RESEARCH, AgentType.SPECIFY, AgentType.PLAN, AgentType.TASKS]
438
+ modes = [
439
+ AgentType.RESEARCH,
440
+ AgentType.SPECIFY,
441
+ AgentType.PLAN,
442
+ AgentType.TASKS,
443
+ AgentType.EXPORT,
444
+ ]
434
445
  self.mode = modes[(modes.index(self.mode) + 1) % len(modes)]
435
446
  self.agent_manager.set_agent(self.mode)
436
447
  # whoops it actually changes focus. Let's be brutal for now
@@ -30,6 +30,11 @@ class AgentModeProvider(Provider):
30
30
  lambda: self.set_mode(AgentType.RESEARCH),
31
31
  help="🔬 Research topics with web search and synthesize findings",
32
32
  )
33
+ yield DiscoveryHit(
34
+ "Switch to Specify Mode",
35
+ lambda: self.set_mode(AgentType.SPECIFY),
36
+ help="📝 Create detailed specifications and requirements documents",
37
+ )
33
38
  yield DiscoveryHit(
34
39
  "Switch to Plan Mode",
35
40
  lambda: self.set_mode(AgentType.PLAN),
@@ -40,6 +45,11 @@ class AgentModeProvider(Provider):
40
45
  lambda: self.set_mode(AgentType.TASKS),
41
46
  help="✅ Generate specific, actionable tasks from research and plans",
42
47
  )
48
+ yield DiscoveryHit(
49
+ "Switch to Export Mode",
50
+ lambda: self.set_mode(AgentType.EXPORT),
51
+ help="📤 Export artifacts and findings to various formats",
52
+ )
43
53
 
44
54
  async def search(self, query: str) -> AsyncGenerator[Hit, None]:
45
55
  """Search for mode commands."""
@@ -70,6 +80,12 @@ class AgentModeProvider(Provider):
70
80
  lambda: self.set_mode(AgentType.TASKS),
71
81
  AgentType.TASKS,
72
82
  ),
83
+ (
84
+ "Switch to Export Mode",
85
+ "📤 Export artifacts and findings to various formats",
86
+ lambda: self.set_mode(AgentType.EXPORT),
87
+ AgentType.EXPORT,
88
+ ),
73
89
  ]
74
90
 
75
91
  for title, help_text, callback, mode in commands:
@@ -204,7 +204,6 @@ class AgentResponseWidget(Widget):
204
204
  self,
205
205
  part: ToolCallPart,
206
206
  ) -> str:
207
- return "*Answer to continue*"
208
207
  if isinstance(part.args, str):
209
208
  try:
210
209
  _args = json.loads(part.args) if part.args.strip() else {}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shotgun-sh
3
- Version: 0.1.0.dev18
3
+ Version: 0.1.0.dev20
4
4
  Summary: AI-powered research, planning, and task management CLI tool
5
5
  Project-URL: Homepage, https://shotgun.sh/
6
6
  Project-URL: Repository, https://github.com/shotgun-sh/shotgun
@@ -1,15 +1,16 @@
1
1
  shotgun/__init__.py,sha256=P40K0fnIsb7SKcQrFnXZ4aREjpWchVDhvM1HxI4cyIQ,104
2
2
  shotgun/build_constants.py,sha256=RXNxMz46HaB5jucgMVpw8a2yCJqjbhTOh0PddyEVMN8,713
3
3
  shotgun/logging_config.py,sha256=qWPTKu6IhaA_qiHQFhx8zTphm6oHMZFXox2nieyV32M,6795
4
- shotgun/main.py,sha256=gDH81bxf9gG8Qoq-zs9cMorCzLCyDJpFg2cmUnGMoiI,4790
4
+ shotgun/main.py,sha256=pVyyDjIK0P_s-ptqp_GOjLbj1IhG6UXhny5kfKl2s-U,4883
5
5
  shotgun/posthog_telemetry.py,sha256=7drAXtedvZmpPqq4_9dI19kJ_xEHGk7XKXQk797QvCM,4954
6
6
  shotgun/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  shotgun/sentry_telemetry.py,sha256=3r9on0GQposn9aX6Dkb9mrfaVQl_dIZzhu9BjE838AU,2854
8
8
  shotgun/telemetry.py,sha256=aBwCRFU97oiIK5K13OhT7yYCQUAVQyrvnoG-aX3k2ZE,3109
9
9
  shotgun/agents/__init__.py,sha256=8Jzv1YsDuLyNPFJyckSr_qI4ehTVeDyIMDW4omsfPGc,25
10
- shotgun/agents/agent_manager.py,sha256=N9BUoGCydfiHVxLImG4JraSO4niQJqJPcj82M0ATT6g,16828
10
+ shotgun/agents/agent_manager.py,sha256=JviJvtbfDb4KLg4jT9dcMahUsCnZeNIlo0dk-s3_xPM,17120
11
11
  shotgun/agents/artifact_state.py,sha256=WkspYQe-9CvBS90PapBsX997yvJ5KWH-qtSXIWmfvp0,2121
12
- shotgun/agents/common.py,sha256=my-Y7VNNpDDYxDJ4hlRmTs7lIS8tBKFvR9ew7uKxcPE,11369
12
+ shotgun/agents/common.py,sha256=7IRpfxgSJLcib6KgzWpbxKS5Mh2VOAVKUl66U1c5B-I,11448
13
+ shotgun/agents/export.py,sha256=wGsGoucbonzPu9DExFrxDY02jr5niTy1xEJrhdCM43M,2904
13
14
  shotgun/agents/models.py,sha256=6edILmN7caDAmf8x-qgl7lA42tl2b-ZsiC3da8tS3Xw,7127
14
15
  shotgun/agents/plan.py,sha256=mn0S4r-uXWjerMTzfJLJo7n0pweNp_v8TI53wOxMdZ4,2984
15
16
  shotgun/agents/research.py,sha256=tee5gHT0d1Iupr5MI9ogNTh35xqh0j2N71rmb4dUtG0,3224
@@ -18,8 +19,8 @@ shotgun/agents/tasks.py,sha256=ChPet4pw1cIJUWqBM05CKIKzEXOFAlAov9QqQOcPK-w,2935
18
19
  shotgun/agents/config/__init__.py,sha256=Fl8K_81zBpm-OfOW27M_WWLSFdaHHek6lWz95iDREjQ,318
19
20
  shotgun/agents/config/constants.py,sha256=c1k7LFvx29rzQCUXxyfr2PukwS5ol8rH8AXQaxALPVM,526
20
21
  shotgun/agents/config/manager.py,sha256=kwMbPjz0kEH_WCQAamESGjHdE8d_P-ztel4NL4FWNUw,10662
21
- shotgun/agents/config/models.py,sha256=CSA7bt22fYB1OJ17hngcoL2XyKD2QmZrRBtAc7fPoFE,6019
22
- shotgun/agents/config/provider.py,sha256=qvgHKpKrI2pC9Qb9ahojgaNAD1DqM6vPg9o6NPaX0-0,5949
22
+ shotgun/agents/config/models.py,sha256=bX4zVTY5n7qQRlEOcA0SFmyPef9MvxcFW9hKLf_thLs,6018
23
+ shotgun/agents/config/provider.py,sha256=ScT1NfmaXJdewP1UAAD51MLR00YbmPAM53oeMfrVzq8,7202
23
24
  shotgun/agents/history/__init__.py,sha256=XFQj2a6fxDqVg0Q3juvN9RjV_RJbgvFZtQOCOjVJyp4,147
24
25
  shotgun/agents/history/compaction.py,sha256=KY_ZvRvvlrB6eLPGqtlC6H8h4HPPOtuPcUkgQJUjK5I,2890
25
26
  shotgun/agents/history/constants.py,sha256=yWY8rrTZarLA3flCCMB_hS2NMvUDRDTwP4D4j7MIh1w,446
@@ -61,6 +62,7 @@ shotgun/artifacts/templates/specify/prd.yaml,sha256=LTtTOERjYe1iGV7Wj-WJEExcbHp-
61
62
  shotgun/artifacts/templates/specify/product_spec.yaml,sha256=BAubivc75VnNZVRqGK9kX1TxZDn-e2_eYbuZGaKvk2U,13953
62
63
  shotgun/cli/__init__.py,sha256=_F1uW2g87y4bGFxz8Gp8u7mq2voHp8vQIUtCmm8Tojo,40
63
64
  shotgun/cli/config.py,sha256=LbjxDNPdetYJiwlcyOYLnqwzALfgU-m54cfstUshbrs,8715
65
+ shotgun/cli/export.py,sha256=3hIwK2_OM1MFYSTfzBxsGuuBGm5fo0XdxASfQ5Uqb3Y,2471
64
66
  shotgun/cli/models.py,sha256=LoajeEK7MEDUSnZXb1Li-dbhXqne812YZglx-LcVpiQ,181
65
67
  shotgun/cli/plan.py,sha256=T-eu-I9z-dSoKqJ-KI8X5i5Mm0VL1BfornxRiUjTgnk,2324
66
68
  shotgun/cli/research.py,sha256=qvBBtX3Wyn6pDZlJpcEvbeK-0iTOXegi71tm8HKVYaE,2490
@@ -85,15 +87,16 @@ shotgun/codebase/core/parser_loader.py,sha256=LZRrDS8Sp518jIu3tQW-BxdwJ86lnsTteI
85
87
  shotgun/prompts/__init__.py,sha256=RswUm0HMdfm2m2YKUwUsEdRIwoczdbI7zlucoEvHYRo,132
86
88
  shotgun/prompts/loader.py,sha256=jy24-E02pCSmz2651aCT2NgHfRrHAGMYvKrD6gs0Er8,4424
87
89
  shotgun/prompts/agents/__init__.py,sha256=YRIJMbzpArojNX1BP5gfxxois334z_GQga8T-xyWMbY,39
90
+ shotgun/prompts/agents/export.j2,sha256=W_OiTRTBmQiB5zZp54Xi2Je4nSeYQoG29QXcq_T04ZY,4333
88
91
  shotgun/prompts/agents/plan.j2,sha256=mogmrjqLx5xSXYqWdvLqcObZSfLVLQI39JpVs3Z-V84,2494
89
92
  shotgun/prompts/agents/research.j2,sha256=cLwPdIvv1MvVaHZYLdBhON-8qk-c3kjrRTF1-7Bc-vI,3069
90
93
  shotgun/prompts/agents/specify.j2,sha256=1CC2SHsxA1Yma0gSFsq-k3VpwtEohN9nh2qeRMMRPRA,1809
91
94
  shotgun/prompts/agents/tasks.j2,sha256=OYW1zsYRJxoQF4yVMqJNgi4SNz3YmcP4sljHmmqAu4Q,3613
92
95
  shotgun/prompts/agents/partials/artifact_system.j2,sha256=kaqkMU-t2x3M7z-4HU4KffSFug1WM5VDsin6tCkxjHg,1528
93
96
  shotgun/prompts/agents/partials/codebase_understanding.j2,sha256=AQmN04VRzGmLbxKKthMK4hkJZ9mIU1NMKIpTDOHJrPM,5051
94
- shotgun/prompts/agents/partials/common_agent_system_prompt.j2,sha256=UgEHSudzfsCcKHp-Nt6tlsel8ap93z7yevbt0r9SSSg,1663
97
+ shotgun/prompts/agents/partials/common_agent_system_prompt.j2,sha256=FFqN6C9pT64_yo5EZ4rmUNIn4LmHjSzwE_IT9QlHueA,1906
95
98
  shotgun/prompts/agents/partials/content_formatting.j2,sha256=MG0JB7SSp8YV5akDWpbs2f9DcdREIYqLp38NnoWLeQ0,1854
96
- shotgun/prompts/agents/partials/interactive_mode.j2,sha256=dx58RoPK7HUvydOM7qEKBU33xKOj8QIVDh39RAY-90c,940
99
+ shotgun/prompts/agents/partials/interactive_mode.j2,sha256=9sYPbyc46HXg3k1FT_LugIQvOyNDnMQwsMIgOgN-_aY,1100
97
100
  shotgun/prompts/agents/state/artifact_templates_available.j2,sha256=Jb31uOnURfLSG8RKQxHZE8zivans_sG6hKgPbC91pfk,819
98
101
  shotgun/prompts/agents/state/existing_artifacts_available.j2,sha256=gb5gKYeOXcJmIkkDS1JOm68AEymLutlxNow5HTtev7I,739
99
102
  shotgun/prompts/agents/state/system_state.j2,sha256=NFuBOo7cGy0tQrnDUs3wGO19oytGNHK2K8tgoG4cw1M,274
@@ -118,25 +121,25 @@ shotgun/sdk/services.py,sha256=WJi_AANWJZPdWdq9LntP5nlYgLxLlsFyXt28DGYNoJo,1132
118
121
  shotgun/tui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
122
  shotgun/tui/app.py,sha256=LjqQ4ylwVS7278bB6zZ5Uey6oD2pH9dljWymUVgYyPE,3661
120
123
  shotgun/tui/styles.tcss,sha256=ETyyw1bpMBOqTi5RLcAJUScdPWTvAWEqE9YcT0kVs_E,121
121
- shotgun/tui/commands/__init__.py,sha256=Bvm2EwIpYXp0jsf-d4t1wMptziCpY5TJKPItN05ts-0,2393
124
+ shotgun/tui/commands/__init__.py,sha256=Wy8s8TBSA3twK6agtsf57EFV2VfL8HGvEBF1VOg5-mM,2535
122
125
  shotgun/tui/components/prompt_input.py,sha256=Ss-htqraHZAPaehGE4x86ij0veMjc4UgadMXpbdXr40,2229
123
126
  shotgun/tui/components/spinner.py,sha256=ovTDeaJ6FD6chZx_Aepia6R3UkPOVJ77EKHfRmn39MY,2427
124
127
  shotgun/tui/components/splash.py,sha256=vppy9vEIEvywuUKRXn2y11HwXSRkQZHLYoVjhDVdJeU,1267
125
128
  shotgun/tui/components/vertical_tail.py,sha256=kkCH0WjAh54jDvRzIaOffRZXUKn_zHFZ_ichfUpgzaE,1071
126
- shotgun/tui/screens/chat.py,sha256=2jtjRBU6r-V5frEud-NqIYLHTi0C5HX6uLAXOwYuUo8,24564
129
+ shotgun/tui/screens/chat.py,sha256=OpB4z6mnK7_uITUX50blSOm_Ox3h4gMAkp1XwCT-OLE,24916
127
130
  shotgun/tui/screens/chat.tcss,sha256=2Yq3E23jxsySYsgZf4G1AYrYVcpX0UDW6kNNI0tDmtM,437
128
131
  shotgun/tui/screens/directory_setup.py,sha256=lIZ1J4A6g5Q2ZBX8epW7BhR96Dmdcg22CyiM5S-I5WU,3237
129
132
  shotgun/tui/screens/provider_config.py,sha256=A_tvDHF5KLP5PV60LjMJ_aoOdT3TjI6_g04UIUqGPqM,7126
130
133
  shotgun/tui/screens/splash.py,sha256=E2MsJihi3c9NY1L28o_MstDxGwrCnnV7zdq00MrGAsw,706
131
134
  shotgun/tui/screens/chat_screen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
132
- shotgun/tui/screens/chat_screen/command_providers.py,sha256=4Q8jR7wN4e2q0SWHSsISZP-POyu1B9lyXgoOTKB4ZLc,7198
133
- shotgun/tui/screens/chat_screen/history.py,sha256=0rSb512ZhkF8zzqkWfwHp-Cmu5VIqL-LzPkohwlHe4Q,7447
135
+ shotgun/tui/screens/chat_screen/command_providers.py,sha256=O7ZiKb6Id4pbWC2SnQxYBJ09zNklylQrnVTmCkDVC0Q,7847
136
+ shotgun/tui/screens/chat_screen/history.py,sha256=qFgAAhxrJtge8NE1TK_Ii9iHLnouT4YPZlu0jZjp3-o,7409
134
137
  shotgun/utils/__init__.py,sha256=WinIEp9oL2iMrWaDkXz2QX4nYVPAm8C9aBSKTeEwLtE,198
135
138
  shotgun/utils/env_utils.py,sha256=8QK5aw_f_V2AVTleQQlcL0RnD4sPJWXlDG46fsHu0d8,1057
136
139
  shotgun/utils/file_system_utils.py,sha256=l-0p1bEHF34OU19MahnRFdClHufThfGAjQ431teAIp0,1004
137
140
  shotgun/utils/update_checker.py,sha256=Xf-7w3Pos3etzCoT771gJe2HLkA8_V2GrqWy7ni9UqA,11373
138
- shotgun_sh-0.1.0.dev18.dist-info/METADATA,sha256=woXTk-ZMmEwPuNJXm-LS5ZG0DPFM8ZH39VLVWEhdvZU,11271
139
- shotgun_sh-0.1.0.dev18.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
140
- shotgun_sh-0.1.0.dev18.dist-info/entry_points.txt,sha256=asZxLU4QILneq0MWW10saVCZc4VWhZfb0wFZvERnzfA,45
141
- shotgun_sh-0.1.0.dev18.dist-info/licenses/LICENSE,sha256=YebsZl590zCHrF_acCU5pmNt0pnAfD2DmAnevJPB1tY,1065
142
- shotgun_sh-0.1.0.dev18.dist-info/RECORD,,
141
+ shotgun_sh-0.1.0.dev20.dist-info/METADATA,sha256=g9CjTDvqkqLPW9gP95NmAnZW8idJLHDpgZQjn3QRGrM,11271
142
+ shotgun_sh-0.1.0.dev20.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
143
+ shotgun_sh-0.1.0.dev20.dist-info/entry_points.txt,sha256=asZxLU4QILneq0MWW10saVCZc4VWhZfb0wFZvERnzfA,45
144
+ shotgun_sh-0.1.0.dev20.dist-info/licenses/LICENSE,sha256=YebsZl590zCHrF_acCU5pmNt0pnAfD2DmAnevJPB1tY,1065
145
+ shotgun_sh-0.1.0.dev20.dist-info/RECORD,,