Bump max-tool-rounds 8→100; guard against malformed tool args JSON

ober

c9e9560476392d931895b20fb18a6e01af0dd4b5

diff --git a/lib/jcode/core/agent.sls b/lib/jcode/core/agent.sls
index 461acd7..6596110 100644
--- a/lib/jcode/core/agent.sls
+++ b/lib/jcode/core/agent.sls
@@ -37,7 +37,7 @@
   (def current-stream-cb (make-parameter #f))
   (def current-tool-cb (make-parameter #f))
   (def current-usage-cb (make-parameter #f))
-  (def *max-tool-rounds* 8)
+  (def *max-tool-rounds* 100)
   (def *prune-protect-chars* 16000)
   (def *tool-result-stub* "[Old tool result cleared]")
   (def (refresh-system-prompt messages)
@@ -206,16 +206,36 @@
              (map thread-join! threads))))
   (def (execute-single-tool tc)
        (let* ([name (tool-call-name tc)]
-              [args (string->json-object (tool-call-arguments tc))]
+              [raw-args (tool-call-arguments tc)]
+              [args (guard (e [list #t #f])
+                      (string->json-object raw-args))]
               [cb (current-tool-cb)])
-         (when cb (cb 'start name args))
-         (let ([result (tool-execute name args)])
-           (log-debug
-             logger
-             "tool-result"
-             `((tool . ,name) (result-length . ,(string-length result))))
-           (when cb (cb 'end name args))
-           (make-tool-result (tool-call-id tc) result))))
+         (if (not args)
+             (begin
+               (log-error
+                 logger
+                 "tool-args-parse-failed"
+                 `((tool . ,name)
+                    (raw-args
+                      .
+                      ,(if (> (string-length raw-args) 200)
+                           (substring raw-args 0 200)
+                           raw-args))))
+               (make-tool-result
+                 (tool-call-id tc)
+                 (format
+                   "Error: malformed tool arguments JSON — ~a"
+                   raw-args)))
+             (begin
+               (when cb (cb 'start name args))
+               (let ([result (tool-execute name args)])
+                 (log-debug
+                   logger
+                   "tool-result"
+                   `((tool . ,name)
+                      (result-length . ,(string-length result))))
+                 (when cb (cb 'end name args))
+                 (make-tool-result (tool-call-id tc) result))))))
   (def (get-current-provider)
        (let* ([provider-name (or (current-provider-override)
                                  (config-provider))]
diff --git a/src/jcode/core/agent.ss b/src/jcode/core/agent.ss
index d56e237..0a349c2 100644
--- a/src/jcode/core/agent.ss
+++ b/src/jcode/core/agent.ss
@@ -66,7 +66,7 @@ Prefer using the edit tool over write for modifying existing files."
 (def current-tool-cb (make-parameter #f))
 (def current-usage-cb (make-parameter #f))
 
-(def *max-tool-rounds* 8)
+(def *max-tool-rounds* 100)
 (def *prune-protect-chars* 16000)  ;; ~4k tokens of recent tool results to keep
 (def *tool-result-stub* "[Old tool result cleared]")
 
@@ -196,13 +196,25 @@ Prefer using the edit tool over write for modifying existing files."
 
 (def (execute-single-tool tc)
   (let* ((name (tool-call-name tc))
-         (args (string->json-object (tool-call-arguments tc)))
+         (raw-args (tool-call-arguments tc))
+         (args (guard (e [#t #f])
+                 (string->json-object raw-args)))
          (cb (current-tool-cb)))
-    (when cb (cb 'start name args))
-    (let ((result (tool-execute name args)))
-      (log-debug logger "tool-result" `((tool . ,name) (result-length . ,(string-length result))))
-      (when cb (cb 'end name args))
-      (make-tool-result (tool-call-id tc) result))))
+    (if (not args)
+      (begin
+        (log-error logger "tool-args-parse-failed"
+          `((tool . ,name)
+            (raw-args . ,(if (> (string-length raw-args) 200)
+                           (substring raw-args 0 200)
+                           raw-args))))
+        (make-tool-result (tool-call-id tc)
+          (format "Error: malformed tool arguments JSON — ~a" raw-args)))
+      (begin
+        (when cb (cb 'start name args))
+        (let ((result (tool-execute name args)))
+          (log-debug logger "tool-result" `((tool . ,name) (result-length . ,(string-length result))))
+          (when cb (cb 'end name args))
+          (make-tool-result (tool-call-id tc) result))))))
 
 (def (get-current-provider)
   (let* ((provider-name (or (current-provider-override) (config-provider)))