nanocode-cli 0.2.4__tar.gz → 0.2.6__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.
- {nanocode_cli-0.2.4/nanocode_cli.egg-info → nanocode_cli-0.2.6}/PKG-INFO +1 -1
- {nanocode_cli-0.2.4 → nanocode_cli-0.2.6}/nanocode.py +15 -26
- {nanocode_cli-0.2.4 → nanocode_cli-0.2.6/nanocode_cli.egg-info}/PKG-INFO +1 -1
- {nanocode_cli-0.2.4 → nanocode_cli-0.2.6}/pyproject.toml +1 -1
- {nanocode_cli-0.2.4 → nanocode_cli-0.2.6}/LICENSE +0 -0
- {nanocode_cli-0.2.4 → nanocode_cli-0.2.6}/MANIFEST.in +0 -0
- {nanocode_cli-0.2.4 → nanocode_cli-0.2.6}/README.md +0 -0
- {nanocode_cli-0.2.4 → nanocode_cli-0.2.6}/nanocode_cli.egg-info/SOURCES.txt +0 -0
- {nanocode_cli-0.2.4 → nanocode_cli-0.2.6}/nanocode_cli.egg-info/dependency_links.txt +0 -0
- {nanocode_cli-0.2.4 → nanocode_cli-0.2.6}/nanocode_cli.egg-info/entry_points.txt +0 -0
- {nanocode_cli-0.2.4 → nanocode_cli-0.2.6}/nanocode_cli.egg-info/requires.txt +0 -0
- {nanocode_cli-0.2.4 → nanocode_cli-0.2.6}/nanocode_cli.egg-info/top_level.txt +0 -0
- {nanocode_cli-0.2.4 → nanocode_cli-0.2.6}/setup.cfg +0 -0
|
@@ -41,7 +41,7 @@ from prompt_toolkit.patch_stdout import patch_stdout
|
|
|
41
41
|
|
|
42
42
|
JsonValue: TypeAlias = Any
|
|
43
43
|
Json: TypeAlias = dict[str, JsonValue]
|
|
44
|
-
__version__ = "0.2.
|
|
44
|
+
__version__ = "0.2.6"
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
class Error(Exception): ...
|
|
@@ -820,6 +820,7 @@ class SearchTool(Tool):
|
|
|
820
820
|
return [
|
|
821
821
|
"Search files or directories before Read; default is fixed text.",
|
|
822
822
|
"Prefix pattern with re: for regex search.",
|
|
823
|
+
"Search is line-oriented; regex patterns must not contain newlines.",
|
|
823
824
|
"Use A|B|C for literal OR search in fixed mode.",
|
|
824
825
|
"Optional context=N or N sets nearby context lines.",
|
|
825
826
|
"Optional glob matches file basename or path relative to cwd.",
|
|
@@ -827,7 +828,7 @@ class SearchTool(Tool):
|
|
|
827
828
|
|
|
828
829
|
@classmethod
|
|
829
830
|
def signature(cls) -> str:
|
|
830
|
-
return "Search(pattern, path[,
|
|
831
|
+
return "Search(pattern, path[, option...]) -> SearchToolResult<matches>; option is context=N|N or glob_pattern"
|
|
831
832
|
|
|
832
833
|
@classmethod
|
|
833
834
|
def example(cls) -> list[str]:
|
|
@@ -850,6 +851,8 @@ class SearchTool(Tool):
|
|
|
850
851
|
pattern = raw_pattern[3:] if regex else raw_pattern
|
|
851
852
|
if not pattern:
|
|
852
853
|
raise ToolCallError("pattern cannot be empty")
|
|
854
|
+
if regex and "\n" in pattern:
|
|
855
|
+
raise ToolCallError("multiline regex is not supported; Search is line-oriented. Search each line separately or Read a nearby range.")
|
|
853
856
|
glob_pattern = ""
|
|
854
857
|
context_lines = cls.CONTEXT_LINES
|
|
855
858
|
for raw_option in args[2:]:
|
|
@@ -1734,8 +1737,10 @@ Input:
|
|
|
1734
1737
|
- Latest_User_Input: latest user message
|
|
1735
1738
|
- Tools: available tool specs
|
|
1736
1739
|
|
|
1737
|
-
Output
|
|
1738
|
-
|
|
1740
|
+
Output MUST be exactly one JSON object.
|
|
1741
|
+
No markdown, prose, code fences, XML tags, native tool calls, or text outside JSON.
|
|
1742
|
+
Put normal replies in message_to_user.
|
|
1743
|
+
Put tool calls only in JSON tool_calls.
|
|
1739
1744
|
|
|
1740
1745
|
Schema:
|
|
1741
1746
|
{
|
|
@@ -1966,6 +1971,7 @@ class ModelClient:
|
|
|
1966
1971
|
"model": self.session.model,
|
|
1967
1972
|
"messages": messages,
|
|
1968
1973
|
"temperature": self.session.temperature,
|
|
1974
|
+
"response_format": {"type": "json_object"},
|
|
1969
1975
|
}
|
|
1970
1976
|
extra_params = self._reasoning_params()
|
|
1971
1977
|
payload.update(extra_params)
|
|
@@ -2675,7 +2681,6 @@ class ConversationCompactor:
|
|
|
2675
2681
|
@final
|
|
2676
2682
|
class Agent:
|
|
2677
2683
|
MAX_CONSECUTIVE_FORMAT_ERRORS: ClassVar[int] = 3
|
|
2678
|
-
MAX_CONSECUTIVE_SUMMARY_GATES: ClassVar[int] = 1
|
|
2679
2684
|
|
|
2680
2685
|
def __init__(self, session: Session):
|
|
2681
2686
|
self.session = session
|
|
@@ -2725,7 +2730,6 @@ class Agent:
|
|
|
2725
2730
|
self.maybe_auto_compact()
|
|
2726
2731
|
self.session.append_conversation(UserMessage(content=user_input))
|
|
2727
2732
|
consecutive_format_errors = 0
|
|
2728
|
-
consecutive_summary_gates = 0
|
|
2729
2733
|
|
|
2730
2734
|
for _ in range(self.session.max_agent_steps):
|
|
2731
2735
|
response = self.step()
|
|
@@ -2758,25 +2762,6 @@ class Agent:
|
|
|
2758
2762
|
continue
|
|
2759
2763
|
consecutive_format_errors = 0
|
|
2760
2764
|
tool_calls = _json_list(response.get("tool_calls"))
|
|
2761
|
-
summary_gate = self._format_tool_summary_gate(tool_calls)
|
|
2762
|
-
if summary_gate:
|
|
2763
|
-
consecutive_summary_gates += 1
|
|
2764
|
-
if consecutive_summary_gates <= self.MAX_CONSECUTIVE_SUMMARY_GATES:
|
|
2765
|
-
self.state_updater.latest_report = ""
|
|
2766
|
-
self.latest_agent_feedback = summary_gate
|
|
2767
|
-
self._report_gate(
|
|
2768
|
-
on_message,
|
|
2769
|
-
"Retrying: model needs to summarize the latest tool results.",
|
|
2770
|
-
self._compact_gate_report(summary_gate),
|
|
2771
|
-
)
|
|
2772
|
-
continue
|
|
2773
|
-
self._report_gate(
|
|
2774
|
-
on_message,
|
|
2775
|
-
"Continuing: model did not summarize tool results after one retry.",
|
|
2776
|
-
"Tool_Summary_Gate: allowing continuation after one missing-summary retry.",
|
|
2777
|
-
)
|
|
2778
|
-
else:
|
|
2779
|
-
consecutive_summary_gates = 0
|
|
2780
2765
|
self.apply_response(response)
|
|
2781
2766
|
if on_message is not None and self.state_updater.latest_report:
|
|
2782
2767
|
on_message(self.state_updater.latest_report)
|
|
@@ -2828,7 +2813,11 @@ class Agent:
|
|
|
2828
2813
|
return headline
|
|
2829
2814
|
|
|
2830
2815
|
def step(self) -> Json:
|
|
2831
|
-
response = self.request(self.build_system_prompt(), self.build_user_prompt(), activity="main")
|
|
2816
|
+
response = self.request(self.build_system_prompt(), self.build_user_prompt(consume_latest_tool_results=False), activity="main")
|
|
2817
|
+
if _json_str(response.get("_format_error")):
|
|
2818
|
+
return response
|
|
2819
|
+
self.latest_tool_call_results = ""
|
|
2820
|
+
self.latest_agent_feedback = ""
|
|
2832
2821
|
self.state_updater.apply_tool_call_summaries(response)
|
|
2833
2822
|
return response
|
|
2834
2823
|
|
|
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
|