<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Proxy on tsvinc</title>
		<link>https://tsvinc.dev/tags/proxy/</link>
		<description>Recent content in Proxy on tsvinc</description>
		<generator>Hugo</generator>
		<language>en-us</language>
		
		
		
		
			<lastBuildDate>Mon, 26 Oct 2026 00:00:00 +0000</lastBuildDate>
		
			<atom:link href="https://tsvinc.dev/tags/proxy/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>Bun&#39;s fetch had no way to skip the proxy</title>
				<link>https://tsvinc.dev/posts/fetch-had-no-proxy-off-switch/</link>
				<pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/fetch-had-no-proxy-off-switch/</guid>
				<description>&lt;p&gt;&lt;em&gt;Builds on &lt;a href=&#34;https://tsvinc.dev/posts/model-that-only-says-run/&#34;&gt;The model that only says RUN&lt;/a&gt;, which describes the fake model server and the six agent harnesses these templates set up.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;Bun&#39;s documentation for &lt;code&gt;fetch&lt;/code&gt; has a paragraph I only found after the fix was in: pass &lt;code&gt;proxy: false&lt;/code&gt; &amp;quot;to connect directly regardless of the environment&amp;quot;. The Bun my tests ran on, 1.3.10, accepts that option without complaint and then sends the request to the proxy anyway.&lt;/p&gt;&#xA;&lt;p&gt;That gap cost my agents their models. The config templates I keep for six terminal coding agents find local model servers in two places. At install time a Python tool asks each candidate host for its model list and writes the result into the configs. At run time a TypeScript module does the same thing inside OpenCode, pi and omp. Same hosts, same question, two languages.&lt;/p&gt;</description>
			</item>
			<item>
				<title>The benchmark said it was waiting. Once.</title>
				<link>https://tsvinc.dev/posts/bench-said-waiting-once/</link>
				<pubDate>Sun, 25 Oct 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/bench-said-waiting-once/</guid>
				<description>&lt;p&gt;At 12:36 on 25 October the proxy learned to see the A9&#39;s benchmark between two of its jobs. At 12:58 it learned to see the benchmark waiting behind the proxy&#39;s own engine. At 13:14 it learned that the benchmark mentions the waiting exactly once. At 13:59 it learned that once means once for the whole queue, not once per job. Four commits on a feature branch in 83 minutes, and each one found somewhere else the benchmark could be. Four more review passes went over them before any of it shipped, as v0.3.1, at 15:16.&lt;/p&gt;</description>
			</item>
			<item>
				<title>The design review found a Konsole tab</title>
				<link>https://tsvinc.dev/posts/design-review-konsole-tab/</link>
				<pubDate>Sun, 25 Oct 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/design-review-konsole-tab/</guid>
				<description>&lt;p&gt;Before I read the design review of my LAN proxy, three reports from three sides, I wrote down my own, so that afterwards I couldn&#39;t pretend to have seen anything coming. Three findings, four positions I&#39;d defend. The first finding was a real one: every request body went through a JSON parser three or four times before the proxy forwarded it, about 30 ms for a 1.4 MB request by my estimate. The performance review measured 20.5 ms for a 1.2 MB body through the whole proxy, against 0.48 ms direct, and rated it MEDIUM.&lt;/p&gt;</description>
			</item>
			<item>
				<title>The first engine on the A9 was started to be stopped</title>
				<link>https://tsvinc.dev/posts/started-to-be-stopped/</link>
				<pubDate>Sun, 25 Oct 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/started-to-be-stopped/</guid>
				<description>&lt;p&gt;Stopping a process is the easy half of proving that my LLM proxy gives a GPU back. On the A9 the hard half was letting it take the GPU at all. The one rule I keep about that box is that nothing gets in its benchmark&#39;s way, and the proxy had never started an engine there. The day before, its idle stop had sent the A9 a stop anyway (&lt;a href=&#34;https://tsvinc.dev/posts/cutting-a-stream-doesnt-cancel-the-turn/&#34;&gt;how idle stop managed that&lt;/a&gt;).&lt;/p&gt;</description>
			</item>
			<item>
				<title>The proxy said unloaded. The model was loading.</title>
				<link>https://tsvinc.dev/posts/status-said-unloaded/</link>
				<pubDate>Sun, 25 Oct 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/status-said-unloaded/</guid>
				<description>&lt;p&gt;Ten times in sixteen seconds the probe asked my proxy for its model list, and ten times it got back the same 54,031 bytes, with the model it had just asked to load listed as &lt;code&gt;unloaded&lt;/code&gt;. After fifteen seconds of that, the probe wrote its verdict and moved on:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;alias&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;3090-flint-40b&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;&amp;#34;configured_context&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;131072&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;3090-flint-40b returned to unloaded during load&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;&amp;#34;total_s&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;18.4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Four of the seven models in that run got the same line. None of them had unloaded. The 3090 box&#39;s router had accepted each load, exactly as asked.&lt;/p&gt;</description>
			</item>
			<item>
				<title>The shutdown grace that never ran</title>
				<link>https://tsvinc.dev/posts/shutdown-grace-never-ran/</link>
				<pubDate>Sun, 25 Oct 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/shutdown-grace-never-ran/</guid>
				<description>&lt;p&gt;The net/http documentation spends two sentences on the trap, in the comment on &lt;code&gt;Server.Shutdown&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// When Shutdown is called, [Serve], [ServeTLS], [ListenAndServe], and&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// [ListenAndServeTLS] immediately return [ErrServerClosed]. Make sure the&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// program doesn&amp;#39;t exit and waits instead for Shutdown to return.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;My LAN proxy for local models did the other thing. It started &lt;code&gt;Shutdown&lt;/code&gt; in a goroutine with a five-second budget, let &lt;code&gt;ListenAndServe&lt;/code&gt; return, and returned from &lt;code&gt;main&lt;/code&gt;. Until v0.3.0, every restart cut every stream going through it within milliseconds of the &lt;code&gt;SIGTERM&lt;/code&gt;, logged nothing about the requests it cut, and exited with status 0. The proxy needs a restart after every config edit, and its streams are coding agents&#39; turns against models on two GPU boxes, which can run for minutes.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Cutting a stream doesn&#39;t cancel the turn</title>
				<link>https://tsvinc.dev/posts/cutting-a-stream-doesnt-cancel-the-turn/</link>
				<pubDate>Sat, 24 Oct 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/cutting-a-stream-doesnt-cancel-the-turn/</guid>
				<description>&lt;p&gt;The plan was a router. One OpenAI- and Anthropic-compatible URL on a mini-PC, two GPU boxes behind it, read the request&#39;s &lt;code&gt;model&lt;/code&gt;, pick the box, forward the bytes. I started it at 23:37 one night. By 22:04 the next evening it was starting and stopping llama.cpp builds on the 3090 box (the A9&#39;s benchmarks kept it out that day), deciding when a request has to wait, and shutting engines down after fifteen idle minutes so a benchmark could have the GPU back.&lt;/p&gt;</description>
			</item>
			<item>
				<title>The fixes had the bugs</title>
				<link>https://tsvinc.dev/posts/fixes-had-the-bugs/</link>
				<pubDate>Sat, 24 Oct 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/fixes-had-the-bugs/</guid>
				<description>&lt;p&gt;Marking a fix done sounds like the easy part. Write the change, write a test, watch the suite go green, tick the box. I had 45 findings for my LAN proxy for local models, from a round of research into what coding agents and other clients send and what llama.cpp&#39;s endpoints expect. I had an afternoon of fixes, and a green suite.&lt;/p&gt;&#xA;&lt;p&gt;The fixes then went through an independent re-review, pass after pass, each one starting from the findings and the code rather than from my summary of what I&#39;d done. Seven passes found 11, 8, 10, 4, 2, 1 and 0 bugs. They weren&#39;t new findings about clients. They were in the fixes, and in the fixes of the fixes, and two of them could take the whole proxy down.&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
