Skip to content

Parsers And Tools

Native parsers and tools are part of the agent loop. Parsers turn model text into structured data; handlers decide how repair and tool-result prompts are fed back into the next model call.

Tagged Parsing

DefaultTagParser understands XML blocks, fenced markdown blocks, and signal tags.

from lllm.runtimes.native import DefaultTagParser, Prompt

parser = DefaultTagParser(
    required_xml_tags=["answer"],
    md_tags=["python"],
    signal_tags=["DONE"],
)

prompt = Prompt(
    path="analysis/tagged",
    prompt="Return <answer>...</answer>. Put code in ```python blocks.",
    parser=parser,
)

parsed = prompt.parse(
    "<answer>Use the native runtime.</answer>\n"
    "```python\nprint('ok')\n```\n"
    "<DONE>"
)

assert parsed["xml_tags"]["answer"] == ["Use the native runtime."]
assert parsed["signal_tags"]["DONE"] is True

If required blocks are missing, DefaultTagParser raises ParseError. The agent records that failure on AgentCallSession, appends the prompt returned by prompt.on_exception(session), and recalls the model until the configured exception cap is reached.

Handlers

DefaultSimpleHandler creates:

  • an exception prompt with Error: {error_message}. Please fix.;
  • a tool-result prompt with {call_results};
  • a final prompt when the tool-call limit is reached.

Replace handler when parser repair or tool-result feedback needs richer state. A handler can inspect AgentCallSession and return full Prompt objects, not just strings.

Function Tools

A native Function has two halves:

  • a schema shown to the model;
  • an optional Python implementation called when the model emits a tool call.
from lllm.runtimes.native import FunctionCall, Prompt, tool


@tool(
    description="Add two values.",
    prop_desc={"left": "Left value.", "right": "Right value."},
)
def add(left: int, right: int = 1) -> int:
    return left + right


prompt = Prompt(
    path="math/solve",
    prompt="Solve {question}. Use tools if helpful.",
    function_list=[add],
)

call = add(FunctionCall(name="add", arguments={"left": 2, "right": 3}))
assert call.result == 5

Function.from_callable() inspects signatures and type hints. Tool names are validated so they can be used safely in provider payloads and resource refs. Function.to_tool() returns a copy of a LiteLLM/OpenAI-compatible tool schema, so mutating the returned dictionary does not mutate the original prompt.

Tool References

String entries in function_list are resolved at call time:

prompt = Prompt(
    path="review/main",
    prompt="Review this patch.",
    function_list=[
        "shared.tools:search_code",
        "shared.tactics:lint_patch",
    ],
)

Regular tool refs bind to registered Function resources. Tactic refs are wrapped as native Function tools with tactic_as_function().

MCP Servers

Native prompts can declare MCP servers:

from lllm.runtimes.native import MCP, Prompt

prompt = Prompt(
    path="docs/search",
    prompt="Search the docs when needed.",
    mcp_servers_list=[
        MCP(
            server_label="docs",
            server_url="https://example.invalid/mcp",
            require_approval="manual",
            allowed_tools=["search"],
        )
    ],
)

MCP.to_tool() converts the declaration for LiteLLM. Approval mode is validated as never, manual, or auto.