"""Internal XML bridge with explicit, verifiable workflow requirements."""
import json
import re
import time
import uuid
import hashlib
import torch
def schema(name,description,properties,required):
return {"type":"function","function":{"name":name,"description":description,
"parameters":{"type":"object","properties":properties,"required":required,
"additionalProperties":False}}}
STRING={"type":"string"}
TOOLS=[
schema("calc","Evaluate exact arithmetic on the internal computer. + - * / // % ** gcd and parentheses.",
{"expression":STRING},["expression"]),
schema("put","Save a text file; creates a new revision.",{"name":STRING,"content":STRING},["name","content"]),
schema("get","Read a text file.",{"name":STRING},["name"]),
schema("list_files","List saved files.",{},[]),
schema("delete","Delete a saved file.",{"name":STRING},["name"]),
schema("rollback","Restore a retained file revision, creating a new revision.",
{"name":STRING,"revision":STRING},["name","revision"]),
]
def parse_call(raw):
block=re.search(r"(.*?)",raw,re.S)
if not block:
if "" in raw:raise ValueError("Truncated tool call")
return None
body=block.group(1).strip()
if body.startswith('(.*?)\s*",body,re.S)
if function is None:raise ValueError('Malformed function envelope')
inner=function.group(2)
pattern=r"(.*?)"
pairs=re.findall(pattern,inner,re.S)
if re.sub(pattern,'',inner,flags=re.S).strip():raise ValueError('Malformed parameter envelope')
if len(dict(pairs))!=len(pairs):raise ValueError('Duplicate parameter')
return {'name':function.group(1),'arguments':{k:(v if k in ('content','text','query','forbidden','name') else v.strip()) for k,v in pairs}}
def unique(pairs):
value={}
for key,item in pairs:
if key in value:raise ValueError('Duplicate JSON key')
value[key]=item
return value
def bad_constant(x):raise ValueError('Non-finite JSON number')
value=json.loads(body,object_pairs_hook=unique,parse_constant=bad_constant)
if not isinstance(value,dict) or set(value)-{'name','arguments'} or 'name' not in value:
raise ValueError('Invalid tool-call object')
if not isinstance(value['name'],str) or not re.fullmatch(r'[A-Za-z_]\w*',value['name']):
raise ValueError('Invalid tool name')
args=value.get('arguments',{})
if isinstance(args,str):args=json.loads(args,object_pairs_hook=unique,parse_constant=bad_constant)
if not isinstance(args,dict):raise ValueError('Arguments must be an object')
return {'name':value['name'],'arguments':args}
def execute(model,session,call):
name,args=call["name"],call["arguments"]
choices={t["function"]["name"]:t["function"]["parameters"] for t in TOOLS}
if name not in choices: raise ValueError(f"Unknown tool: {name}")
spec=choices[name]
if not isinstance(args,dict) or set(args)-set(spec["properties"]) or set(spec["required"])-set(args):
raise ValueError("Invalid parameter names")
if any(not isinstance(v,str) for v in args.values()): raise TypeError("String parameters required")
if name=="calc": return model.calculate(args["expression"])
if name=="put": return model(mode="memory",memory_state=session.memory,operation="put_many",files={args["name"]:args["content"]})
if name=="get": return model(mode="memory",memory_state=session.memory,operation="get",**args)
if name=="list_files": return model(mode="memory",memory_state=session.memory,operation="list")
if name=="delete": return model(mode="memory",memory_state=session.memory,operation="put_many",files={args["name"]:None})
if name=="rollback": return model(mode="memory",memory_state=session.memory,operation="rollback",**args)
raise AssertionError(name)
def fulfilled(events,requirements):
cursor=0
for event in events:
if cursor",add_special_tokens=False)
class Stop(StoppingCriteria):
def __call__(self,input_ids,scores,**kwargs):
return input_ids.shape[1]>=len(close) and input_ids[0,-len(close):].tolist()==close
batch=tok.apply_chat_template(session.messages,tools=TOOLS,add_generation_prompt=True,
enable_thinking=False,tokenize=True,return_dict=True,return_tensors="pt")
if batch["input_ids"].shape[1]>16384: raise RuntimeError("Session context exceeds 16K notebook limit")
batch=batch.to(next(model.language_model.parameters()).device)
out=model.language_model.generate(**batch,max_new_tokens=max_new_tokens,do_sample=False,
repetition_penalty=1.1,stopping_criteria=StoppingCriteriaList([Stop()]),
pad_token_id=tok.pad_token_id if tok.pad_token_id is not None else tok.eos_token_id)
return tok.decode(out[0,batch["input_ids"].shape[1]:],skip_special_tokens=False)
def chat(model,session,prompt,required_tools=(),required_files=None,max_calls=12,max_new_tokens=1536,verbose=True):
if model.tokenizer is None: raise RuntimeError("Tokenizer is not attached")
if max_calls<1: raise ValueError("max_calls must be positive")
session.messages.append({"role":"user","content":prompt})
events=[];started=time.perf_counter()
for attempt in range(max_calls+3):
raw=generate_text(model,session,max_new_tokens)
call=parse_call(raw)
if call is None:
missing=[]
if not fulfilled(events,required_tools): missing.append("required ordered calls: "+", ".join(required_tools))
for name,expected in (required_files or {}).items():
try:
actual=model.files(session.memory,"get",name=name)["content"]
if expected not in actual: missing.append("required file content: "+name)
except KeyError: missing.append("required file: "+name)
if missing:
if attempt>=max_calls+1 or len(events)>=max_calls:
raise RuntimeError("Workflow incomplete: "+"; ".join(missing))
session.messages.append({"role":"assistant","content":raw})
session.messages.append({"role":"user","content":
"Execution verification failed. Complete the missing operations before answering: "+"; ".join(missing)})
continue
answer=re.sub(r".*?","",raw,flags=re.S)
if "" in answer: raise RuntimeError("Incomplete reasoning; increase token budget")
answer=re.sub(r"<\|(?:im_end|im_start|endoftext|startoftext)\|>","",answer).strip()
session.messages.append({"role":"assistant","content":answer})
return {"answer":answer,"events":events,"workflow_verified":bool(required_tools or required_files),
"seconds":time.perf_counter()-started}
if len(events)>=max_calls: raise RuntimeError("Tool-call budget exhausted")
identifier="call_"+uuid.uuid4().hex
content=re.sub(r".*?","",raw,flags=re.S).strip()
session.messages.append({"role":"assistant","content":content,
"tool_calls":[{"id":identifier,"type":"function","function":call}]})
try: response={"ok":True,"result":execute(model,session,call)}
except (ValueError,KeyError,TypeError,MemoryError,TimeoutError,RuntimeError) as error:
response={"ok":False,"error":f"{type(error).__name__}: {error}"}
event={"call":call,"response":response}
events.append(event)
previous=session.audit[-1]["hash"] if session.audit else "0"*64
digest=hashlib.sha256((previous+json.dumps(event,sort_keys=True)).encode()).hexdigest()
session.audit.append({**event,"previous":previous,"hash":digest})
if verbose: print("→",call["name"],json.dumps(response,ensure_ascii=False)[:500],flush=True)
session.messages.append({"role":"tool","tool_call_id":identifier,"name":call["name"],
"content":json.dumps(response,ensure_ascii=False)})
raise RuntimeError("Workflow did not finish")