"""Summarize actual wire tool constraints without persisting schemas or prompts.""" import hashlib import json import re from artemis.llm.argument_fingerprint import MAX_TRACKED_TOOLS MAX_REQUEST_BYTES = 4 * 1024 * 1024 def safe_label(value): return value if isinstance(value, str) and re.fullmatch(r"[\w.:-]{1,128}", value) else None def strict_state(tool: dict) -> str: if "strict" not in tool: return "omitted" if tool["strict"] is True: return "true" if tool["strict"] is False: return "false" return "invalid" def schema_summary(schema: dict) -> dict: """Count syntactic schema nodes, not expanded $refs or arbitrary examples.""" result = {"objects": 0, "optional_properties": 0, "open_objects": 0, "nodes": 0} pending = [schema] while pending and result["nodes"] < 1024: node = pending.pop() result["nodes"] += 1 properties = node.get("properties") if node.get("type") == "object" or isinstance(properties, dict): result["objects"] += 1 required = node.get("required") required = required if isinstance(required, list) else [] if isinstance(properties, dict): result["optional_properties"] += sum(k not in required for k in properties) if node.get("additionalProperties") is not False: result["open_objects"] += 1 children = [] for key in ("properties", "$defs", "definitions"): if isinstance(node.get(key), dict): children.extend(node[key].values()) for key in ("anyOf", "oneOf", "allOf", "prefixItems"): if isinstance(node.get(key), list): children.extend(node[key]) children.extend(node.get(k) for k in ("items", "additionalProperties", "not")) remaining = max(0, 1024 - result["nodes"] - len(pending)) eligible = [v for v in children if isinstance(v, dict)] if len(eligible) > remaining: result["truncated"] = True pending.extend(eligible[:remaining]) result["truncated"] = bool(pending) or result.get("truncated", False) try: result["sha256"] = hashlib.sha256( json.dumps(schema, sort_keys=True, separators=(",", ":"), ensure_ascii=True).encode() ).hexdigest() except (RecursionError, TypeError, ValueError): result["sha256"] = None result["truncated"] = True return result def tool_constraints(tools) -> dict: records = [] pending = tools[:MAX_TRACKED_TOOLS] if isinstance(tools, list) else [] truncated = isinstance(tools, list) and len(tools) > MAX_TRACKED_TOOLS visited = 0 while pending and visited < MAX_TRACKED_TOOLS: tool = pending.pop(0) visited += 1 if not isinstance(tool, dict): continue if tool.get("type") == "namespace": nested = tool.get("tools") if isinstance(nested, list): remaining = MAX_TRACKED_TOOLS - len(pending) - visited truncated = truncated or len(nested) > remaining pending.extend(nested[:remaining]) continue function = tool.get("function", tool) if not isinstance(function, dict): continue record = { "type": safe_label(tool.get("type")), "name": safe_label(function.get("name")), "strict": strict_state(function), } if isinstance(function.get("parameters"), dict): record["schema"] = schema_summary(function["parameters"]) records.append(record) return {"tools": records, "truncated": truncated or bool(pending), "observation": "available"} def request_constraints(body: bytes) -> dict: if len(body) > MAX_REQUEST_BYTES: return {"observation": "body_too_large"} try: payload = json.loads(body) except (ValueError, UnicodeError, RecursionError): return {"observation": "invalid_json"} if not isinstance(payload, dict): return {"observation": "not_an_object"} result = tool_constraints(payload.get("tools")) limit = payload.get("max_output_tokens") result["max_output_tokens"] = limit if type(limit) is int and limit > 0 else None return result