@stratusagent/provider-openai 0.11.4

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 Stratus Labs
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,74 @@
1
+ # @stratusagent/provider-openai
2
+
3
+ The OpenAI-compatible chat-completions provider, as a **plugin**. It
4
+ registers a provider named `openai-compatible` through the plugin seam
5
+ ([19](../../docs/roadmap/19-registration-seams.md)), and a soul selects it
6
+ the way it selects a built-in:
7
+
8
+ ```markdown
9
+ ---
10
+ id: ava
11
+ provider: openai-compatible
12
+ model: llama3
13
+ credentials: [openai.apiKey]
14
+ ---
15
+ ```
16
+
17
+ ## Install and enable
18
+
19
+ ```bash
20
+ npm install @stratusagent/provider-openai
21
+ ```
22
+
23
+ ```jsonc
24
+ // ~/.stratus/config.json — a trusted config only
25
+ {
26
+ "plugins": {
27
+ "@stratusagent/provider-openai": {
28
+ "enabled": true,
29
+ "baseUrl": "http://127.0.0.1:11434/v1", // any chat-completions endpoint; omit for api.openai.com
30
+ "model": "llama3" // the default when a soul names none
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ Then store the key it uses, as a **named credential** — the agent's own
37
+ entry, or one the fleet shares — and list it in each soul's `credentials:`:
38
+
39
+ ```bash
40
+ stratus credential set openai.apiKey # shared by every agent that lists it
41
+ stratus credential set openai.apiKey --agent ava # ava's own account
42
+ ```
43
+
44
+ ## Settings
45
+
46
+ | Key | What it sets |
47
+ | --- | --- |
48
+ | `baseUrl` | The endpoint. Default: the OpenAI API |
49
+ | `model` | The model when a soul or config names none. A run with neither is refused, naming both places |
50
+ | `headers` | Extra request headers, name to value |
51
+ | `vision` | Whether the model takes images. Default `true`; `false` for a text-only model |
52
+ | `requestTimeoutMs` | Upper bound on one request. Default five minutes; `0` disables |
53
+
54
+ ## How this differs from `provider: openai`
55
+
56
+ Same adapter — `createOpenAICompatibleProvider` from
57
+ `@stratusagent/providers`, unchanged — arriving the way a third party's
58
+ provider would, which is why it exists:
59
+
60
+ - **The key is a per-agent credential, resolved on every request.**
61
+ `openai.apiKey` goes through the manifest-bound resolver for the agent
62
+ the request is for: its own entry first, then the shared one. Two agents
63
+ on one installed plugin can bill to two accounts, a rotated key takes
64
+ effect on the next turn, and an agent whose soul does not list the name
65
+ cannot use it. Nothing here reads `process.env`.
66
+ - **The endpoint is the plugin's setting**, not a stored sign-in's binding.
67
+ The built-in `openai` selection keeps its stored sign-in, its
68
+ endpoint-bound key, and `STRATUS_API_KEY`; none of that reaches this
69
+ plugin, and none of it is needed here.
70
+ - **It works as a fallback target**: `fallbackProvider: openai-compatible`
71
+ with a `fallbackModel` fails over to it under the same rules as a
72
+ built-in.
73
+
74
+ Diagnostics show it as `plugin:openai-compatible`.
@@ -0,0 +1,36 @@
1
+ import type { JsonObject, Plugin } from '@stratusagent/core';
2
+ /**
3
+ * The name a soul selects this provider by. Not `openai`: that name is the
4
+ * built-in adapter with its stored sign-in and endpoint binding, and a
5
+ * plugin may not shadow a built-in — the host refuses the manifest.
6
+ */
7
+ export declare const OPENAI_COMPATIBLE_PROVIDER_NAME = "openai-compatible";
8
+ /** The credential this plugin resolves, per calling agent — declared in the manifest. */
9
+ export declare const OPENAI_API_KEY_CREDENTIAL = "openai.apiKey";
10
+ export interface OpenAiProviderPluginOptions {
11
+ /** Test injection: the transport the adapter sends on. */
12
+ fetch?: typeof fetch;
13
+ }
14
+ /**
15
+ * The OpenAI-compatible adapter, reached through the provider seam.
16
+ *
17
+ * The adapter is `@stratusagent/providers`' `createOpenAICompatibleProvider`
18
+ * unchanged; what this package adds is the two things a plugin provider
19
+ * gets that a built-in does not. Its settings — the endpoint, a default
20
+ * model, extra headers — come from its own config block. And its key comes
21
+ * through the manifest-bound credential resolver, **per calling agent**:
22
+ * `openai.apiKey` is a named credential the soul allowlists, resolved on
23
+ * every request from the agent the request is for, so two agents on one
24
+ * installed plugin can bill to two accounts, and a rotated key needs no
25
+ * restart. The adapter takes a fixed key, so one is built per (selection,
26
+ * key) and kept — never one per turn.
27
+ *
28
+ * Nothing here reads `process.env`, and the built-in `openai` selection —
29
+ * the stored sign-in, the endpoint binding, `STRATUS_API_KEY` — is
30
+ * untouched: this is the same adapter arriving the way a third party's
31
+ * would, which is the point of building it.
32
+ */
33
+ export declare const createOpenAiProviderPlugin: (config?: JsonObject, options?: OpenAiProviderPluginOptions) => Plugin;
34
+ /** The loader's entry point. See docs/architecture/plugins.md. */
35
+ export declare const createPlugin: (config: JsonObject) => Plugin;
36
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,UAAU,EAEV,MAAM,EAGP,MAAM,oBAAoB,CAAC;AAG5B;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,sBAAsB,CAAC;AAEnE,yFAAyF;AACzF,eAAO,MAAM,yBAAyB,kBAAkB,CAAC;AAEzD,MAAM,WAAW,2BAA2B;IAC1C,0DAA0D;IAC1D,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAiBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,0BAA0B,GACrC,SAAQ,UAAe,EACvB,UAAS,2BAAgC,KACxC,MA6EF,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,YAAY,GAAI,QAAQ,UAAU,KAAG,MAA4C,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,111 @@
1
+ import { createOpenAICompatibleProvider } from '@stratusagent/providers';
2
+ /**
3
+ * The name a soul selects this provider by. Not `openai`: that name is the
4
+ * built-in adapter with its stored sign-in and endpoint binding, and a
5
+ * plugin may not shadow a built-in — the host refuses the manifest.
6
+ */
7
+ export const OPENAI_COMPATIBLE_PROVIDER_NAME = 'openai-compatible';
8
+ /** The credential this plugin resolves, per calling agent — declared in the manifest. */
9
+ export const OPENAI_API_KEY_CREDENTIAL = 'openai.apiKey';
10
+ const readString = (value) => (typeof value === 'string' && value.length > 0 ? value : undefined);
11
+ const readHeaders = (value) => {
12
+ const headers = {};
13
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
14
+ return headers;
15
+ }
16
+ for (const [name, entry] of Object.entries(value)) {
17
+ if (typeof entry === 'string') {
18
+ headers[name] = entry;
19
+ }
20
+ }
21
+ return headers;
22
+ };
23
+ /**
24
+ * The OpenAI-compatible adapter, reached through the provider seam.
25
+ *
26
+ * The adapter is `@stratusagent/providers`' `createOpenAICompatibleProvider`
27
+ * unchanged; what this package adds is the two things a plugin provider
28
+ * gets that a built-in does not. Its settings — the endpoint, a default
29
+ * model, extra headers — come from its own config block. And its key comes
30
+ * through the manifest-bound credential resolver, **per calling agent**:
31
+ * `openai.apiKey` is a named credential the soul allowlists, resolved on
32
+ * every request from the agent the request is for, so two agents on one
33
+ * installed plugin can bill to two accounts, and a rotated key needs no
34
+ * restart. The adapter takes a fixed key, so one is built per (selection,
35
+ * key) and kept — never one per turn.
36
+ *
37
+ * Nothing here reads `process.env`, and the built-in `openai` selection —
38
+ * the stored sign-in, the endpoint binding, `STRATUS_API_KEY` — is
39
+ * untouched: this is the same adapter arriving the way a third party's
40
+ * would, which is the point of building it.
41
+ */
42
+ export const createOpenAiProviderPlugin = (config = {}, options = {}) => {
43
+ const baseUrl = readString(config.baseUrl);
44
+ const configuredModel = readString(config.model);
45
+ const headers = readHeaders(config.headers);
46
+ const vision = typeof config.vision === 'boolean' ? config.vision : undefined;
47
+ const requestTimeoutMs = typeof config.requestTimeoutMs === 'number' ? config.requestTimeoutMs : undefined;
48
+ return {
49
+ name: 'provider-openai',
50
+ setup(context) {
51
+ if (!context.providers) {
52
+ throw new Error(`This host hands plugins no provider handle, so @stratusagent/provider-openai cannot register ${OPENAI_COMPATIBLE_PROVIDER_NAME}.`);
53
+ }
54
+ const credentials = context.credentials;
55
+ context.providers.register({
56
+ name: OPENAI_COMPATIBLE_PROVIDER_NAME,
57
+ // The chat-completions adapter answers in one response; nothing
58
+ // reaches `onDelta`, so a host must not arm a stall watchdog over it.
59
+ streams: false,
60
+ create(selection) {
61
+ const model = selection.model ?? configuredModel;
62
+ if (model === undefined) {
63
+ throw new Error(`No model for provider ${OPENAI_COMPATIBLE_PROVIDER_NAME}: set model: in the soul, or model in plugins["@stratusagent/provider-openai"].`);
64
+ }
65
+ // One adapter per key this selection has been asked to use. A
66
+ // fleet of agents on one account shares one; an agent on its own
67
+ // account gets its own; a rotated key gets a fresh one.
68
+ const adapters = new Map();
69
+ const adapterFor = (apiKey) => {
70
+ let adapter = adapters.get(apiKey);
71
+ if (!adapter) {
72
+ adapter = createOpenAICompatibleProvider({
73
+ model,
74
+ apiKey,
75
+ name: OPENAI_COMPATIBLE_PROVIDER_NAME,
76
+ headers,
77
+ ...(baseUrl !== undefined ? { baseUrl } : {}),
78
+ ...(selection.systemPrompt !== undefined ? { systemPrompt: selection.systemPrompt } : {}),
79
+ ...(vision !== undefined ? { vision } : {}),
80
+ ...(requestTimeoutMs !== undefined ? { requestTimeoutMs } : {}),
81
+ ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),
82
+ });
83
+ adapters.set(apiKey, adapter);
84
+ }
85
+ return adapter;
86
+ };
87
+ return {
88
+ name: OPENAI_COMPATIBLE_PROVIDER_NAME,
89
+ async generate(request) {
90
+ if (!credentials) {
91
+ throw new Error(`This host hands plugins no credential resolver, so ${OPENAI_COMPATIBLE_PROVIDER_NAME} cannot reach ${OPENAI_API_KEY_CREDENTIAL} for agent ${request.session.agent.id}.`);
92
+ }
93
+ // The calling agent's key, every request — its own entry,
94
+ // then the fleet's shared one — and refused, naming the
95
+ // remedy, rather than read from the environment.
96
+ const apiKey = await credentials.resolve(request.session.agent, OPENAI_API_KEY_CREDENTIAL);
97
+ if (apiKey === undefined) {
98
+ throw new Error(`No ${OPENAI_API_KEY_CREDENTIAL} credential resolves for agent ${request.session.agent.id}. `
99
+ + `Store one with \`stratus credential set ${OPENAI_API_KEY_CREDENTIAL}\` (or per agent with --agent), and list it in the soul's credentials:.`);
100
+ }
101
+ return adapterFor(apiKey).generate(request);
102
+ },
103
+ };
104
+ },
105
+ });
106
+ },
107
+ };
108
+ };
109
+ /** The loader's entry point. See docs/architecture/plugins.md. */
110
+ export const createPlugin = (config) => createOpenAiProviderPlugin(config);
111
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,88 @@
1
+ {
2
+ "name": "@stratusagent/provider-openai",
3
+ "version": "0.11.4",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ },
12
+ "./package.json": "./package.json"
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "engines": {
18
+ "node": ">=22.13 <23 || >=23.4"
19
+ },
20
+ "dependencies": {
21
+ "@stratusagent/core": "0.11.4",
22
+ "@stratusagent/providers": "0.11.4"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^24.6.0",
26
+ "typescript": "^5.9.3",
27
+ "@stratusagent/plugins": "0.11.4",
28
+ "@stratusagent/state": "0.11.4"
29
+ },
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/stratuslabs/agent.git",
34
+ "directory": "packages/provider-openai"
35
+ },
36
+ "description": "The OpenAI-compatible chat-completions provider as a Stratus plugin: registers `openai-compatible`, selectable by a soul, credentialed per agent through the plugin seam",
37
+ "keywords": [
38
+ "stratus",
39
+ "agent",
40
+ "ai",
41
+ "llm",
42
+ "stratus-plugin",
43
+ "openai",
44
+ "provider"
45
+ ],
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "stratus": {
50
+ "pluginVersion": 1,
51
+ "contributes": {
52
+ "providers": [
53
+ {
54
+ "name": "openai-compatible"
55
+ }
56
+ ]
57
+ },
58
+ "credentials": [
59
+ "openai.apiKey"
60
+ ],
61
+ "config": {
62
+ "type": "object",
63
+ "properties": {
64
+ "baseUrl": {
65
+ "type": "string"
66
+ },
67
+ "model": {
68
+ "type": "string"
69
+ },
70
+ "headers": {
71
+ "type": "object"
72
+ },
73
+ "vision": {
74
+ "type": "boolean"
75
+ },
76
+ "requestTimeoutMs": {
77
+ "type": "integer"
78
+ }
79
+ },
80
+ "additionalProperties": false
81
+ }
82
+ },
83
+ "scripts": {
84
+ "build": "tsc -b",
85
+ "typecheck": "tsc --noEmit --project tsconfig.test.json",
86
+ "test": "node --test --experimental-strip-types"
87
+ }
88
+ }