@formthefog/stratus 2026.2.17

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/src/config.ts ADDED
@@ -0,0 +1,70 @@
1
+ import type { OpenClawPluginConfigSchema } from "openclaw/plugin-sdk";
2
+ import type { StratusPluginConfig } from "./types.js";
3
+
4
+ export const StratusConfigSchema: OpenClawPluginConfigSchema = {
5
+ parse(value: unknown): StratusPluginConfig {
6
+ const raw =
7
+ value && typeof value === "object" && !Array.isArray(value)
8
+ ? (value as Record<string, unknown>)
9
+ : {};
10
+
11
+ const enabled = typeof raw.enabled === "boolean" ? raw.enabled : true;
12
+ const apiKey = typeof raw.apiKey === "string" ? raw.apiKey : process.env.STRATUS_API_KEY;
13
+ const baseUrl = typeof raw.baseUrl === "string" ? raw.baseUrl : "https://dev.api.stratus.run";
14
+
15
+ const provider =
16
+ raw.provider && typeof raw.provider === "object" && !Array.isArray(raw.provider)
17
+ ? (raw.provider as Record<string, unknown>)
18
+ : {};
19
+
20
+ const providerEnabled = typeof provider.enabled === "boolean" ? provider.enabled : true;
21
+ const defaultModel =
22
+ typeof provider.defaultModel === "string"
23
+ ? provider.defaultModel
24
+ : "stratus-x1ac-base-claude-sonnet-4-5";
25
+
26
+ const tools =
27
+ raw.tools && typeof raw.tools === "object" && !Array.isArray(raw.tools)
28
+ ? (raw.tools as Record<string, unknown>)
29
+ : {};
30
+
31
+ const embeddings =
32
+ tools.embeddings && typeof tools.embeddings === "object"
33
+ ? (tools.embeddings as Record<string, unknown>)
34
+ : {};
35
+ const rollout =
36
+ tools.rollout && typeof tools.rollout === "object"
37
+ ? (tools.rollout as Record<string, unknown>)
38
+ : {};
39
+
40
+ return {
41
+ enabled,
42
+ apiKey,
43
+ baseUrl,
44
+ provider: {
45
+ enabled: providerEnabled,
46
+ defaultModel,
47
+ },
48
+ tools: {
49
+ embeddings: {
50
+ enabled: typeof embeddings.enabled === "boolean" ? embeddings.enabled : true,
51
+ },
52
+ rollout: {
53
+ enabled: typeof rollout.enabled === "boolean" ? rollout.enabled : true,
54
+ },
55
+ },
56
+ };
57
+ },
58
+ uiHints: {
59
+ enabled: { label: "Enabled" },
60
+ apiKey: { label: "API Key", sensitive: true },
61
+ baseUrl: { label: "Base URL", placeholder: "https://dev.api.stratus.run" },
62
+ "provider.enabled": { label: "Provider Enabled" },
63
+ "provider.defaultModel": {
64
+ label: "Default Model",
65
+ placeholder: "stratus-x1ac-base-claude-sonnet-4-5",
66
+ },
67
+ "tools.embeddings.enabled": { label: "Embeddings Tool Enabled" },
68
+ "tools.rollout.enabled": { label: "Rollout Tool Enabled" },
69
+ },
70
+ };
package/src/setup.ts ADDED
@@ -0,0 +1,210 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import * as os from "os";
4
+
5
+ /**
6
+ * Interactive setup command for Stratus plugin
7
+ *
8
+ * @purpose Handles automated configuration of Stratus plugin including OpenClaw config, auth profiles, and environment setup
9
+ */
10
+
11
+ interface SetupResult {
12
+ success: boolean;
13
+ message: string;
14
+ details?: string[];
15
+ }
16
+
17
+ export async function setupStratus(prompter?: any): Promise<SetupResult> {
18
+ const details: string[] = [];
19
+
20
+ try {
21
+ // Step 1: Check for existing API key
22
+ const apiKey = process.env.STRATUS_API_KEY;
23
+
24
+ if (!apiKey) {
25
+ return {
26
+ success: false,
27
+ message: "STRATUS_API_KEY not found",
28
+ details: [
29
+ "Please set your Stratus API key as an environment variable:",
30
+ "",
31
+ " export STRATUS_API_KEY=stratus_sk_your_key_here",
32
+ "",
33
+ "Or add to your shell config (~/.zshrc or ~/.bashrc):",
34
+ "",
35
+ " echo 'export STRATUS_API_KEY=stratus_sk_your_key_here' >> ~/.zshrc",
36
+ " source ~/.zshrc",
37
+ "",
38
+ "Get your API key at: https://stratus.run",
39
+ ],
40
+ };
41
+ }
42
+
43
+ details.push("✓ Using STRATUS_API_KEY from environment");
44
+
45
+ // Paths
46
+ const homeDir = os.homedir();
47
+ const openclawConfig = path.join(homeDir, ".openclaw", "openclaw.json");
48
+ const authProfiles = path.join(
49
+ homeDir,
50
+ ".openclaw",
51
+ "agents",
52
+ "main",
53
+ "agent",
54
+ "auth-profiles.json"
55
+ );
56
+
57
+ // Step 2: Update OpenClaw config
58
+ details.push("🔧 Updating OpenClaw configuration...");
59
+
60
+ if (fs.existsSync(openclawConfig)) {
61
+ // Backup
62
+ const backupPath = `${openclawConfig}.backup-${Date.now()}`;
63
+ fs.copyFileSync(openclawConfig, backupPath);
64
+ details.push(` 📦 Created backup: ${path.basename(backupPath)}`);
65
+
66
+ // Read and update config
67
+ const config = JSON.parse(fs.readFileSync(openclawConfig, "utf-8"));
68
+
69
+ // Add models.providers.stratus if not present
70
+ if (!config.models) {
71
+ config.models = {};
72
+ }
73
+ if (!config.models.providers) {
74
+ config.models.providers = {};
75
+ }
76
+ if (!config.models.providers.stratus) {
77
+ config.models.providers.stratus = {
78
+ baseUrl: "https://dev.api.stratus.run/v1",
79
+ api: "openai-completions",
80
+ models: [
81
+ {
82
+ id: "stratus-x1ac-base-claude-sonnet-4-5",
83
+ name: "Stratus X1AC Base (Claude 4.5 Sonnet)",
84
+ reasoning: true,
85
+ input: ["text", "image"],
86
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
87
+ contextWindow: 200000,
88
+ maxTokens: 8192,
89
+ },
90
+ ],
91
+ };
92
+ details.push(" ✓ Added Stratus provider configuration");
93
+ } else {
94
+ details.push(" ✓ Stratus provider already configured");
95
+ }
96
+
97
+ // Add model alias
98
+ if (!config.agents?.defaults?.models) {
99
+ if (!config.agents) config.agents = {};
100
+ if (!config.agents.defaults) config.agents.defaults = {};
101
+ if (!config.agents.defaults.models) config.agents.defaults.models = {};
102
+ }
103
+
104
+ if (!config.agents.defaults.models["stratus/stratus-x1ac-base-claude-sonnet-4-5"]) {
105
+ config.agents.defaults.models["stratus/stratus-x1ac-base-claude-sonnet-4-5"] = {
106
+ alias: "stratus",
107
+ params: {},
108
+ };
109
+ details.push(" ✓ Added model alias 'stratus'");
110
+ } else {
111
+ details.push(" ✓ Model alias already configured");
112
+ }
113
+
114
+ // Write updated config
115
+ fs.writeFileSync(openclawConfig, JSON.stringify(config, null, 2));
116
+ } else {
117
+ return {
118
+ success: false,
119
+ message: "OpenClaw config not found",
120
+ details: [
121
+ "Run 'openclaw setup' first to initialize OpenClaw",
122
+ "",
123
+ "Need help? Check the docs: https://docs.openclaw.ai",
124
+ ],
125
+ };
126
+ }
127
+
128
+ // Step 3: Update auth profiles
129
+ details.push("🔑 Configuring authentication...");
130
+
131
+ const authDir = path.dirname(authProfiles);
132
+ if (!fs.existsSync(authDir)) {
133
+ fs.mkdirSync(authDir, { recursive: true });
134
+ }
135
+
136
+ let authConfig: any;
137
+ if (fs.existsSync(authProfiles)) {
138
+ // Backup
139
+ const backupPath = `${authProfiles}.backup-${Date.now()}`;
140
+ fs.copyFileSync(authProfiles, backupPath);
141
+
142
+ // Update existing
143
+ authConfig = JSON.parse(fs.readFileSync(authProfiles, "utf-8"));
144
+ } else {
145
+ // Create new
146
+ authConfig = {
147
+ version: 1,
148
+ profiles: {},
149
+ lastGood: {},
150
+ usageStats: {},
151
+ };
152
+ }
153
+
154
+ // Add Stratus profile
155
+ authConfig.profiles["stratus:default"] = {
156
+ type: "api_key",
157
+ provider: "stratus",
158
+ key: apiKey,
159
+ };
160
+ authConfig.lastGood.stratus = "stratus:default";
161
+
162
+ fs.writeFileSync(authProfiles, JSON.stringify(authConfig, null, 2));
163
+ details.push(" ✓ Updated auth profile");
164
+
165
+ return {
166
+ success: true,
167
+ message: "Setup complete! 🎉",
168
+ details: [
169
+ ...details,
170
+ "",
171
+ "🎯 Next steps:",
172
+ " 1. Restart gateway: openclaw gateway stop && openclaw gateway install",
173
+ " 2. Verify: openclaw models list | grep stratus",
174
+ " 3. Test: openclaw agent 'Hello Stratus!' --model stratus",
175
+ "",
176
+ "📚 Available tools:",
177
+ " • stratus_embeddings - Generate semantic embeddings",
178
+ " • stratus_rollout - Multi-step task planning",
179
+ ],
180
+ };
181
+ } catch (error) {
182
+ return {
183
+ success: false,
184
+ message: "Setup failed",
185
+ details: [
186
+ error instanceof Error ? error.message : String(error),
187
+ "",
188
+ "Need help? Visit: https://stratus.run/docs",
189
+ "Report issues: https://github.com/formthefog/openclaw-stratus-x1-plugin/issues",
190
+ ],
191
+ };
192
+ }
193
+ }
194
+
195
+ function detectShellConfig(): string | null {
196
+ const homeDir = os.homedir();
197
+ const shell = process.env.SHELL || "";
198
+
199
+ if (shell.includes("zsh")) {
200
+ return path.join(homeDir, ".zshrc");
201
+ } else if (shell.includes("bash")) {
202
+ if (process.platform === "darwin") {
203
+ return path.join(homeDir, ".bash_profile");
204
+ } else {
205
+ return path.join(homeDir, ".bashrc");
206
+ }
207
+ }
208
+
209
+ return null;
210
+ }
package/src/types.ts ADDED
@@ -0,0 +1,56 @@
1
+ export interface StratusEmbeddingsRequest {
2
+ input: string | string[];
3
+ model?: string;
4
+ encoding_format?: "float" | "base64";
5
+ }
6
+
7
+ export interface StratusEmbeddingsResponse {
8
+ object: "list";
9
+ data: Array<{
10
+ object: "embedding";
11
+ index: number;
12
+ embedding: number[] | string;
13
+ }>;
14
+ model: string;
15
+ usage: {
16
+ prompt_tokens: number;
17
+ total_tokens: number;
18
+ };
19
+ }
20
+
21
+ export interface StratusRolloutRequest {
22
+ goal: string;
23
+ initial_state?: string;
24
+ max_steps?: number;
25
+ return_intermediate?: boolean;
26
+ }
27
+
28
+ export interface StratusRolloutStep {
29
+ action?: string;
30
+ description?: string;
31
+ state?: string;
32
+ }
33
+
34
+ export interface StratusRolloutResponse {
35
+ goal: string;
36
+ steps: StratusRolloutStep[];
37
+ success: boolean;
38
+ metadata?: {
39
+ model: string;
40
+ duration_ms?: number;
41
+ };
42
+ }
43
+
44
+ export interface StratusPluginConfig {
45
+ enabled?: boolean;
46
+ apiKey?: string;
47
+ baseUrl?: string;
48
+ provider?: {
49
+ enabled?: boolean;
50
+ defaultModel?: string;
51
+ };
52
+ tools?: {
53
+ embeddings?: { enabled?: boolean };
54
+ rollout?: { enabled?: boolean };
55
+ };
56
+ }
package/verify.sh ADDED
@@ -0,0 +1,110 @@
1
+ #!/bin/bash
2
+
3
+ # Stratus OpenClaw Plugin Verification
4
+ # Checks that everything is configured correctly
5
+
6
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
7
+ echo " 🔍 Stratus Plugin Verification"
8
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
9
+ echo ""
10
+
11
+ ERRORS=0
12
+
13
+ # Check 1: Environment variable
14
+ echo "1️⃣ Checking STRATUS_API_KEY..."
15
+ if [[ -n "$STRATUS_API_KEY" ]]; then
16
+ echo " ✓ STRATUS_API_KEY is set"
17
+ else
18
+ echo " ❌ STRATUS_API_KEY not found in environment"
19
+ ERRORS=$((ERRORS + 1))
20
+ fi
21
+
22
+ # Check 2: OpenClaw config
23
+ echo ""
24
+ echo "2️⃣ Checking OpenClaw configuration..."
25
+ OPENCLAW_CONFIG="$HOME/.openclaw/openclaw.json"
26
+ if [[ -f "$OPENCLAW_CONFIG" ]]; then
27
+ if jq -e '.models.providers.stratus' "$OPENCLAW_CONFIG" > /dev/null 2>&1; then
28
+ echo " ✓ Stratus provider configured"
29
+ else
30
+ echo " ❌ Stratus provider not in config"
31
+ ERRORS=$((ERRORS + 1))
32
+ fi
33
+
34
+ if jq -e '.agents.defaults.models["stratus/stratus-x1ac-base-claude-sonnet-4-5"]' "$OPENCLAW_CONFIG" > /dev/null 2>&1; then
35
+ echo " ✓ Stratus model alias configured"
36
+ else
37
+ echo " ❌ Stratus model alias not configured"
38
+ ERRORS=$((ERRORS + 1))
39
+ fi
40
+ else
41
+ echo " ❌ OpenClaw config not found"
42
+ ERRORS=$((ERRORS + 1))
43
+ fi
44
+
45
+ # Check 3: Auth profile
46
+ echo ""
47
+ echo "3️⃣ Checking authentication profile..."
48
+ AUTH_PROFILES="$HOME/.openclaw/agents/main/agent/auth-profiles.json"
49
+ if [[ -f "$AUTH_PROFILES" ]]; then
50
+ if jq -e '.profiles["stratus:default"]' "$AUTH_PROFILES" > /dev/null 2>&1; then
51
+ echo " ✓ Stratus auth profile exists"
52
+ else
53
+ echo " ❌ Stratus auth profile not found"
54
+ ERRORS=$((ERRORS + 1))
55
+ fi
56
+ else
57
+ echo " ❌ Auth profiles file not found"
58
+ ERRORS=$((ERRORS + 1))
59
+ fi
60
+
61
+ # Check 4: Plugin loaded
62
+ echo ""
63
+ echo "4️⃣ Checking plugin status..."
64
+ if command -v openclaw > /dev/null 2>&1; then
65
+ if openclaw plugins info stratus 2>&1 | grep -q "Status: loaded"; then
66
+ echo " ✓ Plugin loaded successfully"
67
+ else
68
+ echo " ⚠️ Plugin not loaded (restart gateway)"
69
+ fi
70
+
71
+ # Check 5: Models available
72
+ echo ""
73
+ echo "5️⃣ Checking model availability..."
74
+ if openclaw models list 2>&1 | grep -q "stratus"; then
75
+ echo " ✓ Stratus model available"
76
+ else
77
+ echo " ❌ Stratus model not in model list"
78
+ ERRORS=$((ERRORS + 1))
79
+ fi
80
+
81
+ # Check 6: Gateway status
82
+ echo ""
83
+ echo "6️⃣ Checking gateway..."
84
+ if openclaw gateway status 2>&1 | grep -q "RPC probe: ok"; then
85
+ echo " ✓ Gateway operational"
86
+ else
87
+ echo " ⚠️ Gateway not responding"
88
+ fi
89
+ else
90
+ echo " ⚠️ OpenClaw CLI not found (install OpenClaw first)"
91
+ fi
92
+
93
+ echo ""
94
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
95
+ if [[ $ERRORS -eq 0 ]]; then
96
+ echo " ✅ All checks passed!"
97
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
98
+ echo ""
99
+ echo "🎯 Try it out:"
100
+ echo " openclaw agent 'Hello Stratus!' --model stratus"
101
+ echo ""
102
+ exit 0
103
+ else
104
+ echo " ❌ $ERRORS issue(s) found"
105
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
106
+ echo ""
107
+ echo "💡 Try running: ./install.sh"
108
+ echo ""
109
+ exit 1
110
+ fi