tunacode-cli 0.1.21__py3-none-any.whl → 0.1.24__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 tunacode-cli might be problematic. Click here for more details.

tunacode/constants.py CHANGED
@@ -11,7 +11,7 @@ KB = 1024
11
11
  MB = KB * 1024
12
12
 
13
13
  APP_NAME = "TunaCode"
14
- APP_VERSION = "0.1.21"
14
+ APP_VERSION = "0.1.24"
15
15
 
16
16
 
17
17
  GUIDE_FILE_NAME = "AGENTS.md"
@@ -15,6 +15,7 @@ from pydantic_ai.providers.openai import OpenAIProvider
15
15
  from pydantic_ai.retries import AsyncTenacityTransport, RetryConfig, wait_retry_after
16
16
  from tenacity import retry_if_exception_type, stop_after_attempt
17
17
 
18
+ from tunacode.configuration.models import load_models_registry
18
19
  from tunacode.constants import ENV_OPENAI_BASE_URL, SETTINGS_BASE_URL, UI_THINKING_MESSAGE
19
20
  from tunacode.core.agents.delegation_tools import create_research_codebase_tool
20
21
  from tunacode.core.prompting import (
@@ -265,6 +266,22 @@ def load_tunacode_context() -> str:
265
266
  return ""
266
267
 
267
268
 
269
+ def _get_provider_config_from_registry(provider_name: str) -> dict:
270
+ """Get provider config from models registry.
271
+
272
+ Returns dict with 'api' (base_url) and 'env' (list of env var names).
273
+ Returns empty dict if provider not found.
274
+ """
275
+ registry = load_models_registry()
276
+ provider_data = registry.get(provider_name, {})
277
+ return {
278
+ "api": provider_data.get("api"),
279
+ "env": provider_data.get("env", []),
280
+ }
281
+
282
+
283
+
284
+
268
285
  def _create_model_with_retry(
269
286
  model_string: str, http_client: AsyncClient, state_manager: StateManager
270
287
  ):
@@ -272,69 +289,51 @@ def _create_model_with_retry(
272
289
 
273
290
  Parses model string in format 'provider:model_name' and creates
274
291
  appropriate provider and model instances with the retry-enabled HTTP client.
292
+
293
+ Uses models_registry.json for provider configuration (api URL, env vars).
294
+ Only 'anthropic' provider uses AnthropicModel, all others use OpenAI.
275
295
  """
276
- # Extract environment config
277
296
  env = state_manager.session.user_config.get("env", {})
278
-
279
297
  settings = state_manager.session.user_config.get("settings", {})
298
+
299
+ # User overrides for base_url
280
300
  env_base_url_raw = env.get(ENV_OPENAI_BASE_URL)
281
301
  settings_base_url_raw = settings.get(SETTINGS_BASE_URL)
282
302
  env_base_url = _coerce_optional_str(env_base_url_raw, ENV_OPENAI_BASE_URL)
283
303
  settings_base_url = _coerce_optional_str(settings_base_url_raw, SETTINGS_BASE_URL)
284
304
  base_url_override = _resolve_base_url_override(env_base_url, settings_base_url)
285
305
 
286
- # Provider configuration: API key names and base URLs
287
- PROVIDER_CONFIG = {
288
- "anthropic": {"api_key_name": "ANTHROPIC_API_KEY", "base_url": None},
289
- "openai": {"api_key_name": "OPENAI_API_KEY", "base_url": None},
290
- "openrouter": {
291
- "api_key_name": "OPENROUTER_API_KEY",
292
- "base_url": "https://openrouter.ai/api/v1",
293
- },
294
- "azure": {
295
- "api_key_name": "AZURE_OPENAI_API_KEY",
296
- "base_url": env.get("AZURE_OPENAI_ENDPOINT"),
297
- },
298
- "deepseek": {"api_key_name": "DEEPSEEK_API_KEY", "base_url": None},
299
- "cerebras": {
300
- "api_key_name": "CEREBRAS_API_KEY",
301
- "base_url": "https://api.cerebras.ai/v1",
302
- },
303
- }
304
-
305
306
  # Parse model string
306
307
  if ":" in model_string:
307
308
  provider_name, model_name = model_string.split(":", 1)
308
309
  else:
309
- # Auto-detect provider from model name
310
310
  model_name = model_string
311
311
  if model_name.startswith("claude"):
312
312
  provider_name = "anthropic"
313
313
  elif model_name.startswith(("gpt", "o1", "o3")):
314
314
  provider_name = "openai"
315
315
  else:
316
- # Default to treating as model string (pydantic-ai will auto-detect)
317
316
  return model_string
318
317
 
319
- # Create provider with api_key + base_url + http_client
318
+ # Get config from registry
319
+ registry_config = _get_provider_config_from_registry(provider_name)
320
+ api_url = registry_config.get("api")
321
+ env_vars = registry_config.get("env", [])
322
+ api_key_name = env_vars[0] if env_vars else f"{provider_name.upper()}_API_KEY"
323
+
324
+ # Use user override if set, otherwise registry URL
325
+ base_url = base_url_override if base_url_override else api_url
326
+
327
+ # Get API key
328
+ api_key = env.get(api_key_name)
329
+
330
+ # Only anthropic provider uses AnthropicModel, all others use OpenAI
320
331
  if provider_name == "anthropic":
321
- api_key = env.get("ANTHROPIC_API_KEY")
322
- provider = AnthropicProvider(api_key=api_key, http_client=http_client)
332
+ provider = AnthropicProvider(api_key=api_key, base_url=base_url, http_client=http_client)
323
333
  return AnthropicModel(model_name, provider=provider)
324
- elif provider_name in ("openai", "openrouter", "azure", "deepseek", "cerebras"):
325
- # OpenAI-compatible providers all use OpenAIChatModel
326
- config = PROVIDER_CONFIG.get(provider_name, {})
327
- api_key_name = config.get("api_key_name")
328
- api_key = env.get(api_key_name) if api_key_name else None
329
- base_url = config.get("base_url")
330
- if base_url is None and provider_name != "azure":
331
- base_url = base_url_override
334
+ else:
332
335
  provider = OpenAIProvider(api_key=api_key, base_url=base_url, http_client=http_client)
333
336
  return OpenAIChatModel(model_name, provider=provider)
334
- else:
335
- # Unsupported provider, return string and let pydantic-ai handle it
336
- # (won't have retry support but won't break)
337
- return model_string
338
337
 
339
338
 
340
339
  def get_or_create_agent(model: ModelName, state_manager: StateManager) -> PydanticAgent:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tunacode-cli
3
- Version: 0.1.21
3
+ Version: 0.1.24
4
4
  Summary: Your agentic CLI developer.
5
5
  Project-URL: Homepage, https://tunacode.xyz/
6
6
  Project-URL: Repository, https://github.com/alchemiststudiosDOTai/tunacode
@@ -1,12 +1,12 @@
1
1
  tunacode/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- tunacode/constants.py,sha256=BoRbr8KF6D0LJYEVFFNRJHAQbMipCWi3DuIJ6UQhtTg,6221
2
+ tunacode/constants.py,sha256=HCO7azR502kN1Ku4SgbMxb4eu0b-pWlVn0zCJddC3j0,6221
3
3
  tunacode/exceptions.py,sha256=9QgK4pc57lzjsJ4vaSWYB9ruOUMFtJcK6A5y7DTi4ik,10011
4
4
  tunacode/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  tunacode/cli/textual_repl.tcss,sha256=Zi4Bo8YVv8nWYemOrf_zPIjBovA-CfHoncZqjS7fPrI,6095
6
6
  tunacode/configuration/__init__.py,sha256=MbVXy8bGu0yKehzgdgZ_mfWlYGvIdb1dY2Ly75nfuPE,17
7
7
  tunacode/configuration/defaults.py,sha256=uI8w4lGz8Sh9ZeYuvSnSb_TNmy3AZuzX_s9vf-cnqeg,1644
8
8
  tunacode/configuration/models.py,sha256=uk-fRhS6wezlhy7chT3IQareNqV0T_humtxPzLadAq8,4222
9
- tunacode/configuration/models_registry.json,sha256=P-ZmwLf2EFc8-pz65KUlkVxquhV433pl9r3fZj6WK40,848632
9
+ tunacode/configuration/models_registry.json,sha256=Na-uddJEAYbRyGM8sQM_xW6XmZKWurLTCvYNwtBNnrg,861521
10
10
  tunacode/configuration/pricing.py,sha256=lsmDRcL-cLR1SEURsUyJfhqOMh_MQRV2aRBsAF-_LEE,2252
11
11
  tunacode/configuration/settings.py,sha256=2Au6U9DusgVSBCPP0i5B5sXtVRC5SeApXkze713gtFY,1026
12
12
  tunacode/core/__init__.py,sha256=X_qrgtH_2D3d7XyTFQHAL74uOu3Ud8uynt1ikYKCIi4,167
@@ -18,7 +18,7 @@ tunacode/core/agents/main.py,sha256=WRdv5BuTyUm4u1UDGQWRbQeIrfHlXqOIKDhyMSj8ubU,
18
18
  tunacode/core/agents/prompts.py,sha256=Eps3qQm8zdgPnyYOvRYwINMGVa71ttuqGlgtH17-3ag,2357
19
19
  tunacode/core/agents/research_agent.py,sha256=7vno4jVUCvZV5nqI_VCg74Ooi6chj3w1_2CQQayrUZw,8395
20
20
  tunacode/core/agents/agent_components/__init__.py,sha256=FDw5nF_t6RmVwkY99e3Jopgc9OyRGLuJkuLA2JQhSTg,1461
21
- tunacode/core/agents/agent_components/agent_config.py,sha256=g_zAmj-5aEoIqjIFdGFVA7AQ7dXGGx_QUmy10tu-iPI,17038
21
+ tunacode/core/agents/agent_components/agent_config.py,sha256=iavdeNXQxEyulVtZzDNArAzB2xV40VPtlgZaQprWkOA,16661
22
22
  tunacode/core/agents/agent_components/agent_helpers.py,sha256=KVD9VgUwI2L6fWRlAP9_RuDgdF6XZKCZpRXsUXFCa3A,10500
23
23
  tunacode/core/agents/agent_components/message_handler.py,sha256=RswLyhtA2Zx7XxtbdqZGXsNSDMPw9FPJwXxgdaPqPXI,3624
24
24
  tunacode/core/agents/agent_components/node_processor.py,sha256=lik0iSjRNbOILpb3y6mbtHas3MMBD4ln_TznwBO9VpQ,18597
@@ -167,8 +167,8 @@ tunacode/utils/system/paths.py,sha256=NqrVZAtiuayLjkHpOXHhoFK3tvlCaCcaoYGG_kjkbk
167
167
  tunacode/utils/ui/__init__.py,sha256=3weQWW9YYZDhZz-f6wM_ekhJiIjQcMigXeAZAqiiIAM,208
168
168
  tunacode/utils/ui/file_filter.py,sha256=048k1WmufkzKKSOSxT519_j9dcTBxS1yv-Qr4nkbZWM,3972
169
169
  tunacode/utils/ui/helpers.py,sha256=ec5WYbhx-P6Zh47LL6ltyaHPJK9abA5UsWFmY5CF2pA,615
170
- tunacode_cli-0.1.21.dist-info/METADATA,sha256=XuHZ1nMveMt2_YbjjbMVktLvXOZmoUbbG725GQbeHpI,5604
171
- tunacode_cli-0.1.21.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
172
- tunacode_cli-0.1.21.dist-info/entry_points.txt,sha256=pBNNa1Ikbt8pXk39eaj78hUIGx6noRGkOvpWuJ58szQ,50
173
- tunacode_cli-0.1.21.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
174
- tunacode_cli-0.1.21.dist-info/RECORD,,
170
+ tunacode_cli-0.1.24.dist-info/METADATA,sha256=oFM3qoGeeCilkWcMyW1-b1ZiZrnzzrk9ObZjr_8BpWk,5604
171
+ tunacode_cli-0.1.24.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
172
+ tunacode_cli-0.1.24.dist-info/entry_points.txt,sha256=pBNNa1Ikbt8pXk39eaj78hUIGx6noRGkOvpWuJ58szQ,50
173
+ tunacode_cli-0.1.24.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
174
+ tunacode_cli-0.1.24.dist-info/RECORD,,