@formthefog/stratus 2026.3.19 → 2026.3.20

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.
Files changed (3) hide show
  1. package/index.ts +39 -8
  2. package/package.json +1 -1
  3. package/src/setup.ts +33 -4
package/index.ts CHANGED
@@ -4,7 +4,7 @@ import type { StratusPluginConfig } from "./src/types.js";
4
4
  import { createStratusClient } from "./src/client.js";
5
5
  import { StratusConfigSchema } from "./src/config.js";
6
6
  import { setupStratus } from "./src/setup.js";
7
- import { readFileSync, writeFileSync, existsSync } from "fs";
7
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
8
8
  import { join } from "path";
9
9
  import { homedir } from "os";
10
10
 
@@ -232,6 +232,32 @@ const stratusPlugin = {
232
232
  } catch {
233
233
  // Silent fail — don't disrupt gateway startup
234
234
  }
235
+
236
+ if (apiKey) {
237
+ try {
238
+ const authPath = join(homedir(), ".openclaw", "agents", "main", "agent", "auth-profiles.json");
239
+ let authConfig: any = { version: 1, profiles: {}, lastGood: {}, usageStats: {} };
240
+ if (existsSync(authPath)) {
241
+ authConfig = JSON.parse(readFileSync(authPath, "utf-8"));
242
+ }
243
+ const existingProfile = authConfig.profiles["stratus:default"];
244
+ if (!existingProfile || existingProfile.key !== apiKey) {
245
+ authConfig.profiles["stratus:default"] = {
246
+ type: "api_key",
247
+ provider: "stratus",
248
+ key: apiKey,
249
+ };
250
+ authConfig.lastGood.stratus = "stratus:default";
251
+ const authDir = join(homedir(), ".openclaw", "agents", "main", "agent");
252
+ if (!existsSync(authDir)) {
253
+ mkdirSync(authDir, { recursive: true });
254
+ }
255
+ writeFileSync(authPath, JSON.stringify(authConfig, null, 2));
256
+ }
257
+ } catch {
258
+ // Silent fail — don't disrupt gateway startup
259
+ }
260
+ }
235
261
  });
236
262
 
237
263
  if (!pluginConfig.tools?.embeddings?.enabled && !pluginConfig.tools?.rollout?.enabled) {
@@ -385,8 +411,10 @@ const stratusPlugin = {
385
411
  const subcommand = (tokens[0] || "help").toLowerCase();
386
412
 
387
413
  if (subcommand === "setup") {
388
- // Run setup
389
- const result = await setupStratus(ctx.prompter);
414
+ const keyArg = tokens[1];
415
+ const result = keyArg
416
+ ? await setupStratus({ apiKey: keyArg, silent: true })
417
+ : await setupStratus(ctx.prompter);
390
418
 
391
419
  if (result.success) {
392
420
  console.log(`\n✅ ${result.message}\n`);
@@ -400,7 +428,7 @@ const stratusPlugin = {
400
428
  }
401
429
  process.exit(1);
402
430
  }
403
- return { text: "" }; // Return empty to avoid double output
431
+ return { text: "" };
404
432
  } else if (subcommand === "models") {
405
433
  const apiKey = pluginConfig.apiKey || process.env.STRATUS_API_KEY;
406
434
  const models = await generateAllModels(apiKey, pluginConfig.baseUrl);
@@ -475,14 +503,17 @@ const stratusPlugin = {
475
503
  console.log(" openclaw agent 'Hello Stratus!' --model stratus\n");
476
504
  return { text: "" };
477
505
  } else {
478
- // Show help
479
506
  return {
480
507
  text:
481
508
  "🌊 Stratus X1-AC Plugin\n\n" +
482
509
  "Commands:\n" +
483
- " /stratus setup - Interactive setup wizard\n" +
484
- " /stratus verify - Verify configuration\n" +
485
- " /stratus models - List all available models (fetches live from API)\n\n" +
510
+ " /stratus setup - Interactive setup wizard (Formation pool)\n" +
511
+ " /stratus setup <stratus_sk_...> - Non-interactive setup with API key\n" +
512
+ " /stratus verify - Verify configuration & connectivity\n" +
513
+ " /stratus models - List all available models (live from API)\n\n" +
514
+ "Agent/programmatic setup:\n" +
515
+ " /stratus setup stratus_sk_your_key_here\n" +
516
+ " # Or: set STRATUS_API_KEY env var → gateway auto-configures on start\n\n" +
486
517
  "Get your API key: https://stratus.run\n" +
487
518
  "Docs: https://stratus.run/docs\n" +
488
519
  "Issues: https://github.com/formthefog/openclaw-stratus-x1-plugin/issues",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formthefog/stratus",
3
- "version": "2026.3.19",
3
+ "version": "2026.3.20",
4
4
  "description": "Stratus API integration for OpenClaw - action-conditioned JEPA for autonomous agent planning",
5
5
  "keywords": [
6
6
  "agent",
package/src/setup.ts CHANGED
@@ -14,18 +14,29 @@ interface SetupResult {
14
14
  details?: string[];
15
15
  }
16
16
 
17
- export async function setupStratus(prompter?: any): Promise<SetupResult> {
17
+ interface SetupOptions {
18
+ apiKey?: string;
19
+ silent?: boolean;
20
+ }
21
+
22
+ export async function setupStratus(prompterOrOptions?: any, options?: SetupOptions): Promise<SetupResult> {
23
+ const opts: SetupOptions = options ?? (
24
+ prompterOrOptions && typeof prompterOrOptions === "object" && ("apiKey" in prompterOrOptions || "silent" in prompterOrOptions)
25
+ ? prompterOrOptions as SetupOptions
26
+ : {}
27
+ );
28
+
18
29
  const details: string[] = [];
19
30
 
20
31
  try {
21
- const apiKey = process.env.STRATUS_API_KEY;
32
+ const apiKey = opts.apiKey || process.env.STRATUS_API_KEY;
22
33
  const usingFormationPool = !apiKey;
23
34
 
24
35
  if (apiKey) {
25
36
  if (!apiKey.startsWith("stratus_sk_")) {
26
37
  return {
27
38
  success: false,
28
- message: "Invalid STRATUS_API_KEY format",
39
+ message: "Invalid API key format",
29
40
  details: [
30
41
  "API key must start with 'stratus_sk_'",
31
42
  "",
@@ -33,7 +44,7 @@ export async function setupStratus(prompter?: any): Promise<SetupResult> {
33
44
  ],
34
45
  };
35
46
  }
36
- details.push("✓ Using STRATUS_API_KEY from environment (BYOK — no markup)");
47
+ details.push(`✓ Using Stratus API key (BYOK — no markup)${opts.apiKey ? " [provided via arg]" : " [from environment]"}`);
37
48
  } else {
38
49
  details.push("✓ No API key found — using Formation pooled keys (zero-config)");
39
50
  details.push(" ℹ Formation pool applies a 25% markup on usage");
@@ -66,6 +77,7 @@ export async function setupStratus(prompter?: any): Promise<SetupResult> {
66
77
  if (!config.models.providers.stratus) {
67
78
  config.models.providers.stratus = {
68
79
  baseUrl: "https://api.stratus.run/v1",
80
+ ...(apiKey ? { apiKey } : {}),
69
81
  api: "openai-completions",
70
82
  models: [
71
83
  {
@@ -81,9 +93,26 @@ export async function setupStratus(prompter?: any): Promise<SetupResult> {
81
93
  };
82
94
  details.push(" ✓ Added Stratus provider configuration");
83
95
  } else {
96
+ if (apiKey && config.models.providers.stratus.apiKey !== apiKey) {
97
+ config.models.providers.stratus.apiKey = apiKey;
98
+ details.push(" ✓ Updated API key in provider config");
99
+ }
84
100
  details.push(" ✓ Stratus provider already configured");
85
101
  }
86
102
 
103
+ if (!config.plugins) config.plugins = {};
104
+ if (!config.plugins.entries) config.plugins.entries = {};
105
+ if (!config.plugins.entries.stratus) {
106
+ config.plugins.entries.stratus = { enabled: true, config: {} };
107
+ }
108
+ if (apiKey) {
109
+ config.plugins.entries.stratus.config = {
110
+ ...config.plugins.entries.stratus.config,
111
+ apiKey,
112
+ };
113
+ details.push(" ✓ Persisted API key in plugin config");
114
+ }
115
+
87
116
  if (config.agents?.defaults?.models?.["stratus/stratus-x1ac-base-claude-sonnet-4-5"]) {
88
117
  delete config.agents.defaults.models["stratus/stratus-x1ac-base-claude-sonnet-4-5"];
89
118
  details.push(" ✓ Removed restrictive model alias (allows all Stratus models)");