@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.
- package/index.ts +39 -8
- package/package.json +1 -1
- 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
|
-
|
|
389
|
-
const result =
|
|
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: "" };
|
|
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
|
|
484
|
-
" /stratus
|
|
485
|
-
" /stratus
|
|
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
package/src/setup.ts
CHANGED
|
@@ -14,18 +14,29 @@ interface SetupResult {
|
|
|
14
14
|
details?: string[];
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
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
|
|
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(
|
|
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)");
|