shotgun-sh 0.2.1.dev2__py3-none-any.whl → 0.2.1.dev3__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.
- shotgun/agents/config/manager.py +2 -2
- shotgun/agents/config/provider.py +2 -2
- shotgun/cli/config.py +16 -4
- shotgun/tui/screens/chat.py +2 -8
- shotgun/tui/screens/chat_screen/command_providers.py +95 -10
- shotgun/tui/screens/chat_screen/history.py +3 -1
- shotgun/tui/screens/model_picker.py +51 -14
- shotgun/tui/screens/provider_config.py +16 -5
- shotgun/utils/env_utils.py +12 -0
- {shotgun_sh-0.2.1.dev2.dist-info → shotgun_sh-0.2.1.dev3.dist-info}/METADATA +1 -1
- {shotgun_sh-0.2.1.dev2.dist-info → shotgun_sh-0.2.1.dev3.dist-info}/RECORD +14 -14
- {shotgun_sh-0.2.1.dev2.dist-info → shotgun_sh-0.2.1.dev3.dist-info}/WHEEL +0 -0
- {shotgun_sh-0.2.1.dev2.dist-info → shotgun_sh-0.2.1.dev3.dist-info}/entry_points.txt +0 -0
- {shotgun_sh-0.2.1.dev2.dist-info → shotgun_sh-0.2.1.dev3.dist-info}/licenses/LICENSE +0 -0
shotgun/agents/config/manager.py
CHANGED
|
@@ -109,7 +109,7 @@ class ConfigManager:
|
|
|
109
109
|
# Find default model for this provider
|
|
110
110
|
provider_models = {
|
|
111
111
|
ProviderType.OPENAI: ModelName.GPT_5,
|
|
112
|
-
ProviderType.ANTHROPIC: ModelName.
|
|
112
|
+
ProviderType.ANTHROPIC: ModelName.CLAUDE_SONNET_4_5,
|
|
113
113
|
ProviderType.GOOGLE: ModelName.GEMINI_2_5_PRO,
|
|
114
114
|
}
|
|
115
115
|
|
|
@@ -210,7 +210,7 @@ class ConfigManager:
|
|
|
210
210
|
|
|
211
211
|
provider_models = {
|
|
212
212
|
ProviderType.OPENAI: ModelName.GPT_5,
|
|
213
|
-
ProviderType.ANTHROPIC: ModelName.
|
|
213
|
+
ProviderType.ANTHROPIC: ModelName.CLAUDE_SONNET_4_5,
|
|
214
214
|
ProviderType.GOOGLE: ModelName.GEMINI_2_5_PRO,
|
|
215
215
|
}
|
|
216
216
|
if provider_enum in provider_models:
|
|
@@ -219,8 +219,8 @@ def get_provider_model(
|
|
|
219
219
|
if not api_key:
|
|
220
220
|
raise ValueError("Anthropic API key not configured. Set via config.")
|
|
221
221
|
|
|
222
|
-
# Use requested model or default to claude-
|
|
223
|
-
model_name = requested_model if requested_model else ModelName.
|
|
222
|
+
# Use requested model or default to claude-sonnet-4-5
|
|
223
|
+
model_name = requested_model if requested_model else ModelName.CLAUDE_SONNET_4_5
|
|
224
224
|
if model_name not in MODEL_SPECS:
|
|
225
225
|
raise ValueError(f"Model '{model_name.value}' not found")
|
|
226
226
|
spec = MODEL_SPECS[model_name]
|
shotgun/cli/config.py
CHANGED
|
@@ -9,6 +9,7 @@ from rich.table import Table
|
|
|
9
9
|
|
|
10
10
|
from shotgun.agents.config import ProviderType, get_config_manager
|
|
11
11
|
from shotgun.logging_config import get_logger
|
|
12
|
+
from shotgun.utils.env_utils import is_shotgun_account_enabled
|
|
12
13
|
|
|
13
14
|
logger = get_logger(__name__)
|
|
14
15
|
console = Console()
|
|
@@ -162,12 +163,17 @@ def _show_full_config(config: Any) -> None:
|
|
|
162
163
|
table.add_row("", "") # Separator
|
|
163
164
|
|
|
164
165
|
# Provider configurations
|
|
165
|
-
|
|
166
|
+
providers_to_show = [
|
|
166
167
|
("OpenAI", config.openai),
|
|
167
168
|
("Anthropic", config.anthropic),
|
|
168
169
|
("Google", config.google),
|
|
169
|
-
|
|
170
|
-
|
|
170
|
+
]
|
|
171
|
+
|
|
172
|
+
# Only show Shotgun Account if feature flag is enabled
|
|
173
|
+
if is_shotgun_account_enabled():
|
|
174
|
+
providers_to_show.append(("Shotgun Account", config.shotgun))
|
|
175
|
+
|
|
176
|
+
for provider_name, provider_config in providers_to_show:
|
|
171
177
|
table.add_row(f"[bold]{provider_name}[/bold]", "")
|
|
172
178
|
|
|
173
179
|
# API Key
|
|
@@ -207,7 +213,13 @@ def _show_provider_config(provider: ProviderType, config: Any) -> None:
|
|
|
207
213
|
|
|
208
214
|
def _mask_secrets(data: dict[str, Any]) -> None:
|
|
209
215
|
"""Mask secrets in configuration data."""
|
|
210
|
-
|
|
216
|
+
providers = ["openai", "anthropic", "google"]
|
|
217
|
+
|
|
218
|
+
# Only mask shotgun if feature flag is enabled
|
|
219
|
+
if is_shotgun_account_enabled():
|
|
220
|
+
providers.append("shotgun")
|
|
221
|
+
|
|
222
|
+
for provider in providers:
|
|
211
223
|
if provider in data and isinstance(data[provider], dict):
|
|
212
224
|
if "api_key" in data[provider] and data[provider]["api_key"]:
|
|
213
225
|
data[provider]["api_key"] = _mask_value(data[provider]["api_key"])
|
shotgun/tui/screens/chat.py
CHANGED
|
@@ -54,11 +54,8 @@ from ..components.prompt_input import PromptInput
|
|
|
54
54
|
from ..components.spinner import Spinner
|
|
55
55
|
from ..utils.mode_progress import PlaceholderHints
|
|
56
56
|
from .chat_screen.command_providers import (
|
|
57
|
-
AgentModeProvider,
|
|
58
|
-
CodebaseCommandProvider,
|
|
59
57
|
DeleteCodebasePaletteProvider,
|
|
60
|
-
|
|
61
|
-
UsageProvider,
|
|
58
|
+
UnifiedCommandProvider,
|
|
62
59
|
)
|
|
63
60
|
|
|
64
61
|
logger = logging.getLogger(__name__)
|
|
@@ -233,10 +230,7 @@ class ChatScreen(Screen[None]):
|
|
|
233
230
|
]
|
|
234
231
|
|
|
235
232
|
COMMANDS = {
|
|
236
|
-
|
|
237
|
-
ProviderSetupProvider,
|
|
238
|
-
CodebaseCommandProvider,
|
|
239
|
-
UsageProvider,
|
|
233
|
+
UnifiedCommandProvider,
|
|
240
234
|
}
|
|
241
235
|
|
|
242
236
|
value = reactive("")
|
|
@@ -191,30 +191,30 @@ class CodebaseCommandProvider(Provider):
|
|
|
191
191
|
return cast(ChatScreen, self.screen)
|
|
192
192
|
|
|
193
193
|
async def discover(self) -> AsyncGenerator[DiscoveryHit, None]:
|
|
194
|
-
yield DiscoveryHit(
|
|
195
|
-
"Codebase: Index Codebase",
|
|
196
|
-
self.chat_screen.index_codebase_command,
|
|
197
|
-
help="Index a repository into the codebase graph",
|
|
198
|
-
)
|
|
199
194
|
yield DiscoveryHit(
|
|
200
195
|
"Codebase: Delete Codebase Index",
|
|
201
196
|
self.chat_screen.delete_codebase_command,
|
|
202
197
|
help="Delete an existing codebase index",
|
|
203
198
|
)
|
|
199
|
+
yield DiscoveryHit(
|
|
200
|
+
"Codebase: Index Codebase",
|
|
201
|
+
self.chat_screen.index_codebase_command,
|
|
202
|
+
help="Index a repository into the codebase graph",
|
|
203
|
+
)
|
|
204
204
|
|
|
205
205
|
async def search(self, query: str) -> AsyncGenerator[Hit, None]:
|
|
206
206
|
matcher = self.matcher(query)
|
|
207
207
|
commands = [
|
|
208
|
-
(
|
|
209
|
-
"Codebase: Index Codebase",
|
|
210
|
-
self.chat_screen.index_codebase_command,
|
|
211
|
-
"Index a repository into the codebase graph",
|
|
212
|
-
),
|
|
213
208
|
(
|
|
214
209
|
"Codebase: Delete Codebase Index",
|
|
215
210
|
self.chat_screen.delete_codebase_command,
|
|
216
211
|
"Delete an existing codebase index",
|
|
217
212
|
),
|
|
213
|
+
(
|
|
214
|
+
"Codebase: Index Codebase",
|
|
215
|
+
self.chat_screen.index_codebase_command,
|
|
216
|
+
"Index a repository into the codebase graph",
|
|
217
|
+
),
|
|
218
218
|
]
|
|
219
219
|
for title, callback, help_text in commands:
|
|
220
220
|
score = matcher.match(title)
|
|
@@ -269,3 +269,88 @@ class DeleteCodebasePaletteProvider(Provider):
|
|
|
269
269
|
),
|
|
270
270
|
help=graph.repo_path,
|
|
271
271
|
)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
class UnifiedCommandProvider(Provider):
|
|
275
|
+
"""Unified command provider with all commands in alphabetical order."""
|
|
276
|
+
|
|
277
|
+
@property
|
|
278
|
+
def chat_screen(self) -> "ChatScreen":
|
|
279
|
+
from shotgun.tui.screens.chat import ChatScreen
|
|
280
|
+
|
|
281
|
+
return cast(ChatScreen, self.screen)
|
|
282
|
+
|
|
283
|
+
def open_provider_config(self) -> None:
|
|
284
|
+
"""Show the provider configuration screen."""
|
|
285
|
+
self.chat_screen.app.push_screen("provider_config")
|
|
286
|
+
|
|
287
|
+
def open_model_picker(self) -> None:
|
|
288
|
+
"""Show the model picker screen."""
|
|
289
|
+
self.chat_screen.app.push_screen("model_picker")
|
|
290
|
+
|
|
291
|
+
async def discover(self) -> AsyncGenerator[DiscoveryHit, None]:
|
|
292
|
+
"""Provide commands in alphabetical order when palette opens."""
|
|
293
|
+
# Alphabetically ordered commands
|
|
294
|
+
yield DiscoveryHit(
|
|
295
|
+
"Codebase: Delete Codebase Index",
|
|
296
|
+
self.chat_screen.delete_codebase_command,
|
|
297
|
+
help="Delete an existing codebase index",
|
|
298
|
+
)
|
|
299
|
+
yield DiscoveryHit(
|
|
300
|
+
"Codebase: Index Codebase",
|
|
301
|
+
self.chat_screen.index_codebase_command,
|
|
302
|
+
help="Index a repository into the codebase graph",
|
|
303
|
+
)
|
|
304
|
+
yield DiscoveryHit(
|
|
305
|
+
"Open Provider Setup",
|
|
306
|
+
self.open_provider_config,
|
|
307
|
+
help="⚙️ Manage API keys for available providers",
|
|
308
|
+
)
|
|
309
|
+
yield DiscoveryHit(
|
|
310
|
+
"Select AI Model",
|
|
311
|
+
self.open_model_picker,
|
|
312
|
+
help="🤖 Choose which AI model to use",
|
|
313
|
+
)
|
|
314
|
+
yield DiscoveryHit(
|
|
315
|
+
"Show usage",
|
|
316
|
+
self.chat_screen.action_show_usage,
|
|
317
|
+
help="Display usage information for the current session",
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
async def search(self, query: str) -> AsyncGenerator[Hit, None]:
|
|
321
|
+
"""Search for commands in alphabetical order."""
|
|
322
|
+
matcher = self.matcher(query)
|
|
323
|
+
|
|
324
|
+
# Define all commands in alphabetical order
|
|
325
|
+
commands = [
|
|
326
|
+
(
|
|
327
|
+
"Codebase: Delete Codebase Index",
|
|
328
|
+
self.chat_screen.delete_codebase_command,
|
|
329
|
+
"Delete an existing codebase index",
|
|
330
|
+
),
|
|
331
|
+
(
|
|
332
|
+
"Codebase: Index Codebase",
|
|
333
|
+
self.chat_screen.index_codebase_command,
|
|
334
|
+
"Index a repository into the codebase graph",
|
|
335
|
+
),
|
|
336
|
+
(
|
|
337
|
+
"Open Provider Setup",
|
|
338
|
+
self.open_provider_config,
|
|
339
|
+
"⚙️ Manage API keys for available providers",
|
|
340
|
+
),
|
|
341
|
+
(
|
|
342
|
+
"Select AI Model",
|
|
343
|
+
self.open_model_picker,
|
|
344
|
+
"🤖 Choose which AI model to use",
|
|
345
|
+
),
|
|
346
|
+
(
|
|
347
|
+
"Show usage",
|
|
348
|
+
self.chat_screen.action_show_usage,
|
|
349
|
+
"Display usage information for the current session",
|
|
350
|
+
),
|
|
351
|
+
]
|
|
352
|
+
|
|
353
|
+
for title, callback, help_text in commands:
|
|
354
|
+
score = matcher.match(title)
|
|
355
|
+
if score > 0:
|
|
356
|
+
yield Hit(score, matcher.highlight(title), callback, help=help_text)
|
|
@@ -217,7 +217,9 @@ class AgentResponseWidget(Widget):
|
|
|
217
217
|
return ""
|
|
218
218
|
for idx, part in enumerate(self.item.parts):
|
|
219
219
|
if isinstance(part, TextPart):
|
|
220
|
-
|
|
220
|
+
# Only show the circle prefix if there's actual content
|
|
221
|
+
if part.content and part.content.strip():
|
|
222
|
+
acc += f"**⏺** {part.content}\n\n"
|
|
221
223
|
elif isinstance(part, ToolCallPart):
|
|
222
224
|
parts_str = self._format_tool_call_part(part)
|
|
223
225
|
acc += parts_str + "\n\n"
|
|
@@ -35,10 +35,6 @@ class ModelPickerScreen(Screen[None]):
|
|
|
35
35
|
layout: vertical;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
ModelPicker > * {
|
|
39
|
-
height: auto;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
38
|
#titlebox {
|
|
43
39
|
height: auto;
|
|
44
40
|
margin: 2 0;
|
|
@@ -60,6 +56,7 @@ class ModelPickerScreen(Screen[None]):
|
|
|
60
56
|
#model-list {
|
|
61
57
|
margin: 2 0;
|
|
62
58
|
height: auto;
|
|
59
|
+
padding: 1;
|
|
63
60
|
& > * {
|
|
64
61
|
padding: 1 0;
|
|
65
62
|
}
|
|
@@ -70,9 +67,6 @@ class ModelPickerScreen(Screen[None]):
|
|
|
70
67
|
#model-actions > * {
|
|
71
68
|
margin-right: 2;
|
|
72
69
|
}
|
|
73
|
-
#model-list {
|
|
74
|
-
padding: 1;
|
|
75
|
-
}
|
|
76
70
|
"""
|
|
77
71
|
|
|
78
72
|
BINDINGS = [
|
|
@@ -97,16 +91,21 @@ class ModelPickerScreen(Screen[None]):
|
|
|
97
91
|
# Load current selection
|
|
98
92
|
config_manager = self.config_manager
|
|
99
93
|
config = config_manager.load()
|
|
100
|
-
current_model = config.selected_model or ModelName.
|
|
94
|
+
current_model = config.selected_model or ModelName.CLAUDE_SONNET_4_5
|
|
101
95
|
self.selected_model = current_model
|
|
102
96
|
|
|
103
|
-
# Find and highlight current selection
|
|
97
|
+
# Find and highlight current selection (if it's in the filtered list)
|
|
104
98
|
list_view = self.query_one(ListView)
|
|
105
99
|
if list_view.children:
|
|
106
|
-
for i,
|
|
107
|
-
if
|
|
108
|
-
|
|
109
|
-
|
|
100
|
+
for i, child in enumerate(list_view.children):
|
|
101
|
+
if isinstance(child, ListItem) and child.id:
|
|
102
|
+
model_id = child.id.removeprefix("model-")
|
|
103
|
+
# Find the model name
|
|
104
|
+
for model_name in AVAILABLE_MODELS:
|
|
105
|
+
if _sanitize_model_name_for_id(model_name) == model_id:
|
|
106
|
+
if model_name == current_model:
|
|
107
|
+
list_view.index = i
|
|
108
|
+
break
|
|
110
109
|
self.refresh_model_labels()
|
|
111
110
|
|
|
112
111
|
def action_done(self) -> None:
|
|
@@ -141,9 +140,12 @@ class ModelPickerScreen(Screen[None]):
|
|
|
141
140
|
def refresh_model_labels(self) -> None:
|
|
142
141
|
"""Update the list view entries to reflect current selection."""
|
|
143
142
|
current_model = (
|
|
144
|
-
self.config_manager.load().selected_model or ModelName.
|
|
143
|
+
self.config_manager.load().selected_model or ModelName.CLAUDE_SONNET_4_5
|
|
145
144
|
)
|
|
145
|
+
# Update labels for available models only
|
|
146
146
|
for model_name in AVAILABLE_MODELS:
|
|
147
|
+
if not self._is_model_available(model_name):
|
|
148
|
+
continue
|
|
147
149
|
label = self.query_one(
|
|
148
150
|
f"#label-{_sanitize_model_name_for_id(model_name)}", Label
|
|
149
151
|
)
|
|
@@ -155,6 +157,10 @@ class ModelPickerScreen(Screen[None]):
|
|
|
155
157
|
items: list[ListItem] = []
|
|
156
158
|
current_model = self.selected_model
|
|
157
159
|
for model_name in AVAILABLE_MODELS:
|
|
160
|
+
# Only add models that are available
|
|
161
|
+
if not self._is_model_available(model_name):
|
|
162
|
+
continue
|
|
163
|
+
|
|
158
164
|
label = Label(
|
|
159
165
|
self._model_label(model_name, is_current=model_name == current_model),
|
|
160
166
|
id=f"label-{_sanitize_model_name_for_id(model_name)}",
|
|
@@ -165,6 +171,7 @@ class ModelPickerScreen(Screen[None]):
|
|
|
165
171
|
return items
|
|
166
172
|
|
|
167
173
|
def _model_from_item(self, item: ListItem | None) -> ModelName | None:
|
|
174
|
+
"""Get ModelName from a ListItem."""
|
|
168
175
|
if item is None or item.id is None:
|
|
169
176
|
return None
|
|
170
177
|
sanitized_id = item.id.removeprefix("model-")
|
|
@@ -174,6 +181,32 @@ class ModelPickerScreen(Screen[None]):
|
|
|
174
181
|
return model_name
|
|
175
182
|
return None
|
|
176
183
|
|
|
184
|
+
def _is_model_available(self, model_name: ModelName) -> bool:
|
|
185
|
+
"""Check if a model is available based on provider key configuration.
|
|
186
|
+
|
|
187
|
+
A model is available if:
|
|
188
|
+
1. Shotgun Account key is configured (provides access to all models), OR
|
|
189
|
+
2. The model's provider has an API key configured (BYOK mode)
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
model_name: The model to check availability for
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
True if the model can be used, False otherwise
|
|
196
|
+
"""
|
|
197
|
+
config = self.config_manager.load()
|
|
198
|
+
|
|
199
|
+
# If Shotgun Account is configured, all models are available
|
|
200
|
+
if self.config_manager._provider_has_api_key(config.shotgun):
|
|
201
|
+
return True
|
|
202
|
+
|
|
203
|
+
# In BYOK mode, check if the model's provider has a key
|
|
204
|
+
if model_name not in MODEL_SPECS:
|
|
205
|
+
return False
|
|
206
|
+
|
|
207
|
+
spec = MODEL_SPECS[model_name]
|
|
208
|
+
return self.config_manager.has_provider_key(spec.provider)
|
|
209
|
+
|
|
177
210
|
def _model_label(self, model_name: ModelName, is_current: bool) -> str:
|
|
178
211
|
"""Generate label for model with specs and current indicator."""
|
|
179
212
|
if model_name not in MODEL_SPECS:
|
|
@@ -188,6 +221,10 @@ class ModelPickerScreen(Screen[None]):
|
|
|
188
221
|
|
|
189
222
|
label = f"{display_name} · {input_k}K context · {output_k}K output"
|
|
190
223
|
|
|
224
|
+
# Add cost indicator for expensive models
|
|
225
|
+
if model_name == ModelName.CLAUDE_OPUS_4_1:
|
|
226
|
+
label += " · Expensive"
|
|
227
|
+
|
|
191
228
|
if is_current:
|
|
192
229
|
label += " · Current"
|
|
193
230
|
|
|
@@ -12,12 +12,23 @@ from textual.screen import Screen
|
|
|
12
12
|
from textual.widgets import Button, Input, Label, ListItem, ListView, Markdown, Static
|
|
13
13
|
|
|
14
14
|
from shotgun.agents.config import ConfigManager, ProviderType
|
|
15
|
+
from shotgun.utils.env_utils import is_shotgun_account_enabled
|
|
15
16
|
|
|
16
17
|
if TYPE_CHECKING:
|
|
17
18
|
from ..app import ShotgunApp
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
|
|
21
|
+
def get_configurable_providers() -> list[str]:
|
|
22
|
+
"""Get list of configurable providers based on feature flags.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
List of provider identifiers that can be configured.
|
|
26
|
+
Includes shotgun only if SHOTGUN_ACCOUNT_ENABLED is set.
|
|
27
|
+
"""
|
|
28
|
+
providers = ["openai", "anthropic", "google"]
|
|
29
|
+
if is_shotgun_account_enabled():
|
|
30
|
+
providers.append("shotgun")
|
|
31
|
+
return providers
|
|
21
32
|
|
|
22
33
|
|
|
23
34
|
class ProviderConfigScreen(Screen[None]):
|
|
@@ -155,13 +166,13 @@ class ProviderConfigScreen(Screen[None]):
|
|
|
155
166
|
|
|
156
167
|
def refresh_provider_status(self) -> None:
|
|
157
168
|
"""Update the list view entries to reflect configured providers."""
|
|
158
|
-
for provider_id in
|
|
169
|
+
for provider_id in get_configurable_providers():
|
|
159
170
|
label = self.query_one(f"#label-{provider_id}", Label)
|
|
160
171
|
label.update(self._provider_label(provider_id))
|
|
161
172
|
|
|
162
173
|
def _build_provider_items(self) -> list[ListItem]:
|
|
163
174
|
items: list[ListItem] = []
|
|
164
|
-
for provider_id in
|
|
175
|
+
for provider_id in get_configurable_providers():
|
|
165
176
|
label = Label(self._provider_label(provider_id), id=f"label-{provider_id}")
|
|
166
177
|
items.append(ListItem(label, id=f"provider-{provider_id}"))
|
|
167
178
|
return items
|
|
@@ -170,7 +181,7 @@ class ProviderConfigScreen(Screen[None]):
|
|
|
170
181
|
if item is None or item.id is None:
|
|
171
182
|
return None
|
|
172
183
|
provider_id = item.id.removeprefix("provider-")
|
|
173
|
-
return provider_id if provider_id in
|
|
184
|
+
return provider_id if provider_id in get_configurable_providers() else None
|
|
174
185
|
|
|
175
186
|
def _provider_label(self, provider_id: str) -> str:
|
|
176
187
|
display = self._provider_display_name(provider_id)
|
shotgun/utils/env_utils.py
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
"""Utilities for working with environment variables."""
|
|
2
2
|
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def is_shotgun_account_enabled() -> bool:
|
|
7
|
+
"""Check if Shotgun Account feature is enabled via environment variable.
|
|
8
|
+
|
|
9
|
+
Returns:
|
|
10
|
+
True if SHOTGUN_ACCOUNT_ENABLED is set to a truthy value,
|
|
11
|
+
False otherwise
|
|
12
|
+
"""
|
|
13
|
+
return is_truthy(os.environ.get("SHOTGUN_ACCOUNT_ENABLED"))
|
|
14
|
+
|
|
3
15
|
|
|
4
16
|
def is_truthy(value: str | None) -> bool:
|
|
5
17
|
"""Check if a string value represents true.
|
|
@@ -22,9 +22,9 @@ shotgun/agents/tasks.py,sha256=nk8zIl24o01hfzOGyWSbeVWeke6OGseO4Ppciurh13U,2999
|
|
|
22
22
|
shotgun/agents/usage_manager.py,sha256=5d9JC4_cthXwhTSytMfMExMDAUYp8_nkPepTJZXk13w,5017
|
|
23
23
|
shotgun/agents/config/__init__.py,sha256=Fl8K_81zBpm-OfOW27M_WWLSFdaHHek6lWz95iDREjQ,318
|
|
24
24
|
shotgun/agents/config/constants.py,sha256=I3f0ueoQaTg5HddXGCYimCYpj-U57z3IBQYIVJxVIhg,872
|
|
25
|
-
shotgun/agents/config/manager.py,sha256=
|
|
25
|
+
shotgun/agents/config/manager.py,sha256=6WT4xaAfJTyYxpQ9AcMYHG1cjySNmtJDgTzVmqIAMpc,14503
|
|
26
26
|
shotgun/agents/config/models.py,sha256=ZojhfheNO337e1icy_cE2PpBXIl5oHkdajr4azzFF-U,5106
|
|
27
|
-
shotgun/agents/config/provider.py,sha256=
|
|
27
|
+
shotgun/agents/config/provider.py,sha256=_HkmN4WhGcZgtAuaF-RA6ZEOiWQ0oWLufZDxl-3rnn4,10935
|
|
28
28
|
shotgun/agents/history/__init__.py,sha256=XFQj2a6fxDqVg0Q3juvN9RjV_RJbgvFZtQOCOjVJyp4,147
|
|
29
29
|
shotgun/agents/history/compaction.py,sha256=9RMpG0aY_7L4TecbgwHSOkGtbd9W5XZTg-MbzZmNl00,3515
|
|
30
30
|
shotgun/agents/history/constants.py,sha256=yWY8rrTZarLA3flCCMB_hS2NMvUDRDTwP4D4j7MIh1w,446
|
|
@@ -56,7 +56,7 @@ shotgun/agents/tools/web_search/gemini.py,sha256=-fI_deaBT4-_61A7KlKtz8tmKXW50fV
|
|
|
56
56
|
shotgun/agents/tools/web_search/openai.py,sha256=pnIcTV3vwXJQuxPs4I7gQNX18XzM7D7FqeNxnn1E7yw,3437
|
|
57
57
|
shotgun/agents/tools/web_search/utils.py,sha256=GLJ5QV9bT2ubFMuFN7caMN7tK9OTJ0R3GD57B-tCMF0,532
|
|
58
58
|
shotgun/cli/__init__.py,sha256=_F1uW2g87y4bGFxz8Gp8u7mq2voHp8vQIUtCmm8Tojo,40
|
|
59
|
-
shotgun/cli/config.py,sha256=
|
|
59
|
+
shotgun/cli/config.py,sha256=Lrcqxm7W7I6g6iP_K5-yK7QFOgcYt5KIc8A6Wit1Ksg,7835
|
|
60
60
|
shotgun/cli/export.py,sha256=3hIwK2_OM1MFYSTfzBxsGuuBGm5fo0XdxASfQ5Uqb3Y,2471
|
|
61
61
|
shotgun/cli/feedback.py,sha256=Me1dQQgkYwP4AIFwYgfHcPXxFdJ6CzFbCBttKcFd2Q0,1238
|
|
62
62
|
shotgun/cli/models.py,sha256=kwZEldQWUheNsqF_ezgDzRBc6h0Y0JxFw1VMQjZlvPE,182
|
|
@@ -122,26 +122,26 @@ shotgun/tui/components/prompt_input.py,sha256=Ss-htqraHZAPaehGE4x86ij0veMjc4Ugad
|
|
|
122
122
|
shotgun/tui/components/spinner.py,sha256=ovTDeaJ6FD6chZx_Aepia6R3UkPOVJ77EKHfRmn39MY,2427
|
|
123
123
|
shotgun/tui/components/splash.py,sha256=vppy9vEIEvywuUKRXn2y11HwXSRkQZHLYoVjhDVdJeU,1267
|
|
124
124
|
shotgun/tui/components/vertical_tail.py,sha256=kROwTaRjUwVB7H35dtmNcUVPQqNYvvfq7K2tXBKEb6c,638
|
|
125
|
-
shotgun/tui/screens/chat.py,sha256=
|
|
125
|
+
shotgun/tui/screens/chat.py,sha256=CqAv_x6R4zl-MGbtg8KgZWt8OhpBJYpx5gGBQ3oxqgw,30313
|
|
126
126
|
shotgun/tui/screens/chat.tcss,sha256=2Yq3E23jxsySYsgZf4G1AYrYVcpX0UDW6kNNI0tDmtM,437
|
|
127
127
|
shotgun/tui/screens/directory_setup.py,sha256=lIZ1J4A6g5Q2ZBX8epW7BhR96Dmdcg22CyiM5S-I5WU,3237
|
|
128
128
|
shotgun/tui/screens/feedback.py,sha256=cYtmuM3qqKwevstu8gJ9mmk7lkIKZvfAyDEBUOLh-yI,5660
|
|
129
|
-
shotgun/tui/screens/model_picker.py,sha256=
|
|
130
|
-
shotgun/tui/screens/provider_config.py,sha256=
|
|
129
|
+
shotgun/tui/screens/model_picker.py,sha256=ZutEz4w_BJkGGwwdJSj7-kPdIPzmK6ZDHYkEA0q596A,8625
|
|
130
|
+
shotgun/tui/screens/provider_config.py,sha256=pDJKjvl_els-XrbRTwBBDDL0jo_uRa7DMTAZJAJ9NXA,8461
|
|
131
131
|
shotgun/tui/screens/splash.py,sha256=E2MsJihi3c9NY1L28o_MstDxGwrCnnV7zdq00MrGAsw,706
|
|
132
132
|
shotgun/tui/screens/chat_screen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
133
|
-
shotgun/tui/screens/chat_screen/command_providers.py,sha256=
|
|
133
|
+
shotgun/tui/screens/chat_screen/command_providers.py,sha256=qAY09_pKxcTyxJHy9Rlwhs1tAW5QMWXxDwnpparnQmI,12542
|
|
134
134
|
shotgun/tui/screens/chat_screen/hint_message.py,sha256=WOpbk8q7qt7eOHTyyHvh_IQIaublVDeJGaLpsxEk9FA,933
|
|
135
|
-
shotgun/tui/screens/chat_screen/history.py,sha256=
|
|
135
|
+
shotgun/tui/screens/chat_screen/history.py,sha256=Go859iEjw0s5aELKpF42MjLXy7UFQ52XnJMTIkV3aLo,12406
|
|
136
136
|
shotgun/tui/utils/__init__.py,sha256=cFjDfoXTRBq29wgP7TGRWUu1eFfiIG-LLOzjIGfadgI,150
|
|
137
137
|
shotgun/tui/utils/mode_progress.py,sha256=lseRRo7kMWLkBzI3cU5vqJmS2ZcCjyRYf9Zwtvc-v58,10931
|
|
138
138
|
shotgun/utils/__init__.py,sha256=WinIEp9oL2iMrWaDkXz2QX4nYVPAm8C9aBSKTeEwLtE,198
|
|
139
|
-
shotgun/utils/env_utils.py,sha256=
|
|
139
|
+
shotgun/utils/env_utils.py,sha256=5spVCdeqVKtlWoKocPhz_5j_iRN30neqcGUzUuiWmfc,1365
|
|
140
140
|
shotgun/utils/file_system_utils.py,sha256=l-0p1bEHF34OU19MahnRFdClHufThfGAjQ431teAIp0,1004
|
|
141
141
|
shotgun/utils/source_detection.py,sha256=Co6Q03R3fT771TF3RzB-70stfjNP2S4F_ArZKibwzm8,454
|
|
142
142
|
shotgun/utils/update_checker.py,sha256=IgzPHRhS1ETH7PnJR_dIx6lxgr1qHpCkMTgzUxvGjhI,7586
|
|
143
|
-
shotgun_sh-0.2.1.
|
|
144
|
-
shotgun_sh-0.2.1.
|
|
145
|
-
shotgun_sh-0.2.1.
|
|
146
|
-
shotgun_sh-0.2.1.
|
|
147
|
-
shotgun_sh-0.2.1.
|
|
143
|
+
shotgun_sh-0.2.1.dev3.dist-info/METADATA,sha256=f_1fWjFpf7SbFyTIidsUTAgsu4wQSTn2QrH_3fE9ibA,11226
|
|
144
|
+
shotgun_sh-0.2.1.dev3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
145
|
+
shotgun_sh-0.2.1.dev3.dist-info/entry_points.txt,sha256=asZxLU4QILneq0MWW10saVCZc4VWhZfb0wFZvERnzfA,45
|
|
146
|
+
shotgun_sh-0.2.1.dev3.dist-info/licenses/LICENSE,sha256=YebsZl590zCHrF_acCU5pmNt0pnAfD2DmAnevJPB1tY,1065
|
|
147
|
+
shotgun_sh-0.2.1.dev3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|