@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/install.sh ADDED
@@ -0,0 +1,215 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Stratus OpenClaw Plugin Installer
5
+ #
6
+ # Note: You can also use /stratus setup in any OpenClaw chat!
7
+ # This script is an alternative for users who prefer manual setup.
8
+ #
9
+ # Makes installation feel like butter 🧈
10
+
11
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
12
+ echo " 🌊 Stratus X1 OpenClaw Plugin Installer"
13
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
14
+ echo ""
15
+
16
+ # Detect OS
17
+ OS=$(uname -s)
18
+ SHELL_CONFIG=""
19
+
20
+ if [[ "$OS" == "Darwin" ]]; then
21
+ # macOS
22
+ if [[ -n "$ZSH_VERSION" ]] || [[ "$SHELL" == *"zsh"* ]]; then
23
+ SHELL_CONFIG="$HOME/.zshrc"
24
+ else
25
+ SHELL_CONFIG="$HOME/.bash_profile"
26
+ fi
27
+ elif [[ "$OS" == "Linux" ]]; then
28
+ # Linux
29
+ if [[ -n "$ZSH_VERSION" ]] || [[ "$SHELL" == *"zsh"* ]]; then
30
+ SHELL_CONFIG="$HOME/.zshrc"
31
+ else
32
+ SHELL_CONFIG="$HOME/.bashrc"
33
+ fi
34
+ fi
35
+
36
+ # Check for existing API key
37
+ EXISTING_KEY="${STRATUS_API_KEY:-}"
38
+
39
+ if [[ -z "$EXISTING_KEY" ]]; then
40
+ echo "📝 Enter your Stratus API key:"
41
+ echo " (Get one at: https://stratus.run)"
42
+ echo ""
43
+ read -p "API Key: " API_KEY
44
+
45
+ if [[ -z "$API_KEY" ]]; then
46
+ echo "❌ API key is required"
47
+ exit 1
48
+ fi
49
+
50
+ if [[ ! "$API_KEY" =~ ^stratus_sk_ ]]; then
51
+ echo "❌ Invalid API key format (must start with 'stratus_sk_')"
52
+ exit 1
53
+ fi
54
+ else
55
+ echo "✓ Using existing STRATUS_API_KEY from environment"
56
+ API_KEY="$EXISTING_KEY"
57
+ fi
58
+
59
+ echo ""
60
+ echo "🔧 Configuring OpenClaw..."
61
+ echo ""
62
+
63
+ # Paths
64
+ OPENCLAW_CONFIG="$HOME/.openclaw/openclaw.json"
65
+ AUTH_PROFILES="$HOME/.openclaw/agents/main/agent/auth-profiles.json"
66
+ LAUNCHD_PLIST="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
67
+
68
+ # Backup configs
69
+ echo " 📦 Creating backups..."
70
+ if [[ -f "$OPENCLAW_CONFIG" ]]; then
71
+ cp "$OPENCLAW_CONFIG" "${OPENCLAW_CONFIG}.backup-$(date +%Y%m%d-%H%M%S)"
72
+ fi
73
+ if [[ -f "$AUTH_PROFILES" ]]; then
74
+ cp "$AUTH_PROFILES" "${AUTH_PROFILES}.backup-$(date +%Y%m%d-%H%M%S)"
75
+ fi
76
+
77
+ # Update OpenClaw config using jq
78
+ echo " 🔧 Updating OpenClaw configuration..."
79
+
80
+ # Add models.providers.stratus if not present
81
+ if ! jq -e '.models.providers.stratus' "$OPENCLAW_CONFIG" > /dev/null 2>&1; then
82
+ jq --arg baseUrl "https://dev.api.stratus.run/v1" \
83
+ '.models.providers.stratus = {
84
+ baseUrl: $baseUrl,
85
+ api: "openai-completions",
86
+ models: [
87
+ {
88
+ id: "stratus-x1ac-base-claude-sonnet-4-5",
89
+ name: "Stratus X1AC Base (Claude 4.5 Sonnet)",
90
+ reasoning: true,
91
+ input: ["text", "image"],
92
+ cost: {input: 0, output: 0, cacheRead: 0, cacheWrite: 0},
93
+ contextWindow: 200000,
94
+ maxTokens: 8192
95
+ }
96
+ ]
97
+ }' "$OPENCLAW_CONFIG" > "${OPENCLAW_CONFIG}.tmp" && mv "${OPENCLAW_CONFIG}.tmp" "$OPENCLAW_CONFIG"
98
+ echo " ✓ Added Stratus provider configuration"
99
+ else
100
+ echo " ✓ Stratus provider already configured"
101
+ fi
102
+
103
+ # Add model alias to agents.defaults.models if not present
104
+ if ! jq -e '.agents.defaults.models["stratus/stratus-x1ac-base-claude-sonnet-4-5"]' "$OPENCLAW_CONFIG" > /dev/null 2>&1; then
105
+ jq '.agents.defaults.models["stratus/stratus-x1ac-base-claude-sonnet-4-5"] = {
106
+ alias: "stratus",
107
+ params: {}
108
+ }' "$OPENCLAW_CONFIG" > "${OPENCLAW_CONFIG}.tmp" && mv "${OPENCLAW_CONFIG}.tmp" "$OPENCLAW_CONFIG"
109
+ echo " ✓ Added model alias 'stratus'"
110
+ else
111
+ echo " ✓ Model alias already configured"
112
+ fi
113
+
114
+ # Update auth profiles
115
+ echo " 🔑 Configuring authentication..."
116
+ mkdir -p "$(dirname "$AUTH_PROFILES")"
117
+
118
+ if [[ ! -f "$AUTH_PROFILES" ]]; then
119
+ # Create new auth profiles file
120
+ cat > "$AUTH_PROFILES" << EOF
121
+ {
122
+ "version": 1,
123
+ "profiles": {
124
+ "stratus:default": {
125
+ "type": "api_key",
126
+ "provider": "stratus",
127
+ "key": "$API_KEY"
128
+ }
129
+ },
130
+ "lastGood": {
131
+ "stratus": "stratus:default"
132
+ },
133
+ "usageStats": {}
134
+ }
135
+ EOF
136
+ echo " ✓ Created auth profile"
137
+ else
138
+ # Update existing auth profiles
139
+ jq --arg key "$API_KEY" \
140
+ '.profiles["stratus:default"] = {
141
+ type: "api_key",
142
+ provider: "stratus",
143
+ key: $key
144
+ } |
145
+ .lastGood.stratus = "stratus:default"' "$AUTH_PROFILES" > "${AUTH_PROFILES}.tmp" && mv "${AUTH_PROFILES}.tmp" "$AUTH_PROFILES"
146
+ echo " ✓ Updated auth profile"
147
+ fi
148
+
149
+ # Update shell config (optional)
150
+ if [[ -n "$SHELL_CONFIG" ]] && [[ "$EXISTING_KEY" != "$API_KEY" ]]; then
151
+ echo ""
152
+ read -p " Add STRATUS_API_KEY to $SHELL_CONFIG? (y/N): " ADD_TO_SHELL
153
+ if [[ "$ADD_TO_SHELL" =~ ^[Yy]$ ]]; then
154
+ if ! grep -q "STRATUS_API_KEY" "$SHELL_CONFIG"; then
155
+ cat >> "$SHELL_CONFIG" << EOF
156
+
157
+ # Stratus X1 configuration for OpenClaw
158
+ export STRATUS_API_KEY=$API_KEY
159
+ export STRATUS_BASE_URL=https://dev.api.stratus.run/v1
160
+ EOF
161
+ echo " ✓ Added to $SHELL_CONFIG"
162
+ echo " 💡 Run: source $SHELL_CONFIG"
163
+ else
164
+ echo " ⚠️ Already present in $SHELL_CONFIG"
165
+ fi
166
+ fi
167
+ fi
168
+
169
+ # Update LaunchAgent plist (macOS only)
170
+ if [[ "$OS" == "Darwin" ]] && [[ -f "$LAUNCHD_PLIST" ]]; then
171
+ echo ""
172
+ read -p " Add STRATUS_API_KEY to LaunchAgent? (y/N): " ADD_TO_PLIST
173
+ if [[ "$ADD_TO_PLIST" =~ ^[Yy]$ ]]; then
174
+ if ! grep -q "STRATUS_API_KEY" "$LAUNCHD_PLIST"; then
175
+ # Backup plist
176
+ cp "$LAUNCHD_PLIST" "${LAUNCHD_PLIST}.backup-$(date +%Y%m%d-%H%M%S)"
177
+
178
+ # Add environment variables to plist
179
+ /usr/libexec/PlistBuddy -c "Add :EnvironmentVariables:STRATUS_API_KEY string $API_KEY" "$LAUNCHD_PLIST" 2>/dev/null || \
180
+ /usr/libexec/PlistBuddy -c "Set :EnvironmentVariables:STRATUS_API_KEY $API_KEY" "$LAUNCHD_PLIST"
181
+
182
+ /usr/libexec/PlistBuddy -c "Add :EnvironmentVariables:STRATUS_BASE_URL string https://dev.api.stratus.run/v1" "$LAUNCHD_PLIST" 2>/dev/null || \
183
+ /usr/libexec/PlistBuddy -c "Set :EnvironmentVariables:STRATUS_BASE_URL https://dev.api.stratus.run/v1" "$LAUNCHD_PLIST"
184
+
185
+ echo " ✓ Updated LaunchAgent plist"
186
+ echo " 💡 Restart gateway: openclaw gateway stop && openclaw gateway install"
187
+ else
188
+ echo " ⚠️ Already present in LaunchAgent"
189
+ fi
190
+ fi
191
+ fi
192
+
193
+ echo ""
194
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
195
+ echo " ✅ Installation Complete!"
196
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
197
+ echo ""
198
+ echo "🎯 Next steps:"
199
+ echo ""
200
+ echo " 1. Restart OpenClaw gateway:"
201
+ echo " openclaw gateway stop && openclaw gateway install"
202
+ echo ""
203
+ echo " 2. Verify installation:"
204
+ echo " openclaw models list | grep stratus"
205
+ echo " openclaw plugins info stratus"
206
+ echo ""
207
+ echo " 3. Test the Stratus model:"
208
+ echo " openclaw agent 'Hello from Stratus!' --model stratus"
209
+ echo ""
210
+ echo "📚 Available tools:"
211
+ echo " • stratus_embeddings - Generate semantic embeddings"
212
+ echo " • stratus_rollout - Multi-step task planning"
213
+ echo ""
214
+ echo "🌊 Enjoy Stratus X1!"
215
+ echo ""
@@ -0,0 +1,62 @@
1
+ {
2
+ "id": "stratus",
3
+ "providers": ["stratus"],
4
+ "tools": ["stratus_embeddings", "stratus_rollout"],
5
+ "skills": ["./skills/stratus-info"],
6
+ "configSchema": {
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "enabled": {
11
+ "type": "boolean",
12
+ "default": true,
13
+ "description": "Enable Stratus plugin"
14
+ },
15
+ "apiKey": {
16
+ "type": "string",
17
+ "description": "Stratus API key (or use STRATUS_API_KEY env var)"
18
+ },
19
+ "baseUrl": {
20
+ "type": "string",
21
+ "default": "https://dev.api.stratus.run",
22
+ "description": "Stratus API base URL"
23
+ },
24
+ "provider": {
25
+ "type": "object",
26
+ "properties": {
27
+ "enabled": {
28
+ "type": "boolean",
29
+ "default": true
30
+ },
31
+ "defaultModel": {
32
+ "type": "string",
33
+ "default": "stratus-x1ac-base-claude-sonnet-4-5"
34
+ }
35
+ }
36
+ },
37
+ "tools": {
38
+ "type": "object",
39
+ "properties": {
40
+ "embeddings": {
41
+ "type": "object",
42
+ "properties": {
43
+ "enabled": {
44
+ "type": "boolean",
45
+ "default": true
46
+ }
47
+ }
48
+ },
49
+ "rollout": {
50
+ "type": "object",
51
+ "properties": {
52
+ "enabled": {
53
+ "type": "boolean",
54
+ "default": true
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@formthefog/stratus",
3
+ "version": "2026.2.17",
4
+ "description": "Stratus API integration for OpenClaw - action-conditioned JEPA for autonomous agent planning",
5
+ "keywords": [
6
+ "agent",
7
+ "embeddings",
8
+ "jepa",
9
+ "openclaw",
10
+ "planning",
11
+ "stratus",
12
+ "world-model"
13
+ ],
14
+ "license": "MIT",
15
+ "author": "OpenClaw",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/formthefog/openclaw-stratus-x1-plugin.git"
19
+ },
20
+ "bugs": {
21
+ "url": "https://github.com/formthefog/openclaw-stratus-x1-plugin/issues"
22
+ },
23
+ "homepage": "https://stratus.run",
24
+ "type": "module",
25
+ "dependencies": {
26
+ "@sinclair/typebox": "0.34.48"
27
+ },
28
+ "scripts": {},
29
+ "openclaw": {
30
+ "extensions": [
31
+ "./index.ts"
32
+ ]
33
+ }
34
+ }
@@ -0,0 +1,228 @@
1
+ ---
2
+ name: stratus-info
3
+ description: Knowledge base about Stratus X1-AC world model system
4
+ version: 1.0.0
5
+ author: Stratus Team
6
+ ---
7
+
8
+ # Stratus X1-AC Knowledge Base
9
+
10
+ ## What Stratus Actually Is
11
+
12
+ **Stratus is NOT just a language model with extended reasoning.**
13
+
14
+ It's a **three-layer system** combining world modeling, collective intelligence, and blockchain infrastructure:
15
+
16
+ ---
17
+
18
+ ## Layer 1: Core AI (X1 & X1-AC) — The World Model
19
+
20
+ This is a **hybrid architecture** with two capabilities:
21
+
22
+ ### 1. World Model (Predictor): "What happens if I do X?"
23
+ - Predicts future states given current state + action
24
+ - Uses **JEPA** (Joint-Embedding Predictive Architecture)
25
+ - Predicts compressed representations, not raw outputs
26
+ - Enables planning by simulating action sequences before executing
27
+
28
+ ### 2. Policy Head (Action Selector): "What action achieves this goal?"
29
+ - Predicts the best action given current state + goal state
30
+ - Fast decision-making for known patterns
31
+ - Provides confidence scores (low confidence → escalate to LLM)
32
+
33
+ **Key Innovation:**
34
+ Instead of just guessing the next action, Stratus can **simulate the outcome of multiple actions** and pick the one most likely to achieve the goal.
35
+
36
+ Think: playing chess, but for browser automation, coding, research, etc.
37
+
38
+ ---
39
+
40
+ ## Layer 2: Collective Intelligence Network
41
+
42
+ Agents learn from each other in real-time:
43
+
44
+ - When one agent discovers an effective approach, that knowledge flows to all agents
45
+ - **Continuous learning**: successful patterns get canonicalized and fine-tuned into the model
46
+ - **Domain-specific fine-tunes** (e-commerce, dev tools, research, etc.) share learnings back to the base model
47
+
48
+ It's like a hive mind for AI agents — practical distributed learning at scale.
49
+
50
+ ---
51
+
52
+ ## Layer 3: Blockchain Infrastructure (L2 on Ethereum)
53
+
54
+ Handles attribution, rewards, and the economic ecosystem:
55
+
56
+ - Tracks who contributed what to model improvements
57
+ - Distributes rewards to agents/operators/data providers based on contribution quality
58
+ - Creates a marketplace for agent services, task requests, and training data
59
+ - Uses an Ethereum L2 for fast, cheap transactions with mainnet security
60
+
61
+ **Web3 infrastructure for incentivizing better AI.**
62
+
63
+ ---
64
+
65
+ ## What Makes Stratus Different
66
+
67
+ ### Traditional Agents (Reactive)
68
+ ```
69
+ see → think → act → see again
70
+ ```
71
+ ❌ If something unexpected happens, they get confused
72
+
73
+ ### Stratus Agents (Predictive)
74
+ ```
75
+ see → simulate outcomes → pick best action → act
76
+ ```
77
+ ✅ If something unexpected happens, they already anticipated it (or they replan)
78
+
79
+ ---
80
+
81
+ ## Available Models
82
+
83
+ Stratus provides **75 models** in the format:
84
+
85
+ ```
86
+ stratus-x1ac-{size}-{llm}
87
+ ```
88
+
89
+ **Sizes:** `small`, `base`, `large`, `xl`, `huge`
90
+
91
+ **Recommended LLMs:**
92
+ - `claude-sonnet-4-5` - Claude 4.5 Sonnet (recommended)
93
+ - `gpt-4o` - GPT-4 Optimized
94
+ - `claude-haiku-4-5` - Fast, cost-effective
95
+
96
+ **Example:**
97
+ ```bash
98
+ openclaw agent "Plan a multi-step research task" \
99
+ --model stratus/stratus-x1ac-base-claude-sonnet-4-5
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Available Tools
105
+
106
+ ### `stratus_embeddings`
107
+ Generate 768-dimensional semantic state embeddings.
108
+
109
+ **Use cases:**
110
+ - Semantic search over states
111
+ - State similarity comparison
112
+ - Memory indexing
113
+ - Context clustering
114
+
115
+ **Example:**
116
+ ```typescript
117
+ {
118
+ "tool": "stratus_embeddings",
119
+ "input": ["initializing", "loading", "ready", "processing", "error"]
120
+ }
121
+ ```
122
+
123
+ ### `stratus_rollout`
124
+ Multi-step action sequence planning.
125
+
126
+ **Use cases:**
127
+ - Task decomposition
128
+ - Action planning
129
+ - Goal-oriented reasoning
130
+ - Multi-step workflows
131
+
132
+ **Example:**
133
+ ```typescript
134
+ {
135
+ "tool": "stratus_rollout",
136
+ "goal": "book a hotel room in Paris",
137
+ "max_steps": 10
138
+ }
139
+ ```
140
+
141
+ ---
142
+
143
+ ## API Integration
144
+
145
+ Stratus is **OpenAI-compatible**, meaning it's a drop-in replacement:
146
+
147
+ ```javascript
148
+ // Before
149
+ const response = await openai.chat.completions.create({
150
+ model: "gpt-4o",
151
+ messages: [...]
152
+ });
153
+
154
+ // After - just change endpoint and model
155
+ const response = await openai.chat.completions.create({
156
+ model: "stratus-x1ac-base-gpt-4o",
157
+ messages: [...]
158
+ }, {
159
+ baseURL: "https://dev.api.stratus.run/v1"
160
+ });
161
+ ```
162
+
163
+ Stratus handles planning, then routes execution to the specified LLM (GPT-4o, Claude, etc.).
164
+
165
+ ---
166
+
167
+ ## Common Misconceptions
168
+
169
+ | ❌ Wrong | ✅ Correct |
170
+ |----------|-----------|
171
+ | "Stratus is just Claude with extended reasoning" | Stratus is a world model that predicts action consequences + collective learning network |
172
+ | "It's a language model" | It's a hybrid architecture (world model + policy head) that routes to LLMs for execution |
173
+ | "It's an LLM wrapper" | It's a JEPA-based predictive system with its own training and inference pipeline |
174
+
175
+ ---
176
+
177
+ ## Technical Reference
178
+
179
+ For full technical details, see:
180
+ - **Technical Overview:** https://stratus.run/docs/technical-overview
181
+ - **API Documentation:** https://stratus.run/docs/api
182
+ - **GitHub:** https://github.com/formthefog/openclaw-stratus-x1-plugin
183
+
184
+ ---
185
+
186
+ ## Quick Start
187
+
188
+ 1. **Install plugin:**
189
+ ```bash
190
+ openclaw plugins install @hathbanger/stratus
191
+ ```
192
+
193
+ 2. **Set API key:**
194
+ ```bash
195
+ export STRATUS_API_KEY=stratus_sk_your_key_here
196
+ ```
197
+
198
+ 3. **Run setup:**
199
+ ```bash
200
+ /stratus setup
201
+ ```
202
+
203
+ 4. **Test it:**
204
+ ```bash
205
+ openclaw agent "Hello Stratus!" --model stratus
206
+ ```
207
+
208
+ ---
209
+
210
+ ## When to Use Stratus
211
+
212
+ **Best for:**
213
+ - Multi-step planning tasks
214
+ - Browser automation
215
+ - Research workflows
216
+ - Complex decision-making with uncertain outcomes
217
+ - Tasks requiring "what-if" simulation
218
+
219
+ **Overkill for:**
220
+ - Simple Q&A
221
+ - Single-shot text generation
222
+ - Tasks without clear action sequences
223
+
224
+ ---
225
+
226
+ **Remember:** Stratus isn't just "better reasoning" — it's **predictive planning** that fundamentally changes how agents approach tasks.
227
+
228
+ 🌊 Built by the Stratus team | Learn more: https://stratus.run
package/src/client.ts ADDED
@@ -0,0 +1,98 @@
1
+ import type {
2
+ StratusEmbeddingsRequest,
3
+ StratusEmbeddingsResponse,
4
+ StratusPluginConfig,
5
+ StratusRolloutRequest,
6
+ StratusRolloutResponse,
7
+ } from "./types.js";
8
+
9
+ /**
10
+ * SECURITY MANIFEST
11
+ *
12
+ * Environment Variables Accessed:
13
+ * - STRATUS_API_KEY: User's Stratus API key (optional, can use config instead)
14
+ *
15
+ * Network Endpoints:
16
+ * - https://dev.api.stratus.run/v1/embeddings (POST)
17
+ * - https://dev.api.stratus.run/v1/rollout (POST)
18
+ *
19
+ * Data Transmitted:
20
+ * - Authorization header: Bearer token (Stratus API key)
21
+ * - Request body: User-provided text, goals, and parameters
22
+ *
23
+ * Data Retention:
24
+ * - All data sent to Stratus API per their privacy policy: https://stratus.run/privacy
25
+ * - No local storage of credentials beyond process memory
26
+ *
27
+ * Security:
28
+ * - API key validated (must start with 'stratus_sk_')
29
+ * - HTTPS-only connections
30
+ * - Keys never logged or persisted to disk by this plugin
31
+ */
32
+
33
+ export interface StratusClientConfig {
34
+ apiKey: string;
35
+ baseUrl: string;
36
+ }
37
+
38
+ export class StratusClient {
39
+ constructor(private config: StratusClientConfig) {}
40
+
41
+ private async request<T>(endpoint: string, body: unknown): Promise<T> {
42
+ const url = `${this.config.baseUrl}${endpoint}`;
43
+
44
+ const response = await fetch(url, {
45
+ method: "POST",
46
+ headers: {
47
+ Authorization: `Bearer ${this.config.apiKey}`,
48
+ "Content-Type": "application/json",
49
+ },
50
+ body: JSON.stringify(body),
51
+ });
52
+
53
+ if (!response.ok) {
54
+ const errorText = await response.text();
55
+ throw new Error(
56
+ `Stratus API error (${response.status}): ${errorText || response.statusText}`,
57
+ );
58
+ }
59
+
60
+ return response.json();
61
+ }
62
+
63
+ async embeddings(params: StratusEmbeddingsRequest): Promise<StratusEmbeddingsResponse> {
64
+ return this.request<StratusEmbeddingsResponse>("/v1/embeddings", {
65
+ model: params.model || "stratus-x1ac-base",
66
+ input: params.input,
67
+ encoding_format: params.encoding_format || "float",
68
+ });
69
+ }
70
+
71
+ async rollout(params: StratusRolloutRequest): Promise<StratusRolloutResponse> {
72
+ return this.request<StratusRolloutResponse>("/v1/rollout", {
73
+ goal: params.goal,
74
+ initial_state: params.initial_state,
75
+ max_steps: params.max_steps || 10,
76
+ return_intermediate: params.return_intermediate ?? true,
77
+ });
78
+ }
79
+ }
80
+
81
+ export function createStratusClient(config: StratusPluginConfig | undefined): StratusClient {
82
+ const apiKey = config?.apiKey || process.env.STRATUS_API_KEY;
83
+ const baseUrl = config?.baseUrl || "https://dev.api.stratus.run";
84
+
85
+ if (!apiKey) {
86
+ throw new Error(
87
+ "Stratus API key not configured. Set STRATUS_API_KEY env var or plugins.stratus.apiKey in config.",
88
+ );
89
+ }
90
+
91
+ if (!apiKey.startsWith("stratus_sk_")) {
92
+ throw new Error(
93
+ `Invalid Stratus API key format. Expected key starting with 'stratus_sk_', got '${apiKey.substring(0, 10)}...'`,
94
+ );
95
+ }
96
+
97
+ return new StratusClient({ apiKey, baseUrl });
98
+ }