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
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.3"
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", "4096"))
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
- content = args.get("content", "")
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