shotgun-sh 0.1.16.dev2__py3-none-any.whl → 0.2.1.dev2__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 (39) hide show
  1. shotgun/agents/common.py +4 -5
  2. shotgun/agents/config/constants.py +21 -5
  3. shotgun/agents/config/manager.py +149 -57
  4. shotgun/agents/config/models.py +65 -84
  5. shotgun/agents/config/provider.py +172 -84
  6. shotgun/agents/history/compaction.py +1 -1
  7. shotgun/agents/history/history_processors.py +18 -9
  8. shotgun/agents/history/token_counting/__init__.py +31 -0
  9. shotgun/agents/history/token_counting/anthropic.py +89 -0
  10. shotgun/agents/history/token_counting/base.py +67 -0
  11. shotgun/agents/history/token_counting/openai.py +80 -0
  12. shotgun/agents/history/token_counting/sentencepiece_counter.py +119 -0
  13. shotgun/agents/history/token_counting/tokenizer_cache.py +90 -0
  14. shotgun/agents/history/token_counting/utils.py +147 -0
  15. shotgun/agents/history/token_estimation.py +12 -12
  16. shotgun/agents/llm.py +62 -0
  17. shotgun/agents/models.py +2 -2
  18. shotgun/agents/tools/web_search/__init__.py +42 -15
  19. shotgun/agents/tools/web_search/anthropic.py +54 -50
  20. shotgun/agents/tools/web_search/gemini.py +31 -20
  21. shotgun/agents/tools/web_search/openai.py +4 -4
  22. shotgun/cli/config.py +14 -55
  23. shotgun/cli/models.py +2 -2
  24. shotgun/codebase/models.py +4 -4
  25. shotgun/llm_proxy/__init__.py +16 -0
  26. shotgun/llm_proxy/clients.py +39 -0
  27. shotgun/llm_proxy/constants.py +8 -0
  28. shotgun/main.py +6 -0
  29. shotgun/posthog_telemetry.py +5 -3
  30. shotgun/tui/app.py +2 -0
  31. shotgun/tui/screens/chat_screen/command_providers.py +20 -0
  32. shotgun/tui/screens/model_picker.py +215 -0
  33. shotgun/tui/screens/provider_config.py +39 -26
  34. {shotgun_sh-0.1.16.dev2.dist-info → shotgun_sh-0.2.1.dev2.dist-info}/METADATA +2 -2
  35. {shotgun_sh-0.1.16.dev2.dist-info → shotgun_sh-0.2.1.dev2.dist-info}/RECORD +38 -27
  36. shotgun/agents/history/token_counting.py +0 -429
  37. {shotgun_sh-0.1.16.dev2.dist-info → shotgun_sh-0.2.1.dev2.dist-info}/WHEEL +0 -0
  38. {shotgun_sh-0.1.16.dev2.dist-info → shotgun_sh-0.2.1.dev2.dist-info}/entry_points.txt +0 -0
  39. {shotgun_sh-0.1.16.dev2.dist-info → shotgun_sh-0.2.1.dev2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,215 @@
1
+ """Screen for selecting AI model."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, cast
6
+
7
+ from textual import on
8
+ from textual.app import ComposeResult
9
+ from textual.containers import Horizontal, Vertical
10
+ from textual.reactive import reactive
11
+ from textual.screen import Screen
12
+ from textual.widgets import Button, Label, ListItem, ListView, Static
13
+
14
+ from shotgun.agents.config import ConfigManager
15
+ from shotgun.agents.config.models import MODEL_SPECS, ModelName
16
+
17
+ if TYPE_CHECKING:
18
+ from ..app import ShotgunApp
19
+
20
+
21
+ # Available models for selection
22
+ AVAILABLE_MODELS = list(ModelName)
23
+
24
+
25
+ def _sanitize_model_name_for_id(model_name: ModelName) -> str:
26
+ """Convert model name to valid Textual ID by replacing dots with hyphens."""
27
+ return model_name.value.replace(".", "-")
28
+
29
+
30
+ class ModelPickerScreen(Screen[None]):
31
+ """Select AI model to use."""
32
+
33
+ CSS = """
34
+ ModelPicker {
35
+ layout: vertical;
36
+ }
37
+
38
+ ModelPicker > * {
39
+ height: auto;
40
+ }
41
+
42
+ #titlebox {
43
+ height: auto;
44
+ margin: 2 0;
45
+ padding: 1;
46
+ border: hkey $border;
47
+ content-align: center middle;
48
+
49
+ & > * {
50
+ text-align: center;
51
+ }
52
+ }
53
+
54
+ #model-picker-title {
55
+ padding: 1 0;
56
+ text-style: bold;
57
+ color: $text-accent;
58
+ }
59
+
60
+ #model-list {
61
+ margin: 2 0;
62
+ height: auto;
63
+ & > * {
64
+ padding: 1 0;
65
+ }
66
+ }
67
+ #model-actions {
68
+ padding: 1;
69
+ }
70
+ #model-actions > * {
71
+ margin-right: 2;
72
+ }
73
+ #model-list {
74
+ padding: 1;
75
+ }
76
+ """
77
+
78
+ BINDINGS = [
79
+ ("escape", "done", "Back"),
80
+ ]
81
+
82
+ selected_model: reactive[ModelName] = reactive(ModelName.GPT_5)
83
+
84
+ def compose(self) -> ComposeResult:
85
+ with Vertical(id="titlebox"):
86
+ yield Static("Model selection", id="model-picker-title")
87
+ yield Static(
88
+ "Select the AI model you want to use for your tasks.",
89
+ id="model-picker-summary",
90
+ )
91
+ yield ListView(*self._build_model_items(), id="model-list")
92
+ with Horizontal(id="model-actions"):
93
+ yield Button("Select \\[ENTER]", variant="primary", id="select")
94
+ yield Button("Done \\[ESC]", id="done")
95
+
96
+ def on_mount(self) -> None:
97
+ # Load current selection
98
+ config_manager = self.config_manager
99
+ config = config_manager.load()
100
+ current_model = config.selected_model or ModelName.CLAUDE_OPUS_4_1
101
+ self.selected_model = current_model
102
+
103
+ # Find and highlight current selection
104
+ list_view = self.query_one(ListView)
105
+ if list_view.children:
106
+ for i, model_name in enumerate(AVAILABLE_MODELS):
107
+ if model_name == current_model:
108
+ list_view.index = i
109
+ break
110
+ self.refresh_model_labels()
111
+
112
+ def action_done(self) -> None:
113
+ self.dismiss()
114
+
115
+ @on(ListView.Highlighted)
116
+ def _on_model_highlighted(self, event: ListView.Highlighted) -> None:
117
+ model_name = self._model_from_item(event.item)
118
+ if model_name:
119
+ self.selected_model = model_name
120
+
121
+ @on(ListView.Selected)
122
+ def _on_model_selected(self, event: ListView.Selected) -> None:
123
+ model_name = self._model_from_item(event.item)
124
+ if model_name:
125
+ self.selected_model = model_name
126
+ self._select_model()
127
+
128
+ @on(Button.Pressed, "#select")
129
+ def _on_select_pressed(self) -> None:
130
+ self._select_model()
131
+
132
+ @on(Button.Pressed, "#done")
133
+ def _on_done_pressed(self) -> None:
134
+ self.action_done()
135
+
136
+ @property
137
+ def config_manager(self) -> ConfigManager:
138
+ app = cast("ShotgunApp", self.app)
139
+ return app.config_manager
140
+
141
+ def refresh_model_labels(self) -> None:
142
+ """Update the list view entries to reflect current selection."""
143
+ current_model = (
144
+ self.config_manager.load().selected_model or ModelName.CLAUDE_OPUS_4_1
145
+ )
146
+ for model_name in AVAILABLE_MODELS:
147
+ label = self.query_one(
148
+ f"#label-{_sanitize_model_name_for_id(model_name)}", Label
149
+ )
150
+ label.update(
151
+ self._model_label(model_name, is_current=model_name == current_model)
152
+ )
153
+
154
+ def _build_model_items(self) -> list[ListItem]:
155
+ items: list[ListItem] = []
156
+ current_model = self.selected_model
157
+ for model_name in AVAILABLE_MODELS:
158
+ label = Label(
159
+ self._model_label(model_name, is_current=model_name == current_model),
160
+ id=f"label-{_sanitize_model_name_for_id(model_name)}",
161
+ )
162
+ items.append(
163
+ ListItem(label, id=f"model-{_sanitize_model_name_for_id(model_name)}")
164
+ )
165
+ return items
166
+
167
+ def _model_from_item(self, item: ListItem | None) -> ModelName | None:
168
+ if item is None or item.id is None:
169
+ return None
170
+ sanitized_id = item.id.removeprefix("model-")
171
+ # Find the original model name by comparing sanitized versions
172
+ for model_name in AVAILABLE_MODELS:
173
+ if _sanitize_model_name_for_id(model_name) == sanitized_id:
174
+ return model_name
175
+ return None
176
+
177
+ def _model_label(self, model_name: ModelName, is_current: bool) -> str:
178
+ """Generate label for model with specs and current indicator."""
179
+ if model_name not in MODEL_SPECS:
180
+ return model_name.value
181
+
182
+ spec = MODEL_SPECS[model_name]
183
+ display_name = self._model_display_name(model_name)
184
+
185
+ # Format context/output tokens in readable format
186
+ input_k = spec.max_input_tokens // 1000
187
+ output_k = spec.max_output_tokens // 1000
188
+
189
+ label = f"{display_name} · {input_k}K context · {output_k}K output"
190
+
191
+ if is_current:
192
+ label += " · Current"
193
+
194
+ return label
195
+
196
+ def _model_display_name(self, model_name: ModelName) -> str:
197
+ """Get human-readable model name."""
198
+ names = {
199
+ ModelName.GPT_5: "GPT-5 (OpenAI)",
200
+ ModelName.CLAUDE_OPUS_4_1: "Claude Opus 4.1 (Anthropic)",
201
+ ModelName.CLAUDE_SONNET_4_5: "Claude Sonnet 4.5 (Anthropic)",
202
+ ModelName.GEMINI_2_5_PRO: "Gemini 2.5 Pro (Google)",
203
+ }
204
+ return names.get(model_name, model_name.value)
205
+
206
+ def _select_model(self) -> None:
207
+ """Save the selected model."""
208
+ try:
209
+ self.config_manager.update_selected_model(self.selected_model)
210
+ self.refresh_model_labels()
211
+ self.notify(
212
+ f"Selected model: {self._model_display_name(self.selected_model)}"
213
+ )
214
+ except Exception as exc: # pragma: no cover - defensive; textual path
215
+ self.notify(f"Failed to select model: {exc}", severity="error")
@@ -16,6 +16,9 @@ from shotgun.agents.config import ConfigManager, ProviderType
16
16
  if TYPE_CHECKING:
17
17
  from ..app import ShotgunApp
18
18
 
19
+ # Provider identifiers for configuration screen (LLM providers + Shotgun Account)
20
+ CONFIGURABLE_PROVIDERS = ["openai", "anthropic", "google", "shotgun"]
21
+
19
22
 
20
23
  class ProviderConfigScreen(Screen[None]):
21
24
  """Collect API keys for available providers."""
@@ -73,7 +76,7 @@ class ProviderConfigScreen(Screen[None]):
73
76
  ("escape", "done", "Back"),
74
77
  ]
75
78
 
76
- selected_provider: reactive[ProviderType] = reactive(ProviderType.OPENAI)
79
+ selected_provider: reactive[str] = reactive("openai")
77
80
 
78
81
  def compose(self) -> ComposeResult:
79
82
  with Vertical(id="titlebox"):
@@ -102,7 +105,7 @@ class ProviderConfigScreen(Screen[None]):
102
105
  list_view = self.query_one(ListView)
103
106
  if list_view.children:
104
107
  list_view.index = 0
105
- self.selected_provider = ProviderType.OPENAI
108
+ self.selected_provider = "openai"
106
109
  self.set_focus(self.query_one("#api-key", Input))
107
110
 
108
111
  def action_done(self) -> None:
@@ -152,45 +155,55 @@ class ProviderConfigScreen(Screen[None]):
152
155
 
153
156
  def refresh_provider_status(self) -> None:
154
157
  """Update the list view entries to reflect configured providers."""
155
- for provider in ProviderType:
156
- label = self.query_one(f"#label-{provider.value}", Label)
157
- label.update(self._provider_label(provider))
158
+ for provider_id in CONFIGURABLE_PROVIDERS:
159
+ label = self.query_one(f"#label-{provider_id}", Label)
160
+ label.update(self._provider_label(provider_id))
158
161
 
159
162
  def _build_provider_items(self) -> list[ListItem]:
160
163
  items: list[ListItem] = []
161
- for provider in ProviderType:
162
- label = Label(self._provider_label(provider), id=f"label-{provider.value}")
163
- items.append(ListItem(label, id=f"provider-{provider.value}"))
164
+ for provider_id in CONFIGURABLE_PROVIDERS:
165
+ label = Label(self._provider_label(provider_id), id=f"label-{provider_id}")
166
+ items.append(ListItem(label, id=f"provider-{provider_id}"))
164
167
  return items
165
168
 
166
- def _provider_from_item(self, item: ListItem | None) -> ProviderType | None:
169
+ def _provider_from_item(self, item: ListItem | None) -> str | None:
167
170
  if item is None or item.id is None:
168
171
  return None
169
172
  provider_id = item.id.removeprefix("provider-")
170
- try:
171
- return ProviderType(provider_id)
172
- except ValueError:
173
- return None
173
+ return provider_id if provider_id in CONFIGURABLE_PROVIDERS else None
174
174
 
175
- def _provider_label(self, provider: ProviderType) -> str:
176
- display = self._provider_display_name(provider)
175
+ def _provider_label(self, provider_id: str) -> str:
176
+ display = self._provider_display_name(provider_id)
177
177
  status = (
178
- "Configured"
179
- if self.config_manager.has_provider_key(provider)
180
- else "Not configured"
178
+ "Configured" if self._has_provider_key(provider_id) else "Not configured"
181
179
  )
182
180
  return f"{display} · {status}"
183
181
 
184
- def _provider_display_name(self, provider: ProviderType) -> str:
182
+ def _provider_display_name(self, provider_id: str) -> str:
185
183
  names = {
186
- ProviderType.OPENAI: "OpenAI",
187
- ProviderType.ANTHROPIC: "Anthropic",
188
- ProviderType.GOOGLE: "Google Gemini",
184
+ "openai": "OpenAI",
185
+ "anthropic": "Anthropic",
186
+ "google": "Google Gemini",
187
+ "shotgun": "Shotgun Account",
189
188
  }
190
- return names.get(provider, provider.value.title())
191
-
192
- def _input_placeholder(self, provider: ProviderType) -> str:
193
- return f"{self._provider_display_name(provider)} API key"
189
+ return names.get(provider_id, provider_id.title())
190
+
191
+ def _input_placeholder(self, provider_id: str) -> str:
192
+ return f"{self._provider_display_name(provider_id)} API key"
193
+
194
+ def _has_provider_key(self, provider_id: str) -> bool:
195
+ """Check if provider has a configured API key."""
196
+ if provider_id == "shotgun":
197
+ # Check shotgun key directly
198
+ config = self.config_manager.load()
199
+ return self.config_manager._provider_has_api_key(config.shotgun)
200
+ else:
201
+ # Check LLM provider key
202
+ try:
203
+ provider = ProviderType(provider_id)
204
+ return self.config_manager.has_provider_key(provider)
205
+ except ValueError:
206
+ return False
194
207
 
195
208
  def _save_api_key(self) -> None:
196
209
  input_widget = self.query_one("#api-key", Input)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shotgun-sh
3
- Version: 0.1.16.dev2
3
+ Version: 0.2.1.dev2
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
@@ -23,7 +23,6 @@ Classifier: Topic :: Utilities
23
23
  Requires-Python: >=3.11
24
24
  Requires-Dist: anthropic>=0.39.0
25
25
  Requires-Dist: genai-prices>=0.0.27
26
- Requires-Dist: google-generativeai>=0.8.5
27
26
  Requires-Dist: httpx>=0.27.0
28
27
  Requires-Dist: jinja2>=3.1.0
29
28
  Requires-Dist: kuzu>=0.7.0
@@ -33,6 +32,7 @@ Requires-Dist: packaging>=23.0
33
32
  Requires-Dist: posthog>=3.0.0
34
33
  Requires-Dist: pydantic-ai>=0.0.14
35
34
  Requires-Dist: rich>=13.0.0
35
+ Requires-Dist: sentencepiece>=0.2.0
36
36
  Requires-Dist: sentry-sdk[pure-eval]>=2.0.0
37
37
  Requires-Dist: textual-dev>=1.7.0
38
38
  Requires-Dist: textual>=6.1.0
@@ -1,38 +1,45 @@
1
1
  shotgun/__init__.py,sha256=P40K0fnIsb7SKcQrFnXZ4aREjpWchVDhvM1HxI4cyIQ,104
2
2
  shotgun/build_constants.py,sha256=RXNxMz46HaB5jucgMVpw8a2yCJqjbhTOh0PddyEVMN8,713
3
3
  shotgun/logging_config.py,sha256=UKenihvgH8OA3W0b8ZFcItYaFJVe9MlsMYlcevyW1HY,7440
4
- shotgun/main.py,sha256=670RwzIwEIz9QRil37IbVoxWuX66YATqXFLSYSqKw-w,4955
5
- shotgun/posthog_telemetry.py,sha256=ZD_BjRej1v4Mxh7VN3AlXGKV4jIU9SC0uBrH94VQa6c,5885
4
+ shotgun/main.py,sha256=RA3q1xPfqxCu43UmgI2ryZpA-IxPhJb_MJrbLqp9c_g,5140
5
+ shotgun/posthog_telemetry.py,sha256=RGA_rgKxAnIofjkm-cLKzyuckAKz-861gpp97tk8IME,5949
6
6
  shotgun/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  shotgun/sentry_telemetry.py,sha256=L7jFMNAnDIENWVeQYSLpyul2nmIm2w3wnOp2kDP_cic,2902
8
8
  shotgun/telemetry.py,sha256=Ves6Ih3hshpKVNVAUUmwRdtW8NkTjFPg8hEqvFKZ0t0,3208
9
9
  shotgun/agents/__init__.py,sha256=8Jzv1YsDuLyNPFJyckSr_qI4ehTVeDyIMDW4omsfPGc,25
10
10
  shotgun/agents/agent_manager.py,sha256=xq8L0oAFgtFCpKVsyUoMtYJqUyz5XxjWLKNnxoe1zo4,26577
11
- shotgun/agents/common.py,sha256=vt7ECq1rT6GR5Rt63t0whH0R0cydrk7Mty2KyPL8mEg,19045
11
+ shotgun/agents/common.py,sha256=Hr9HigsDopkI0Sr3FThGDv1f67NLemOjcYA6LV9v970,18963
12
12
  shotgun/agents/conversation_history.py,sha256=5J8_1yxdZiiWTq22aDio88DkBDZ4_Lh_p5Iy5_ENszc,3898
13
13
  shotgun/agents/conversation_manager.py,sha256=fxAvXbEl3Cl2ugJ4N9aWXaqZtkrnfj3QzwjWC4LFXwI,3514
14
14
  shotgun/agents/export.py,sha256=Zke952DbJ_lOBUmN-TPHw7qmjbfqsFu1uycBRQI_pkg,2969
15
+ shotgun/agents/llm.py,sha256=hs8j1wwTczGtehzahL1Z_5D4qus5QUx4-h9-m5ZPzm4,2209
15
16
  shotgun/agents/messages.py,sha256=wNn0qC5AqASM8LMaSGFOerZEJPn5FsIOmaJs1bdosuU,1036
16
- shotgun/agents/models.py,sha256=ULN7wdOJebYlNxtbKFTm9nJ9uv8g1C8nAG46XOcscTY,8104
17
+ shotgun/agents/models.py,sha256=IvwwjbJYi5wi9S-budg8g1ezi1VaO57Q-XtegkbTrXg,8096
17
18
  shotgun/agents/plan.py,sha256=s-WfILBOW4l8kY59RUOVtX5MJSuSzFm1nGp6b17If78,3030
18
19
  shotgun/agents/research.py,sha256=lYG7Rytcitop8mXs3isMI3XvYzzI3JH9u0VZz6K9zfo,3274
19
20
  shotgun/agents/specify.py,sha256=7MoMxfIn34G27mw6wrp_F0i2O5rid476L3kHFONDCd0,3137
20
21
  shotgun/agents/tasks.py,sha256=nk8zIl24o01hfzOGyWSbeVWeke6OGseO4Ppciurh13U,2999
21
22
  shotgun/agents/usage_manager.py,sha256=5d9JC4_cthXwhTSytMfMExMDAUYp8_nkPepTJZXk13w,5017
22
23
  shotgun/agents/config/__init__.py,sha256=Fl8K_81zBpm-OfOW27M_WWLSFdaHHek6lWz95iDREjQ,318
23
- shotgun/agents/config/constants.py,sha256=MogArrb2r5rFI6BBzc6NhPz1payGeM6K-t5oIFbJgxg,494
24
- shotgun/agents/config/manager.py,sha256=kwMbPjz0kEH_WCQAamESGjHdE8d_P-ztel4NL4FWNUw,10662
25
- shotgun/agents/config/models.py,sha256=vpVXrtiHsDt2D_h7BLyMiiQeT97vAz2L6lYKx2SEMjo,5909
26
- shotgun/agents/config/provider.py,sha256=pVWf_WM3MNWH0v2fU-peBCqx49X-nW81piQ_M-AKWRE,7249
24
+ shotgun/agents/config/constants.py,sha256=I3f0ueoQaTg5HddXGCYimCYpj-U57z3IBQYIVJxVIhg,872
25
+ shotgun/agents/config/manager.py,sha256=WKVWx77XrD_Jra3-6e-bSUYR4bUYMAsRuQNcy-MpoLY,14499
26
+ shotgun/agents/config/models.py,sha256=ZojhfheNO337e1icy_cE2PpBXIl5oHkdajr4azzFF-U,5106
27
+ shotgun/agents/config/provider.py,sha256=zaQoD8JYEKgTMEJ5etZDSyLhPzD9-EHSOYNfS70BemQ,10931
27
28
  shotgun/agents/history/__init__.py,sha256=XFQj2a6fxDqVg0Q3juvN9RjV_RJbgvFZtQOCOjVJyp4,147
28
- shotgun/agents/history/compaction.py,sha256=Je8-7T2i78gv_QWzgZNe9mvscaHcaTMttQX9xS8M38Q,3509
29
+ shotgun/agents/history/compaction.py,sha256=9RMpG0aY_7L4TecbgwHSOkGtbd9W5XZTg-MbzZmNl00,3515
29
30
  shotgun/agents/history/constants.py,sha256=yWY8rrTZarLA3flCCMB_hS2NMvUDRDTwP4D4j7MIh1w,446
30
31
  shotgun/agents/history/context_extraction.py,sha256=yVka1U6TqNVsORR4JlxpWi9yBt3Quip8g_u3x2Vi9Gs,3564
31
32
  shotgun/agents/history/history_building.py,sha256=6LFDZ60MTPDoGAcmu_mjlnjVYu8YYWdIi-cGbF3jm7A,3532
32
- shotgun/agents/history/history_processors.py,sha256=NbStr6CvszwK3DKO5LCiaVEJI-RAcVnH5dCpHTAHjQo,17731
33
+ shotgun/agents/history/history_processors.py,sha256=D3z-hzrXHxE7OAZaVX4_YAKN_nyxSF5iYMIYO24V_CI,17943
33
34
  shotgun/agents/history/message_utils.py,sha256=aPusAl2RYKbjc7lBxPaNprRHmZEG6fe97q7DQUlhlzU,2918
34
- shotgun/agents/history/token_counting.py,sha256=RasWy84eNjbmqyQDTGAzj1Q1I9ml_G_9R-maWN7gr8s,13839
35
- shotgun/agents/history/token_estimation.py,sha256=iNqhDSqFzG0YYxGijMRzj54GALFglOp0qVMB6G59RhU,4690
35
+ shotgun/agents/history/token_estimation.py,sha256=iRyKq-YDivEpJrULIbQgNpjhOuSC4nHVJYfsWEFV8sQ,4770
36
+ shotgun/agents/history/token_counting/__init__.py,sha256=YZt5Lus--fkF6l1hdkIlp1e_oAIpACNwHOI0FRP4q8s,924
37
+ shotgun/agents/history/token_counting/anthropic.py,sha256=b2LvwKM4dSILGhv_-W4mLMKMUCPLhe1ov9UGW_-iBsw,3011
38
+ shotgun/agents/history/token_counting/base.py,sha256=TN4mzwSyWNQyTuOuCFaU-8AgLdAyquoX3af4qrmkxCs,1904
39
+ shotgun/agents/history/token_counting/openai.py,sha256=XJ2z2HaUG6f3Cw9tCK_yaOsaMJGHpSFF1I30-d3soSI,2350
40
+ shotgun/agents/history/token_counting/sentencepiece_counter.py,sha256=qj1bT7J5nCd5y6Mr42O9K1KTaele0rjdd09FeyyEA70,3987
41
+ shotgun/agents/history/token_counting/tokenizer_cache.py,sha256=Y0V6KMtEwn42M5-zJGAc7YudM8X6m5-j2ekA6YGL5Xk,2868
42
+ shotgun/agents/history/token_counting/utils.py,sha256=d124IDjtd0IYBYrr3gDJGWxSbdP10Vrc7ZistbUosMg,5002
36
43
  shotgun/agents/tools/__init__.py,sha256=QaN80IqWvB5qEcjHqri1-PYvYlO74vdhcwLugoEdblo,772
37
44
  shotgun/agents/tools/file_management.py,sha256=HYNe_QA4T3_bPzSWBYcFZcnWdj8eb4aQ3GB735-G8Nw,7138
38
45
  shotgun/agents/tools/user_interaction.py,sha256=b3ncEpvoD06Cz4hwsS-ppVbQajQj640iWnVfA5WBjAA,1236
@@ -43,16 +50,16 @@ shotgun/agents/tools/codebase/file_read.py,sha256=EGK5yNqiS4cbIEQfDtdKVoJSJYk20N
43
50
  shotgun/agents/tools/codebase/models.py,sha256=8eR3_8DQiBNgB2twu0aC_evIJbugN9KW3gtxMZdGYCE,10087
44
51
  shotgun/agents/tools/codebase/query_graph.py,sha256=vOeyN4-OZj-vpTSk3Z9W5TjraZAepJ-Qjk_zzvum3fU,2115
45
52
  shotgun/agents/tools/codebase/retrieve_code.py,sha256=2VjiqVKJMd9rPV-mGrL4C-N8fqGjYLW6ZInFGbcTxOM,2878
46
- shotgun/agents/tools/web_search/__init__.py,sha256=Sj1tVokrCsJiLRWWTq0zrAolMHEGntRIYnqiyFi8L2E,1840
47
- shotgun/agents/tools/web_search/anthropic.py,sha256=NDhj8MrdxLsmGwHp7uM0IQeJVW2poY58GCUTJEM9dew,4827
48
- shotgun/agents/tools/web_search/gemini.py,sha256=hXjWUF-aTX3B9ViaKe5aF2aHXlaoBA5am40cgilinGE,2981
49
- shotgun/agents/tools/web_search/openai.py,sha256=V8GeqwUAi5wrbRuU41Y38schpXRdyeIfw85-CT5rAhY,3415
53
+ shotgun/agents/tools/web_search/__init__.py,sha256=_9rgs_gv41-wfPvwfWM_Qfq-zvboyQ_srfyneGsxgM4,3182
54
+ shotgun/agents/tools/web_search/anthropic.py,sha256=GelAhAmb-b4o87-3sgxNFfw-G2LXDEjfdZ7XfF0bQD0,4983
55
+ shotgun/agents/tools/web_search/gemini.py,sha256=-fI_deaBT4-_61A7KlKtz8tmKXW50fVx_97WAJTUg4w,3468
56
+ shotgun/agents/tools/web_search/openai.py,sha256=pnIcTV3vwXJQuxPs4I7gQNX18XzM7D7FqeNxnn1E7yw,3437
50
57
  shotgun/agents/tools/web_search/utils.py,sha256=GLJ5QV9bT2ubFMuFN7caMN7tK9OTJ0R3GD57B-tCMF0,532
51
58
  shotgun/cli/__init__.py,sha256=_F1uW2g87y4bGFxz8Gp8u7mq2voHp8vQIUtCmm8Tojo,40
52
- shotgun/cli/config.py,sha256=LbjxDNPdetYJiwlcyOYLnqwzALfgU-m54cfstUshbrs,8715
59
+ shotgun/cli/config.py,sha256=wQhuz8zE2K-fjwxeK2yZt-NkV13kEZAitBqrwPLUvgg,7466
53
60
  shotgun/cli/export.py,sha256=3hIwK2_OM1MFYSTfzBxsGuuBGm5fo0XdxASfQ5Uqb3Y,2471
54
61
  shotgun/cli/feedback.py,sha256=Me1dQQgkYwP4AIFwYgfHcPXxFdJ6CzFbCBttKcFd2Q0,1238
55
- shotgun/cli/models.py,sha256=LoajeEK7MEDUSnZXb1Li-dbhXqne812YZglx-LcVpiQ,181
62
+ shotgun/cli/models.py,sha256=kwZEldQWUheNsqF_ezgDzRBc6h0Y0JxFw1VMQjZlvPE,182
56
63
  shotgun/cli/plan.py,sha256=T-eu-I9z-dSoKqJ-KI8X5i5Mm0VL1BfornxRiUjTgnk,2324
57
64
  shotgun/cli/research.py,sha256=qvBBtX3Wyn6pDZlJpcEvbeK-0iTOXegi71tm8HKVYaE,2490
58
65
  shotgun/cli/specify.py,sha256=ErRQ72Zc75fmxopZbKy0vvnLPuYBLsGynpjj1X6-BwI,2166
@@ -63,7 +70,7 @@ shotgun/cli/codebase/__init__.py,sha256=rKdvx33p0i_BYbNkz5_4DCFgEMwzOOqLi9f5p7XT
63
70
  shotgun/cli/codebase/commands.py,sha256=1N2yOGmok0ZarqXPIpWGcsQrwm_ZJcyWiMxy6tm0j70,8711
64
71
  shotgun/cli/codebase/models.py,sha256=B9vs-d-Bq0aS6FZKebhHT-9tw90Y5f6k_t71VlZpL8k,374
65
72
  shotgun/codebase/__init__.py,sha256=QBgFE2Abd5Vl7_NdYOglF9S6d-vIjkb3C0cpIYoHZEU,309
66
- shotgun/codebase/models.py,sha256=1AAipm6KrGOHmYBBavugnyeOsVkzX-YXAD6dDsSVRWg,5299
73
+ shotgun/codebase/models.py,sha256=5e_7zaPL032n_ghcvs01Uug3BH4jyKiQ3S3U5w21BSM,5296
67
74
  shotgun/codebase/service.py,sha256=nyggapfHKdwkKXyuT9oA0tJ9qf4RNVsOxfY8lC5pHro,8006
68
75
  shotgun/codebase/core/__init__.py,sha256=GWWhJEqChiDXAF4omYCgzgoZmJjwsAf6P1aZ5Bl8OE0,1170
69
76
  shotgun/codebase/core/change_detector.py,sha256=kWCYLWzRzb3IGGOj71KBn7UOCOKMpINJbOBDf98aMxE,12409
@@ -74,6 +81,9 @@ shotgun/codebase/core/language_config.py,sha256=vsqHyuFnumRPRBV1lMOxWKNOIiClO6Fy
74
81
  shotgun/codebase/core/manager.py,sha256=USGLBdDUoFtq6fMFWRtUu2HBC_FI8d6lWcAV4l6fcvk,66000
75
82
  shotgun/codebase/core/nl_query.py,sha256=kPoSJXBlm5rLhzOofZhqPVMJ_Lj3rV2H6sld6BwtMdg,16115
76
83
  shotgun/codebase/core/parser_loader.py,sha256=LZRrDS8Sp518jIu3tQW-BxdwJ86lnsTteI478ER9Td8,4278
84
+ shotgun/llm_proxy/__init__.py,sha256=BLD9NnVzdD0H7gFb65Ajud-Q7SiCymegLRaGx8UkC-Y,435
85
+ shotgun/llm_proxy/clients.py,sha256=wP4UlgtCdrNwWsZLZ9inE3fEIDa-i1j7gsr9oXQf1o4,1037
86
+ shotgun/llm_proxy/constants.py,sha256=E8sqL-8GZzl989T3OS7E1hImSZPj2vqmp3lbM6zGiQU,309
77
87
  shotgun/prompts/__init__.py,sha256=RswUm0HMdfm2m2YKUwUsEdRIwoczdbI7zlucoEvHYRo,132
78
88
  shotgun/prompts/loader.py,sha256=jy24-E02pCSmz2651aCT2NgHfRrHAGMYvKrD6gs0Er8,4424
79
89
  shotgun/prompts/agents/__init__.py,sha256=YRIJMbzpArojNX1BP5gfxxois334z_GQga8T-xyWMbY,39
@@ -104,7 +114,7 @@ shotgun/sdk/exceptions.py,sha256=qBcQv0v7ZTwP7CMcxZST4GqCsfOWtOUjSzGBo0-heqo,412
104
114
  shotgun/sdk/models.py,sha256=X9nOTUHH0cdkQW1NfnMEDu-QgK9oUsEISh1Jtwr5Am4,5496
105
115
  shotgun/sdk/services.py,sha256=J4PJFSxCQ6--u7rb3Ta-9eYtlYcxcbnzrMP6ThyCnw4,705
106
116
  shotgun/tui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
107
- shotgun/tui/app.py,sha256=Ca7pAF2GOR6RvJdK1_P_aqF7OosTm5WRUhxF1M-Ihcs,4994
117
+ shotgun/tui/app.py,sha256=DrULqhxPPDZzz1WQNjXDY_cls4kXJNexYlI1ISrNTKs,5089
108
118
  shotgun/tui/filtered_codebase_service.py,sha256=lJ8gTMhIveTatmvmGLP299msWWTkVYKwvY_2FhuL2s4,1687
109
119
  shotgun/tui/styles.tcss,sha256=ETyyw1bpMBOqTi5RLcAJUScdPWTvAWEqE9YcT0kVs_E,121
110
120
  shotgun/tui/commands/__init__.py,sha256=8D5lvtpqMW5-fF7Bg3oJtUzU75cKOv6aUaHYYszydU8,2518
@@ -116,10 +126,11 @@ shotgun/tui/screens/chat.py,sha256=H3uAE4sQ7iJO33tJhdoW_OkzaNxXgW6BUP-SxoNiohw,3
116
126
  shotgun/tui/screens/chat.tcss,sha256=2Yq3E23jxsySYsgZf4G1AYrYVcpX0UDW6kNNI0tDmtM,437
117
127
  shotgun/tui/screens/directory_setup.py,sha256=lIZ1J4A6g5Q2ZBX8epW7BhR96Dmdcg22CyiM5S-I5WU,3237
118
128
  shotgun/tui/screens/feedback.py,sha256=cYtmuM3qqKwevstu8gJ9mmk7lkIKZvfAyDEBUOLh-yI,5660
119
- shotgun/tui/screens/provider_config.py,sha256=KIsI9bCOzk6wf_WIDHoaWOcrAaXgT4gF6hnX-1ArEn8,7487
129
+ shotgun/tui/screens/model_picker.py,sha256=Lbmsh-wCwFpJ9pEANi6uKpSatKJ2kHVocJ9-wCYMd58,6960
130
+ shotgun/tui/screens/provider_config.py,sha256=nJ7mwhabCo9AGTqi03YWhic9uHkRQstN5UCgg4bdTX0,8126
120
131
  shotgun/tui/screens/splash.py,sha256=E2MsJihi3c9NY1L28o_MstDxGwrCnnV7zdq00MrGAsw,706
121
132
  shotgun/tui/screens/chat_screen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
122
- shotgun/tui/screens/chat_screen/command_providers.py,sha256=A3vOs6J9QXg-JVi47knQdYM2_vA_IygsDJst0xpDibg,8923
133
+ shotgun/tui/screens/chat_screen/command_providers.py,sha256=AlBegXO-meob5TfNqjbs8txPXhScxxbcy7600FW_228,9520
123
134
  shotgun/tui/screens/chat_screen/hint_message.py,sha256=WOpbk8q7qt7eOHTyyHvh_IQIaublVDeJGaLpsxEk9FA,933
124
135
  shotgun/tui/screens/chat_screen/history.py,sha256=NVLA3_tERTyB4vkH71w8ef_M5CszfkwbQOuMb100Fzc,12272
125
136
  shotgun/tui/utils/__init__.py,sha256=cFjDfoXTRBq29wgP7TGRWUu1eFfiIG-LLOzjIGfadgI,150
@@ -129,8 +140,8 @@ shotgun/utils/env_utils.py,sha256=8QK5aw_f_V2AVTleQQlcL0RnD4sPJWXlDG46fsHu0d8,10
129
140
  shotgun/utils/file_system_utils.py,sha256=l-0p1bEHF34OU19MahnRFdClHufThfGAjQ431teAIp0,1004
130
141
  shotgun/utils/source_detection.py,sha256=Co6Q03R3fT771TF3RzB-70stfjNP2S4F_ArZKibwzm8,454
131
142
  shotgun/utils/update_checker.py,sha256=IgzPHRhS1ETH7PnJR_dIx6lxgr1qHpCkMTgzUxvGjhI,7586
132
- shotgun_sh-0.1.16.dev2.dist-info/METADATA,sha256=593zGac-zT_lBaqzrAXKl_N0WxPigfiXnLSWmY92Z14,11233
133
- shotgun_sh-0.1.16.dev2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
134
- shotgun_sh-0.1.16.dev2.dist-info/entry_points.txt,sha256=asZxLU4QILneq0MWW10saVCZc4VWhZfb0wFZvERnzfA,45
135
- shotgun_sh-0.1.16.dev2.dist-info/licenses/LICENSE,sha256=YebsZl590zCHrF_acCU5pmNt0pnAfD2DmAnevJPB1tY,1065
136
- shotgun_sh-0.1.16.dev2.dist-info/RECORD,,
143
+ shotgun_sh-0.2.1.dev2.dist-info/METADATA,sha256=21gMEduUKH5hRYdTHdBTg0vQnEX_7H-gHJU5elXs1t0,11226
144
+ shotgun_sh-0.2.1.dev2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
145
+ shotgun_sh-0.2.1.dev2.dist-info/entry_points.txt,sha256=asZxLU4QILneq0MWW10saVCZc4VWhZfb0wFZvERnzfA,45
146
+ shotgun_sh-0.2.1.dev2.dist-info/licenses/LICENSE,sha256=YebsZl590zCHrF_acCU5pmNt0pnAfD2DmAnevJPB1tY,1065
147
+ shotgun_sh-0.2.1.dev2.dist-info/RECORD,,