Commit Graph
6 Commits
Author SHA1 Message Date
yetone df95ac6bc2 docs, site: Integrating your app or agent with magpie, at docs/integrating.md and usemagpie.ai/docs/integrate (#918, Magixyne)
A developer of an AI app asked how to work with magpie and whether an app can
register itself after one confirmation. The page says what exists: the
gateway (find it via /api/hello and settings.json's port, the OpenAI,
Anthropic, Responses and Gemini endpoints, /v1/models' fields), how a key
magpie-<id> or the User-Agent's first word names the app in Usage, a row on
the Agents page by an adapter PR in internal/agent (config-edit, Cindy-style
own import link confirmed in the app, or a local API) with what the PR needs,
what plugins can and can't do, and what isn't there: no link or API registers
an app or installs a plugin, and magpie://import adds providers only. English
and Chinese pages, linked from every docs page's nav and footer.
TestThirdPartyAppIsCountedAsItself pins the attribution the page promises.
go vet and the gateway tests pass; site node tests pass; pages checked in
headless Chromium (no errors, TOC, no horizontal scroll at 390px).
2026-10-05 22:46:35 +08:00
yetone 2f135ed4d5 plugin, gui, docs: Plugins says which plugins are providers and which are middleware, lists the community's ready-made middleware, and edits a middleware's options in its row (the owner) — the Plugins page still read as if every plugin were a subscription, and nothing showed what a middleware does or let you set its options without editing plugins.json. Every Discover card and Installed row now carries a Provider or Middleware chip (both for a plugin that is both), also for one that is off (isMiddleware/middlewareOnly from the server, read from its files); Discover splits into Subscriptions and Gateway middleware ("runs in magpie's gateway on what every agent sends and gets back, whichever provider serves it"), the latter from market entries with "kind": "middleware" and no providers or icon (the built-in market.json lists the five new @magpie-community/middleware-* packages: param-override, model-map, system-prompt, word-guard, think-tags, mostly New API's channel settings with the same JSON). A middleware row has Options: a JSON editor in the row, starting from the package's magpie.options example when none are set, which validates it is an object, saves (POST /api/plugins/options) for the next request, clears, and cancels with Esc. magpie plugin options takes a short name (model-map for @magpie-community/middleware-model-map; plugin.ShortName, also in SetOptions). en/zh/ja/de. Docs: usemagpie.ai/docs/plugins (en/zh/ja) gains Ready-made middleware and Options and the registry's kind; reference.md, both READMEs and docs/subsystems/gateway-middleware.md likewise. Tested with a real DeepSeek account and real Claude Code through magpie web --gateway in a sandbox HOME, with all five installed and options set by short name: a mapped model named back, max_tokens capped, a prompt appended for claude only, word-guard's 400 and param-override's 403 in the agent's shape, <think> stripped from Chat and Responses streams and a whole Anthropic reply, reasoning_content moved into the text; /api/plugins showed the kinds and the example. TestSetOptionsShortName is new; TestBuiltinMarket checks a middleware entry has no providers or icon and no other kind. plugin-middleware.test.cjs (Chromium and WebKit, en and zh: the chips, Discover's two sections, the options editor with its errors, no select, no scroll, no left border) fails without the change; the other plugin tests and click-scroll pass in WebKit (plugin-market's section name updated; plugin-move fails only under parallel load and passes alone). go vet, go build (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui ./... under a temp HOME pass. 2026-10-05 20:50:09 +08:00
yetone eebd0b4222 plugin, gateway, gui: a plugin can be gateway middleware — onRequest, onEvent and onResponse run in magpie's gateway on what agents send and get back (moejs) — a plugin could only be a subscription provider, run in the Bun host, a process away from the gateway. A plugin may now declare middleware (package.json magpie.middleware, or a *.middleware.js / .mjs file), run in-process by moejs (pure-Go JS engine): compiled once, one runtime per request from a pool, so every hook of a request shares ctx.state. onRequest(body, ctx) sees the agent's body in its own API before routing; what it returns is the body the next middleware and the gateway get, undefined leaves the bytes as they were, ctx.reject(status, msg) answers with an error in the agent's API's shape. onEvent(ev, ctx) sees each SSE event's JSON (export const events = [...] filters by name; an object changes it, null drops it, undefined passes the bytes through untouched; data: [DONE] is no JSON and passes by). onResponse(body, ctx) sees a whole JSON reply, with ctx.status. ctx has protocol, model, stream, path, agent, the plugin's options and state. A hook that throws, returns a non-object or runs past its limit (250ms request/response, 50ms an event, 1s load; interrupted) leaves the request or reply as it was and is counted and logged (60 lines a minute); a compressed reply passes as-is. Files are reloaded within a second of a change. Only agents' requests run through it (serveAgent at the gateway's agent entry points and the Codex backend), never magpie's own titles, classifier or stand-ins; it sees bodies before redaction. A middleware-only package is skipped by the Bun host. The Plugins page marks a middleware with a chip, its hooks, calls and µs per call (JSON in and out counted), failures in red with the last error, and a load error. en/zh/ja/de; docs/reference.md and usemagpie.ai/docs/plugins#middleware (en/zh/ja) with an alias example. Tested with a real DeepSeek account through magpie web --gateway in a sandbox HOME: an alias middleware served "fast" and named it in message_start, a reject came back as 403 permission_error, a Chat stream uppercased; real Claude Code (sandbox CLAUDE_CONFIG_DIR) did Read, Bash and Glob tool turns through three middlewares with 0 failures: ≈1–1.6µs an event, 0.2–0.7ms an onRequest that parses and rewrites Claude Code's ≈80KB body. Real use found two bugs fixed here: [DONE] parsed as JSON (SyntaxError on every Chat stream) and stats leaving out the JSON time. internal/middleware tests (chain, undefined keeps bytes, reject, fail-open on throw/spin/string with the runtime reused, async hook, load errors, off and Bun skip, reload, split/CRLF/filtered/dropped stream events, [DONE] untouched, whole reply and gzip, 64 in parallel; BenchmarkEvent ≈0.9µs, 11 allocs) and TestMiddlewareThroughGateway (alias routed, events by protocol, redaction still upstream, reject in Anthropic's shape; fails without the change) are new; plugin-middleware.test.cjs (Chromium and WebKit, en and zh: chip, hooks and stats, failures with last error, broken and off, no left border) fails without it. The other plugin GUI tests and click-scroll pass in WebKit. go vet, go build (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui ./... under a temp HOME pass (internal/provider failed once under load and passes alone). 2026-10-05 19:14:31 +08:00
yetone c8278a8691 docs: plugins are OpenCode's provider plugins or pi's packages — the Plugins page's intro, magpie plugin's help, the README and the plugin docs (en, zh, ja) said OpenCode only, though pi packages that register a provider run since v0.1.772; the docs gain a pi packages section (what makes a package pi's, what is loaded and left alone, sign-in through onPrompt/onAuth and ctx.ui, pi's files under <config>/pi or PI_CODING_AGENT_DIR, Anthropic Messages requests), the pi-package search and a FAQ entry 2026-10-04 03:10:09 +08:00
yetone 8f385e113b site: usemagpie.ai draws itself in Omarchy's look on Omarchy, in the theme Omarchy has on (owner: 整个官网和文档页面能否智能识别是不是 Omarchy 在访问,如果是 Omarchy 在访问,那么整个页面风格能否变成 Omarchy 风格?而且能够适配当前 Omarchy 就更牛逼了) — every page (home, /import, the docs in en/zh/ja) loads omarchy.js in a Linux desktop browser only; it tells Omarchy by its font (a page may load local("omarchy"), which Omarchy installs system-wide and nothing else has), remembers it, and from then on paints before the page shows: the theme's palette, the system monospace (Omarchy's font), square corners, no shadows or glass, a solid bar, buttons and what's chosen in the accent, images framed in it. Until magpie tells the theme it takes Omarchy's default (tokyo-night, or catppuccin-latte on a light desktop). magpie's gateway answers GET /v1/magpie/omarchy (name, mode, stamp and the CSS variables magpie's own windows use) to this machine only, readable only by usemagpie.ai (CORS + Private Network Access; MAGPIE_SITE_ORIGIN adds an origin to try the site locally), 404 off Omarchy. The page asks it by itself only once the browser allows it to reach this computer; a chip in the corner (Omarchy's logo and the theme) asks once on a click, lists the 22 built-in themes to pick one, and turns the look off; ?omarchy=1|0|<theme> sets it anywhere. Followed while the page shows: a theme set in Omarchy's menu comes through in about 3 s. Tried in the omarchy VM's Chromium 152 with this magpie (nogui serve): detection, the home page and zh docs in tokyo-night, the chip's menu, following the computer, and omarchy-theme-set catppuccin-latte repainting the open page light. TestOmarchyThemeForTheSite covers 404 off Omarchy, the theme and its CORS for usemagpie.ai only, LAN refused and the preflight. go vet, builds (darwin, GOOS=linux, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. The permission prompt from the public site wasn't clicked through in a real browser. 2026-10-03 16:01:53 +08:00
yetone 3c79152eb4 site: docs in Japanese (/docs/ja), and contents that work on a phone (owner: 文档也要支持日语,另外,文档要有友好的目录,在手机端也要有友好的目录) — /docs/ja/{start,intent,plugins,import} translate the English pages; every docs page gets the home page's language menu (English / 中文 / 日本語, the lang cookie) and a ja hreflang, /docs/ja opens the guide, and /ja/'s docs links go to the Japanese pages. docs.js (shared, replacing each page's inline scrollspy) builds the contents: every docs page, the current one's sections under it, the section being read marked with a pill (no left border); the list is sticky and scrolls on its own. Under 900px, where the contents were simply hidden (and under 600px the nav links too, so a phone had no way around the docs), a bar under the nav names the section being read and opens the contents as a menu that closes on a pick, a tap outside or Escape. The nav links give way to the contents under 1000px, long inline code wraps under 1100px, and .doc keeps .wrap's side padding (601-1168px ran the text to the screen's edge). node --test worker.test.mjs passes (/docs/ja redirect added); WebKit at 320-1280, light and dark, en/zh/ja: nothing scrolls sideways, the menu opens, jumps and closes, the bar follows the reading position. 2026-10-03 11:26:23 +08:00