pi-multix
extensionmaintainedPi extension for AI multimodal generation and media processing via the multix CLI: images, video, speech, music, 3D, document conversion, and ffmpeg/ImageMagick optimization.
by — · v0.1.6 · published 3d ago
$ pi install npm:pi-multixSignals
Download trend
1.2K downloads · last 12 weeks (weekly)
README
pi-multix
A pi extension that brings the multix AI multimodal CLI to the pi coding agent: image generation and editing, video generation, speech, transcription, music, sound effects, document conversion, and local media processing.

Install
pi install npm:pi-multix
Pi installs @mrgoonie/multix as a dependency automatically, so the CLI is
bundled and no separate global install is needed.
Other install options
# Pin a version
pi install npm:pi-multix@0.1.0
# From git
pi install git:github.com/bestagentkits/pi-multix
# Project-local instead of global
pi install npm:pi-multix -l
Requirements
- Node.js 20 or newer.
- At least one provider API key for provider-backed work.
multix_medianeeds no key, but requiresffmpegor ImageMagick onPATH.
Keys are read from process.env, then <cwd>/.env, then ~/.multix/.env:
| Provider | Environment variables |
|---|---|
| OpenAI | OPENAI_API_KEY |
| Gemini | GEMINI_API_KEY |
| MiniMax | MINIMAX_API_KEY |
| OpenRouter | OPENROUTER_API_KEY |
| Leonardo | LEONARDO_API_KEY |
| BytePlus | BYTEPLUS_API_KEY or ARK_API_KEY |
| ElevenLabs | ELEVENLABS_API_KEY |
| Cloudflare | CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN (video also needs CLOUDFLARE_AI_GATEWAY_ID and REPLICATE_API_TOKEN) |
Tools
| Tool | Purpose |
|---|---|
multix_check | Report which provider keys, ffmpeg, and ImageMagick are available |
multix_models | Provider and model inventory, and key management without handling secrets |
multix_image | Generate an image, or edit an existing one (image-to-image) |
multix_video | Text-to-video, image-to-video, and async job status |
multix_audio | TTS, transcription, music, sound effects, voice cloning |
multix_media | Local ffmpeg/ImageMagick compress, resize, and split |
multix_doc | Documents to Markdown, file analysis, structured extraction |
multix_run | Any other multix command, with an explicit argv array |
The extension also ships a multix skill containing provider-selection decision
trees and reference behavior, so the agent picks a sensible provider instead of
guessing.
Adding an API key
Never paste a key into the chat. Tool arguments are written to the pi session
log on disk and sent to the model provider as part of the conversation, so
multix_models deliberately has no parameter that accepts a key. Keys reach
~/.multix/.env by one of two routes instead.
Let a human enter it, without it ever reaching the model:
mkdir -p ~/.multix
# `read -rs` keeps the value off the screen and out of shell history.
read -rs KEY && printf 'GEMINI_API_KEY=%s\n' "$KEY" >> ~/.multix/.env
Or import it from a file or an already-exported environment variable, passing only a name or a path:
multix_models action=scaffold
multix_models action=set-key variable=GEMINI_API_KEY fromFile=~/.gemini-key consume=true
multix_models action=providers
multix_models action=unset-key variable=GEMINI_API_KEY
set-key reports only which variable changed, never the value. The file is
written atomically with mode 600, a value cannot contain a line break (which
would inject another variable), and an existing value is never replaced without
overwrite=true. Run multix_check afterwards to confirm the CLI can see it;
multix reads the file on every invocation, so no restart is needed.
Examples
Once installed, these are model-facing tool calls rather than shell commands:
multix_image action=generate provider=gemini prompt="a red fox in snow" aspectRatio=16:9
multix_image action=i2i provider=gemini prompt="make it watercolor" refs=["./photo.jpg"]
multix_video action=i2v provider=byteplus image="./frame.png" prompt="camera pans left" download=true
multix_audio action=tts provider=openai text="Hello world" output="hello.mp3"
multix_audio action=transcribe provider=elevenlabs input="./call.mp3" format=srt
multix_doc action=convert input=["report.pdf"] output="report.md"
multix_media action=optimize input="big.mp4" output="small.mp4" targetSize=50
multix_run args=["leonardo","upscale","<generatedImageId>"]
Behavior worth knowing
- Output location. Generated files go to
./multix-output/unlessMULTIX_OUTPUT_DIRor theoutputparameter redirects them. - Output format is detected, not assumed. Providers choose the container, and
the CLI copies those bytes to
outputverbatim, so asking forout.pngcan yield JPEG data under a.pngname.multix_imagereads the file's magic bytes and renames a mismatched output to the extension its content actually has, reporting both paths. It does not transcode, and it never overwrites an existing file. - Strict parameters. A parameter the chosen provider does not support is
rejected with an error naming the supported set, instead of being dropped
silently. Use
extraArgsfor anything not modelled. extraArgsis argv, not a shell string. One array element is one argv token, appended verbatim. No shell is involved, so never add quotes or operators. Example:extraArgs: ["--steps", "6"].- Long jobs. Video and 3D generation commonly exceeds a minute. Pass
waitordownloadso the CLI blocks until the file exists, and raisetimeoutMswhen needed. The default is 10 minutes, 15 for video. - Failures are errors. A non-zero exit makes the tool call fail with the CLI's stdout and stderr attached, so provider diagnostics reach the model instead of being hidden.
- No shell injection. Every invocation uses
execFilewith an argv array. Prompts, paths, and URLs are never interpreted by a shell.
Configuration
| Variable | Effect |
|---|---|
MULTIX_BIN | Absolute path to the multix CLI entry, or a command name to use instead of the bundled dependency. Useful for a custom or globally installed CLI, or for testing a newer release. |
MULTIX_OUTPUT_DIR | Where multix writes generated files. |
The bundled CLI is resolved by walking up from the extension directory, so both
pi layouts work: a dependency installed inside the package, and one hoisted to a
parent node_modules.
Development
npm install
npm run verify # typecheck, unit tests, build, then loader verification
npm run test # unit tests only
npm run typecheck # tsc --noEmit
npm run build # bundle to dist/
npm run verify:loading # load the built bundle through pi's real loader
npm run verify:loading is the integration check. It loads the built bundle
through pi's extension loader (jiti plus pi's bundled-module alias map), asserts
that all seven tools register with prompt metadata, runs the real CLI through a
registered tool, confirms a non-zero exit surfaces the CLI diagnostics, and
confirms the bundled skill is discoverable.
Keep the typebox devDependency in step with the version pi bundles; the
architecture notes explain why.
Releasing
Releases publish from CI with no stored npm credential. Pushing a v* tag runs
.github/workflows/publish.yml, which uses
npm's trusted publishing: GitHub
mints a short-lived OIDC token for the job and the npm CLI exchanges it for a
publish credential scoped to that run. There is no NPM_TOKEN secret anywhere in
this repository, and npm attaches a provenance attestation automatically.
# 1. bump the version in package.json
# 2. tag it, with the tag matching the version exactly
git tag -a v0.2.0 -m "pi-multix 0.2.0"
git push origin v0.2.0
The workflow refuses to publish when the tag and package.json version disagree,
and npm publish runs the prepublishOnly gate (npm run verify) first, so an
untested release cannot be uploaded.
One-time setup on npmjs.com
Trusted publishing is configured on the package, not in this repository. npm
verifies these values only when a publish is attempted, so a typo surfaces as an
ENEEDAUTH failure at release time rather than when saving.
- Open the package settings for
pi-multix→ Trusted Publisher. - Choose GitHub Actions and fill in:
- Organization or user:
bestagentkits - Repository:
pi-multix - Workflow filename:
publish.yml(filename only, and it is case-sensitive)
- Organization or user:
- Under Allowed actions, permit
npm publish. Leaving it at staged-only blocks a direct publish.
Once a CI release has succeeded, consider tightening the package under Settings → Publishing access to Require two-factor authentication and disallow tokens. That does not affect trusted publishing, and it removes the long-lived-token path entirely.
Design notes
The extension shells out to the multix CLI rather than importing its internals.
multix's public library entry point exports only its core module, so providers
and command modules are not a public contract and importing them would mean
fragile deep imports into dist/. The CLI's argv surface, by contrast, is
documented and stable, and it already covers every provider.
See docs/architecture.md for resolution, argv construction, and the TypeBox type-identity constraint, and docs/provider-matrix.md for which provider supports which action.
License
MIT