nimcode 0.3.3__tar.gz → 0.3.4__tar.gz

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.
Files changed (39) hide show
  1. {nimcode-0.3.3 → nimcode-0.3.4}/PKG-INFO +1 -1
  2. {nimcode-0.3.3 → nimcode-0.3.4}/README.md +14 -0
  3. {nimcode-0.3.3 → nimcode-0.3.4}/setup.py +1 -1
  4. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/agent.py +13 -4
  5. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/config.py +6 -1
  6. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/nim_client.py +5 -4
  7. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/tools.py +10 -3
  8. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/updater.py +6 -1
  9. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode.egg-info/PKG-INFO +1 -1
  10. {nimcode-0.3.3 → nimcode-0.3.4}/setup.cfg +0 -0
  11. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/__init__.py +0 -0
  12. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/cli.py +0 -0
  13. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/lenient_parser.py +0 -0
  14. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/mcp_client.py +0 -0
  15. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/memory.py +0 -0
  16. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/permissions.py +0 -0
  17. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/plugin_manager.py +0 -0
  18. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/rag.py +0 -0
  19. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/repl.py +0 -0
  20. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode/watcher.py +0 -0
  21. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode.egg-info/SOURCES.txt +0 -0
  22. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode.egg-info/dependency_links.txt +0 -0
  23. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode.egg-info/entry_points.txt +0 -0
  24. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode.egg-info/requires.txt +0 -0
  25. {nimcode-0.3.3 → nimcode-0.3.4}/src/nimcode.egg-info/top_level.txt +0 -0
  26. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_agent.py +0 -0
  27. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_cli.py +0 -0
  28. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_config.py +0 -0
  29. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_lenient_parser.py +0 -0
  30. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_mcp_client.py +0 -0
  31. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_memory.py +0 -0
  32. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_nim_client.py +0 -0
  33. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_permissions.py +0 -0
  34. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_plugin_manager.py +0 -0
  35. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_repl.py +0 -0
  36. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_repl_extra.py +0 -0
  37. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_repl_trust.py +0 -0
  38. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_tools.py +0 -0
  39. {nimcode-0.3.3 → nimcode-0.3.4}/tests/test_updater.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nimcode
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: A standalone, robust coding agent for NVIDIA NIM models.
5
5
  Author: Autonomous Agent
6
6
  Requires-Dist: httpx>=0.27.0
@@ -121,6 +121,20 @@ NimCode creates a `.nimcode` directory inside your projects. This directory acts
121
121
  - `.nimcode/skills/`: Any custom guidelines, framework rules, or memories you teach the agent.
122
122
  - `.nimcode/history/`: File backups for `/undo` capabilities.
123
123
 
124
+ ### Advanced Configuration (Timeouts)
125
+
126
+ NimCode's limits and timeouts can be customized through the `.nimcode/settings.json` file. Setting any timeout to `0` will completely disable it (infinite timeout).
127
+
128
+ ```json
129
+ {
130
+ "timeout_command": 1200, // Max time for bash commands (in seconds)
131
+ "timeout_llm": 120, // Max time for LLM API responses (in seconds)
132
+ "timeout_format": 10, // Max time for auto-formatters like black/prettier
133
+ "timeout_browser": 15000, // Max time for browser operations (in milliseconds)
134
+ "timeout_updater": 3 // Max time for update checks
135
+ }
136
+ ```
137
+
124
138
  ## 🛡️ Requirements
125
139
 
126
140
  - Python 3.8+
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="nimcode",
5
- version="0.3.3",
5
+ version="0.3.4",
6
6
  packages=find_packages(where="src"),
7
7
  package_dir={"": "src"},
8
8
  install_requires=[
@@ -53,7 +53,12 @@ class Agent:
53
53
  self.settings = load_settings()
54
54
  self.model = model or self.settings.get("model", "meta/llama-3.1-70b-instruct")
55
55
  api_base_url = self.settings.get("api_base_url", "https://integrate.api.nvidia.com/v1")
56
- self.client = NimClient(api_key=api_key, base_url=api_base_url, model=self.model)
56
+ self.client = NimClient(
57
+ api_key=api_key,
58
+ base_url=api_base_url,
59
+ model=self.model,
60
+ timeout=self.settings.get("timeout_llm", 120.0)
61
+ )
57
62
 
58
63
  # Initialize MCP Manager
59
64
  self.mcp = MCPManager(self.settings)
@@ -338,8 +343,10 @@ class Agent:
338
343
  if file_path.endswith(".py"):
339
344
  import subprocess
340
345
  try:
341
- subprocess.run(["black", "-q", file_path], capture_output=True, timeout=10)
342
- lint = subprocess.run(["flake8", "--select=E9,F821,F822,F823", file_path], capture_output=True, text=True, timeout=10)
346
+ t_fmt = self.settings.get("timeout_format", 10)
347
+ t_fmt = None if t_fmt == 0 else t_fmt
348
+ subprocess.run(["black", "-q", file_path], capture_output=True, timeout=t_fmt)
349
+ lint = subprocess.run(["flake8", "--select=E9,F821,F822,F823", file_path], capture_output=True, text=True, timeout=t_fmt)
343
350
  if lint.returncode != 0:
344
351
  import sys
345
352
  if sys.stdin.isatty():
@@ -357,7 +364,9 @@ class Agent:
357
364
  elif file_path.endswith((".js", ".ts", ".jsx", ".tsx")):
358
365
  import subprocess
359
366
  try:
360
- subprocess.run(["npx", "--yes", "prettier", "--write", file_path], capture_output=True, timeout=10)
367
+ t_fmt = self.settings.get("timeout_format", 10)
368
+ t_fmt = None if t_fmt == 0 else t_fmt
369
+ subprocess.run(["npx", "--yes", "prettier", "--write", file_path], capture_output=True, timeout=t_fmt)
361
370
  except Exception:
362
371
  pass
363
372
  except KeyboardInterrupt:
@@ -10,7 +10,12 @@ def load_settings() -> Dict[str, Any]:
10
10
  settings = {
11
11
  "model": "meta/llama-3.1-70b-instruct",
12
12
  "api_base_url": "https://integrate.api.nvidia.com/v1",
13
- "mcp_servers": {}
13
+ "mcp_servers": {},
14
+ "timeout_command": 1200, # Timeout for bash commands (seconds)
15
+ "timeout_llm": 120, # Timeout for LLM API calls (seconds)
16
+ "timeout_format": 10, # Timeout for formatting/linting tools (seconds)
17
+ "timeout_browser": 15000, # Timeout for browser actions (milliseconds)
18
+ "timeout_updater": 3 # Timeout for update checks (seconds)
14
19
  }
15
20
 
16
21
  # Global settings
@@ -8,10 +8,11 @@ from typing import List, Dict, Any, Optional, AsyncGenerator
8
8
  logger = logging.getLogger(__name__)
9
9
 
10
10
  class NimClient:
11
- def __init__(self, api_key: str, base_url: str = "https://integrate.api.nvidia.com/v1", model: str = "meta/llama-3.1-70b-instruct"):
11
+ def __init__(self, api_key: str, base_url: str = "https://integrate.api.nvidia.com/v1", model: str = "meta/llama-3.1-70b-instruct", timeout: float = 120.0):
12
12
  self.api_key = api_key
13
13
  self.base_url = base_url.rstrip("/")
14
14
  self.model = model
15
+ self.timeout = None if timeout == 0 else timeout
15
16
  self.headers = {
16
17
  "Authorization": f"Bearer {self.api_key}",
17
18
  "Content-Type": "application/json",
@@ -39,7 +40,7 @@ class NimClient:
39
40
  f"{self.base_url}/chat/completions",
40
41
  headers=self.headers,
41
42
  json=payload,
42
- timeout=60.0
43
+ timeout=self.timeout
43
44
  )
44
45
  response.raise_for_status()
45
46
  data = response.json()
@@ -70,7 +71,7 @@ class NimClient:
70
71
  f"{self.base_url}/chat/completions",
71
72
  headers=self.headers,
72
73
  json=payload,
73
- timeout=60.0
74
+ timeout=self.timeout
74
75
  )
75
76
  response.raise_for_status()
76
77
  data = response.json()
@@ -98,7 +99,7 @@ class NimClient:
98
99
  chunk_yielded = False
99
100
  try:
100
101
  async with httpx.AsyncClient() as client:
101
- async with client.stream("POST", f"{self.base_url}/chat/completions", headers=self.headers, json=payload, timeout=120.0) as response:
102
+ async with client.stream("POST", f"{self.base_url}/chat/completions", headers=self.headers, json=payload, timeout=self.timeout) as response:
102
103
  if response.status_code in [408, 429, 500, 502, 503, 504, 529]:
103
104
  raise httpx.HTTPStatusError(f"Temporary server error {response.status_code}", request=response.request, response=response)
104
105
 
@@ -239,6 +239,8 @@ class ToolRegistry:
239
239
  return f"Started task '{task_id}' in the background. Check logs at {log_file}. Use /tasks to manage."
240
240
 
241
241
  try:
242
+ t_cmd = settings.get("timeout_command", 1200)
243
+ t_cmd = None if t_cmd == 0 else t_cmd
242
244
  result = subprocess.run(
243
245
  command,
244
246
  shell=True,
@@ -246,7 +248,7 @@ class ToolRegistry:
246
248
  stdout=subprocess.PIPE,
247
249
  stderr=subprocess.PIPE,
248
250
  text=True,
249
- timeout=1200
251
+ timeout=t_cmd
250
252
  )
251
253
  out = result.stdout + "\n" + result.stderr
252
254
  out = out.strip()
@@ -257,7 +259,7 @@ class ToolRegistry:
257
259
 
258
260
  return out if out else "Command executed successfully with no output."
259
261
  except subprocess.TimeoutExpired:
260
- return "Error: Command timed out after 1200 seconds."
262
+ return f"Error: Command timed out after {t_cmd} seconds."
261
263
  except Exception as e:
262
264
  return f"Error running bash: {e}"
263
265
 
@@ -565,11 +567,16 @@ class ToolRegistry:
565
567
  try:
566
568
  from playwright.sync_api import sync_playwright
567
569
  import base64
570
+ from .config import load_settings
571
+
572
+ settings = load_settings()
573
+ t_browser = settings.get("timeout_browser", 15000)
574
+ t_browser = 0 if t_browser == 0 else t_browser
568
575
 
569
576
  with sync_playwright() as p:
570
577
  browser = p.chromium.launch(headless=True)
571
578
  page = browser.new_page()
572
- page.goto(url, wait_until="networkidle", timeout=15000)
579
+ page.goto(url, wait_until="networkidle", timeout=t_browser)
573
580
 
574
581
  screenshot_bytes = page.screenshot(type="jpeg", quality=50)
575
582
  b64_img = base64.b64encode(screenshot_bytes).decode('utf-8')
@@ -13,7 +13,12 @@ class AutoUpdater:
13
13
  Returns the latest version string if > CURRENT_VERSION, else None.
14
14
  """
15
15
  try:
16
- async with httpx.AsyncClient(timeout=3.0) as client:
16
+ from .config import load_settings
17
+ settings = load_settings()
18
+ t_upd = settings.get("timeout_updater", 3.0)
19
+ t_upd = None if t_upd == 0 else t_upd
20
+
21
+ async with httpx.AsyncClient(timeout=t_upd) as client:
17
22
  response = await client.get("https://pypi.org/pypi/nimcode/json")
18
23
  if response.status_code == 200:
19
24
  data = response.json()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nimcode
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: A standalone, robust coding agent for NVIDIA NIM models.
5
5
  Author: Autonomous Agent
6
6
  Requires-Dist: httpx>=0.27.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes