pi-multix

extensionmaintained

Pi 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-multix
downloads/mo
1.1K
stars
6
last push
2d ago
open issues
0

Signals

license: MITtestspi manifest: missinginstall size: —deps: 0peer deps: 0

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.

Isometric engraving-style illustration of the multix CLI: a central processing machine wired to modules for images, video, speech, music, documents, and 3D models

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_media needs no key, but requires ffmpeg or ImageMagick on PATH.

Keys are read from process.env, then <cwd>/.env, then ~/.multix/.env:

ProviderEnvironment variables
OpenAIOPENAI_API_KEY
GeminiGEMINI_API_KEY
MiniMaxMINIMAX_API_KEY
OpenRouterOPENROUTER_API_KEY
LeonardoLEONARDO_API_KEY
BytePlusBYTEPLUS_API_KEY or ARK_API_KEY
ElevenLabsELEVENLABS_API_KEY
CloudflareCLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN (video also needs CLOUDFLARE_AI_GATEWAY_ID and REPLICATE_API_TOKEN)

Tools

ToolPurpose
multix_checkReport which provider keys, ffmpeg, and ImageMagick are available
multix_modelsProvider and model inventory, and key management without handling secrets
multix_imageGenerate an image, or edit an existing one (image-to-image)
multix_videoText-to-video, image-to-video, and async job status
multix_audioTTS, transcription, music, sound effects, voice cloning
multix_mediaLocal ffmpeg/ImageMagick compress, resize, and split
multix_docDocuments to Markdown, file analysis, structured extraction
multix_runAny 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/ unless MULTIX_OUTPUT_DIR or the output parameter redirects them.
  • Output format is detected, not assumed. Providers choose the container, and the CLI copies those bytes to output verbatim, so asking for out.png can yield JPEG data under a .png name. multix_image reads 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 extraArgs for anything not modelled.
  • extraArgs is 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 wait or download so the CLI blocks until the file exists, and raise timeoutMs when 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 execFile with an argv array. Prompts, paths, and URLs are never interpreted by a shell.

Configuration

VariableEffect
MULTIX_BINAbsolute 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_DIRWhere 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.

  1. Open the package settings for pi-multix → Trusted Publisher.
  2. Choose GitHub Actions and fill in:
    • Organization or user: bestagentkits
    • Repository: pi-multix
    • Workflow filename: publish.yml (filename only, and it is case-sensitive)
  3. 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