nexcoder 0.1.1__tar.gz → 0.1.3__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 (45) hide show
  1. {nexcoder-0.1.1 → nexcoder-0.1.3}/PKG-INFO +1 -1
  2. {nexcoder-0.1.1 → nexcoder-0.1.3}/pyproject.toml +1 -1
  3. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/agent.py +13 -4
  4. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/cli.py +1 -0
  5. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/config.py +1 -1
  6. {nexcoder-0.1.1 → nexcoder-0.1.3}/.github/workflows/ci.yml +0 -0
  7. {nexcoder-0.1.1 → nexcoder-0.1.3}/.github/workflows/publish.yml +0 -0
  8. {nexcoder-0.1.1 → nexcoder-0.1.3}/.gitignore +0 -0
  9. {nexcoder-0.1.1 → nexcoder-0.1.3}/CHANGELOG.md +0 -0
  10. {nexcoder-0.1.1 → nexcoder-0.1.3}/LICENSE +0 -0
  11. {nexcoder-0.1.1 → nexcoder-0.1.3}/README.md +0 -0
  12. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/__init__.py +0 -0
  13. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/api_client.py +0 -0
  14. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/context.py +0 -0
  15. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/exceptions.py +0 -0
  16. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/indexer/__init__.py +0 -0
  17. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/indexer/index.py +0 -0
  18. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/indexer/parser.py +0 -0
  19. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/indexer/scanner.py +0 -0
  20. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/memory/__init__.py +0 -0
  21. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/memory/decisions.py +0 -0
  22. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/memory/errors.py +0 -0
  23. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/memory/project.py +0 -0
  24. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/planner.py +0 -0
  25. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/py.typed +0 -0
  26. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/reviewer.py +0 -0
  27. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/safety.py +0 -0
  28. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/test_runner.py +0 -0
  29. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/tools/__init__.py +0 -0
  30. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/tools/file_ops.py +0 -0
  31. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/tools/git_ops.py +0 -0
  32. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/tools/search.py +0 -0
  33. {nexcoder-0.1.1 → nexcoder-0.1.3}/src/nex/tools/shell.py +0 -0
  34. {nexcoder-0.1.1 → nexcoder-0.1.3}/tests/conftest.py +0 -0
  35. {nexcoder-0.1.1 → nexcoder-0.1.3}/tests/test_agent.py +0 -0
  36. {nexcoder-0.1.1 → nexcoder-0.1.3}/tests/test_chat.py +0 -0
  37. {nexcoder-0.1.1 → nexcoder-0.1.3}/tests/test_cli.py +0 -0
  38. {nexcoder-0.1.1 → nexcoder-0.1.3}/tests/test_context.py +0 -0
  39. {nexcoder-0.1.1 → nexcoder-0.1.3}/tests/test_errors.py +0 -0
  40. {nexcoder-0.1.1 → nexcoder-0.1.3}/tests/test_indexer.py +0 -0
  41. {nexcoder-0.1.1 → nexcoder-0.1.3}/tests/test_memory.py +0 -0
  42. {nexcoder-0.1.1 → nexcoder-0.1.3}/tests/test_rate_limiter.py +0 -0
  43. {nexcoder-0.1.1 → nexcoder-0.1.3}/tests/test_safety.py +0 -0
  44. {nexcoder-0.1.1 → nexcoder-0.1.3}/tests/test_test_runner.py +0 -0
  45. {nexcoder-0.1.1 → nexcoder-0.1.3}/tests/test_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nexcoder
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: The coding agent that remembers — AI coding assistant with persistent memory and error learning.
5
5
  Project-URL: Homepage, https://github.com/nex-ai/nex-ai
6
6
  Project-URL: Repository, https://github.com/nex-ai/nex-ai
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "nexcoder"
7
- version = "0.1.1"
7
+ version = "0.1.3"
8
8
  description = "The coding agent that remembers — AI coding assistant with persistent memory and error learning."
9
9
  readme = {file = "README.md", content-type = "text/markdown"}
10
10
  license = "MIT"
@@ -497,7 +497,7 @@ class Agent:
497
497
 
498
498
  # Update memory after each subtask
499
499
  await self._generate_memory_update(
500
- memory, subtask.description, sub_result, haiku_model
500
+ memory, subtask.description, sub_result, haiku_model, rate_limiter
501
501
  )
502
502
  memory.prune_section("Session Log")
503
503
  project_memory = memory.load()
@@ -659,6 +659,7 @@ class Agent:
659
659
  subtask_description: str,
660
660
  result: SubtaskResult,
661
661
  haiku_model: str,
662
+ rate_limiter: RateLimiter | None = None,
662
663
  ) -> None:
663
664
  """Summarize a completed subtask and append to Session Log.
664
665
 
@@ -670,6 +671,7 @@ class Agent:
670
671
  subtask_description: What the subtask was supposed to do.
671
672
  result: The subtask result with text, files, and iterations.
672
673
  haiku_model: Model ID for the summary call.
674
+ rate_limiter: Optional rate limiter to pace the API call.
673
675
  """
674
676
  truncated = result.text[:500]
675
677
  files_str = ", ".join(result.files_touched[:10]) or "none"
@@ -678,12 +680,20 @@ class Agent:
678
680
  )
679
681
 
680
682
  try:
683
+ if rate_limiter is not None:
684
+ estimated = ContextAssembler.estimate_tokens(user_msg)
685
+ await rate_limiter.wait_if_needed(estimated)
686
+
681
687
  response = await self._client.send_message(
682
688
  messages=[{"role": "user", "content": user_msg}],
683
689
  system=_MEMORY_SUMMARY_PROMPT,
684
690
  model=haiku_model,
685
691
  max_tokens=256,
686
692
  )
693
+
694
+ if rate_limiter is not None:
695
+ rate_limiter.record(response.input_tokens)
696
+
687
697
  summary = ""
688
698
  for block in response.content:
689
699
  if block.get("type") == "text":
@@ -693,9 +703,8 @@ class Agent:
693
703
  if summary:
694
704
  today = datetime.now(tz=UTC).strftime("%Y-%m-%d")
695
705
  memory.append("Session Log", f"- [{today}] {summary}")
696
- except Exception:
697
- # Memory updates are best-effort; never fail the main task
698
- pass
706
+ except Exception as exc:
707
+ console.print(f"[yellow]Memory update skipped:[/yellow] {exc}")
699
708
 
700
709
  def _generate_mid_subtask_memory_update(
701
710
  self,
@@ -59,6 +59,7 @@ _CONFIG_TEMPLATE = """\
59
59
  # model = "claude-sonnet-4-20250514"
60
60
  # max_iterations = 25
61
61
  # dry_run = false
62
+ token_rate_limit = 25000
62
63
  """
63
64
 
64
65
 
@@ -52,7 +52,7 @@ class NexConfig:
52
52
  nex_dir: Path = field(default_factory=lambda: Path(".nex"))
53
53
  test_command: str = ""
54
54
  test_timeout: int = 120
55
- token_rate_limit: int = 0
55
+ token_rate_limit: int = 25_000
56
56
  subtask_token_budget: int = 20_000
57
57
 
58
58
 
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes