@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 +21 -0
- package/dist/factory.d.ts +12 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +35 -0
- package/dist/factory.js.map +1 -0
- package/dist/index.d.ts +92 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +520 -0
- package/dist/index.js.map +1 -0
- package/dist/key-name.d.ts +27 -0
- package/dist/key-name.d.ts.map +1 -0
- package/dist/key-name.js +34 -0
- package/dist/key-name.js.map +1 -0
- package/dist/store.d.ts +12 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +108 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +36 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +64 -0
- package/src/configure.test.ts +157 -0
- package/src/discovery.test.ts +40 -0
- package/src/factory.test.ts +36 -0
- package/src/factory.ts +47 -0
- package/src/index.test.ts +662 -0
- package/src/index.ts +660 -0
- package/src/key-name.test.ts +61 -0
- package/src/key-name.ts +39 -0
- package/src/store.test.ts +115 -0
- package/src/store.ts +123 -0
- package/src/types.ts +38 -0
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"}
|
package/dist/factory.js
ADDED
|
@@ -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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|