Mutation in generator; category H (stop) scoring and judge; category K variants and tool schema variant; evalset plan
- mutation.py: negation mutants, skip WHILE/DO blocks (endless loop blocked RFC ~8 min) - generator: accept only after mutation check; survivors go back as repair feedback - runner/judge.py: stop tasks scored 100/30/0; gap by keywords, else judge model - proxy: tool schema variant generic_v0 (draft); generator make_k_variant - evalset.py: 88 slots for step F (A-I, H, K) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,24 @@ MODEL_TOOLS = {
|
||||
}
|
||||
WRITE_TOOLS = {"sap_create_object", "sap_push_source", "sap_push_element",
|
||||
"sap_push_message", "sap_activate"}
|
||||
# Tool schema variants (category K; small variation in training). Draft until abap-mcp-arayuz.md exists.
|
||||
# The model sees the variant names and argument names; the proxy translates them to EPOD.
|
||||
VARIANTS = {
|
||||
"generic_v0": {
|
||||
"tools": {"search_object": "sap_search_object", "read_source": "sap_pull_source",
|
||||
"object_structure": "sap_object_structure", "where_used": "sap_usage_references",
|
||||
"create_object": "sap_create_object", "write_source": "sap_push_source",
|
||||
"activate": "sap_activate", "syntax_check": "sap_syntax_check",
|
||||
"run_unit_tests": "sap_run_unit_test", "run_atc": "sap_atc_run",
|
||||
"object_members": "sap_object_members", "element_info": "sap_element_info",
|
||||
"inactive_objects": "sap_inactive_objects", "short_dumps": "sap_short_dumps",
|
||||
"sql_query": "sap_sql_query", "write_element": "sap_push_element",
|
||||
"write_message": "sap_push_message", "check_object": "sap_check_object",
|
||||
"pretty_print": "sap_pretty_print", "run_class": "sap_run_class"},
|
||||
"args": {"objectName": "name", "objectType": "type", "functionGroup": "function_group",
|
||||
"packageName": "package", "includeType": "include", "className": "class_name"},
|
||||
},
|
||||
}
|
||||
RUN_PREFIX = re.compile(r"^Z\d[0-9A-Z]{5,6}_", re.I)
|
||||
|
||||
|
||||
@@ -20,8 +38,9 @@ class BudgetExceeded(Exception):
|
||||
|
||||
|
||||
class ToolProxy:
|
||||
def __init__(self, mcp, prefix, budget, log_path):
|
||||
def __init__(self, mcp, prefix, budget, log_path, tool_schema=None):
|
||||
self.mcp = mcp
|
||||
self.variant = VARIANTS.get(tool_schema) if tool_schema else None
|
||||
self.prefix = prefix.upper()
|
||||
self.max_calls = budget.get("max_tool_calls", 60)
|
||||
self.max_activations = budget.get("max_activations", 15)
|
||||
@@ -32,7 +51,31 @@ class ToolProxy:
|
||||
self.log = open(log_path, "a")
|
||||
|
||||
def schemas(self):
|
||||
return [t for t in self.mcp.list_tools() if t["name"] in MODEL_TOOLS]
|
||||
tools = [t for t in self.mcp.list_tools() if t["name"] in MODEL_TOOLS]
|
||||
if not self.variant:
|
||||
return tools
|
||||
back = {v: k for k, v in self.variant["tools"].items()}
|
||||
amap = self.variant["args"]
|
||||
out = []
|
||||
for t in tools:
|
||||
if t["name"] not in back:
|
||||
continue
|
||||
sch = json.loads(json.dumps(t.get("inputSchema", {})))
|
||||
sch["properties"] = {amap.get(k, k): v for k, v in sch.get("properties", {}).items()}
|
||||
if "required" in sch:
|
||||
sch["required"] = [amap.get(k, k) for k in sch["required"]]
|
||||
desc = t.get("description", "")
|
||||
for epod, alias in list(back.items()) + list(amap.items()):
|
||||
desc = re.sub(rf"\b{re.escape(epod)}\b", alias, desc)
|
||||
out.append(dict(t, name=back[t["name"]], description=desc, inputSchema=sch))
|
||||
return out
|
||||
|
||||
def _translate(self, tool, args):
|
||||
"""Variant name and arguments to EPOD. EPOD names stay valid (the oracle uses them)."""
|
||||
if not self.variant or tool not in self.variant["tools"]:
|
||||
return tool, args
|
||||
back = {v: k for k, v in self.variant["args"].items()}
|
||||
return self.variant["tools"][tool], {back.get(k, k): v for k, v in (args or {}).items()}
|
||||
|
||||
def _foreign(self, name):
|
||||
n = (name or "").upper()
|
||||
@@ -52,6 +95,10 @@ class ToolProxy:
|
||||
|
||||
def call(self, tool, args):
|
||||
entry = {"t": time.time(), "tool": tool, "args": args}
|
||||
shown = tool
|
||||
tool, args = self._translate(tool, args)
|
||||
if shown != tool:
|
||||
entry.update(tool=tool, args=args, variant_tool=shown)
|
||||
if tool not in MODEL_TOOLS:
|
||||
result = (True, f"Tool {tool} is not available.")
|
||||
elif self.calls >= self.max_calls:
|
||||
|
||||
Reference in New Issue
Block a user