@moxxy/plugin-provider-admin 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Moxxy (moxxy.ai)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,12 @@
1
+ import { type ProviderDef } from '@moxxy/sdk';
2
+ import { validateOpenAICompatKey } from '@moxxy/plugin-provider-openai';
3
+ import type { StoredProvider } from './types.js';
4
+ /**
5
+ * Re-export the shared OpenAI-compatible key validator so existing
6
+ * consumers (and `index.ts`) keep a single import surface. The probe
7
+ * lives in `@moxxy/plugin-provider-openai` — we don't keep a local copy.
8
+ */
9
+ export { validateOpenAICompatKey };
10
+ /** Build a runtime ProviderDef from a stored entry by dispatching on `kind`. */
11
+ export declare function buildProviderDef(entry: StoredProvider): ProviderDef;
12
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAA8B,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACpG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;GAIG;AACH,OAAO,EAAE,uBAAuB,EAAE,CAAC;AA2BnC,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,WAAW,CASnE"}
@@ -0,0 +1,35 @@
1
+ import { MoxxyError } from '@moxxy/sdk';
2
+ import { defineOpenAICompatProvider, validateOpenAICompatKey } from '@moxxy/plugin-provider-openai';
3
+ /**
4
+ * Re-export the shared OpenAI-compatible key validator so existing
5
+ * consumers (and `index.ts`) keep a single import surface. The probe
6
+ * lives in `@moxxy/plugin-provider-openai` — we don't keep a local copy.
7
+ */
8
+ export { validateOpenAICompatKey };
9
+ const PROVIDER_DEF_BUILDERS = {
10
+ // For `openai-compat` we delegate to the shared {@link defineOpenAICompatProvider}
11
+ // factory that the built-in vendor plugins (xai/zai/google/local) also use: it
12
+ // forces the vendor's slug + baseURL + default model + catalog onto the shared
13
+ // OpenAI client and wires validateKey against the same baseURL, so the
14
+ // setup-wizard / `moxxy doctor --check-keys` paths work end-to-end. The runtime
15
+ // config only carries the resolved API key, so the factory's narrow pick keeps
16
+ // just that and the vendor's stored baseURL/defaultModel win.
17
+ 'openai-compat': (entry) => defineOpenAICompatProvider({
18
+ name: entry.name,
19
+ baseURL: entry.baseURL,
20
+ defaultModel: entry.defaultModel,
21
+ models: entry.models,
22
+ }),
23
+ };
24
+ /** Build a runtime ProviderDef from a stored entry by dispatching on `kind`. */
25
+ export function buildProviderDef(entry) {
26
+ const build = PROVIDER_DEF_BUILDERS[entry.kind];
27
+ if (!build) {
28
+ throw new MoxxyError({
29
+ code: 'CONFIG_INVALID',
30
+ message: `provider-admin: unsupported kind ${String(entry.kind)}`,
31
+ });
32
+ }
33
+ return build(entry);
34
+ }
35
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAoB,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAGpG;;;;GAIG;AACH,OAAO,EAAE,uBAAuB,EAAE,CAAC;AAUnC,MAAM,qBAAqB,GAAuD;IAChF,mFAAmF;IACnF,+EAA+E;IAC/E,+EAA+E;IAC/E,uEAAuE;IACvE,gFAAgF;IAChF,+EAA+E;IAC/E,8DAA8D;IAC9D,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE,CACzB,0BAA0B,CAAC;QACzB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC;CACL,CAAC;AAEF,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,KAAqB;IACpD,MAAM,KAAK,GAAG,qBAAqB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,UAAU,CAAC;YACnB,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,oCAAoC,MAAM,CAAE,KAA2B,CAAC,IAAI,CAAC,EAAE;SACzF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC;AACtB,CAAC"}
@@ -0,0 +1,92 @@
1
+ import { type Plugin, type ProviderAdminView, type ProviderDef } from '@moxxy/sdk';
2
+ import { providersConfigPath, readProvidersConfig, removeStoredProvider, upsertStoredProvider } from './store.js';
3
+ export { providersConfigPath, readProvidersConfig, upsertStoredProvider, removeStoredProvider };
4
+ export type { StoredProvider, StoredProviderOpenAICompat, StoredProvidersConfig } from './types.js';
5
+ export { buildProviderDef, validateOpenAICompatKey } from './factory.js';
6
+ export { providerApiKeyName, storedProviderApiKeyName } from './key-name.js';
7
+ /**
8
+ * Minimal subset of the in-process ProviderRegistry the admin plugin
9
+ * needs. Keeping the surface narrow lets us pass either the live
10
+ * `session.providers` from the CLI or a fake from tests.
11
+ */
12
+ export interface ProviderRegistryLike {
13
+ register(def: ProviderDef): void;
14
+ replace(def: ProviderDef): void;
15
+ unregister(name: string): void;
16
+ list(): ReadonlyArray<ProviderDef>;
17
+ /**
18
+ * Name of the currently-active provider, when the registry tracks one. The
19
+ * live `session.providers` implements this; the narrow fake used in tests may
20
+ * not — hence optional. Used to detect when a `replace()`/`unregister()`
21
+ * targets the active provider so we can rebuild (or refuse).
22
+ */
23
+ getActiveName?(): string | null;
24
+ /**
25
+ * Rebuild + activate a provider's instance. `replace()` drops the cached
26
+ * instance, so replacing the ACTIVE provider's def MUST be followed by
27
+ * `setActive(name, config)` or `getActive()` throws on the next turn (the
28
+ * invariant documented on core's ProviderRegistry).
29
+ */
30
+ setActive?(name: string, config?: Record<string, unknown>): unknown;
31
+ }
32
+ export interface BuildProviderAdminPluginOptions {
33
+ /** Live provider registry — the plugin (un)registers stored defs against it. */
34
+ readonly providerRegistry: ProviderRegistryLike;
35
+ /** Override the on-disk path. Tests inject a tmp file here. */
36
+ readonly configPath?: string;
37
+ /**
38
+ * Optional credential resolver. When supplied AND a reconfigure/replace
39
+ * targets the currently-active provider, the plugin rebuilds the active
40
+ * instance with this config so `getActive()` keeps working without a manual
41
+ * re-select. Without it the plugin leaves the active instance alone (the host
42
+ * — e.g. the runner, which owns the credential resolver — is responsible for
43
+ * the rebuild). Mirrors the runner's `setActive` config resolution.
44
+ */
45
+ readonly resolveActiveConfig?: (name: string) => Promise<Record<string, unknown>> | Record<string, unknown>;
46
+ }
47
+ /**
48
+ * Shared state + critical-section helpers for one wired plugin instance. Both
49
+ * {@link buildProviderAdminPlugin} and {@link buildProviderAdminPluginWithApi}
50
+ * drive the SAME engine so the built-in guard, active-provider rebuild and the
51
+ * registry-mutation lock are consistent across the tools and the configure API.
52
+ */
53
+ interface ProviderAdminEngine {
54
+ readonly providerRegistry: ProviderRegistryLike;
55
+ readonly configPath?: string;
56
+ /** Names registered BY THIS PLUGIN (provider_add/configure/onInit). */
57
+ readonly ownNames: Set<string>;
58
+ /**
59
+ * Is `name` a host built-in (code provider) we must never replace? Evaluated
60
+ * LAZILY against the LIVE registry minus our own names — NOT snapshotted at
61
+ * build time, because the CLI builds this plugin BEFORE the host registers
62
+ * its built-in provider defs, so a build-time snapshot is empty and the guard
63
+ * is dead (a `provider_add({name:'openai'})` would silently hot-swap the real
64
+ * built-in's def). A name present in the live registry that we did not put
65
+ * there is, by definition, a built-in.
66
+ */
67
+ isBuiltin(name: string): boolean;
68
+ /** Serialize the capture→registry-mutate→persist→rollback section per name. */
69
+ withLock<T>(name: string, fn: () => Promise<T>): Promise<T>;
70
+ /**
71
+ * After `replace()` on the active provider, the cached instance is dropped
72
+ * (core ProviderRegistry invariant) so `getActive()` throws until rebuilt.
73
+ * Rebuild it with resolved config when the host wired a resolver. No-op when
74
+ * `name` isn't active or the registry doesn't track an active provider.
75
+ */
76
+ rebuildActiveIfNeeded(name: string): Promise<void>;
77
+ }
78
+ /**
79
+ * Like {@link buildProviderAdminPlugin} but also returns a
80
+ * {@link ProviderAdminView} api the host can stash on the session
81
+ * (`session.providerAdmin`) so channels — and the runner's
82
+ * `provider.configure` method — can edit a stored provider without going
83
+ * through the model. Mirrors `buildMcpAdminPluginWithApi`.
84
+ */
85
+ export declare function buildProviderAdminPluginWithApi(opts: BuildProviderAdminPluginOptions): {
86
+ readonly plugin: Plugin;
87
+ readonly api: ProviderAdminView;
88
+ };
89
+ export declare function buildProviderAdminPlugin(opts: BuildProviderAdminPluginOptions, sharedEngine?: ProviderAdminEngine): Plugin;
90
+ export declare const providerAdminPlugin: Plugin;
91
+ export default providerAdminPlugin;
92
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,MAAM,EACX,KAAK,iBAAiB,EAEtB,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAsBpB,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,CAAC;AAChG,YAAY,EAAE,cAAc,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAE7E;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,OAAO,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC;IACnC;;;;;OAKG;IACH,aAAa,CAAC,IAAI,MAAM,GAAG,IAAI,CAAC;IAChC;;;;;OAKG;IACH,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;CACrE;AAED,MAAM,WAAW,+BAA+B;IAC9C,gFAAgF;IAChF,QAAQ,CAAC,gBAAgB,EAAE,oBAAoB,CAAC;IAChD,+DAA+D;IAC/D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7G;AAkJD;;;;;GAKG;AACH,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,gBAAgB,EAAE,oBAAoB,CAAC;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B;;;;;;;;OAQG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,+EAA+E;IAC/E,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5D;;;;;OAKG;IACH,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAsFD;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,+BAA+B,GAAG;IACtF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;CACjC,CA8CA;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,+BAA+B,EACrC,YAAY,CAAC,EAAE,mBAAmB,GACjC,MAAM,CAmMR;AAcD,eAAO,MAAM,mBAAmB,EAAE,MAsC9B,CAAC;AAGL,eAAe,mBAAmB,CAAC"}