terminal Supratim Get Started
Phase 0c complete

Model Reliability Test

Empirical go/no-go: can models reliably drive Supratim's agentic tool loop? Sarvam baseline + Ollama Cloud free tier โ€” real API calls, real transcripts.

๐Ÿ“… 2026-06-16 โ€“ 17 ๐Ÿ’ฐ Sarvam ~โ‚น1.81 ยท Ollama free tier ๐Ÿ›  6 tasks ร— 4 models โœ… Phase 0c complete
Before building MCP integration and deeper agentic features, we needed ground truth on the models we ship with. A model that silently fails or loops indefinitely is worse than no model โ€” it burns API quota, produces no output, and poisons downstream runs. This was not a benchmark; it was a go/no-go signal for Phase 2 defaults.

Methodology

ItemDetail
Toolsupratim --print "<task>" โ€” Pi print mode, one fresh session per task, no simulation
Harnessscripts/run-eval.ps1 โ€” PowerShell job runner, per-task timeout, stdout/stderr capture
DebugSUPRATIM_DEBUG=1 โ†’ api-debug.ts logs per-turn request shape, HTTP status, token counts to debug-<ts>.jsonl
Token reporting[tokens] in=X out=Y cost=โ‚นZ emitted to stderr after every run (friction #12 resolved)
PassesPhase 0 initial (120 s timeout) + extended (105b: 600 s no-timeout; 30b: 180 s + debug logging)

Task Battery โ€” 6 Escalating Tasks

#TaskCapability probed
T1Read src/cli.ts and summarise itSingle read tool call
T2Find every TODO/FIXME in src/, output as file:lineread + bash/grep chain
T3Add error handling to storeApiKey; show final fileread โ†’ edit, valid patch
T4Run npm run build; fix if broken; report resultbash โ†’ react โ†’ report
T5Add --dry-run flag wired through parser, handler, and --helpMulti-file coherent edit
T6List every export from src/ never imported anywhereCross-file reasoning, no obvious shortcut

Results โ€” Initial Pass (120 s timeout)

ModelT1T2T3T4T5T6
sarvam-105b โœ… 25 s โœ… 11 s โœ… 12 s โœ… 41 s โฑ timeout โฑ timeout
sarvam-30b โœ… 9 s โœ… 7 s โœ… 11 s โš ๏ธ empty โŒ empty โŒ empty

Results โ€” Pass 2: Extended (105b: no timeout; 30b: debug logging)

ModelTaskElapsedTurnsOutput tokensCostOutcome
sarvam-105bT559 s213,666โ‚น0.54Partial โ€” loop closed, code bug (no tsc check)
sarvam-105bT66 s0โ€”โ€”Blocked โ€” rate-limited after T5
sarvam-30bT412 s2213โ‚น0.01Partial โ€” ran build, minimal report
sarvam-30bT5186 s (killed)185+~22โ€“49/turn~โ‚น0.06Fail โ€” infinite tool loop
sarvam-30bT63 s0โ€”โ€”Blocked โ€” rate-limited after T5's loop
sarvam-30b (maxTokens=8192)T44 s0โ€”โ€”Fail โ€” API hard-rejects >4096

Results โ€” Pass 3: BOM fix + guards live

! Root cause of all prior retry failures: UTF-8 BOM

All T5/T6 retries after Pass 2 showed "models not available" โ€” attributed to rate-limiting but actually caused by PowerShell's Set-Content -Encoding UTF8 writing a BOM (0xEF BB BF) to ~/.supratim/models.json. JSON.parse rejected the file silently. Fixed by using [System.Text.UTF8Encoding]::new($false) throughout the harness.

ModelTaskElapsedTurnsOutput tokensCostOutcome
sarvam-105b + guardsT599 s30 (cut)3,022โ‚น0.92Cut by turn-limit โ€” partial edit, loop
sarvam-105b + guardsT655 s30 (cut)2,871โ‚น1.24Cut by turn-limit โ€” collapsed at turn 2

Results โ€” Phase 0c: Ollama Cloud free tier

Same battery on Ollama Cloud free plan (qwen3-coder:480b, devstral-2:123b). Cost is not a variable here โ€” we compared wall-clock time and whether the loop converges. Sarvam baseline included for timing only.
Tasksarvam-105bqwen3-coder:480bdevstral-2:123b
T125 s19 s26 s
T211 s29 s12 s
T312 s54 s15 s
T441 s111 s18 s
T5loop107 s โœ“loop
T6never done251 s โœ“55 s โœ“
โ˜… Ollama free tier wins on hard tasks โ€” not on price

qwen3-coder:480b is the only model that completed all 6 tasks. devstral-2:123b finished T6 in 55 s (vs 251 s) but looped on T5 like Sarvam. Sarvam 105b never completed cross-file T6 in any pass. On Ollama free, the trade-off is speed vs loop reliability, not rupees.

Findings

1 sarvam-30b enters an infinite tool-call loop on T5

Every turn in the 30b T5 run ended with tool_result_count: 1 โ€” the model never stopped dispatching tools. All HTTP responses were 200. The API was healthy. After turn 1 (1,277 output tokens), every subsequent turn collapsed to 22โ€“49 output tokens โ€” just enough to emit another tool call, never a final text response.

Turn  1: in=3,789  out=1,277  tools=1  โ† first productive turn Turn  2: in=4,212  out=39     tools=1 Turn  3: in=4,455  out=22     tools=1 Turn  4: in=4,778  out=22     tools=1 ... Turn 185: in=24,636 out=49     tools=1  โ† killed at 180 s

Root cause: sarvam-30b cannot decide when to stop calling tools on multi-step edit tasks. It keeps dispatching rather than synthesising a conclusion. The earlier "silent empty response" description was correct in effect but wrong in cause โ€” the model was not silent, it was spinning.

2 The 4096 output token cap is a hard Sarvam tier limit

Setting maxTokens: 8192 in user config causes the Sarvam API to reject the first real request (after the 20-token validation call succeeds), surfacing as "Sarvam models are not available." This is not a config issue โ€” the API hard-rejects max_tokens > 4096 on the starter tier. It cannot be worked around.

Validation call (20 tokens) โ†’ โœ… success  |  First agent request (max_tokens=8192) โ†’ โŒ rejected
3 sarvam-105b also loops โ€” the pattern is not 30b-exclusive

Pass 3 showed 105b collapsing to 21-token tool calls on both T5 and T6 after 2โ€“6 productive turns. The signature is identical to 30b's loop:

T1: out=1,170 tools=1 โ† productive\nT2: out=300 tools=1 โ† productive\nT3: out=11 tools=1 โ† collapsing\nT4: out=330 tools=1 โ† brief recovery (tsc gate firing)\nT6-T14: out=21-22 tools=1 โ† loop (9 consecutive turns)\nT15: out=294 tools=1 โ† another brief recovery\nT16-T30: out=19-43 tools=1 โ† loop โ€” cut by guard

105b makes more productive attempts and the tsc gate causes brief recoveries, but it cannot sustain convergence across 30 turns on multi-file tasks. T6 (cross-file) collapsed after turn 2 and produced 14โ€“19 tokens per turn for 28 remaining turns.

The turn-limit guard is essential for both models. Pass 3 confirmed: 105b T5 cost โ‚น0.92 at 30 turns; without the guard it would have run indefinitely.

4 30b's loop burns the hourly API quota

After 30b's 185-turn T5 run (180 s of continuous API calls), the account was rate-limited for over 75 minutes. All retry attempts failed during this window. The turn-limit guard would have cut the 30b loop at 30 turns (~25 s, ~โ‚น0.06) instead of 185 turns.

5 PowerShell UTF-8 BOM silently corrupts models.json

PowerShell 5.x Set-Content -Encoding UTF8 writes a BOM (0xEF 0xBB 0xBF) prefix. The eval harness wrote it during the MaxTokens patch-and-restore step. JSON.parse failed with "Unexpected token '๏ปฟ'" โ€” surfaced as "models not available." All harness writes now use [System.Text.UTF8Encoding]::new($false).

This masked all retry failures for ~75 minutes as "rate-limiting" when they were actually a JSON parse error. The real rate limit cleared much sooner.
6 Token reporting (friction #12) is now live

Every --print run now emits a cost summary to stderr. Previously evaluation runs had no visibility into spend.

[tokens] in=119362 out=3666 cacheRead=0 req=21 cost=โ‚น0.5361

Guards Shipped (Phase 0b)

๐Ÿ”ฌ

ts-verify

After every edit/write to a .ts file, runs tsc --noEmit and appends the result to tool output. The model sees compile errors inline. Disable: SUPRATIM_TSC_VERIFY=0

๐Ÿ›‘

turn-limit

Aborts the agent loop after SUPRATIM_MAX_TURNS turns (default: 30). Normal complex tasks use 5โ€“25 turns; over 30 is almost certainly a loop. Disable: SUPRATIM_MAX_TURNS=0

Inferences

1Both 30b and 105b loop on multi-file tasks. 105b collapses to 21-token calls after 2โ€“6 productive turns; 30b from turn 2.
2105b remains the better default. Makes more productive turns, partially implements changes, recovers briefly when tsc gate fires.
3Turn-limit guard is essential for both models โ€” now shipped. Pass 3 confirmed: cuts 105b loop at 30 turns (โ‚น0.92) vs 185+ (โ‚น4+).
4tsc-verify gate causes brief recoveries but can't prevent the loop. Valuable for surfacing errors; insufficient alone for convergence.
5maxTokens is immovable at 4096 on the starter tier.
6PowerShell UTF-8 BOM corrupts models.json silently. Use UTF8NoBOM for all harness writes.
7Ollama free tier solves T6; Sarvam doesn't. qwen3 completed all 6; devstral T6 in 55 s. Cost N/A on free โ€” compare time and convergence.

Verdict

Sarvam default

sarvam-105b

Fast T1โ€“T4. Loops on T5/T6. โ‚น quota + rate-limit risk. Turn-limit guard essential.

Ollama ยท reliability

qwen3-coder:480b

Only model to finish all 6 tasks on free tier. Slower on simple tasks; converges on hard ones.

Ollama ยท speed

devstral-2:123b

Fastest T2โ€“T4 and T6 (55 s). Loops on T5. Best when task is read/analyse, not multi-file edit.

Not for agentic use

sarvam-30b

Infinite tool-dispatch loop on any task >2 turns. Suitable only for fast single-turn queries.

What This Means for the Project

โœ… Shipped

  • Default model โ†’ sarvam-105b
  • ts-verify โ€” post-edit tsc --noEmit gate
  • turn-limit โ€” 30-turn abort guard
  • api-debug โ€” SUPRATIM_DEBUG=1 per-turn logging
  • Print-mode [tokens] reporting

๐Ÿ”ง Phase 2 scope

  • BYOK: Sarvam default + Ollama Cloud as optional provider
  • Structured exploration for T6-class tasks
  • Turn-limit + tsc-verify on all providers

๐Ÿ”ฌ Phase 2 investigation

  • reasoning_effort: "low" for both models โ€” may reduce loop
  • Improve "models not available" error โ€” surface root cause (BOM, rate limit, API rejection)