Documentation
¶
Overview ¶
Package plugin runs OpenCode's provider plugins for magpie.
A subscription a vendor may object to being used outside its own app is not built into magpie: a plugin signs in to it and makes its requests, the way OpenCode's plugins do (opencode-gemini-auth and the like), and magpie runs those same plugins. They are npm packages (or local files) written against OpenCode's plugin API (@opencode-ai/plugin, v1): their auth hook gives the sign-in methods and a loader whose fetch carries the requests, their config and provider hooks the models. magpie runs them under Bun, downloaded the first time a plugin is added, in one process (host.js) it talks to over stdin and stdout.
What magpie keeps: plugins.json, the plugins and the config handed to them (OpenCode's, its provider section: a plugin's options); the npm packages under plugins/; plugin-auth.json, the sign-ins, in OpenCode's auth.json shape (so one can be moved between the two).
Index ¶
- Constants
- Variables
- func AuthPath() string
- func Auths(provider string) map[string]map[string]any
- func Bun(ctx context.Context) (string, error)
- func Call(ctx context.Context, method string, params, out any) error
- func Dir() string
- func Fetch(ctx context.Context, r FetchRequest) (*http.Response, error)
- func HasBun() bool
- func Icon(spec, id string) string
- func Import(ctx context.Context, provider string, auth map[string]any) (string, error)
- func Info(ctx context.Context, names []string) map[string]NPM
- func Installed(spec string) string
- func IsPath(spec string) bool
- func KeepUpdated(ctx context.Context)
- func ListedAt() (time.Time, bool)
- func Name(spec string) string
- func Official(pkg string) bool
- func OnChange(f func())
- func OnSignIn(f func(provider, account, said string))
- func PackageName(spec string) string
- func Pinned(spec string) bool
- func ProviderOf(key string) string
- func Remove(ctx context.Context, name string) error
- func Restart()
- func Restore(ctx context.Context, provider, key string, auth map[string]any) error
- func Running() bool
- func SetConfig(cfg map[string]any) error
- func SetOff(name string, off bool) error
- func Settle()
- func SignOut(ctx context.Context, provider, account string) error
- func SignedIn(provider string) bool
- func Take(ctx context.Context, provider string, keys []string) (map[string]map[string]any, error)
- func Target(spec string) string
- func Update(ctx context.Context) error
- func Upgrade(ctx context.Context, name string) error
- func UseCached(ps []Provider)
- func Validate(ctx context.Context, provider string, method int, key, value string) (string, error)
- func Version(spec string) string
- type Account
- type Authorization
- type Checked
- type Entry
- type FetchRequest
- type Hit
- type List
- type Listing
- type Loaded
- type Method
- type Model
- type NPM
- type Options
- type Page
- type Prompt
- type Provider
- type Saved
- type Updated
- type Updates
- type Usage
- type UsageResets
- type UsageWindow
- type Waiting
Constants ¶
const BunVersion = "1.3.14"
BunVersion is the Bun magpie downloads to run plugins with, the first time one is needed.
const MarketURL = "https://raw.githubusercontent.com/magpie-community/plugins/main/registry.json"
MarketURL is where the list is kept; MAGPIE_PLUGIN_MARKET moves it, and "off" keeps to the built-in copy.
const NewAccount = "new"
NewAccount is the account a sign-in goes to when it is a new one: the provider's own id while nothing is kept there. A sign-in to an account already signed in replaces that one's instead.
Variables ¶
var ErrFailed = errors.New("the sign-in failed")
ErrFailed is a sign-in the plugin says failed.
Functions ¶
func AuthPath ¶
func AuthPath() string
AuthPath is the plugins' sign-ins, OpenCode's auth.json in shape.
func Auths ¶ added in v0.1.506
Auths are provider's sign-ins as plugin-auth.json keeps them, by key.
func Bun ¶
Bun is the bun to run plugins with: $MAGPIE_BUN when set, else the one magpie downloaded, downloading it now when there is none yet.
func Fetch ¶
Fetch sends r through the provider's plugin — its loader's fetch, or Bun's own when it gives none — and streams back the reply.
func Icon ¶ added in v0.1.497
Icon is the icon the market gives the plugin spec, or else any listed plugin signing in to provider id; "" when none does. It never goes to the network: the list fetched last, else the cached copy, else the one built in.
func Import ¶ added in v0.1.506
Import keeps auth (a plugin-auth.json entry) as one more of provider's accounts — or, the same account as one kept already, in its place — and gives the account's key. The plugin's host is started for it: it alone writes the file while it runs.
func Info ¶ added in v0.1.489
Info is what npm says of each package, asked at most hourly and all at once; a package npm doesn't have has no Version.
func Installed ¶ added in v0.1.489
Installed is the version of the plugin spec installed, "" for a path or one not installed.
func IsPath ¶
IsPath is whether spec names a file or folder rather than a package, as OpenCode tells them apart.
func KeepUpdated ¶ added in v0.1.573
KeepUpdated looks for plugin updates a little after magpie starts, then every updateEvery, run by the magpie serving the gateway (one magpie, never two at once).
func ListedAt ¶ added in v0.1.552
ListedAt is when the plugins last listed their providers and models, as a built-in's list is dated by when it was fetched.
func Name ¶
Name is the package spec names, without its version: "@scope/x" of "@scope/x@1.2", or the path.
func Official ¶ added in v0.1.573
Official is whether the package is the community's, magpie's own, which magpie keeps up to date by itself.
func OnChange ¶
func OnChange(f func())
OnChange registers f to be told when a plugin sign-in or the plugins change (a sign-in saved or refreshed, a plugin added).
func OnSignIn ¶ added in v0.1.547
func OnSignIn(f func(provider, account, said string))
OnSignIn registers f to be told what a plugin said, outside an answer, its account's sign-in is: "expired", "kept" or "renewed" (a models hook's error saying it).
func PackageName ¶ added in v0.1.506
PackageName is the npm package spec is: its name, or, for a plugin added from a folder or file (a checkout of it), the name its package.json gives.
func Pinned ¶ added in v0.1.573
Pinned is whether spec names a version (or a range or a tag other than latest): the user chose it, and it stays.
func ProviderOf ¶ added in v0.1.500
ProviderOf is the provider an account key is one of.
func Restart ¶
func Restart()
Restart stops the host, so the next call starts one with the plugins as they are now. A host answering calls (a reply streaming, a sign-in waiting for its browser) finishes them first, while the calls made from now on go to the new one: a plugin updating never cuts a reply.
func Settle ¶
func Settle()
Settle waits for Cached's refreshes to end, then stops the host: for tests, whose folders the host runs in go when they end.
func Take ¶ added in v0.1.506
Take gives provider's accounts named by keys (every one when there are none) and signs them out in one step, so the plugin renews none of their tokens after it gave them.
func Target ¶
Target is where the plugin is to load from: the installed package's folder, or the path.
func Update ¶
Update installs the version of each npm plugin its spec says now (latest, for the most part).
func UseCached ¶ added in v0.1.538
func UseCached(ps []Provider)
UseCached is for tests: Cached answers with ps, as though the plugins had just been asked, without Bun; nil forgets them.
Types ¶
type Account ¶ added in v0.1.500
type Account struct {
Key string `json:"key"`
Type string `json:"type"`
AccountID string `json:"accountId"`
// Hint tells an account with no id from another: the end of its key.
Hint string `json:"hint,omitempty"`
// Models are the ids of the provider's models this account has, when
// the provider has more than one account; none, it has them all.
Models []string `json:"models,omitempty"`
FellBack bool `json:"fellBack,omitempty"`
}
Account is one account a provider is signed in to: Key is where plugin-auth.json keeps it (the provider's id, else id#slot).
type Authorization ¶
type Authorization struct {
Session string `json:"session"`
URL string `json:"url"`
Instructions string `json:"instructions"`
Method string `json:"method"`
}
Authorization is an OAuth sign-in begun: the page to open, and whether the plugin waits for it itself ("auto") or needs the code the page shows pasted back ("code").
type Checked ¶ added in v0.1.552
type Checked struct {
Models []string `json:"models"`
Usage *Usage `json:"usage"`
Refused string `json:"refused"`
}
Checked is what trying an account gave: the model ids the plugin lists for it, its usage read (nil when the plugin tells none), and why its models hook said the vendor refused the sign-in, if it did.
func Check ¶ added in v0.1.506
Check tries one of provider's accounts as a request would — its auth loader, then its models as the plugin lists them for it — and reads its usage, which asks the vendor of the account itself. It fails when the plugin reached none of the places it asked (the vendor offline): a models hook falling back to a list it keeps proves nothing.
type Entry ¶
type Entry struct {
// Spec is how it was added: an npm package (name, name@version) or a
// path to a file or folder.
Spec string `json:"spec"`
// Off is set on a plugin the user turned off.
Off bool `json:"off,omitempty"`
// Options are handed to the plugin as its second argument, as
// OpenCode's ["name", {options}] does.
Options map[string]any `json:"options,omitempty"`
}
Entry is one plugin the user added.
type FetchRequest ¶
type FetchRequest struct {
Provider string `json:"provider"`
Account string `json:"account,omitempty"` // the provider's first when ""
Model string `json:"model"`
NPM string `json:"npm"`
URL string `json:"url"`
Method string `json:"method"`
Headers map[string]string `json:"headers"`
Body []byte `json:"-"`
Session string `json:"session,omitempty"`
// Proxy is the provider's or the account's own proxy (netproxy.With):
// "direct", or its URL; "" follows magpie's. Fetch takes it from ctx
// when it isn't set.
Proxy string `json:"proxy,omitempty"`
}
FetchRequest is a request a provider's plugin makes.
type List ¶
type List struct {
Plugins []Entry `json:"plugins"`
// Config is OpenCode's config the plugins are handed: its provider
// section says what a plugin reads of it
// (provider.google.options.projectId).
Config map[string]any `json:"config,omitempty"`
}
List is plugins.json.
type Listing ¶ added in v0.1.489
type Listing struct {
Package string `json:"package"`
Name string `json:"name"`
Icon string `json:"icon,omitempty"`
Providers []string `json:"providers,omitempty"` // OpenCode's ids of those it signs in to
Community bool `json:"community,omitempty"` // written by magpie's community
Replaces string `json:"replaces,omitempty"` // the built-in subscription it does the work of
Summary map[string]string `json:"summary,omitempty"` // by language: en, zh
}
Listing is a plugin the market suggests.
type Method ¶
type Method struct {
Type string `json:"type"`
Label string `json:"label"`
// Placeholder is the hint an "api" method gives in its key's field
// (magpie's own field: OpenCode's says "API key")
Placeholder string `json:"placeholder,omitempty"`
}
Method is a way a plugin signs in: "oauth" (a browser, then a code pasted back or not) or "api" (a key).
type Model ¶
type Model struct {
ID string `json:"id"`
Name string `json:"name"`
NPM string `json:"npm"` // the AI SDK package it is spoken to with
URL string `json:"url"`
APIID string `json:"apiId"`
Context int `json:"context"`
Input int `json:"input"`
Output int `json:"output"`
Reasoning bool `json:"reasoning"`
Image bool `json:"image"`
Released string `json:"released"`
Variants []string `json:"variants"`
// Free is set by the plugin on a model the plan serves at no cost to
// its allowance (WorkBuddy's "credits": "x0.00")
Free bool `json:"free"`
Cost *struct {
Input float64 `json:"input"`
Output float64 `json:"output"`
} `json:"cost"`
// ImageSaid is whether the plugin (or models.dev) said if it takes
// images: Image false without it is not known
ImageSaid bool `json:"imageSaid"`
}
Model is a model a plugin's provider serves, as OpenCode lists it.
type NPM ¶ added in v0.1.489
type NPM struct {
Version string `json:"version,omitempty"` // latest; none when npm has no such package
Description string `json:"description,omitempty"`
Publisher string `json:"publisher,omitempty"`
License string `json:"license,omitempty"`
Homepage string `json:"homepage,omitempty"`
Repository string `json:"repository,omitempty"`
Weekly int `json:"weekly"` // downloads last week
}
NPM is what npm says of a package now.
type Options ¶
type Options struct {
BaseURL string `json:"baseURL"`
APIKey string `json:"apiKey"`
Headers map[string]string `json:"headers"`
Fetch bool `json:"fetch"`
}
Options is what the provider's auth loader gave: where its requests go, the key the AI SDK would send, and whether it carries them itself.
type Prompt ¶
type Prompt struct {
Type string `json:"type"` // text, select
Key string `json:"key"`
Message string `json:"message"`
Placeholder string `json:"placeholder,omitempty"`
Options []struct {
Label string `json:"label"`
Value string `json:"value"`
Hint string `json:"hint,omitempty"`
} `json:"options,omitempty"`
}
Prompt is a question a sign-in method asks before it starts.
type Provider ¶
type Provider struct {
ID string `json:"id"` // OpenCode's: google, github-copilot
Spec string `json:"spec"` // the plugin
Name string `json:"name"`
NPM string `json:"npm"`
API string `json:"api"`
Methods []Method `json:"methods"`
// Icon is the picture the plugin gives the provider, as it said it:
// an https URL or a data:image URI (internal/provider keeps it)
Icon string `json:"icon,omitempty"`
// Usage says the plugin tells each account's allowance (auth.usage)
Usage bool `json:"usage"`
SignedIn bool `json:"signedIn"`
AuthType string `json:"authType"`
AccountID string `json:"accountId"`
Models []Model `json:"models"`
// FellBack says the plugin's models hook couldn't fetch its vendor's
// list and gave the default one back.
FellBack bool `json:"fellBack,omitempty"`
// Accounts are the accounts signed in to it, the one kept under its
// own id first; SignedIn, AuthType and AccountID are that one's.
Accounts []Account `json:"accounts"`
}
Provider is a provider a plugin signs in to.
type Saved ¶ added in v0.1.500
Saved is where a sign-in was kept: the provider (a plugin may sign in to another than asked) and the account's key.
type Updated ¶ added in v0.1.573
type Updated struct {
Package string `json:"package"`
From string `json:"from"`
To string `json:"to"`
At time.Time `json:"at"`
}
Updated is a plugin magpie updated by itself.
type Updates ¶ added in v0.1.573
type Updates struct {
Checked time.Time `json:"checked"`
// Waiting are the plugins with a newer version that magpie leaves to
// the reader: someone else's, or one pinned to a version.
Waiting []Waiting `json:"waiting"`
// Updated are the plugins magpie updated by itself, the latest last.
Updated []Updated `json:"updated"`
}
Updates is what magpie's last look at npm found for the plugins.
func CheckUpdates ¶ added in v0.1.573
CheckUpdates asks npm for each plugin's newest version, updates the community's (unpinned, switched on) to it and notes the others' as waiting. The plugins updated are loaded again, a reply streaming through the old ones finishing first.
func PendingUpdates ¶ added in v0.1.573
func PendingUpdates() Updates
PendingUpdates is what the last look found, less what has changed since: a plugin updated, removed or switched off since waits no more.
type Usage ¶ added in v0.1.514
type Usage struct {
Plan string `json:"plan"`
Until string `json:"until"` // RFC 3339, "" when not told
Renew string `json:"renew"`
Balance string `json:"balance"`
Error string `json:"error"`
User string `json:"user"`
SignIn string `json:"signIn"` // "expired", "kept", "renewed" or ""
Windows []UsageWindow `json:"windows"`
Resets *UsageResets `json:"resets"`
}
Usage is how much of its allowance one account has used, as the plugin's auth.usage tells it (host.js has the shape).
type UsageResets ¶ added in v0.1.514
type UsageResets struct {
Count int `json:"count"`
Until string `json:"until"`
ByWindow bool `json:"byWindow"`
FiveHour int `json:"fiveHour"`
Weekly int `json:"weekly"`
}
UsageResets are the rate-limit resets an account may spend.
type UsageWindow ¶ added in v0.1.514
type UsageWindow struct {
Name string `json:"name"`
Used float64 `json:"used"` // percent
ResetsAt string `json:"resetsAt"` // RFC 3339
ResetSecs int64 `json:"resetSecs"`
Display string `json:"display"`
Span float64 `json:"span"` // seconds
Model string `json:"model"`
Models []string `json:"models"`
NotModels []string `json:"notModels"`
Aside bool `json:"aside"`
}