<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sathish Chelliah</title>
    <description>The latest articles on DEV Community by Sathish Chelliah (@sschelliah).</description>
    <link>https://dev.to/sschelliah</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3961221%2F515788df-5add-4d22-8eb0-4977a1360ccb.png</url>
      <title>DEV Community: Sathish Chelliah</title>
      <link>https://dev.to/sschelliah</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sschelliah"/>
    <language>en</language>
    <item>
      <title>Giving Your Digital Employee a Company Credit Card (With Limits)</title>
      <dc:creator>Sathish Chelliah</dc:creator>
      <pubDate>Sun, 31 May 2026 13:36:12 +0000</pubDate>
      <link>https://dev.to/sschelliah/giving-your-digital-employee-a-company-credit-card-with-limits-2f35</link>
      <guid>https://dev.to/sschelliah/giving-your-digital-employee-a-company-credit-card-with-limits-2f35</guid>
      <description>&lt;h1&gt;
  
  
  Giving Your Digital Employee a Company Credit Card (With Limits)
&lt;/h1&gt;

&lt;p&gt;The engineering behind AI spending limits.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Problem
&lt;/h2&gt;

&lt;p&gt;Here's how the $30K bill plays out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Day 1:  Agent runs 50 tasks, costs $12. Looks great.
Day 5:  Agent discovers premium model. Uses it for everything. $80/day.
Day 10: Agent runs 200 tasks/day. $400/day.
Day 20: Agent enters a loop. $2,000/day.
Day 30: You check your bill. $30,000.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Budget Engine: Lazy Auto-Reset
&lt;/h2&gt;

&lt;p&gt;Instead of a midnight cron job (which creates a thundering herd), agent-gov uses &lt;strong&gt;lazy evaluation&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_and_reset_budget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;last_reset&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;  &lt;span class="c1"&gt;# No reset needed
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;paused&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;reset_daily_budget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;key_hash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why lazy?&lt;/strong&gt; An agent that makes no calls doesn't need a reset. The first call of the day triggers a single UPDATE. The thundering herd becomes a gentle trickle.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Cost Problem
&lt;/h2&gt;

&lt;p&gt;Agent says: "Estimated cost: $0.50." Reality: $15.00/call.&lt;/p&gt;

&lt;p&gt;agent-gov's &lt;strong&gt;tool registry&lt;/strong&gt; knows the real cost:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;register_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cost_per_call&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;workspace_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        INSERT INTO tools (name, cost_per_call, description, registered_at, workspace_id)
        VALUES (?, ?, ?, ?, ?)
        ON CONFLICT(name) DO UPDATE SET
            cost_per_call = excluded.cost_per_call
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cost_per_call&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;workspace_id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Budget Pools
&lt;/h2&gt;

&lt;p&gt;For teams running multiple agents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agent-gov pool create production-agents &lt;span class="nt"&gt;--budget&lt;/span&gt; 1000
agent-gov pool member add web-agent &lt;span class="nt"&gt;--pool&lt;/span&gt; production-agents &lt;span class="nt"&gt;--max-per-agent&lt;/span&gt; 200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now web agent is capped at $200/month even though the pool has $1,000.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Data Model
&lt;/h2&gt;

&lt;p&gt;Two SQLite tables, two queries per call, sub-millisecond overhead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;agents&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;key_hash&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;daily_budget&lt;/span&gt; &lt;span class="nb"&gt;REAL&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;spent_today&lt;/span&gt; &lt;span class="nb"&gt;REAL&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;calls_today&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;paused&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;last_reset&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;cost_events&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="n"&gt;AUTOINCREMENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;agent_hash&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;agent_name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;timestamp&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tool_name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="nb"&gt;REAL&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent_hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;em&gt;Part 3 of "Taming Your AI" series. &lt;a href="https://github.com/sschelliah2026-source/agent-gov" rel="noopener noreferrer"&gt;agent-gov&lt;/a&gt; is open-source, MIT-licensed. 45 tests, zero database setup.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>finops</category>
      <category>devops</category>
    </item>
    <item>
      <title>Your AI Assistant Just Bought a $30,000 Cloud Subscription</title>
      <dc:creator>Sathish Chelliah</dc:creator>
      <pubDate>Sun, 31 May 2026 13:36:11 +0000</pubDate>
      <link>https://dev.to/sschelliah/your-ai-assistant-just-bought-a-30000-cloud-subscription-1pdg</link>
      <guid>https://dev.to/sschelliah/your-ai-assistant-just-bought-a-30000-cloud-subscription-1pdg</guid>
      <description>&lt;h1&gt;
  
  
  Your AI Assistant Just Bought a $30,000 Cloud Subscription
&lt;/h1&gt;

&lt;p&gt;A postmortem of the $30K Claude bill incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Story
&lt;/h2&gt;

&lt;p&gt;In May 2026, a story made the rounds: &lt;strong&gt;"AWS user gets $30K Claude bill after cost alert misses it."&lt;/strong&gt; Two weeks later, another company reported a $38,000 AWS Bedrock bill caused by a prompt caching miss.&lt;/p&gt;

&lt;p&gt;A single prompt cache miss. $38,000. Not a billion-dollar enterprise. A regular business running AI agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Runaway Costs Actually Happen
&lt;/h2&gt;

&lt;p&gt;When you tell an AI agent to "research competitors and draft a report," here's the execution graph:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Search API        -&amp;gt; $0.03
2. Web scrape        -&amp;gt; $0.01
3. GPT-4 summary    -&amp;gt; $0.35
4. Agent decides: "not polished enough"
5. GPT-4 premium    -&amp;gt; $2.50
6. Image gen API    -&amp;gt; $1.00
7. Regenerate x 3   -&amp;gt; $7.50
8. Total            -&amp;gt; $13.39 for one report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An agent doesn't know the difference between a $0.01 action and a $10 action.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture of Prevention
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A library can be monkey-patched. A proxy is a network boundary agents &lt;em&gt;must&lt;/em&gt; cross.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;agent-gov is a FastAPI reverse proxy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Your config changes from:
&lt;/span&gt;&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.openai.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="c1"&gt;# To:
&lt;/span&gt;&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8080/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The proxy runs a 4-stage decision tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/proxy/call&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;proxy_tool_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ToolCall&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;key_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agent_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Stage 1: Auth - known agent?
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Stage 2: Paused?
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;paused&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Stage 3: Lazy budget reset
&lt;/span&gt;    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check_and_reset_budget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Stage 4: Real cost lookup (not agent's estimate)
&lt;/span&gt;    &lt;span class="n"&gt;registered_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;actual_cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;registered_tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cost_per_call&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;registered_tool&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;estimated_cost&lt;/span&gt;

    &lt;span class="c1"&gt;# Stage 5: Budget check
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;spent_today&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;actual_cost&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;daily_budget&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pause_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Budget exceeded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Approved
&lt;/span&gt;    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_agent_spend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actual_cost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log_cost_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actual_cost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;approved&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;spent_today&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;updated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;spent_today&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Anti-Cheat: Tool Registry
&lt;/h2&gt;

&lt;p&gt;If you trust the agent's estimated cost, an agent can claim GPT-4 costs $0.01 when it's $12.50.&lt;/p&gt;

&lt;p&gt;agent-gov uses a &lt;strong&gt;tool registry&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;registered_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;actual_cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;registered_tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cost_per_call&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;registered_tool&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;estimated_cost&lt;/span&gt;
&lt;span class="c1"&gt;# cost_source: "registry" or "client_estimate"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A test proves agents can't lie:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_proxy_uses_registered_cost&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Tool registered at Rs 500/call
&lt;/span&gt;    &lt;span class="c1"&gt;# Agent with Rs 100 budget claims Rs 1
&lt;/span&gt;    &lt;span class="c1"&gt;# Result: 429 - Blocked!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Proxy Wins Over Library
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Network boundary&lt;/strong&gt; - agents must cross it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Can't be bypassed&lt;/strong&gt; by rogue import or version bump&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language-agnostic&lt;/strong&gt; - works with any framework&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Externally monitorable&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;agent-gov-saas
agent-gov start
agent-gov config &lt;span class="nb"&gt;set &lt;/span&gt;budget 25.00 &lt;span class="nt"&gt;--agent&lt;/span&gt; my-bot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Auto-paused at $25. No $30K surprise.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Part 1 of "Taming Your AI" series. &lt;a href="https://github.com/sschelliah2026-source/agent-gov" rel="noopener noreferrer"&gt;agent-gov&lt;/a&gt; is open-source, MIT-licensed.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>ai</category>
      <category>devops</category>
    </item>
    <item>
      <title>5 Real-World AI Agent Cost Disasters (And How agent-gov Prevents Them)</title>
      <dc:creator>Sathish Chelliah</dc:creator>
      <pubDate>Sun, 31 May 2026 13:26:26 +0000</pubDate>
      <link>https://dev.to/sschelliah/5-real-world-ai-agent-cost-disasters-and-how-agent-gov-prevents-them-2od9</link>
      <guid>https://dev.to/sschelliah/5-real-world-ai-agent-cost-disasters-and-how-agent-gov-prevents-them-2od9</guid>
      <description>&lt;h1&gt;
  
  
  5 Real-World AI Agent Cost Disasters (And How agent-gov Prevents Them)
&lt;/h1&gt;

&lt;p&gt;AI agents are incredible. They write code, answer support tickets, scrape the web, process PDFs, and run entire workflows without you lifting a finger. They also — left to their own devices — have a spectacular talent for burning through money.&lt;/p&gt;

&lt;p&gt;If you've deployed production agents, you've felt this. The Slack ping at 3 AM. The cloud cost report where one agent outspent your entire dev team. The creeping dread when you realize your agent has been calling GPT-4 in a tight loop for six hours.&lt;/p&gt;

&lt;p&gt;Below are five real disasters — names changed — and exactly how &lt;strong&gt;agent-gov&lt;/strong&gt; would have prevented each one.&lt;/p&gt;




&lt;h2&gt;
  
  
  Disaster #1: The Recursive Ouroboros
&lt;/h2&gt;

&lt;p&gt;A content-aggregation agent was supposed to crawl RSS feeds, summarize articles, and post daily digests. One mistake: the agent's output channel was also one of its inputs.&lt;/p&gt;

&lt;p&gt;The agent posted a summary to Slack. Slack's webhook fired. The agent saw new content and summarized &lt;em&gt;the summary&lt;/em&gt;. Three hours later: &lt;strong&gt;14,000 API calls to GPT-4 Turbo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Cost:&lt;/strong&gt; ~$560 in API costs. The entire monthly budget was $200.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How agent-gov Prevents It:&lt;/strong&gt; Auto-Pause. Set a $25 per-agent threshold. The agent hits it within ~40 minutes and stops.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agent-gov policies create content-digest &lt;span class="nt"&gt;--max-cost&lt;/span&gt; 25 &lt;span class="nt"&gt;--action&lt;/span&gt; pause
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Disaster #2: The Over-Engineered Bug
&lt;/h2&gt;

&lt;p&gt;A real estate agent researched property comparables. A bug caused it to repeat the same search 47 times. The cache key was wrong — a trailing space made "90210 schools" and "90210 schools " different lookups.&lt;/p&gt;

&lt;p&gt;12 addresses × 47 loops × 3 API calls = &lt;strong&gt;1,692 calls for 12 houses&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Cost:&lt;/strong&gt; ~$220 in wasted API calls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How agent-gov Prevents It:&lt;/strong&gt; Per-tool cost tracking registers the true cost of every tool. The fast-loop bug accumulates cost at unrealistic speed — flagged within minutes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agent-gov tool-cost &lt;span class="nb"&gt;set &lt;/span&gt;premium-real-estate-api &lt;span class="nt"&gt;--per-call&lt;/span&gt; 0.05
agent-gov tool-cost &lt;span class="nb"&gt;set &lt;/span&gt;gpt4-analysis &lt;span class="nt"&gt;--per-call&lt;/span&gt; 0.035
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Disaster #3: The Budget Hog
&lt;/h2&gt;

&lt;p&gt;A consultancy set up 5 agents sharing a $1,000 monthly pool. One consultant kicked off a massive research job. The web agent ran for two days.&lt;/p&gt;

&lt;p&gt;The other 4 agents silently starved. Nobody noticed until a client complained.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Cost:&lt;/strong&gt; ~$4,000 in lost revenue from missed leads. The web agent consumed $780 of $1,000.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How agent-gov Prevents It:&lt;/strong&gt; Per-agent caps inside shared pools.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agent-gov pool create production-agents &lt;span class="nt"&gt;--budget&lt;/span&gt; 1000
agent-gov pool member add web-agent &lt;span class="nt"&gt;--pool&lt;/span&gt; production-agents &lt;span class="nt"&gt;--max-per-agent&lt;/span&gt; 200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Disaster #4: The $0.01 Budget That Cost $100
&lt;/h2&gt;

&lt;p&gt;A developer set a $0.01 budget for a test agent. The agent triggered a serverless function charged to a different billing account with no cap. 500,000 product updates ran overnight.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Cost:&lt;/strong&gt; $112.43 in uncapped charges. The agent's tracker showed $0.0062.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How agent-gov Prevents It:&lt;/strong&gt; Register the function as a tool with its true cost. 500,000 × $0.0002 = $100 — instantly exceeding the $0.01 budget. Agent paused after the first call.&lt;/p&gt;

&lt;p&gt;Cost attribution makes debugging 3 seconds instead of 3 hours:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agent-gov runs inspect run-abc123
- LLM calls: $0.0062
- Tool calls: cloudflare-function: 500,000 x $0.0002 = $100.00
- Total: $100.01
- Budget: $0.01 -&amp;gt; PAUSED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Disaster #5: The Multi-Tenant Billing Fiasco
&lt;/h2&gt;

&lt;p&gt;A B2B SaaS company offered AI agents as a feature. Each customer had its own agents. Billed $500/month, expected ~$200 in compute.&lt;/p&gt;

&lt;p&gt;Customer A deployed 14 agents across 40 campaigns. Three months later: &lt;strong&gt;$4,200 compute vs $1,500 billed&lt;/strong&gt;. Customer A wiped out the quarter's margin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Cost:&lt;/strong&gt; $2,700 lost on one customer. No visibility until quarterly review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How agent-gov Prevents It:&lt;/strong&gt; Workspace isolation with per-workspace budgets.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agent-gov workspace create customer-a &lt;span class="nt"&gt;--budget&lt;/span&gt; 200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When Customer A pushes past $200, agent-gov alerts or pauses. The SaaS company can offer tiered plans. Overconsumption becomes an upgrade opportunity.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Common Thread
&lt;/h2&gt;

&lt;p&gt;Every disaster shares the same root cause: &lt;strong&gt;agents had no cost guardrails&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;AI agents are fundamentally different from traditional software. A traditional API handles one request. An agent can branch, loop, call external APIs — the execution path is a tree, not a line.&lt;/p&gt;

&lt;p&gt;You can't budget for what you can't see. And you can't control what you haven't measured.&lt;/p&gt;

&lt;p&gt;Agent-gov gives you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Visibility&lt;/strong&gt; — Real-time cost tracking per agent, per tool, per workspace&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control&lt;/strong&gt; — Hard budget caps with auto-pause and alerting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolation&lt;/strong&gt; — Per-agent budgets inside shared pools, per-workspace billing&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The agents are coming — they're already here. The question isn't whether you'll deploy them. It's whether you'll know what they cost before the bill arrives.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Agent-gov is open source and available on GitHub. Set up your first cost policy in under a minute.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>devops</category>
      <category>python</category>
    </item>
    <item>
      <title>Inside agent-gov: Architecture of an Agent Cost Governance Platform</title>
      <dc:creator>Sathish Chelliah</dc:creator>
      <pubDate>Sun, 31 May 2026 13:21:01 +0000</pubDate>
      <link>https://dev.to/sschelliah/inside-agent-gov-architecture-of-an-agent-cost-governance-platform-27jl</link>
      <guid>https://dev.to/sschelliah/inside-agent-gov-architecture-of-an-agent-cost-governance-platform-27jl</guid>
      <description>&lt;h1&gt;
  
  
  Inside agent-gov: Architecture of an Agent Cost Governance Platform
&lt;/h1&gt;

&lt;p&gt;AI agents orchestrate complex workflows — calling LLMs, scraping pages, querying databases, sending emails. Each call costs real money. Without a governance layer, a single buggy loop can burn through your budget before anyone notices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;agent-gov&lt;/strong&gt; is an open-source reverse proxy that intercepts every tool call your agents make, enforces budgets in real time, and auto-pauses out-of-control agents. Built as a FastAPI service with SQLite persistence, running 45 tests in 0.3 seconds.&lt;/p&gt;

&lt;p&gt;This post walks through the architecture: the proxy pattern, the four-stage decision tree, cost tracking with a tool registry, multi-tenancy via workspaces, and the lazy auto-reset pattern.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Proxy Pattern
&lt;/h2&gt;

&lt;p&gt;Every AI agent tool call passes through agent-gov before reaching the actual tool. The agent sends a &lt;code&gt;POST /proxy/call&lt;/code&gt; with its API key, tool name, and estimated cost. agent-gov validates, budgets, and logs — then returns a 200 to approve or a 429 to reject.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ToolCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;agent_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
    &lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
    &lt;span class="n"&gt;estimated_cost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ge&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The proxy doesn't execute the tool itself — it guards access. The agent only proceeds if the proxy returns 200. This is the &lt;strong&gt;gatekeeper pattern&lt;/strong&gt;: a lightweight decision layer between the agent and the outside world.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent -&amp;gt; POST /proxy/call -&amp;gt; agent-gov -&amp;gt; 200/429 -&amp;gt; Agent decides
                                                      |
                                                 Calls actual tool
                                                      |
                                                      v
                                               OpenAI / Browser / API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why a proxy instead of a library? A library can be monkey-patched, removed, or forgotten. A proxy is a network boundary that agents &lt;em&gt;must&lt;/em&gt; cross — it can't be bypassed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Decision Tree: Auth -&amp;gt; Check -&amp;gt; Budget -&amp;gt; Log
&lt;/h2&gt;

&lt;p&gt;Every proxy call runs through a four-stage pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/proxy/call&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;proxy_tool_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ToolCall&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;key_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agent_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Step 1: Auth
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid API key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Step 2: Paused check
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;paused&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Agent &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; is paused.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Step 3: Auto-reset budget if new day
&lt;/span&gt;    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check_and_reset_budget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Step 4: Look up REAL tool cost
&lt;/span&gt;    &lt;span class="n"&gt;registered_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;actual_cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;registered_tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cost_per_call&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;registered_tool&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;estimated_cost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Step 5: Budget check
&lt;/span&gt;    &lt;span class="n"&gt;new_total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;spent_today&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;actual_cost&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;new_total&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;daily_budget&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pause_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Budget exceeded — agent auto-paused.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Step 6: Approved — update spend and log
&lt;/span&gt;    &lt;span class="n"&gt;updated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_agent_spend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actual_cost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log_cost_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actual_cost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;approved&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Exit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Does the API key hash match?&lt;/td&gt;
&lt;td&gt;401 — Invalid key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pause&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Is the agent paused?&lt;/td&gt;
&lt;td&gt;429 — Agent paused&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reset&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;New day since last call?&lt;/td&gt;
&lt;td&gt;(silent)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Budget&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Would this exceed the daily cap?&lt;/td&gt;
&lt;td&gt;429 + auto-pause&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Log&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;INSERT cost event&lt;/td&gt;
&lt;td&gt;200 — Approved&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Cost Tracking: Registry vs. Estimate
&lt;/h2&gt;

&lt;p&gt;The trickiest design decision was cost determination. Trusting the agent's &lt;code&gt;estimated_cost&lt;/code&gt; is fragile — agents can under-report.&lt;/p&gt;

&lt;p&gt;agent-gov uses a &lt;strong&gt;tool registry&lt;/strong&gt;: an UPSERT-able table of known tools with real per-call costs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;registered_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;actual_cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;registered_tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cost_per_call&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
               &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;registered_tool&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;estimated_cost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the tool is registered, its &lt;strong&gt;true cost&lt;/strong&gt; is used. The response includes a &lt;code&gt;cost_source&lt;/code&gt; field so clients know which path was taken.&lt;/p&gt;

&lt;p&gt;The test proves an agent can't lie its way past governance: an agent with a $100 budget claiming a $1 estimate for a tool registered at $500/call gets blocked with 429.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-Tenancy: Workspace Isolation
&lt;/h2&gt;

&lt;p&gt;v0.5 introduced workspaces — isolated tenants with their own agents, tools, and cost events. Each workspace gets a unique ID and API key. Every database row carries a &lt;code&gt;workspace_id&lt;/code&gt; FK column.&lt;/p&gt;

&lt;p&gt;Schema migration uses &lt;code&gt;PRAGMA table_info&lt;/code&gt; to add columns only when missing — SQLite doesn't support &lt;code&gt;IF NOT EXISTS&lt;/code&gt; for &lt;code&gt;ALTER TABLE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Tests verify workspace isolation: two workspaces, agents in each, neither can see the other's data.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Auto-Reset Pattern: Lazy Daily Budgets
&lt;/h2&gt;

&lt;p&gt;Instead of a midnight cron job creating a thundering herd, agent-gov uses &lt;strong&gt;lazy evaluation&lt;/strong&gt;: every proxy call checks if a reset is needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_and_reset_budget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;last_reset&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;paused&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;reset_daily_budget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;key_hash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An agent that makes no calls doesn't need a reset. The thundering herd becomes a gentle trickle.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The next evolution: per-tool budget caps, webhook-based alerts, and a management API. But the foundation — a simple, testable, async governance proxy — is solid.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;agent-gov is open source and MIT licensed. 45 tests. Zero database setup.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>architecture</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>Announcing agent-gov: Open-Source AI Agent Cost Governance</title>
      <dc:creator>Sathish Chelliah</dc:creator>
      <pubDate>Sun, 31 May 2026 13:20:59 +0000</pubDate>
      <link>https://dev.to/sschelliah/announcing-agent-gov-open-source-ai-agent-cost-governance-nj9</link>
      <guid>https://dev.to/sschelliah/announcing-agent-gov-open-source-ai-agent-cost-governance-nj9</guid>
      <description>&lt;h1&gt;
  
  
  Announcing agent-gov: Open-Source AI Agent Cost Governance
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Stop waking up to surprise $500 bills from your AI agents.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The 3 AM Wake-Up Call
&lt;/h2&gt;

&lt;p&gt;It was 3:47 AM on a Tuesday. My phone buzzed — a Cloudflare bill alert. Then another. Then Stripe. By the time I stumbled to my laptop, three different providers had collectively racked up &lt;strong&gt;$487&lt;/strong&gt; in just six hours.&lt;/p&gt;

&lt;p&gt;What happened? A single AI coding agent had gotten stuck in a loop. It was re-analyzing the same bug, calling the same expensive LLM endpoint over and over, spawning sub-agents that spawned &lt;em&gt;their own&lt;/em&gt; sub-agents. Nobody put a governor on it. Nobody thought they needed to.&lt;/p&gt;

&lt;p&gt;If you've built anything with AI agents — auto-PR reviewers, customer-support bots, code-gen pipelines, web-research assistants — you've either had this nightmare or you're one sleep cycle away from it. The fundamental problem is simple: &lt;strong&gt;agents spend money the same way junior devs write code — enthusiastically, autonomously, and without asking permission.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most teams solve this with spreadsheets and hope. Some bolt on a cloud budget alert &lt;em&gt;after&lt;/em&gt; the first blowup. A few give up on agents entirely.&lt;/p&gt;

&lt;p&gt;We wanted a real answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter agent-gov
&lt;/h2&gt;

&lt;p&gt;Today I'm releasing &lt;strong&gt;agent-gov&lt;/strong&gt; — an open-source, MIT-licensed cost governance platform purpose-built for AI agents. It's a lightweight reverse proxy that sits &lt;em&gt;between&lt;/em&gt; your agents and their LLM providers, tracking every cent, enforcing daily budgets, and &lt;strong&gt;auto-pausing agents that overspend.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;pip install agent-gov-saas
agent-gov start
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Thirty seconds from zero to governance.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;Agent-gov is transparent to your agents. You point them at a local proxy endpoint instead of directly at the API, and agent-gov handles the rest:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Intercept&lt;/strong&gt; — every model call routes through agent-gov's FastAPI proxy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Look up real costs&lt;/strong&gt; — the built-in tool registry knows exact per-token pricing for hundreds of models&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enforce budgets&lt;/strong&gt; — if an agent exceeds its daily allocation, agent-gov blocks the call&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persist everything&lt;/strong&gt; — all usage is written to SQLite via aiosqlite&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No lock-in. No cloud dependency. No per-seat licensing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features in v0.5
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reverse proxy middleware&lt;/strong&gt; — drop-in for any OpenAI-compatible client&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQLite persistence&lt;/strong&gt; — full audit trail of every call, token, and dollar&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool registry with real cost tables&lt;/strong&gt; — priced by model, provider, and input/output token rates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Daily budgets with auto-reset&lt;/strong&gt; — configure per-agent, per-workspace, or globally&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-pause on over-budget&lt;/strong&gt; — agents get a structured policy block&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-tenant workspaces&lt;/strong&gt; — isolate costs by team or project&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker support&lt;/strong&gt; — &lt;code&gt;docker compose up&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;45 tests, 0.3 seconds&lt;/strong&gt; — tight, fast, well-tested codebase&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quickstart
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;agent-gov-saas
agent-gov start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set a $5 daily budget:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agent-gov config &lt;span class="nb"&gt;set &lt;/span&gt;budget 5.00 &lt;span class="nt"&gt;--agent&lt;/span&gt; code-review-bot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why We Built This
&lt;/h2&gt;

&lt;p&gt;The AI agent ecosystem is exploding. But the operational maturity around it is where web apps were in 2009. We're all running agents without guardrails because nobody has built the guardrails yet.&lt;/p&gt;

&lt;p&gt;Agent-gov is the &lt;strong&gt;circuit breaker&lt;/strong&gt; for your agent infrastructure — the thing that prevents a single runaway loop from costing you a week of GPU credits.&lt;/p&gt;

&lt;p&gt;The project is MIT-licensed because cost governance isn't a moat — it's table stakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Involved
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/sschelliah2026-source/agent-gov" rel="noopener noreferrer"&gt;github.com/sschelliah2026-source/agent-gov&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install:&lt;/strong&gt; &lt;code&gt;pip install agent-gov-saas&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Don't learn you need cost governance at 3 AM.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with FastAPI, SQLite, and a healthy fear of surprise bills.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>ai</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
