@moxxy/plugin-provider-openai 0.1.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.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # @moxxy/plugin-provider-openai
2
+
3
+ The **OpenAI** `LLMProvider` for [moxxy](https://moxxy.ai) — streams Chat
4
+ Completions with `tool_calls` and translates moxxy's `ProviderRequest`/event
5
+ shape ↔ the OpenAI wire format. Register it into a
6
+ [`Session`](https://www.npmjs.com/package/@moxxy/core) to route turns to OpenAI.
7
+
8
+ Because it speaks the OpenAI Chat Completions API, it also drives any
9
+ **OpenAI-compatible** endpoint (z.ai, xAI, Google's OpenAI shim, Ollama / local)
10
+ via the `baseURL` override.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm i @moxxy/core @moxxy/sdk @moxxy/mode-default @moxxy/plugin-provider-openai
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ```ts
21
+ import { Session, collectTurn, autoAllowResolver } from '@moxxy/core';
22
+ import defaultModePlugin from '@moxxy/mode-default';
23
+ import openaiPlugin from '@moxxy/plugin-provider-openai';
24
+
25
+ const session = new Session({ cwd: process.cwd(), permissionResolver: autoAllowResolver });
26
+ session.pluginHost.registerStatic(defaultModePlugin);
27
+ session.pluginHost.registerStatic(openaiPlugin);
28
+
29
+ session.providers.setActive('openai', {
30
+ apiKey: process.env.OPENAI_API_KEY,
31
+ // model: 'gpt-5.2', // optional — defaults to the built-in catalog
32
+ });
33
+
34
+ console.log((await collectTurn(session, 'Hello!')).findLast((e) => e.type === 'assistant_message')?.content);
35
+ ```
36
+
37
+ ### Point at an OpenAI-compatible vendor
38
+
39
+ ```ts
40
+ session.providers.setActive('openai', {
41
+ apiKey: process.env.GROQ_API_KEY,
42
+ baseURL: 'https://api.groq.com/openai/v1',
43
+ // model: '...' // the vendor's model id
44
+ });
45
+ ```
46
+
47
+ ## Config (`OpenAIProviderConfig`)
48
+
49
+ | field | meaning |
50
+ |---|---|
51
+ | `apiKey` | the API key (or wire it through the Session's `secretResolver`) |
52
+ | `baseURL` | override the API base for an OpenAI-compatible vendor |
53
+ | `model` / `models` | pick / override the advertised model catalog |
54
+
55
+ ## Exports
56
+
57
+ `default` / `openaiPlugin` (register this), `openaiProviderDef`, `OpenAIProvider`,
58
+ `openAIModels`, `validateKey`, and `defineOpenAICompatProvider` (build a provider
59
+ for another OpenAI-compatible vendor in a few lines).
60
+
61
+ ## License
62
+
63
+ MIT
@@ -0,0 +1,72 @@
1
+ import { type ModelDescriptor, type ProviderAuthDescriptor, type ProviderDef } from '@moxxy/sdk';
2
+ /**
3
+ * The slice of the registry's untyped `Record<string, unknown>` config that an
4
+ * OpenAI-compatible vendor actually forwards. The provider registry hands
5
+ * `createClient` a `Record<string, unknown>` (resolved credentials + any
6
+ * persisted provider config); only these three optional strings are ever
7
+ * meaningful to the underlying {@link OpenAIProvider}, so we narrow to them.
8
+ */
9
+ export interface OpenAICompatConfig {
10
+ readonly apiKey?: string;
11
+ readonly baseURL?: string;
12
+ readonly defaultModel?: string;
13
+ }
14
+ /**
15
+ * Narrow the registry's untyped config down to the handful of optional string
16
+ * fields an OpenAI-compatible vendor forwards (`apiKey`/`baseURL`/`defaultModel`).
17
+ * A blanket `config as OpenAIProviderConfig` cast would silently smuggle any
18
+ * wrong-typed field straight through to the client; this pick keeps only
19
+ * known-good strings so a bad value falls back to the vendor defaults instead.
20
+ */
21
+ export declare function pickOpenAICompatConfig(config: Record<string, unknown>): OpenAICompatConfig;
22
+ export interface DefineOpenAICompatProviderSpec {
23
+ /**
24
+ * Vendor slug (e.g. `xai`, `zai`, `google`, `local`). Stamped onto the
25
+ * underlying client so usage stats, provider_request/response events and
26
+ * error context attribute to the vendor, NOT `openai`.
27
+ */
28
+ readonly name: string;
29
+ /** Vendor base URL. Config may override it (narrow string pick); else this default is used. */
30
+ readonly baseURL: string;
31
+ /** Default model when a request didn't pin one. Config may override it (narrow string pick). */
32
+ readonly defaultModel: string;
33
+ /** The vendor's model catalog, forced onto the client (so context-window/capability lookups hit the vendor's models). */
34
+ readonly models: ReadonlyArray<ModelDescriptor>;
35
+ /** Auth descriptor surfaced to the setup wizard / `moxxy login`. */
36
+ readonly auth?: ProviderAuthDescriptor;
37
+ /**
38
+ * Key validation. When `true` (the default), wire `validateOpenAICompatKey`
39
+ * to probe `baseURL`'s `/models`. When `false`, omit `validateKey` entirely
40
+ * (local servers don't authenticate, so probing a possibly-offline box would
41
+ * surface confusing setup errors).
42
+ */
43
+ readonly validate?: boolean;
44
+ /**
45
+ * Optional override for resolving the API key from the narrowed config.
46
+ * Defaults to `config.apiKey`. The `local` provider uses this to fall back to
47
+ * an env var + placeholder, since the OpenAI SDK requires a non-empty key but
48
+ * local servers don't authenticate.
49
+ */
50
+ readonly resolveApiKey?: (config: OpenAICompatConfig) => string | undefined;
51
+ /**
52
+ * Optional override for resolving the base URL from the narrowed config.
53
+ * Defaults to `config.baseURL ?? baseURL`. The `local` provider uses this to
54
+ * insert an env-var fallback (`LOCAL_MODEL_BASE_URL`) between the config and
55
+ * the static default, read per-call.
56
+ */
57
+ readonly resolveBaseURL?: (config: OpenAICompatConfig) => string;
58
+ }
59
+ /**
60
+ * Build a {@link ProviderDef} for any vendor that speaks the OpenAI Chat
61
+ * Completions wire protocol. Centralizes the construction shared by xai / zai /
62
+ * google / local and the runtime-registered (`provider-admin`) vendors: it
63
+ * reuses the shared {@link OpenAIProvider} with the vendor slug + base URL +
64
+ * default model + catalog forced on, and (unless `validate: false`) wires
65
+ * `validateOpenAICompatKey` against the vendor's base URL.
66
+ *
67
+ * The per-vendor file becomes a single declarative call carrying only the
68
+ * vendor's constants; the cfg-narrowing + slug-forcing + validate wiring live
69
+ * here once.
70
+ */
71
+ export declare function defineOpenAICompatProvider(spec: DefineOpenAICompatProviderSpec): ProviderDef;
72
+ //# sourceMappingURL=compat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compat.d.ts","sourceRoot":"","sources":["../src/compat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,eAAe,EAAE,KAAK,sBAAsB,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAIjH;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB,CAO1F;AAED,MAAM,WAAW,8BAA8B;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+FAA+F;IAC/F,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,gGAAgG;IAChG,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,yHAAyH;IACzH,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAChD,oEAAoE;IACpE,QAAQ,CAAC,IAAI,CAAC,EAAE,sBAAsB,CAAC;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,MAAM,GAAG,SAAS,CAAC;IAC5E;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,MAAM,CAAC;CAClE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,8BAA8B,GAAG,WAAW,CAqB5F"}
package/dist/compat.js ADDED
@@ -0,0 +1,53 @@
1
+ import { defineProvider } from '@moxxy/sdk';
2
+ import { OpenAIProvider } from './provider.js';
3
+ import { validateKey as validateOpenAICompatKey } from './validate.js';
4
+ /**
5
+ * Narrow the registry's untyped config down to the handful of optional string
6
+ * fields an OpenAI-compatible vendor forwards (`apiKey`/`baseURL`/`defaultModel`).
7
+ * A blanket `config as OpenAIProviderConfig` cast would silently smuggle any
8
+ * wrong-typed field straight through to the client; this pick keeps only
9
+ * known-good strings so a bad value falls back to the vendor defaults instead.
10
+ */
11
+ export function pickOpenAICompatConfig(config) {
12
+ const str = (v) => (typeof v === 'string' ? v : undefined);
13
+ return {
14
+ apiKey: str(config.apiKey),
15
+ baseURL: str(config.baseURL),
16
+ defaultModel: str(config.defaultModel),
17
+ };
18
+ }
19
+ /**
20
+ * Build a {@link ProviderDef} for any vendor that speaks the OpenAI Chat
21
+ * Completions wire protocol. Centralizes the construction shared by xai / zai /
22
+ * google / local and the runtime-registered (`provider-admin`) vendors: it
23
+ * reuses the shared {@link OpenAIProvider} with the vendor slug + base URL +
24
+ * default model + catalog forced on, and (unless `validate: false`) wires
25
+ * `validateOpenAICompatKey` against the vendor's base URL.
26
+ *
27
+ * The per-vendor file becomes a single declarative call carrying only the
28
+ * vendor's constants; the cfg-narrowing + slug-forcing + validate wiring live
29
+ * here once.
30
+ */
31
+ export function defineOpenAICompatProvider(spec) {
32
+ const resolveApiKey = spec.resolveApiKey ?? ((cfg) => cfg.apiKey);
33
+ const resolveBaseURL = spec.resolveBaseURL ?? ((cfg) => cfg.baseURL ?? spec.baseURL);
34
+ return defineProvider({
35
+ name: spec.name,
36
+ models: [...spec.models],
37
+ createClient: (config) => {
38
+ const cfg = pickOpenAICompatConfig(config);
39
+ return new OpenAIProvider({
40
+ apiKey: resolveApiKey(cfg),
41
+ name: spec.name,
42
+ baseURL: resolveBaseURL(cfg),
43
+ defaultModel: cfg.defaultModel ?? spec.defaultModel,
44
+ models: spec.models,
45
+ });
46
+ },
47
+ ...(spec.validate === false
48
+ ? {}
49
+ : { validateKey: (key) => validateOpenAICompatKey(key, { baseURL: spec.baseURL }) }),
50
+ ...(spec.auth ? { auth: spec.auth } : {}),
51
+ });
52
+ }
53
+ //# sourceMappingURL=compat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compat.js","sourceRoot":"","sources":["../src/compat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAuE,MAAM,YAAY,CAAC;AACjH,OAAO,EAAE,cAAc,EAA6B,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,WAAW,IAAI,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAevE;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAA+B;IACpE,MAAM,GAAG,GAAG,CAAC,CAAU,EAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACxF,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;QAC1B,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;QAC5B,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC;KACvC,CAAC;AACJ,CAAC;AAwCD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAAoC;IAC7E,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC,GAAuB,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACtF,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC,GAAuB,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;IACzG,OAAO,cAAc,CAAC;QACpB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE;YACvB,MAAM,GAAG,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;YAC3C,OAAO,IAAI,cAAc,CAAC;gBACxB,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC;gBAC1B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC;gBAC5B,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY;gBACnD,MAAM,EAAE,IAAI,CAAC,MAAM;aACW,CAAC,CAAC;QACpC,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,KAAK;YACzB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,uBAAuB,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAC9F,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1C,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { OpenAIProvider, openAIModels, type OpenAIProviderConfig } from './provider.js';
2
+ export { OpenAIProvider, openAIModels };
3
+ export type { OpenAIProviderConfig };
4
+ export { toOpenAIMessages, toOpenAITools } from './translate.js';
5
+ export { validateKey, type ValidateKeyDeps, type ValidationResult } from './validate.js';
6
+ export { validateKey as validateOpenAICompatKey } from './validate.js';
7
+ export { defineOpenAICompatProvider, pickOpenAICompatConfig, type DefineOpenAICompatProviderSpec, type OpenAICompatConfig, } from './compat.js';
8
+ export declare const openaiProviderDef: import("@moxxy/sdk").ProviderDef;
9
+ export declare const openaiPlugin: import("@moxxy/sdk").Plugin;
10
+ export default openaiPlugin;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAExF,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;AACxC,YAAY,EAAE,oBAAoB,EAAE,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIzF,OAAO,EAAE,WAAW,IAAI,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAIvE,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,EACtB,KAAK,8BAA8B,EACnC,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AAIrB,eAAO,MAAM,iBAAiB,kCAK5B,CAAC;AAEH,eAAO,MAAM,YAAY,6BAIvB,CAAC;AAEH,eAAe,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
1
+ import { defineProvider, definePlugin } from '@moxxy/sdk';
2
+ import { OpenAIProvider, openAIModels } from './provider.js';
3
+ export { OpenAIProvider, openAIModels };
4
+ export { toOpenAIMessages, toOpenAITools } from './translate.js';
5
+ export { validateKey } from './validate.js';
6
+ // DI-friendly alias: any OpenAI-compatible vendor (same `models.list` probe)
7
+ // can reuse this validator. Re-exported under a vendor-neutral name so other
8
+ // packages don't couple to the OpenAI-specific `validateKey` symbol.
9
+ export { validateKey as validateOpenAICompatKey } from './validate.js';
10
+ // Shared factory for OpenAI-Chat-Completions-compatible vendors (xai/zai/google/
11
+ // local + runtime provider-admin entries). Captures the slug-forcing client
12
+ // construction + config narrowing + validateKey wiring in one place.
13
+ export { defineOpenAICompatProvider, pickOpenAICompatConfig, } from './compat.js';
14
+ import { validateKey as validateOpenAIKey } from './validate.js';
15
+ export const openaiProviderDef = defineProvider({
16
+ name: 'openai',
17
+ models: [...openAIModels],
18
+ createClient: (config) => new OpenAIProvider(config),
19
+ validateKey: (key) => validateOpenAIKey(key),
20
+ });
21
+ export const openaiPlugin = definePlugin({
22
+ name: '@moxxy/plugin-provider-openai',
23
+ version: '0.0.0',
24
+ providers: [openaiProviderDef],
25
+ });
26
+ export default openaiPlugin;
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,YAAY,EAA6B,MAAM,eAAe,CAAC;AAExF,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,WAAW,EAA+C,MAAM,eAAe,CAAC;AACzF,6EAA6E;AAC7E,6EAA6E;AAC7E,qEAAqE;AACrE,OAAO,EAAE,WAAW,IAAI,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACvE,iFAAiF;AACjF,4EAA4E;AAC5E,qEAAqE;AACrE,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,GAGvB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,WAAW,IAAI,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEjE,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC;IAC9C,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,CAAC,GAAG,YAAY,CAAC;IACzB,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,cAAc,CAAC,MAA8B,CAAC;IAC5E,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC;CAC7C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAC;IACvC,IAAI,EAAE,+BAA+B;IACrC,OAAO,EAAE,OAAO;IAChB,SAAS,EAAE,CAAC,iBAAiB,CAAC;CAC/B,CAAC,CAAC;AAEH,eAAe,YAAY,CAAC"}
@@ -0,0 +1,44 @@
1
+ import OpenAI from 'openai';
2
+ import type { LLMProvider, ModelDescriptor, ProviderEvent, ProviderRequest } from '@moxxy/sdk';
3
+ export interface OpenAIProviderConfig {
4
+ readonly apiKey?: string;
5
+ readonly baseURL?: string;
6
+ readonly defaultModel?: string;
7
+ readonly client?: OpenAI;
8
+ /**
9
+ * Override the reported provider name (events, usage stats, error
10
+ * context). Defaults to `'openai'`. Runtime-registered OpenAI-compatible
11
+ * vendors (provider_add → z.ai, deepseek, groq, …) reuse this class and
12
+ * MUST pass their own slug here, otherwise their traffic and errors are
13
+ * all misattributed to OpenAI.
14
+ */
15
+ readonly name?: string;
16
+ /**
17
+ * Override the advertised model catalog. Defaults to the OpenAI catalog.
18
+ * Runtime-registered vendors pass their own descriptors so context-window
19
+ * lookups (compaction/elision budgets) and capability gating
20
+ * (supportsImages/supportsDocuments) work against the vendor's models
21
+ * instead of missing on the OpenAI list.
22
+ */
23
+ readonly models?: ReadonlyArray<ModelDescriptor>;
24
+ }
25
+ /**
26
+ * Model catalog as of OpenAI's 2026 API surface. The 5.x family supersedes
27
+ * the 4o family but the older ones stay listed so existing configs keep
28
+ * working without a forced migration.
29
+ *
30
+ * Output/context numbers are the public documented limits as of April-May
31
+ * 2026; verify against https://developers.openai.com/api/docs/models when
32
+ * picking a model for a long-context workload.
33
+ */
34
+ export declare const openAIModels: ReadonlyArray<ModelDescriptor>;
35
+ export declare class OpenAIProvider implements LLMProvider {
36
+ readonly name: string;
37
+ readonly models: ReadonlyArray<ModelDescriptor>;
38
+ private readonly client;
39
+ private readonly defaultModel;
40
+ constructor(config?: OpenAIProviderConfig);
41
+ stream(req: ProviderRequest): AsyncIterable<ProviderEvent>;
42
+ countTokens(req: Pick<ProviderRequest, 'model' | 'messages' | 'system' | 'tools'>): Promise<number>;
43
+ }
44
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,aAAa,EACb,eAAe,EAEhB,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;CAClD;AAED;;;;;;;;GAQG;AAMH,eAAO,MAAM,YAAY,EAAE,aAAa,CAAC,eAAe,CAyBvD,CAAC;AASF,qBAAa,cAAe,YAAW,WAAW;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,MAAM,GAAE,oBAAyB;IAYtC,MAAM,CAAC,GAAG,EAAE,eAAe,GAAG,aAAa,CAAC,aAAa,CAAC;IAoM3D,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;CAQ1G"}
@@ -0,0 +1,261 @@
1
+ import OpenAI from 'openai';
2
+ import { estimateTextTokens, toFriendlyError } from '@moxxy/sdk';
3
+ import { toOpenAIMessages, toOpenAITools } from './translate.js';
4
+ /**
5
+ * Model catalog as of OpenAI's 2026 API surface. The 5.x family supersedes
6
+ * the 4o family but the older ones stay listed so existing configs keep
7
+ * working without a forced migration.
8
+ *
9
+ * Output/context numbers are the public documented limits as of April-May
10
+ * 2026; verify against https://developers.openai.com/api/docs/models when
11
+ * picking a model for a long-context workload.
12
+ */
13
+ // The gpt-5.x family are reasoning models (`supportsReasoning`): they accept
14
+ // `reasoning_effort` and, on backends that stream a summary, surface reasoning
15
+ // deltas. Official OpenAI Chat Completions doesn't stream a reasoning summary
16
+ // (Responses-API only), so the flag mainly gates the config UI + effort there;
17
+ // OpenAI-compatible reasoning backends (DeepSeek/z.ai/local) do stream it.
18
+ export const openAIModels = [
19
+ // GPT-5.5 family (released April 23, 2026): newest frontier class.
20
+ { id: 'gpt-5.5', contextWindow: 1_050_000, maxOutputTokens: 128_000, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true, supportsReasoning: true },
21
+ { id: 'gpt-5.5-pro', contextWindow: 1_050_000, maxOutputTokens: 128_000, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true, supportsReasoning: true },
22
+ // GPT-5.4 family: cheaper general-purpose tier; -mini and -nano are the
23
+ // new sweet-spot defaults for high-volume agentic workloads.
24
+ { id: 'gpt-5.4', contextWindow: 1_000_000, maxOutputTokens: 128_000, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true, supportsReasoning: true },
25
+ { id: 'gpt-5.4-pro', contextWindow: 1_000_000, maxOutputTokens: 128_000, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true, supportsReasoning: true },
26
+ { id: 'gpt-5.4-mini', contextWindow: 400_000, maxOutputTokens: 128_000, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true, supportsReasoning: true },
27
+ { id: 'gpt-5.4-nano', contextWindow: 400_000, maxOutputTokens: 128_000, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true, supportsReasoning: true },
28
+ // GPT-5.3-Codex: agentic coding specialist. Vision-capable.
29
+ { id: 'gpt-5.3-codex', contextWindow: 400_000, maxOutputTokens: 128_000, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true, supportsReasoning: true },
30
+ // GPT-5.2 and GPT-5: prior reasoning models, configurable effort.
31
+ { id: 'gpt-5.2', contextWindow: 400_000, maxOutputTokens: 128_000, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true, supportsReasoning: true },
32
+ { id: 'gpt-5', contextWindow: 400_000, maxOutputTokens: 128_000, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true, supportsReasoning: true },
33
+ // GPT-4 family: kept for explicit-pin use cases.
34
+ // 4.1 is text-only; 4o/4o-mini are vision + document capable; 4-turbo predates file inputs.
35
+ { id: 'gpt-4.1', contextWindow: 1_000_000, maxOutputTokens: 32_768, supportsTools: true, supportsStreaming: true },
36
+ { id: 'gpt-4o', contextWindow: 128_000, maxOutputTokens: 16_384, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true },
37
+ { id: 'gpt-4o-mini', contextWindow: 128_000, maxOutputTokens: 16_384, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true },
38
+ { id: 'gpt-4-turbo', contextWindow: 128_000, maxOutputTokens: 4_096, supportsTools: true, supportsStreaming: true, supportsImages: true },
39
+ ];
40
+ export class OpenAIProvider {
41
+ name;
42
+ models;
43
+ client;
44
+ defaultModel;
45
+ constructor(config = {}) {
46
+ this.name = config.name ?? 'openai';
47
+ this.models = config.models ?? openAIModels;
48
+ this.client =
49
+ config.client ??
50
+ new OpenAI({
51
+ apiKey: config.apiKey ?? process.env.OPENAI_API_KEY,
52
+ ...(config.baseURL ? { baseURL: config.baseURL } : {}),
53
+ });
54
+ this.defaultModel = config.defaultModel ?? 'gpt-5.4-mini';
55
+ }
56
+ async *stream(req) {
57
+ const messages = toOpenAIMessages(req.messages);
58
+ // `req.system` is the hook-injection side channel (e.g. the memory
59
+ // consolidation nudge): extra system text delivered IN ADDITION to any
60
+ // system-role messages already in `req.messages`. Insert it right after
61
+ // the leading system message(s) so it reads as system guidance without
62
+ // reordering the conversation.
63
+ if (req.system) {
64
+ let insertAt = 0;
65
+ while (insertAt < messages.length && messages[insertAt].role === 'system')
66
+ insertAt += 1;
67
+ messages.splice(insertAt, 0, { role: 'system', content: req.system });
68
+ }
69
+ const tools = req.tools && req.tools.length > 0 ? toOpenAITools(req.tools) : undefined;
70
+ const model = req.model || this.defaultModel;
71
+ yield { type: 'message_start', model };
72
+ // GPT-5.x (and OpenAI's reasoning models) renamed the token cap field
73
+ // from `max_tokens` to `max_completion_tokens` and ALSO reject the
74
+ // legacy name with a 400. Use the new name for any model whose id
75
+ // starts with gpt-5 / o1 / o3; keep the legacy name for the gpt-4
76
+ // family so existing callers don't regress.
77
+ const usesCompletionTokens = /^(?:gpt-5|o1|o3)/.test(model);
78
+ const tokenLimitKey = usesCompletionTokens ? 'max_completion_tokens' : 'max_tokens';
79
+ // Reasoning preview is gated by the per-provider toggle (`req.reasoning`).
80
+ // When on, request `reasoning_effort` for OpenAI reasoning models (improves
81
+ // depth + makes a summary available where the backend streams one) and
82
+ // surface the streamed reasoning/reasoning_content deltas.
83
+ const emitReasoning = req.reasoning != null && req.reasoning !== false;
84
+ const reasoningEffort = typeof req.reasoning === 'object' ? req.reasoning.effort : undefined;
85
+ // Type the request body as the SDK's streaming-create params so field
86
+ // names/value types are checked. The local `OpenAIChatMessage` /
87
+ // `OpenAIToolDef` shapes genuinely diverge from the SDK's wide message/tool
88
+ // unions (we build a narrower, hand-rolled shape), so cast ONLY those two
89
+ // fields — not the whole body — keeping the rest type-checked.
90
+ const params = {
91
+ model,
92
+ messages: messages,
93
+ ...(tools
94
+ ? { tools: tools }
95
+ : {}),
96
+ ...(req.temperature !== undefined ? { temperature: req.temperature } : {}),
97
+ ...(req.maxTokens ? { [tokenLimitKey]: req.maxTokens } : {}),
98
+ // Send `reasoning_effort` independently of the token-field heuristic.
99
+ // The two are unrelated concerns: `usesCompletionTokens` picks the cap
100
+ // FIELD NAME for the OpenAI-hosted reasoning models, while effort applies
101
+ // to any reasoning backend. OpenAI-compatible vendors (z.ai GLM,
102
+ // DeepSeek-R1, vLLM, Ollama) honor reasoning_effort but their model ids
103
+ // never match the gpt-5/o1/o3 regex, so gating effort on it silently
104
+ // dropped a user-requested effort for exactly those backends. The
105
+ // descriptor's `supportsReasoning` already gates this upstream via
106
+ // req.reasoning.
107
+ ...(emitReasoning && reasoningEffort ? { reasoning_effort: reasoningEffort } : {}),
108
+ stream: true,
109
+ // OpenAI only emits the final `usage` chunk when this is set;
110
+ // without it `raw.usage` is null on every chunk and token usage
111
+ // (and cache-read counts) are silently lost for every streamed turn.
112
+ stream_options: { include_usage: true },
113
+ };
114
+ let stream;
115
+ try {
116
+ stream = (await this.client.chat.completions.create(params,
117
+ // Pass the AbortSignal into the SDK request options so cancelling
118
+ // mid-stream tears down the underlying HTTP request instead of just
119
+ // stopping our consumption loop. Without this, Esc / Ctrl+C felt
120
+ // like nothing happened — the model kept generating and the user
121
+ // got charged for tokens after the cancel.
122
+ req.signal ? { signal: req.signal } : undefined));
123
+ }
124
+ catch (err) {
125
+ // A cancel can surface as a thrown AbortError from the create() await —
126
+ // report the clean terminal 'aborted' event (parity with the Anthropic
127
+ // provider) so callers that suppress error UI on user cancel don't get a
128
+ // noisy classified provider error.
129
+ if (req.signal?.aborted) {
130
+ yield { type: 'error', message: 'aborted', retryable: false };
131
+ return;
132
+ }
133
+ yield { type: 'error', ...toFriendlyError(err, { provider: this.name }) };
134
+ return;
135
+ }
136
+ const pending = new Map();
137
+ let stopReason = 'end_turn';
138
+ let usageIn = 0;
139
+ let usageOut = 0;
140
+ let usageCacheRead = 0;
141
+ try {
142
+ for await (const raw of stream) {
143
+ if (req.signal?.aborted) {
144
+ yield { type: 'error', message: 'aborted', retryable: false };
145
+ return;
146
+ }
147
+ // Usage arrives in a FINAL chunk that has an empty `choices` array
148
+ // (only when stream_options.include_usage is set), so it must be read
149
+ // before the `!choice` guard below — otherwise it's `continue`d past.
150
+ if (raw.usage) {
151
+ usageIn = raw.usage.prompt_tokens ?? usageIn;
152
+ usageOut = raw.usage.completion_tokens ?? usageOut;
153
+ // `prompt_tokens` already includes the cached portion; surface the
154
+ // cached count so cache hit-rate accounting works (parity with the
155
+ // Anthropic provider's cache_read_input_tokens).
156
+ usageCacheRead = raw.usage.prompt_tokens_details?.cached_tokens ?? usageCacheRead;
157
+ }
158
+ const choice = raw.choices?.[0];
159
+ if (!choice)
160
+ continue;
161
+ const delta = choice.delta ?? {};
162
+ if (typeof delta.content === 'string' && delta.content) {
163
+ yield { type: 'text_delta', delta: delta.content };
164
+ }
165
+ if (emitReasoning) {
166
+ const reasoning = delta.reasoning_content ?? delta.reasoning;
167
+ if (typeof reasoning === 'string' && reasoning) {
168
+ yield { type: 'reasoning_delta', delta: reasoning };
169
+ }
170
+ }
171
+ if (delta.tool_calls) {
172
+ for (const tcDelta of delta.tool_calls) {
173
+ const idx = tcDelta.index ?? 0;
174
+ let entry = pending.get(idx);
175
+ if (!entry) {
176
+ entry = {
177
+ id: tcDelta.id ?? `call_${idx}`,
178
+ name: tcDelta.function?.name ?? '',
179
+ argsBuffer: '',
180
+ emittedStart: false,
181
+ };
182
+ pending.set(idx, entry);
183
+ }
184
+ else if (tcDelta.id) {
185
+ entry.id = tcDelta.id;
186
+ }
187
+ if (tcDelta.function?.name && !entry.name)
188
+ entry.name = tcDelta.function.name;
189
+ if (tcDelta.function?.name && !entry.emittedStart && entry.name) {
190
+ entry.emittedStart = true;
191
+ yield { type: 'tool_use_start', id: entry.id, name: entry.name };
192
+ }
193
+ if (typeof tcDelta.function?.arguments === 'string') {
194
+ entry.argsBuffer += tcDelta.function.arguments;
195
+ yield { type: 'tool_use_delta', id: entry.id, partialInput: tcDelta.function.arguments };
196
+ }
197
+ }
198
+ }
199
+ if (choice.finish_reason) {
200
+ stopReason = mapStopReason(choice.finish_reason);
201
+ }
202
+ }
203
+ }
204
+ catch (err) {
205
+ // The SDK rejects the iterator with an AbortError once req.signal fires;
206
+ // emit the clean 'aborted' event instead of a classified provider error
207
+ // (parity with the Anthropic provider and the in-loop abort check above).
208
+ if (req.signal?.aborted) {
209
+ yield { type: 'error', message: 'aborted', retryable: false };
210
+ return;
211
+ }
212
+ yield { type: 'error', ...toFriendlyError(err, { provider: this.name }) };
213
+ return;
214
+ }
215
+ // Flush tool_use_end events with parsed arguments.
216
+ for (const entry of pending.values()) {
217
+ let parsed = {};
218
+ if (entry.argsBuffer) {
219
+ try {
220
+ parsed = JSON.parse(entry.argsBuffer);
221
+ }
222
+ catch {
223
+ parsed = { _rawPartial: entry.argsBuffer };
224
+ }
225
+ }
226
+ if (entry.emittedStart) {
227
+ yield { type: 'tool_use_end', id: entry.id, input: parsed };
228
+ }
229
+ }
230
+ yield {
231
+ type: 'message_end',
232
+ stopReason,
233
+ usage: usageIn > 0 || usageOut > 0
234
+ ? {
235
+ inputTokens: usageIn,
236
+ outputTokens: usageOut,
237
+ ...(usageCacheRead > 0 ? { cacheReadTokens: usageCacheRead } : {}),
238
+ }
239
+ : undefined,
240
+ };
241
+ }
242
+ async countTokens(req) {
243
+ // OpenAI doesn't expose a free token counter; fall back to a coarse estimate.
244
+ const blob = (req.system ?? '') +
245
+ req.messages.map((m) => m.content.map((c) => ('text' in c ? c.text : JSON.stringify(c))).join('')).join('') +
246
+ (req.tools ?? []).map((t) => t.name + t.description).join('');
247
+ return estimateTextTokens(blob);
248
+ }
249
+ }
250
+ function mapStopReason(s) {
251
+ if (s === 'tool_calls')
252
+ return 'tool_use';
253
+ if (s === 'length')
254
+ return 'max_tokens';
255
+ if (s === 'stop')
256
+ return 'end_turn';
257
+ if (s === 'content_filter')
258
+ return 'error';
259
+ return 'end_turn';
260
+ }
261
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { ProviderMessage, ToolDef } from '@moxxy/sdk';
2
+ export type OpenAIUserContentPart = {
3
+ type: 'text';
4
+ text: string;
5
+ } | {
6
+ type: 'image_url';
7
+ image_url: {
8
+ url: string;
9
+ };
10
+ } | {
11
+ type: 'file';
12
+ file: {
13
+ filename?: string;
14
+ file_data: string;
15
+ };
16
+ };
17
+ export interface OpenAIChatMessage {
18
+ role: 'system' | 'user' | 'assistant' | 'tool';
19
+ content?: string | ReadonlyArray<OpenAIUserContentPart> | null;
20
+ tool_calls?: Array<{
21
+ id: string;
22
+ type: 'function';
23
+ function: {
24
+ name: string;
25
+ arguments: string;
26
+ };
27
+ }>;
28
+ tool_call_id?: string;
29
+ name?: string;
30
+ }
31
+ export interface OpenAIToolDef {
32
+ type: 'function';
33
+ function: {
34
+ name: string;
35
+ description: string;
36
+ parameters: unknown;
37
+ };
38
+ }
39
+ export declare function toOpenAIMessages(messages: ReadonlyArray<ProviderMessage>): OpenAIChatMessage[];
40
+ export declare function toOpenAITools(tools: ReadonlyArray<ToolDef>): OpenAIToolDef[];
41
+ //# sourceMappingURL=translate.d.ts.map