Sunday, September 27, 2026

GROKBOT :: I Asked an “AI Teammate” to Fill One Form. It Couldn’t.

I have been a fan of Grok for a long time now..  I endured the lack of a CLI when every other provider offered it. I saw how it was not included originally with CLI tools providers like Cursor for a long time too. 

Then they released Grok Build and a CLI tool. I like it.. I am not thrilled with the usage quota options and the billing felt very odd at the start (I posted about that before) but better once it opened it up to Supergrok users. Now of X bought Cursor, so now Grok basically has 2 CLI tools. Never feels like a smart business move to have 2 competing products under your own roof, so clearly one of these will fade away, time will tell.  I think now that GrokBot it gaining acceptance Grok Build CLI will likely go away, sucks that is the one I like. 

So ... I agree with Elon in some regards as well  "Grok is falling behind" and frankly a little all over the place but the falling behind part of me.. is when you release a product that cannot even work with your other products. 

I spent some time today trying to use Grok Bot like the pitch says you can: as an AI employee that sits on a computer, opens a browser, and does the work.

xAI’s own pages say it plainly:

“Grok Bot is your team of always-on agents. They have their own computer, work inside tools and apps like you do, and keep working 24/7.” — https://x.ai/news/introducing-grok-bot

“AI teammates you can give real work to. Bots can sign in to your tools, use them just like you do, and come back with finished work.” — https://x.ai/bot

So I gave it real work.

The test was simple. Generate short vertical videos of a consistent AI character in Grok Imagine. The character has a reference id. You put that reference in the prompt. The face locks. You hit generate.

Without that reference, you get a random character. Tokens burn. The take is useless.

So the real job was not “write a good prompt.” The real job was: put the reference in the box.


What worked when I did it myself

I can paste this into Imagine and it works:

Adult character reference @1fd6abc-xxxxxxx...

When I paste it by hand, Grok keeps the reference. The face locks. Generation is usable.

Settings were never the hard part. Video. 720p. 6 seconds. 9:16. The bot could flip those toggles fine.

What failed when the bot did it

Every automated attempt to put that same reference into the same box failed.

  • Typing the @ id into the field stripped it. The box left the prompt with no reference.
  • Typing bare @ opened the wrong picker (“No attachments to reference”).
  • Putting the full prompt on the OS clipboard and pasting with Ctrl+V also stripped the @ id. Same result: text without the reference, no chip, no lock.

So I even used Grok Bot to audit the failure. Populate only. No Submit. Screenshot the box.

Result: fail. Clipboard held the full string with the id. After automated paste, the id was gone.

I can populate the form. The bot cannot.

Why that is a product failure

If your product is “AI teammate,” the bar is not clever chat.

The bar is: open the tool the job needs, fill the field that makes the job real, and keep going.

Grok Bot can talk about scenes. It can rewrite prompts. It can argue about camera physics. It can hand me paste-ready text so I do the one step that matters.

That is not a teammate. That is an idea generator with a desktop.

An assistant that cannot put a reference into a form — especially a form on the same company’s Imagine product — is not ready for the job it is sold as.

What I learned the hard way

  1. Prompt quality and form control are different skills. I got good prompts out of the loop. I did not get generation.
  2. “It works when I paste” is not the same as “the agent can paste.” Manual success hid an automation gap.
  3. Settings success is a fake green light. Toggles worked. The one token that mattered did not survive.
  4. If the agent can’t lock identity, it can’t ship character content. Everything else is theater.


What I expect next

I am not asking for magic video.

I am asking for the boring thing: reliably insert a character reference into Grok Imagine so it stays there as a locked reference, then submit when told.

I am asking for the tool to be able to work with the company’s own tools before I trust it to do anything more.

Until that works, call it what it is. A writing assistant with a browser. Not an AI teammate.

 

Thursday, September 17, 2026

Union Alpha on OpenRouter: An Honest Scorecard for the Free Stealth Model

Union Alpha on OpenRouter: An Honest Scorecard for the Free Stealth Model

stealth/union-alpha landed September 16 — free, anonymous, multimodal, 262k context. I put it through a scripted battery, compared fingerprints against named peers, and kept the transcripts. The engine is usable. The envelope has sharp edges. And we can prove more about what it is than the marketing copy admits.


What the registry actually claims

Pulled live from OpenRouter's model API on 2026-09-17:

ClaimValue
Model idstealth/union-alpha
Context window262,144
Max output131,072
Modalitiestext+image → text
Tool calling / structured outputboth listed
Reasoning controlsnone exposed
Pricing$0 / $0 (preview)
Tokenizer field"Other"
Listed2026-09-16

Two rows matter immediately. Context is a 256k-class window, not a million. And there is no reasoning dial in the public parameter list — if someone tells you to "turn thinking down," that control is not on this route.


How I tested

Ground truths are computed by the script: products, letter counts, vault codes planted in a haystack the script built, shapes and serials rendered into a PNG the script drew. The grader is regex and arithmetic. Structural prompts also ran against named models on my Ollama Cloud shelf and same-gateway OpenRouter peers so exclusions have neighbors, not vibes.

  • Objective reasoning — 847×396, chained ops with a decimal midpoint, letter count, changed-numbers bat/ball trap
  • Structured output — strict json_schema extraction, three runs
  • Tool calling — single, parallel (Tokyo + Paris + 12*9), forced tool_choice=calculator on "just say hello"
  • Long context — needles at 10%/50%/90% plus a phantom honesty probe, laddered at ~50k / ~180k / ~250k / ~300k
  • Vision — ground-truth image with large code, small serial, four shapes
  • Latency / streaming — TTFT and completion shape on a ~250-word technical paragraph
  • Tokenizer fingerprint — six adversarial strings vs GLM-5.3-Flash, GLM-5.3, Qwen3.5, DeepSeek-V4-Flash, Kimi-K2.7-Code, MiniMax-M3, Gemma4 via Ollama Cloud; same-gateway OpenRouter vs qwen/qwen3.5-plus; local llama3.1:8b; and raw Meta-Llama-3-8B/tokenizer.json pairwise deltas

What held up

TestResultDetail
Reasoning battery4/4335412; 86.95; letter count 12; ball = 10 cents. All clean.
Vision5/5OX-7391, serial KX-4417, red circle / blue rect / yellow triangle / green line. Wall time 1.89s.
Single tool callPASSget_weather({"city":"Tokyo"})
Parallel tool callsPASSThree separate calls: Tokyo, Paris, 12*9. No duplicate-key collapse.
Exact format followPASSFive-line LINE1..LINE5 contract honored.
Long-context retrievalclean through ~250kNeedles hit at 54,856 / 179,807 / 250,447 reported prompt tokens.
Honesty at depthperfectPhantom needle answered NONE at every successful rung.

Parallel tools matter for agents: three clean function calls with legal JSON, no duplicate-key collapse. Long context matters too: the listing is 262k, and inside that window retrieval holds. At ~250k reported tokens — all three needles, honest NONE on the phantom. That is not "context theater." That is a working 256k-class window.


Where it broke

1. Strict JSON schema hard-fails (0/3)

The registry lists response_format. I sent a strict schema for an order extraction. Three runs. Three provider 400s from Stealth — a hard reject:

{"error":{"message":"Provider returned error","code":400,
 "metadata":{"raw":"ERROR","provider_name":"Stealth"}}}

Different failure mode, same practical rule: do not trust structured-output parameters on this route. Ask for JSON in the prompt, parse, validate yourself.

2. Forced tool_choice is ignored

Forced calculator on "Just say hello to me. Do not check anything." Response:

Hello! 👋 Nice to meet you. How can I help you today?

Zero tool calls. Finish reason stop. Correct social manners, wrong contract.

On Ollama Cloud the same forced-choice prompt was also ignored by GLM-5.3-Flash, GLM-5.3, DeepSeek-V4-Flash, Kimi-K2.7-Code, and MiniMax-M3. So on that shelf this failure is not unique to union. Treat forced choice as unverified until your own stack proves it.

3. The "reasoning effort" dial does nothing here

I sent reasoning: {effort: low|high|max} on the same multiplication. Answers were correct all three times. Token shape was not:

Effort claimedCompletion tokensReasoning tokens reportedWall
low49010.99s
high52010.86s
max52010.69s

Union-alpha swallows the parameter. That matches the registry: no reasoning controls exposed. Do not budget as if you can turn thinking down.

4. Past the listed window, it fails honestly

At a ~300k target (past the 262,144 listing), the route returned HTTP 400 after retries — not an empty 200. Honest cliff, still a hard stop. Cap prompts under the listed 262k with margin; I would stay under ~200k for production agent loops until you measure your own workload.

5. Interactive latency is the tax

Streaming a ~250-word technical paragraph:

  • Time to first visible token: 44.63s
  • Visible text: ~1,746 characters
  • Reported completion tokens: 2,669 (most of that is invisible thinking / billing, not the paragraph you read)
  • Effective visible throughput on wall clock: roughly ~10 tokens/sec class, not a snappy chat model

Warm literal PONG came back in ~6–8s. Fine for batch and agent steps that can wait. Not what you want for a human sitting on the other side of a blinking cursor.


Head-to-head on the Ollama Cloud shelf

Same structural prompts, named models I already run — including the Qwen shelf, because if the vision tower smells Qwen-family you still have to check whether the whole model is Qwen:

Model847×396Parallel toolsForced tool_choice
stealth/union-alpha (OpenRouter)✓ 335412✓✗ ignored
glm-5.3-flash:cloud✓ (with thinking)✓✗ ignored
glm-5.3:cloud✓ (with thinking)✓✗ ignored
qwen3.5:cloud△ thinking-heavy / empty content at 256–512 cap✓✗ ignored
qwen3.5:397b-cloud△ same shape as qwen3.5:cloud✓✗ ignored
deepseek-v4-flash:cloud✓✓✗ ignored
kimi-k2.7-code:cloud✓ (with thinking)✓✗ ignored
minimax-m3:cloud✓ (with thinking)✓✗ ignored

Retired on this host today (HTTP 410): qwen3-vl:235b-cloud, qwen3-vl:235b-instruct-cloud, qwen3-next:80b-cloud, qwen3-coder-next:cloud. So the live Qwen comparison is the 3.5 line, not the old VL SKUs.

Read the table for what it is: union-alpha is not uniquely broken on forced choice in this Ollama sample, and not uniquely strong on parallel tools either — GLM and Qwen3.5 both emit clean Tokyo/Paris/12*9 calls. The structural scorecard above is about union; the shelf just keeps "broken everywhere" vs "broken here" honest.


So what is it? What we can prove vs what we still can't

I wanted a fingerprint with a flat residual — the kind of proof that survives a second look — not a vibes ranking. Here is what actually locked, and what bounced off Stealth's accounting.

Proven in this lab (concrete)

1. Vision tower billing matches the Qwen2-VL family formula — exactly. I sent solid red PNGs at eight sizes and recorded OpenRouter prompt_tokens:

Image sizeprompt_tokensmax(22, ceil(H/28)²+6)pt − formula
322022−2
642022−2
962022−2
1282931−2
1925355−2
256104106−2
384200202−2
512365367−2

Eight sizes. Residual after a constant −2 text overhead: 0.0 mean abs, 0.0 stdev. That is a real fingerprint hit. The vision encoder is Qwen2-VL-family shaped. That does not mean the whole model is stock Qwen — only that the image token accounting matches that tower family (28px patch merge curve).

2. Stealth text prompt_tokens are not a trustworthy tokenizer. Same probe, eight repeats:

  • English pangram: mostly 27, once 9
  • Digit run: mostly 84, once 199
  • Russian sentence: stable 36 in that window — but an earlier run reported 2 for the same string

Two counting modes flipping under identical prompts. That is why a Llama-3 text proof via usage keeps failing: the meter lies often enough to destroy pairwise delta matching. Same-gateway residuals vs meta-llama/llama-3.3-70b-instruct, z-ai/glm-5.3-flash, qwen/qwen3.5-27b, and deepseek/deepseek-v4.1-flash were all non-flat; pairwise hits topped out at 6/36 (Llama) vs 2/36 (GLM) / 1/36 (Qwen). Not a hit.

3. Hard exclusions still hold on the discriminative axes. When union sits on its common digit mode (~84), named peers on the same OpenRouter day land elsewhere: GLM-5.3-Flash 139, Qwen3.5-27b 210. Ollama Cloud digit deltas against union were GLM +52, Qwen3.5 +123/+127. Not GLM-5.3-Flash. Not stock Qwen3.5 text. Not Claude/GPT/Grok.

Not proven (and I will not pretend otherwise)

Text vocab species — Llama-3 vs private/other — is not locked by this battery. The llama3.1:8b 8.8/−10 row is not a fingerprint. Local Meta-Llama-3 tokenizer.json pairwise vs Stealth usage is not a fingerprint while the counter flips 27↔9. Llama-3-class text remains a candidate (and matches what stronger external probes have claimed), not a scorecard win from our usage method.

My call, stated plainly:

  • Proven here: vision tower is Qwen2-VL-family (billing curve, 8/8, residual 0).
  • Proven here: Stealth text token accounting is bimodal / unreliable (stability flips).
  • High confidence exclusions: not GLM-5.3-Flash, not stock Qwen3.5 text, not Claude/GPT/Grok.
  • Best synthesis: a cross-lineage multimodal — Qwen2-VL-class vision + a non-Qwen3.5 text backbone (Llama-3-class or private), unnamed post-train, Stealth front. That is an assembly claim, not a public SKU name.
  • Exact weights / vendor: still unnamed until a reveal.

If you're running it today

  1. Use it for agent loops that need clean parallel tool calls and can tolerate multi-second to multi-ten-second waits.
  2. Do not use response_format / strict json_schema on this route. Prompt for JSON, validate locally.
  3. Do not depend on forced tool_choice. Design the prompt so the tool call is the natural next step.
  4. Cap context under ~200k even though 250k retrieved in lab. Leave headroom for tools and system prompts.
  5. Expect the meter. Free stealth previews end. Architect like a price row (or a rename) shows up.
  6. Validate one call end-to-end before any batch. Free endpoints hide cost; they do not hide broken contracts.

The whole thing in five lines

# the engine is real
reasoning 4/4, vision 5/5, needles clean through ~250k, honest NONE

# the envelope still bites
json_schema -> HTTP 400     forced tool_choice -> ignored
reasoning.effort -> theater  interactive TTFT -> ~45s on long answers

# proven positive fingerprint
vision billing = Qwen2-VL formula max(22, ceil(H/28)^2+6)  [8/8 sizes, residual 0]

# proven that text usage ID is blocked
Stealth prompt_tokens flip (pangram 27<->9, digits 84<->199)

# exclusions still solid
not GLM, not stock Qwen3.5 text, not Claude/GPT/Grok

# the discipline
don't guess -- inspect

Related reading


Keith is a database consultant and infrastructure engineer with 25+ years of open-source experience. He builds the ApocryiaAI brand and DRAVEN work under 3k1o LLC (apocryia.com). He writes about MySQL, Proxmox, AI memory, multi-agent workflows, and building technology you can actually inspect.