openclaw-nexos-provider 0.1.0 → 0.4.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # openclaw-nexos-provider
2
2
 
3
- An [OpenClaw](https://openclaw.ai) provider plugin for [Nexos AI](https://nexos.ai) —
3
+ An [OpenClaw](https://openclaw.ai) provider plugin for [nexos.ai](https://nexos.ai) —
4
4
  a unified AI gateway that exposes Claude, GPT, Gemini, Grok, and 60+ other models
5
5
  through a single API endpoint and one API key.
6
6
 
@@ -25,12 +25,13 @@ openclaw plugins install openclaw-nexos-provider
25
25
 
26
26
  ## Configure
27
27
 
28
- Set your Nexos API key (either works):
28
+ Provide your nexos.ai API key via the environment (this is all the provider
29
+ needs — OpenClaw detects it from `NEXOS_API_KEY`):
29
30
 
30
31
  ```bash
31
32
  export NEXOS_API_KEY="your-nexos-key"
32
- # or, interactively:
33
- openclaw onboard --nexos-api-key "your-nexos-key"
33
+ # optional, to run onboarding for the provider explicitly:
34
+ openclaw onboard --auth-choice nexos-api-key
34
35
  ```
35
36
 
36
37
  Then pick a model:
package/dist/index.js CHANGED
@@ -18,8 +18,9 @@ var MODEL_PREFIX_PRIORITIES = {
18
18
  "anthropic.claude": 400,
19
19
  grok: 600
20
20
  };
21
- function beautifyName(name) {
22
- return name.replace(/-/g, " ").replace(/\./g, " ").replace(/@/g, " @ ").replace(/\b\w/g, (l) => l.toUpperCase());
21
+ function costPerMillion(perToken) {
22
+ const value = typeof perToken === "string" ? Number.parseFloat(perToken) : perToken;
23
+ return Number.isFinite(value) && value > 0 ? value * 1e6 : 0;
23
24
  }
24
25
  function prioritizeModel(name) {
25
26
  for (const [pattern, priority] of Object.entries(MODEL_REGEX_PRIORITIES)) {
@@ -38,25 +39,29 @@ function buildNexosCatalog(apiData) {
38
39
  const models = [];
39
40
  for (const model of data) {
40
41
  const nexosModelId = model.nexos_model_id;
41
- const rawName = model.name;
42
- if (!nexosModelId || !rawName) {
42
+ const alias = model.name || model.id;
43
+ if (!nexosModelId || !alias) {
43
44
  continue;
44
45
  }
45
- const alias = `Nexos ${beautifyName(rawName)}`;
46
46
  const endpoints = Array.isArray(model.endpoints) ? model.endpoints : ["chat_completions"];
47
47
  models.push({
48
48
  alias,
49
49
  nexosModelId,
50
- priority: prioritizeModel(rawName),
50
+ priority: prioritizeModel(alias),
51
51
  endpoints,
52
52
  definition: {
53
53
  id: nexosModelId,
54
54
  name: alias,
55
55
  reasoning: true,
56
56
  input: ["text", "image"],
57
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
58
- maxTokens: DEFAULT_MAX_TOKENS,
59
- contextWindow: DEFAULT_CONTEXT_WINDOW,
57
+ cost: {
58
+ input: costPerMillion(model.pricing?.input_cost_per_token),
59
+ output: costPerMillion(model.pricing?.output_cost_per_token),
60
+ cacheRead: 0,
61
+ cacheWrite: 0
62
+ },
63
+ maxTokens: typeof model.max_tokens === "number" && model.max_tokens > 0 ? model.max_tokens : DEFAULT_MAX_TOKENS,
64
+ contextWindow: typeof model.context_length === "number" && model.context_length > 0 ? model.context_length : DEFAULT_CONTEXT_WINDOW,
60
65
  compat: {
61
66
  supportsStore: true,
62
67
  supportsDeveloperRole: true,
@@ -138,8 +143,25 @@ function selectModels(models, providerId) {
138
143
  const { completions, anthropic } = splitByEndpoint(models);
139
144
  return providerId === NEXOS_PROVIDER_ANTHROPIC ? anthropic : completions;
140
145
  }
141
- function registerNexosProvider(api, providerId, label) {
146
+ async function buildNexosProviderResult(providerId, apiKey) {
147
+ if (!apiKey) {
148
+ return null;
149
+ }
150
+ let models;
151
+ try {
152
+ models = await getNexosCatalog(apiKey);
153
+ } catch {
154
+ return null;
155
+ }
156
+ const selected = selectModels(models, providerId);
157
+ if (selected.length === 0) {
158
+ return null;
159
+ }
142
160
  const kind = providerId === NEXOS_PROVIDER_ANTHROPIC ? "anthropic" : "completions";
161
+ return { provider: buildProviderConfig({ models: selected, apiKey, kind }) };
162
+ }
163
+ function registerNexosProvider(api, providerId, label) {
164
+ const isPrimary = providerId === NEXOS_PROVIDER_COMPLETIONS;
143
165
  api.registerProvider({
144
166
  id: providerId,
145
167
  label,
@@ -149,34 +171,37 @@ function registerNexosProvider(api, providerId, label) {
149
171
  createProviderApiKeyAuthMethod({
150
172
  providerId,
151
173
  methodId: "api-key",
152
- label: "Nexos AI API key",
153
- hint: "API key from your Nexos AI dashboard",
174
+ label: "nexos.ai API key",
175
+ hint: "API key from your nexos.ai dashboard",
154
176
  optionKey: "nexosApiKey",
155
177
  flagName: "--nexos-api-key",
156
178
  envVar: "NEXOS_API_KEY",
157
- promptMessage: "Enter your Nexos AI API key"
179
+ promptMessage: "Enter your nexos.ai API key",
180
+ // Expose the provider in `openclaw onboard` / auth-choice so the
181
+ // host runs its models.json materialization for nexos.
182
+ wizard: isPrimary ? {
183
+ choiceId: "nexos-api-key",
184
+ choiceLabel: "nexos.ai API key",
185
+ groupId: "nexos",
186
+ groupLabel: "nexos.ai",
187
+ onboardingScopes: ["text-inference"]
188
+ } : void 0
158
189
  })
159
190
  ],
191
+ // Live catalog: consulted at runtime (picker/refresh).
160
192
  catalog: {
161
193
  order: "simple",
162
194
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
163
- run: async (ctx) => {
164
- const apiKey = resolveNexosApiKey(ctx, providerId);
165
- if (!apiKey) {
166
- return null;
167
- }
168
- let models;
169
- try {
170
- models = await getNexosCatalog(apiKey);
171
- } catch {
172
- return null;
173
- }
174
- const selected = selectModels(models, providerId);
175
- if (selected.length === 0) {
176
- return null;
177
- }
178
- return { provider: buildProviderConfig({ models: selected, apiKey, kind }) };
179
- }
195
+ run: async (ctx) => buildNexosProviderResult(providerId, resolveNexosApiKey(ctx, providerId))
196
+ },
197
+ // Static catalog: consulted by the host's models.json generator to
198
+ // materialize selectable models (this build only lets you select models
199
+ // present in the agent's static catalog). Declared as `runtime` discovery
200
+ // in the manifest. Resolves the key from the environment since no ctx is
201
+ // provided here.
202
+ staticCatalog: {
203
+ order: "simple",
204
+ run: async () => buildNexosProviderResult(providerId, process.env.NEXOS_API_KEY)
180
205
  }
181
206
  });
182
207
  api.registerModelCatalogProvider({
@@ -206,11 +231,11 @@ function registerNexosProvider(api, providerId, label) {
206
231
  }
207
232
  var index_default = definePluginEntry({
208
233
  id: "nexos",
209
- name: "Nexos AI",
210
- description: "Nexos AI unified gateway \u2014 access Claude, GPT, Gemini, Grok and 60+ models through one API key.",
234
+ name: "nexos.ai",
235
+ description: "nexos.ai unified gateway \u2014 access Claude, GPT, Gemini, Grok and 60+ models through one API key.",
211
236
  register(api) {
212
- registerNexosProvider(api, NEXOS_PROVIDER_COMPLETIONS, "Nexos AI");
213
- registerNexosProvider(api, NEXOS_PROVIDER_ANTHROPIC, "Nexos AI (Claude)");
237
+ registerNexosProvider(api, NEXOS_PROVIDER_COMPLETIONS, "nexos.ai");
238
+ registerNexosProvider(api, NEXOS_PROVIDER_ANTHROPIC, "nexos.ai (Claude)");
214
239
  }
215
240
  });
216
241
  export {
@@ -1,9 +1,9 @@
1
1
  ---
2
- title: "Nexos AI"
3
- summary: "Use Nexos AI's unified gateway (Claude, GPT, Gemini, Grok, and more) in OpenClaw via one API key"
2
+ title: "nexos.ai"
3
+ summary: "Use nexos.ai's unified gateway (Claude, GPT, Gemini, Grok, and more) in OpenClaw via one API key"
4
4
  ---
5
5
 
6
- Nexos AI is a unified AI gateway that provides OpenAI-compatible access to models
6
+ nexos.ai is a unified AI gateway that provides OpenAI-compatible access to models
7
7
  from many providers — Anthropic, OpenAI, Google, xAI, Mistral, and more — through
8
8
  a single API endpoint and API key.
9
9
 
@@ -17,12 +17,13 @@ This plugin registers two OpenClaw providers, both authenticated with
17
17
 
18
18
  ## Getting started
19
19
 
20
- 1. Get an API key from your Nexos AI dashboard.
21
- 2. Provide it to OpenClaw:
20
+ 1. Get an API key from your nexos.ai dashboard.
21
+ 2. Provide it to OpenClaw via the environment (auto-detected):
22
22
 
23
23
  ```bash
24
- openclaw onboard --nexos-api-key "$NEXOS_API_KEY"
25
- # or set NEXOS_API_KEY in the environment
24
+ export NEXOS_API_KEY="your-nexos-key"
25
+ # optional: run onboarding for the provider explicitly
26
+ openclaw onboard --auth-choice nexos-api-key
26
27
  ```
27
28
 
28
29
  3. Verify the models are available:
@@ -1,11 +1,17 @@
1
1
  {
2
2
  "id": "nexos",
3
- "name": "Nexos AI",
4
- "description": "Nexos AI unified gateway — access Claude, GPT, Gemini, Grok and 60+ models through one API key.",
3
+ "name": "nexos.ai",
4
+ "description": "nexos.ai unified gateway — access Claude, GPT, Gemini, Grok and 60+ models through one API key.",
5
5
  "providers": ["nexos", "nexos-anthropic"],
6
6
  "modelSupport": {
7
7
  "modelPrefixes": ["nexos/", "nexos-anthropic/"]
8
8
  },
9
+ "modelCatalog": {
10
+ "discovery": {
11
+ "nexos": "runtime",
12
+ "nexos-anthropic": "runtime"
13
+ }
14
+ },
9
15
  "setup": {
10
16
  "providers": [
11
17
  { "id": "nexos", "envVars": ["NEXOS_API_KEY"] },
@@ -20,12 +26,12 @@
20
26
  "provider": "nexos",
21
27
  "method": "api-key",
22
28
  "choiceId": "nexos-api-key",
23
- "choiceLabel": "Nexos AI API key",
29
+ "choiceLabel": "nexos.ai API key",
24
30
  "groupId": "nexos",
25
- "groupLabel": "Nexos AI",
31
+ "groupLabel": "nexos.ai",
26
32
  "cliFlag": "--nexos-api-key",
27
33
  "cliOption": "--nexos-api-key <key>",
28
- "cliDescription": "Nexos AI API key"
34
+ "cliDescription": "nexos.ai API key"
29
35
  }
30
36
  ],
31
37
  "activation": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "openclaw-nexos-provider",
3
- "version": "0.1.0",
4
- "description": "Nexos AI model provider plugin for OpenClaw — access Claude, GPT, Gemini, Grok and 60+ models through one API key.",
3
+ "version": "0.4.0",
4
+ "description": "nexos.ai model provider plugin for OpenClaw — access Claude, GPT, Gemini, Grok and 60+ models through one API key.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "fizikiukas",