<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Tool-Calling on cameronqj</title>
    <link>https://cameronqj.com/tags/tool-calling/</link>
    <description>Recent content in Tool-Calling on cameronqj</description>
    <generator>Hugo</generator>
    <language>en-US</language>
    <copyright>Cameron Jones</copyright>
    <lastBuildDate>Sun, 19 Jul 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://cameronqj.com/tags/tool-calling/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>structured-output-agent</title>
      <link>https://cameronqj.com/projects/structured-output-agent/</link>
      <pubDate>Sun, 19 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://cameronqj.com/projects/structured-output-agent/</guid>
      <description>A small Python runtime for schema-validated model responses, bounded recovery, typed tool contracts, and sanitized audit events.</description>
      <content:encoded><![CDATA[<p><strong>Status:</strong> Experimental runtime<br>
<strong>Code:</strong> <a href="https://github.com/cameronqj/structured-output-agent">github.com/cameronqj/structured-output-agent</a></p>
<p>Valid JSON is only the first boundary. The shape can be correct while the requested tool is unauthorized, its arguments are unsafe, or the tool returns data the rest of the application should not trust.</p>
<p>This runtime puts schemas on both sides of the model/tool boundary. It uses Pydantic validation, a hard attempt budget, typed failures, and an explicit registry that validates tool arguments and results around application-owned code. Plain prose never becomes a tool call, and provider failures stop rather than entering a blind retry loop.</p>
<p>The evidence is intentionally modest. Hermetic tests with scripted models and deterministic tools cover malformed output, recovery budgets, authorization, and result validation. There is not yet a frozen provider-response corpus or enough provider-specific integration evidence to claim broad runtime reliability.</p>
<h2 id="read-the-design">Read the design</h2>
<ul>
<li><a href="https://github.com/cameronqj/structured-output-agent/blob/main/docs/architecture.md">Architecture and attempt semantics</a></li>
<li><a href="https://github.com/cameronqj/structured-output-agent/blob/main/docs/testing.md">Test coverage and evidence limits</a></li>
<li><a href="https://github.com/cameronqj/structured-output-agent/blob/main/docs/adr/0004-explicit-tool-registry.md">Explicit tool-authority decision</a></li>
<li><a href="https://github.com/cameronqj/structured-output-agent/blob/main/docs/experiment-log.md">Experiment status</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>react-planning-agent</title>
      <link>https://cameronqj.com/projects/react-planning-agent/</link>
      <pubDate>Sun, 19 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://cameronqj.com/projects/react-planning-agent/</guid>
      <description>A typed ReAct state machine with explicit planning steps, separate budgets, cycle detection, and sanitized traces.</description>
      <content:encoded><![CDATA[<p><strong>Status:</strong> Experimental runtime<br>
<strong>Code:</strong> <a href="https://github.com/cameronqj/react-planning-agent">github.com/cameronqj/react-planning-agent</a></p>
<p>ReAct loops are easy to demo and surprisingly easy to leave unbounded. A model can repeat a plausible action, burn retries on malformed output, or keep planning after it has stopped making progress.</p>
<p>This project wraps <code>observe → decide → act → reflect</code> in a typed state machine. Iterations, tool calls, and structured-output recovery have separate budgets. Exact repeated actions and repeated application-visible state keys stop deterministic cycles. Model, validation, tool, and budget failures return typed summaries rather than escaping as uncontrolled exceptions.</p>
<p>The offline vertical slice covers single-tool and multistep flows. One live local-server run discovered a model and completed an addition tool call. That is useful integration evidence, but it is one narrow path. It does not establish open-ended planning reliability or broad compatibility across providers.</p>
<h2 id="read-the-evidence">Read the evidence</h2>
<ul>
<li><a href="https://github.com/cameronqj/react-planning-agent/blob/main/docs/architecture.md">Architecture and dependency boundary</a></li>
<li><a href="https://github.com/cameronqj/react-planning-agent/blob/main/docs/experiment-log.md">Offline and live experiment record</a></li>
<li><a href="https://github.com/cameronqj/react-planning-agent/blob/main/docs/testing.md">Testing boundaries</a></li>
<li><a href="https://github.com/cameronqj/react-planning-agent/blob/main/docs/adr/0004-cycle-detection.md">Cycle-detection decision</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>toolcall-repair-bench</title>
      <link>https://cameronqj.com/projects/toolcall-repair-bench/</link>
      <pubDate>Thu, 09 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://cameronqj.com/projects/toolcall-repair-bench/</guid>
      <description>An archived precision-first benchmark whose follow-up testing disproved its original broad premise.</description>
      <content:encoded><![CDATA[<p><strong>Status:</strong> Concluded and archived<br>
<strong>Code:</strong> <a href="https://github.com/cameronqj/toolcall-repair-bench">github.com/cameronqj/toolcall-repair-bench</a></p>
<p>I built this benchmark to answer what looked like a practical question: how often could a conservative repair layer recover malformed local-model tool calls without inventing unsafe intent?</p>
<p>The first version treated unsafe false positives as more important than recall or F1. Then endpoint-controlled follow-up testing changed the conclusion. <code>llama.cpp</code> produced 27 of 27 clean non-streaming calls and 36 of 36 clean streaming/parallel calls. Ollama&rsquo;s parsed chat path produced 3 of 3 and then 16 of 16 clean calls, including the model that seeded the original investigation.</p>
<p>The broad &ldquo;local models need tool-call repair&rdquo; premise did not survive. The original 117-case corpus had captured raw, unparsed completion output, so its leaderboard cannot support a general model or library comparison. I archived the project rather than keep polishing a benchmark for a problem the normal serving path had already solved.</p>
<p>The useful artifact is the correction: capture point and serving stack mattered more than the model-level explanation I started with.</p>
<h2 id="read-the-finding">Read the finding</h2>
<ul>
<li><a href="https://github.com/cameronqj/toolcall-repair-bench/blob/main/findings/README.md">Finding and reproduction procedure</a></li>
<li><a href="https://github.com/cameronqj/toolcall-repair-bench/blob/main/docs/adr/0006-premise-is-a-serving-stack-artifact.md">Why the project was archived</a></li>
<li><a href="https://github.com/cameronqj/toolcall-repair-bench/blob/main/EVALUATION.md">Precision-first methodology</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>local-tool-proxy</title>
      <link>https://cameronqj.com/projects/local-tool-proxy/</link>
      <pubDate>Sun, 14 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://cameronqj.com/projects/local-tool-proxy/</guid>
      <description>An archived compatibility proxy for conservative repair of malformed local-model tool calls on raw-completion paths.</description>
      <content:encoded><![CDATA[<p><strong>Status:</strong> Concluded and archived<br>
<strong>Code:</strong> <a href="https://github.com/cameronqj/local-tool-proxy">github.com/cameronqj/local-tool-proxy</a></p>
<p>This started with a concrete failure: a local model expressed a tool call as JSON inside ordinary response text, while the client expected an OpenAI-style structured tool call.</p>
<p>The proxy repairs only a narrow class of responses. It checks the requested name and arguments against the tools declared by the client, then abstains when intent is unclear. On the companion 117-case raw-output corpus, version 0.1.0 reached 87.5% precision and 38.2% recall on recoverable cases, with two unsafe false positives. Real OpenCode samples still failed the final task-level check even when the protocol shape improved.</p>
<p>Later endpoint-controlled testing explained why. Current parsed chat endpoints already returned clean tool calls, including for the seed model. The proxy is therefore relevant mainly to raw-completion consumers and older or misconfigured serving stacks. It is archived because that scope is too narrow to justify an active compatibility layer.</p>
<h2 id="read-the-evidence">Read the evidence</h2>
<ul>
<li><a href="https://github.com/cameronqj/local-tool-proxy/blob/main/docs/experiment-log.md">Experiment log and failed task verification</a></li>
<li><a href="https://github.com/cameronqj/local-tool-proxy/blob/main/docs/model-stops-using-tools-analysis.md">Where protocol repair stops helping</a></li>
<li><a href="https://github.com/cameronqj/toolcall-repair-bench/blob/main/findings/README.md">Serving-stack scope correction</a></li>
</ul>
]]></content:encoded>
    </item>
  </channel>
</rss>
