@miller-tech/uap 1.20.16 → 1.20.17

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miller-tech/uap",
3
- "version": "1.20.16",
3
+ "version": "1.20.17",
4
4
  "description": "Autonomous AI agent memory system with CLAUDE.md protocol enforcement",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -3634,6 +3634,16 @@ def _validate_tool_call_arguments(
3634
3634
  ),
3635
3635
  )
3636
3636
 
3637
+ if _is_garbled_tool_arguments(arg_text):
3638
+ return ToolResponseIssue(
3639
+ kind="invalid_tool_args",
3640
+ reason=f"arguments for '{tool_name}' contain garbled/degenerate content",
3641
+ retry_hint=(
3642
+ f"Emit exactly one `{tool_name}` tool call with well-formed JSON arguments. "
3643
+ "Do not repeat closing braces, brackets, or digits."
3644
+ ),
3645
+ )
3646
+
3637
3647
  if _contains_required_placeholder(parsed):
3638
3648
  return ToolResponseIssue(
3639
3649
  kind="invalid_tool_args",
@@ -3650,3 +3650,49 @@ class TestCompletionContractGuardrails(unittest.TestCase):
3650
3650
  self.assertEqual(reason, "completion_pending")
3651
3651
  self.assertEqual(monitor.tool_turn_phase, "review")
3652
3652
  self.assertEqual(monitor.completion_recovery_attempts, 1)
3653
+
3654
+
3655
+ class TestGarbledArgsRetry(unittest.TestCase):
3656
+ """Tests for garbled tool arguments triggering retry via _validate_tool_call_arguments."""
3657
+
3658
+ def test_garbled_runaway_braces_triggers_retry(self):
3659
+ """Garbled brace imbalance should return an invalid_tool_args issue."""
3660
+ # Valid JSON but with extreme brace imbalance in string value
3661
+ garbled_args = '{"todos": "}}}}}}}}}}}}}"}'
3662
+ issue = proxy._validate_tool_call_arguments(
3663
+ "TodoWrite", garbled_args, {}, {"TodoWrite"}
3664
+ )
3665
+ self.assertTrue(issue.has_issue())
3666
+ self.assertEqual(issue.kind, "invalid_tool_args")
3667
+ self.assertIn("garbled", issue.reason)
3668
+
3669
+ def test_garbled_repetitive_digits_triggers_retry(self):
3670
+ """Repetitive digit patterns should return an invalid_tool_args issue."""
3671
+ garbled_args = '{"value": "398859738398859738398859738"}'
3672
+ issue = proxy._validate_tool_call_arguments(
3673
+ "Bash", garbled_args, {}, {"Bash"}
3674
+ )
3675
+ self.assertTrue(issue.has_issue())
3676
+ self.assertEqual(issue.kind, "invalid_tool_args")
3677
+ self.assertIn("garbled", issue.reason)
3678
+
3679
+ def test_clean_args_pass_garbled_check(self):
3680
+ """Well-formed tool arguments should not be flagged as garbled."""
3681
+ clean_args = '{"command": "echo hello world"}'
3682
+ issue = proxy._validate_tool_call_arguments(
3683
+ "Bash", clean_args, {}, {"Bash"}
3684
+ )
3685
+ self.assertFalse(issue.has_issue())
3686
+
3687
+ def test_garbled_detection_before_schema_validation(self):
3688
+ """Garbled args should be caught even without schema info."""
3689
+ garbled_args = '{"content": "' + "0" * 40 + '"}'
3690
+ issue = proxy._validate_tool_call_arguments(
3691
+ "Write", garbled_args, {}, {"Write"}
3692
+ )
3693
+ self.assertTrue(issue.has_issue())
3694
+ self.assertEqual(issue.kind, "invalid_tool_args")
3695
+
3696
+ def test_env_sync_malformed_retry_max(self):
3697
+ """PROXY_MALFORMED_TOOL_RETRY_MAX should be 3."""
3698
+ self.assertEqual(proxy.PROXY_MALFORMED_TOOL_RETRY_MAX, 3)