1"""Shared parsing/serialization helpers for the Claude mapper."""
2
3from __future__ import annotations
4
5from typing import Any
6
7from lexigram.ai.relay.mappers.base import new_uuid
8from lexigram.contracts.ai.llm import FunctionCall, ToolCall
9from lexigram.contracts.ai.relay.dto import ClaudeContent
10from lexigram.contracts.ai.relay.types import RelayFormat
11from lexigram.serialization import loads_str
12
13_TARGET = RelayFormat.CLAUDE
14
15
16def _tool_call_from_block(block: ClaudeContent) -> ToolCall:
17 """Convert a Claude ``tool_use`` block into a canonical ``ToolCall``."""
18 return ToolCall(
19 id=block.tool_use_id or "",
20 type="custom",
21 function=FunctionCall(name=block.name or "", arguments=block.input or {}),
22 )
23
24
25def _tool_call_to_block(tool_call: ToolCall) -> ClaudeContent:
26 """Serialize a canonical ``ToolCall`` as a Claude ``tool_use`` block."""
27 arguments: Any = tool_call.function.arguments if tool_call.function else {}
28 if isinstance(arguments, str):
29 try:
30 arguments = loads_str(arguments)
31 except ValueError:
32 arguments = {}
33 elif not isinstance(arguments, dict):
34 arguments = {}
35 return ClaudeContent(
36 type="tool_use",
37 tool_use_id=tool_call.id or f"call_{new_uuid()}",
38 name=tool_call.function.name if tool_call.function else "",
39 input=arguments,
40 )