Files
magpie/internal/settings
ArvakandClaude Sonnet 5.5 f1906bca6a gateway: draw and film through a Grok subscription (Grok Imagine) (#360)
* gateway: draw through a Grok subscription (Grok Imagine)

A Grok subscription (SuperGrok, X Premium+) could not draw: Drawers() returned
nothing for it and draw() refused with "Grok (SuperGrok) can't draw: magpie
draws only through an OpenAI-compatible API, and Grok (SuperGrok) has none".
Grok Build's own image_gen / image_edit tools call the backend's Imagine API
at <cli-chat-proxy.grok.com/v1>/images/generations and /images/edits with the
CLI's sign-in, which magpie already uses for chat.

- drawsGrok / grokDrawers: a Grok account draws with grok-imagine-image and
  grok-imagine-image-quality, like a ChatGPT account does with GPT Image
- the Imagine API takes an aspect ratio, not a size or quality: size
  WIDTHxHEIGHT is matched to the nearest ratio it accepts (aspectAmong,
  aspectOf is unchanged); the image is asked for as base64
- an edit is JSON with the images as data URLs
- a plan's images cost nothing extra, so AutoDrawer ranks Grok with ChatGPT
  (ChatGPT still wins a tie on release date)
- provider.grokBase is exported as GrokBase, like CodexBase, for the test

Tested against a real SuperGrok account through the gateway: generation,
16:9, the quality model and an edit. Video is not covered: the Grok CLI's
video tools need zero data retention off or a storage bucket.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* gateway: film through a Grok subscription, and a generate_video tool for agents

A Grok account that draws (c6578bc) can make videos too: Grok Imagine's
video endpoints sit behind the same sign-in.

The gateway speaks OpenAI's Videos API, so its SDK works as it is:
POST /v1/videos, GET /v1/videos/{id}, GET /v1/videos/{id}/content. A
request is taken on at once and polled; the id carries the provider and
the vendor's request id, so nothing is kept in the gateway and a restart
loses no video. Status is mapped (pending at 0% -> queued, pending ->
in_progress, done -> completed, failed/expired -> failed, with why).
seconds (1-15, the vendor's limit, which it says when exceeded), size
(-> aspect ratio and 480p/720p/1080p by the shorter side), input_reference
for image-to-video (URL, data URL, {image_url}, or a multipart file) and
reference_images are taken; a model that isn't a Grok video model is
refused by name. /content answers 409 until the video is ready.

`magpie mcp image` lists a second tool, generate_video: it starts the
video, waits (up to 10 minutes), saves the mp4 into the project
(generated-videos/ unless path says where, never over a file) and says
where, so an agent can animate an image it just drew by passing its path.

Checked against a real SuperGrok account: text-to-video, image-to-video
(input_reference), reference_images, both video models, the OpenAI
Python SDK (videos.create/retrieve/download_content), the MCP tool end to
end with two videos at once, and the error paths. Unit tests use a fake
Grok upstream.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* gateway: videos follow the Settings' off switch, and an id can't change the vendor's path

Review of the video change:

- Image generation "off" turns off the video a request that names no model
  gets (videomaker, beside drawer), so generate_video says it is off too.
- A video id is put in the vendor's URL with the account's token: its parts
  must be [A-Za-z0-9_-]+ (parseVideoID) and the vendor id is path-escaped, so
  video_grok.x%3Fa=1.1 and %2F answer 404 and ask the vendor nothing.
- The id carries a short mark of the account that started it; after a switch
  the video says it was started with another account instead of the vendor's
  not-found.
- generate_video waits up to ten minutes, and Codex gives a tool a minute:
  magpie-image's Codex entry gets tool_timeout_sec (Goose's timeout) of
  eleven minutes, the user's own value kept.
- grok-imagine-video stops at 720p (the vendor turns 1080p away for it; 1.5
  makes 1080p), so a 1080p size is asked at 720p there.
- A model may be named without its provider (grok-imagine-video).
- "seconds": 6.0 is 6; 6.5 is still refused.
- completed_at is left out: the vendor doesn't say when a video finished,
  and a time made up at each poll changed each time.

Checked against a real SuperGrok account: bare model name, seconds 2.0,
1080p on the base model asked at 720p (the mp4 is 1280x720), 1080p accepted
on 1.5, both malformed ids, no completed_at.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* gateway: TestVideoModelByItsBareName asks its two models in a fixed order

It checked the body of the second request the upstream got, but asked the
two models by ranging over a map, so it failed about one run in seven
(Ubuntu CI). Ask them from a slice.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* library: an installed magpie-image gets the longer tool timeout on the next sync

magpie-image already ships, so many users have it in Codex and Goose as it was
written before: no tool_timeout_sec in Codex, and the timeout: 300 every Goose
server was given. syncMCP skipped an entry whose command, args and env were
unchanged, so an upgrade left Codex at its one-minute default, and Goose kept
300 as if the user had chosen it.

- mcpFile.behind says an entry lacks the timeout magpie gives the server now:
  Codex's tool_timeout_sec is missing, or Goose's timeout is still exactly the
  300 magpie wrote. syncMCP rewrites such an entry; merged() doesn't keep that
  300 as the user's. A value the user chose (any other number) is left alone.
- Test: an entry as main wrote it is given 660 in both, one the user set stays,
  and a second sync changes nothing. It fails without the change ("changed []").

Also, from the review:
- seconds is validated once in readFilming: a decimal number that is whole and
  at least 1 (hex, inf, nan, underscores, negatives and 0 are refused), and the
  object echoes 6 for 6.0.
- imagemcp: Run's doc comment is above Run again.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 04:59:22 +08:00
..
tray: the menu bar shows several subscriptions' usage side by side (KevinXC on Discord) — Settings → Usage in the menu bar picked one card; its menu now ticks any number (kept open while ticking, saved once when it closes, Off unticks all, a ticked card that has gone stays listed to untick) and the pill says "3 subscriptions". settings.TrayUsages keeps them in order; a file with only the older trayUsage shows that one, and trayUsage is still written as the first for an older magpie. On the Mac the bird and a cell per card are drawn as one image by AppKit on the status item's button: the card's logo (a black glyph tinted in the menu bar's text colour, a coloured one as it is, the name's letter in a ring when there is none) and its two windows stacked, "42%" over "18%", in the bar's colour light or dark and sharp at any scale; the bird's flap goes through it. Arc flags run into numbers (Codex's logo) are spaced out for AppKit's SVG reader. A row longer than 10 characters (a plan's balance read from its page) is cut with an ellipsis in the bar and whole in the tooltip. Windows and Linux show the cards as text, " | " between them. TestTrayUsageCells, TestSVGArcFlags, TestTrayImage (darwin, renders 0-3 cards light and dark at 2x), TestTrayUsagesMigrate and tray-usages.test.cjs (Chromium, WebKit, en/zh) are new. go vet, go build (darwin GUI), go build -tags nogui (darwin, GOOS=linux), GOOS=windows go build, go test -tags nogui ./..., go test ./internal/gui pass; tray-usages, settings-groups, panel-*, click-scroll, old-webkit pass. Not seen in a live menu bar.
2026-09-30 19:45:44 +08:00