"""Debug LLM orchestrator 400 on second call""" import sys, os, json, asyncio sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) os.environ['DJANGO_SETTINGS_MODULE'] = 'tianxuan.settings' import django; django.setup() from analysis.session_store import SessionStore from analysis.data_loader import load_csv_directory from analysis.tool_registry import handle_call import urllib.request store = SessionStore(); store.drop_all() csv = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'data', 'complex_test.csv') lf, schema, rc, fc, mem = load_csv_directory(csv) store.store_dataset('ds', lf, schema=schema, metadata={'row_count': rc, 'csv_glob': csv}) TOOLS = [{"type": "function", "function": {"name": "profile_data", "description": "Get column statistics", "parameters": {"type": "object", "properties": {"dataset_id": {"type": "string"}}, "required": ["dataset_id"]}}}] # Step 1: Get tool call from LLM msgs = [{"role": "user", "content": "Call profile_data with ds"}] payload = json.dumps({"model": "deepseek-v4-flash", "messages": msgs, "tools": TOOLS, "tool_choice": "auto", "max_tokens": 200}).encode() req = urllib.request.Request('https://api.deepseek.com/chat/completions', data=payload, headers={'Content-Type': 'application/json', 'Authorization': 'Bearer sk-360ef76d59674d6b8bc2eb160327dd39'}, method='POST') resp = json.loads(urllib.request.urlopen(req, timeout=10).read()) msg = resp["choices"][0]["message"] tc = msg["tool_calls"][0] print(f'Got tool call: {tc["function"]["name"]}') # Execute tool result = asyncio.run(handle_call(tc["function"]["name"], json.loads(tc["function"]["arguments"]))) content = json.dumps(result, default=str, ensure_ascii=False) print(f'Result length: {len(content)}') # Step 2: Send back - with correct message format msgs2 = msgs + [msg, {"role": "tool", "tool_call_id": tc["id"], "content": content[:2000]}] payload2 = json.dumps({"model": "deepseek-v4-flash", "messages": msgs2, "tools": TOOLS, "tool_choice": "auto", "max_tokens": 200}).encode() req2 = urllib.request.Request('https://api.deepseek.com/chat/completions', data=payload2, headers={'Content-Type': 'application/json', 'Authorization': 'Bearer sk-360ef76d59674d6b8bc2eb160327dd39'}, method='POST') try: resp2 = json.loads(urllib.request.urlopen(req2, timeout=10).read()) print(f'Step 2 OK: {resp2["choices"][0]["message"]["content"][:100]}') except urllib.error.HTTPError as e: body = e.read().decode()[:500] print(f'Step 2 400: {body}')