Merge pull request #32 from hjertefolger/fix/azure-call-id-and-fstring
fix(azure): normalize tool call IDs and f-string with backslashes
This commit is contained in:
@@ -89,11 +89,15 @@ class AzureAdapter:
|
||||
"azure_response": resp_content,
|
||||
"request_body": body,
|
||||
}
|
||||
error_message = f"""\nCheck "azure_response" for the error details:
|
||||
\t{json.dumps(report, indent=4).replace("\n", "\n\t")}
|
||||
If the issue persists, report it to:
|
||||
\thttps://github.com/gabrii/Cursor-Azure-GPT-5/issues
|
||||
Including all the details above"""
|
||||
# Precompute pretty JSON to avoid backslashes inside f-string expressions
|
||||
report_pretty = json.dumps(report, indent=4).replace("\n", "\n\t")
|
||||
error_message = (
|
||||
'\nCheck "azure_response" for the error details:\n'
|
||||
f"\t{report_pretty}\n"
|
||||
"If the issue persists, report it to:\n"
|
||||
"\thttps://github.com/gabrii/Cursor-Azure-GPT-5/issues\n"
|
||||
"Including all the details above"
|
||||
)
|
||||
console.rule(f"[red]Request failed with status code {resp.status_code}[/red]")
|
||||
console.print(error_message)
|
||||
return Response(
|
||||
|
||||
@@ -28,6 +28,29 @@ class RequestAdapter:
|
||||
self.adapter = adapter # AzureAdapter instance for shared config/env
|
||||
|
||||
# ---- Helpers (kept local to minimize cross-module coupling) ----
|
||||
def _normalize_call_id(
|
||||
self, original: Optional[str], mapping: Dict[str, str]
|
||||
) -> Optional[str]:
|
||||
"""Return a <=64 char stable call_id.
|
||||
|
||||
- Azure Responses API limits function call ids to 64 chars.
|
||||
- Cursor/OpenAI tool_call ids may exceed that. We map any long ids
|
||||
to a deterministic 64-char hex digest for this request, while
|
||||
preserving pairing between function_call and function_call_output.
|
||||
"""
|
||||
if not original:
|
||||
return original
|
||||
if len(original) <= 64:
|
||||
# Still ensure consistent mapping if we've seen it before
|
||||
return mapping.get(original, original)
|
||||
if original in mapping:
|
||||
return mapping[original]
|
||||
import hashlib
|
||||
|
||||
norm = hashlib.sha256(original.encode("utf-8")).hexdigest() # 64 hex chars
|
||||
mapping[original] = norm
|
||||
return norm
|
||||
|
||||
def _parse_json_body(self, req: Request, body: bytes) -> Optional[Any]:
|
||||
if not body:
|
||||
return None
|
||||
@@ -73,6 +96,9 @@ class RequestAdapter:
|
||||
return "\n".join([p for p in parts if p])
|
||||
return json.dumps(c, ensure_ascii=False)
|
||||
|
||||
# Maintain stable mapping of long tool call ids within a single request
|
||||
call_id_map: Dict[str, str] = {}
|
||||
|
||||
for m in messages:
|
||||
role = m.get("role")
|
||||
c = m.get("content")
|
||||
@@ -83,11 +109,16 @@ class RequestAdapter:
|
||||
continue
|
||||
# For user/assistant/tools as inputs
|
||||
if role == "tool":
|
||||
# Map tool outputs back to a normalized call id
|
||||
original_tool_call_id = m.get("tool_call_id")
|
||||
norm_call_id = self._normalize_call_id(
|
||||
original_tool_call_id, call_id_map
|
||||
)
|
||||
item = {
|
||||
"type": "function_call_output",
|
||||
"output": content_to_text(c),
|
||||
"status": "completed",
|
||||
"call_id": m.get("tool_call_id"),
|
||||
"call_id": norm_call_id,
|
||||
}
|
||||
input_items.append(item)
|
||||
else:
|
||||
@@ -106,11 +137,13 @@ class RequestAdapter:
|
||||
if tool_calls := m.get("tool_calls"):
|
||||
for tool_call in tool_calls:
|
||||
function = tool_call.get("function", {})
|
||||
original_id = tool_call.get("id")
|
||||
norm_call_id = self._normalize_call_id(original_id, call_id_map)
|
||||
item = {
|
||||
"type": "function_call",
|
||||
"name": function.get("name"),
|
||||
"arguments": function.get("arguments"),
|
||||
"call_id": tool_call.get("id"),
|
||||
"call_id": norm_call_id,
|
||||
}
|
||||
input_items.append(item)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user