wrencode 0.1.4.3__tar.gz → 0.1.4.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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wrencode
|
|
3
|
-
Version: 0.1.4.
|
|
3
|
+
Version: 0.1.4.4
|
|
4
4
|
Summary: A minimal agentic coding assistant in a single Python file
|
|
5
5
|
Project-URL: Homepage, https://github.com/almostly/wrencode
|
|
6
6
|
Project-URL: Repository, https://github.com/almostly/wrencode
|
|
@@ -74,7 +74,7 @@ for _dir in (os.path.dirname(os.path.abspath(__file__)), os.getcwd()):
|
|
|
74
74
|
# -----------------------------------------------------------------------------------------------
|
|
75
75
|
# Backend Configuration
|
|
76
76
|
# -----------------------------------------------------------------------------------------------
|
|
77
|
-
WRENCODE_VERSION = "0.1.4.
|
|
77
|
+
WRENCODE_VERSION = "0.1.4.4"
|
|
78
78
|
|
|
79
79
|
# Per-backend defaults. "kind" controls how a backend is treated:
|
|
80
80
|
# api - hosted HTTP API, needs an API key
|
|
@@ -222,7 +222,7 @@ def apply_backend(backend: str, model: str = "", api_key: str = "") -> None:
|
|
|
222
222
|
# -----------------------------------------------------------------------------------------------
|
|
223
223
|
# Constants & Environment Variables
|
|
224
224
|
# -----------------------------------------------------------------------------------------------
|
|
225
|
-
MAX_TOKENS = int(os.environ.get("MAX_TOKENS", "
|
|
225
|
+
MAX_TOKENS = int(os.environ.get("MAX_TOKENS", "8192"))
|
|
226
226
|
MAX_READ_BYTES = int(os.environ.get("MAX_READ_BYTES", str(4 * 1024 * 1024)))
|
|
227
227
|
MAX_READ_LINES = int(os.environ.get("MAX_READ_LINES", "800"))
|
|
228
228
|
GREP_MAX = int(os.environ.get("GREP_MAX_MATCHES", "80"))
|
|
@@ -600,7 +600,9 @@ def read(args: dict[str, Any]) -> str:
|
|
|
600
600
|
def write(args: dict[str, Any]) -> str:
|
|
601
601
|
"""Write content to a file, creating parent directories as needed."""
|
|
602
602
|
path = resolve_tool_path(_require_str(args, "path"))
|
|
603
|
-
|
|
603
|
+
if "content" not in args:
|
|
604
|
+
return "error: 'content' is required (model response may have been truncated; raise MAX_TOKENS)"
|
|
605
|
+
content = args["content"]
|
|
604
606
|
approval = confirm("write")
|
|
605
607
|
if approval != "ok":
|
|
606
608
|
return approval
|
|
@@ -1276,8 +1278,31 @@ def _openai_headers() -> dict[str, str]:
|
|
|
1276
1278
|
return {"Content-Type": "application/json", "Authorization": f"Bearer {API_KEY}"}
|
|
1277
1279
|
|
|
1278
1280
|
|
|
1281
|
+
def _warn_if_truncated(data: dict[str, Any]) -> None:
|
|
1282
|
+
"""Print a stderr warning if the API truncated the response at max_tokens.
|
|
1283
|
+
A truncated `tool_use` may be missing required fields (e.g. `content` for
|
|
1284
|
+
`write`), so callers need to know to raise MAX_TOKENS rather than silently
|
|
1285
|
+
treating an empty operation as success.
|
|
1286
|
+
"""
|
|
1287
|
+
if BACKEND == "anthropic":
|
|
1288
|
+
truncated = data.get("stop_reason") == "max_tokens"
|
|
1289
|
+
out_tokens = data.get("usage", {}).get("output_tokens")
|
|
1290
|
+
else:
|
|
1291
|
+
finish = (data.get("choices") or [{}])[0].get("finish_reason")
|
|
1292
|
+
truncated = finish == "length"
|
|
1293
|
+
out_tokens = data.get("usage", {}).get("completion_tokens")
|
|
1294
|
+
if truncated:
|
|
1295
|
+
print(
|
|
1296
|
+
f"{YELLOW}Warning: response truncated at MAX_TOKENS={MAX_TOKENS} "
|
|
1297
|
+
f"(output_tokens={out_tokens}). Tool calls may be incomplete — "
|
|
1298
|
+
f"raise MAX_TOKENS and retry.{RESET}",
|
|
1299
|
+
file=sys.stderr,
|
|
1300
|
+
)
|
|
1301
|
+
|
|
1302
|
+
|
|
1279
1303
|
def _parse_native_response(data: dict[str, Any]) -> tuple[str, list["ToolCall"]]:
|
|
1280
1304
|
"""Parse a native (Anthropic / OpenAI) API response into display text and tool calls."""
|
|
1305
|
+
_warn_if_truncated(data)
|
|
1281
1306
|
if BACKEND == "anthropic":
|
|
1282
1307
|
blocks = data.get("content", [])
|
|
1283
1308
|
text = "\n".join(b["text"] for b in blocks if b.get("type") == "text").strip()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|