@miller-tech/uap 1.15.12 → 1.15.13

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.15.12",
3
+ "version": "1.15.13",
4
4
  "description": "Autonomous AI agent memory system with CLAUDE.md protocol enforcement",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1351,19 +1351,28 @@ def _sanitize_tool_schema_for_llama(schema):
1351
1351
  """
1352
1352
 
1353
1353
  removed = 0
1354
+ property_map_keys = {"properties", "definitions", "$defs", "dependentSchemas"}
1354
1355
 
1355
- def _walk(node):
1356
+ def _walk(node, parent_key=None):
1356
1357
  nonlocal removed
1357
1358
  if isinstance(node, dict):
1358
1359
  cleaned = {}
1359
1360
  for key, value in node.items():
1360
- if key in {"pattern", "patternProperties"}:
1361
+ key_is_property_name = parent_key in property_map_keys
1362
+ if (
1363
+ key == "pattern"
1364
+ and isinstance(value, str)
1365
+ and not key_is_property_name
1366
+ ):
1361
1367
  removed += 1
1362
1368
  continue
1363
- cleaned[key] = _walk(value)
1369
+ if key == "patternProperties" and not key_is_property_name:
1370
+ removed += 1
1371
+ continue
1372
+ cleaned[key] = _walk(value, key)
1364
1373
  return cleaned
1365
1374
  if isinstance(node, list):
1366
- return [_walk(item) for item in node]
1375
+ return [_walk(item, parent_key) for item in node]
1367
1376
  return node
1368
1377
 
1369
1378
  return _walk(schema), removed
@@ -154,6 +154,30 @@ class TestToolSchemaSanitization(unittest.TestCase):
154
154
  self.assertNotIn("patternProperties", params)
155
155
  self.assertNotIn("pattern", params["properties"]["meta"]["properties"]["tag"])
156
156
 
157
+ def test_convert_tools_keeps_property_named_pattern(self):
158
+ anthropic_tools = [
159
+ {
160
+ "name": "ScheduleTool",
161
+ "description": "test",
162
+ "input_schema": {
163
+ "type": "object",
164
+ "required": ["pattern", "subject"],
165
+ "properties": {
166
+ "pattern": {
167
+ "type": "string",
168
+ "description": "User-provided matching pattern",
169
+ },
170
+ "subject": {"type": "string"},
171
+ },
172
+ },
173
+ }
174
+ ]
175
+
176
+ converted = proxy._convert_anthropic_tools_to_openai(anthropic_tools)
177
+ params = converted[0]["function"]["parameters"]
178
+ self.assertIn("pattern", params["required"])
179
+ self.assertEqual(params["properties"]["pattern"]["type"], "string")
180
+
157
181
 
158
182
  class TestStreamGuardedPathSelection(unittest.TestCase):
159
183
  def test_required_tool_turn_uses_guarded_non_stream(self):