diff --git a/apps/docs/app/global.css b/apps/docs/app/global.css
index 2968717af..53bc8db7f 100644
--- a/apps/docs/app/global.css
+++ b/apps/docs/app/global.css
@@ -119,6 +119,19 @@ aside#nd-sidebar {
}
}
+/* Hide TOC popover on tablet/medium screens (768px - 1279px) */
+/* Keeps it visible on mobile (<768px) for easy navigation */
+/* Desktop (>=1280px) already hides it via fumadocs xl:hidden */
+@media (min-width: 768px) and (max-width: 1279px) {
+ #nd-docs-layout {
+ --fd-toc-popover-height: 0px !important;
+ }
+
+ [data-toc-popover] {
+ display: none !important;
+ }
+}
+
/* Desktop only: Apply custom navbar offset, sidebar width and margin offsets */
/* On mobile, let fumadocs handle the layout natively */
@media (min-width: 1024px) {
diff --git a/apps/docs/content/docs/en/copilot/index.mdx b/apps/docs/content/docs/en/copilot/index.mdx
index fdcdad8d5..e222d8e55 100644
--- a/apps/docs/content/docs/en/copilot/index.mdx
+++ b/apps/docs/content/docs/en/copilot/index.mdx
@@ -5,45 +5,25 @@ title: Copilot
import { Callout } from 'fumadocs-ui/components/callout'
import { Card, Cards } from 'fumadocs-ui/components/card'
import { Image } from '@/components/ui/image'
-import { MessageCircle, Package, Zap, Infinity as InfinityIcon, Brain, BrainCircuit } from 'lucide-react'
+import { MessageCircle, Hammer, Zap, Globe, Paperclip, History, RotateCcw, Brain } from 'lucide-react'
-Copilot is your in-editor assistant that helps you build and edit workflows with Sim Copilot, as well as understand and improve them. It can:
+Copilot is your in-editor assistant that helps you build and edit workflows. It can:
- **Explain**: Answer questions about Sim and your current workflow
- **Guide**: Suggest edits and best practices
-- **Edit**: Make changes to blocks, connections, and settings when you approve
+- **Build**: Add blocks, wire connections, and configure settings
+- **Debug**: Analyze execution issues and optimize performance
- Copilot is a Sim-managed service. For self-hosted deployments, generate a Copilot API key in the hosted app (sim.ai → Settings → Copilot)
+ Copilot is a Sim-managed service. For self-hosted deployments:
1. Go to [sim.ai](https://sim.ai) → Settings → Copilot and generate a Copilot API key
- 2. Set `COPILOT_API_KEY` in your self-hosted environment to that value
+ 2. Set `COPILOT_API_KEY` in your self-hosted environment
-## Context Menu (@)
-
-Use the `@` symbol to reference various resources and give Copilot more context about your workspace:
-
-
-
-The `@` menu provides access to:
-- **Chats**: Reference previous copilot conversations
-- **All workflows**: Reference any workflow in your workspace
-- **Workflow Blocks**: Reference specific blocks from workflows
-- **Blocks**: Reference block types and templates
-- **Knowledge**: Reference your uploaded documents and knowledgebase
-- **Docs**: Reference Sim documentation
-- **Templates**: Reference workflow templates
-- **Logs**: Reference execution logs and results
-
-This contextual information helps Copilot provide more accurate and relevant assistance for your specific use case.
-
## Modes
+Switch between modes using the mode selector at the bottom of the input area.
+
-
- Agent
+
+ Build
}
>
- Build-and-edit mode. Copilot proposes specific edits (add blocks, wire variables, tweak settings) and applies them when you approve.
+ Workflow building mode. Copilot can add blocks, wire connections, edit configurations, and debug issues.
-
-
-
+## Models
-## Depth Levels
+Select your preferred AI model using the model selector at the bottom right of the input area.
-
-
-
- Fast
-
- }
- >
- Quickest and cheapest. Best for small edits, simple workflows, and minor tweaks.
-
-
-
- Auto
-
- }
- >
- Balanced speed and reasoning. Recommended default for most tasks.
-
-
-
- Advanced
-
- }
- >
- More reasoning for larger workflows and complex edits while staying performant.
-
-
-
- Behemoth
-
- }
- >
- Maximum reasoning for deep planning, debugging, and complex architectural changes.
-
-
+**Available Models:**
+- Claude 4.5 Opus, Sonnet (default), Haiku
+- GPT 5.2 Codex, Pro
+- Gemini 3 Pro
-### Mode Selection Interface
+Choose based on your needs: faster models for simple tasks, more capable models for complex workflows.
-You can easily switch between different reasoning modes using the mode selector in the Copilot interface:
+## Context Menu (@)
-
+Use the `@` symbol to reference resources and give Copilot more context:
-The interface allows you to:
-- **Select reasoning level**: Choose from Fast, Auto, Advanced, or Behemoth
-- **Enable MAX mode**: Toggle for maximum reasoning capabilities when you need the most thorough analysis
-- **See mode descriptions**: Understand what each mode is optimized for
+| Reference | Description |
+|-----------|-------------|
+| **Chats** | Previous copilot conversations |
+| **Workflows** | Any workflow in your workspace |
+| **Workflow Blocks** | Blocks in the current workflow |
+| **Blocks** | Block types and templates |
+| **Knowledge** | Uploaded documents and knowledge bases |
+| **Docs** | Sim documentation |
+| **Templates** | Workflow templates |
+| **Logs** | Execution logs and results |
-Choose your mode based on the complexity of your task - use Fast for simple questions and Behemoth for complex architectural changes.
+Type `@` in the input field to open the context menu, then search or browse to find what you need.
-## Billing and Cost Calculation
+## Slash Commands (/)
-### How Costs Are Calculated
+Use slash commands for quick actions:
-Copilot usage is billed per token from the underlying LLM:
+| Command | Description |
+|---------|-------------|
+| `/fast` | Fast mode execution |
+| `/research` | Research and exploration mode |
+| `/actions` | Execute agent actions |
-- **Input tokens**: billed at the provider's base rate (**at-cost**)
-- **Output tokens**: billed at **1.5×** the provider's base output rate
+**Web Commands:**
-```javascript
-copilotCost = (inputTokens × inputPrice + outputTokens × (outputPrice × 1.5)) / 1,000,000
-```
+| Command | Description |
+|---------|-------------|
+| `/search` | Search the web |
+| `/read` | Read a specific URL |
+| `/scrape` | Scrape web page content |
+| `/crawl` | Crawl multiple pages |
-| Component | Rate Applied |
-|----------|----------------------|
-| Input | inputPrice |
-| Output | outputPrice × 1.5 |
+Type `/` in the input field to see available commands.
-
- Pricing shown reflects rates as of September 4, 2025. Check provider documentation for current pricing.
-
+## Chat Management
+
+### Starting a New Chat
+
+Click the **+** button in the Copilot header to start a fresh conversation.
+
+### Chat History
+
+Click **History** to view previous conversations grouped by date. You can:
+- Click a chat to resume it
+- Delete chats you no longer need
+
+### Editing Messages
+
+Hover over any of your messages and click **Edit** to modify and resend it. This is useful for refining your prompts.
+
+### Message Queue
+
+If you send a message while Copilot is still responding, it gets queued. You can:
+- View queued messages in the expandable queue panel
+- Send a queued message immediately (aborts current response)
+- Remove messages from the queue
+
+## File Attachments
+
+Click the attachment icon to upload files with your message. Supported file types include:
+- Images (preview thumbnails shown)
+- PDFs
+- Text files, JSON, XML
+- Other document formats
+
+Files are displayed as clickable thumbnails that open in a new tab.
+
+## Checkpoints & Changes
+
+When Copilot makes changes to your workflow, it saves checkpoints so you can revert if needed.
+
+### Viewing Checkpoints
+
+Hover over a Copilot message and click the checkpoints icon to see saved workflow states for that message.
+
+### Reverting Changes
+
+Click **Revert** on any checkpoint to restore your workflow to that state. A confirmation dialog will warn that this action cannot be undone.
+
+### Accepting Changes
+
+When Copilot proposes changes, you can:
+- **Accept**: Apply the proposed changes (`Mod+Shift+Enter`)
+- **Reject**: Dismiss the changes and keep your current workflow
+
+## Thinking Blocks
+
+For complex requests, Copilot may show its reasoning process in expandable thinking blocks:
+
+- Blocks auto-expand while Copilot is thinking
+- Click to manually expand/collapse
+- Shows duration of the thinking process
+- Helps you understand how Copilot arrived at its solution
+
+## Options Selection
+
+When Copilot presents multiple options, you can select using:
+
+| Control | Action |
+|---------|--------|
+| **1-9** | Select option by number |
+| **Arrow Up/Down** | Navigate between options |
+| **Enter** | Select highlighted option |
+
+Selected options are highlighted; unselected options appear struck through.
+
+## Keyboard Shortcuts
+
+| Shortcut | Action |
+|----------|--------|
+| `@` | Open context menu |
+| `/` | Open slash commands |
+| `Arrow Up/Down` | Navigate menu items |
+| `Enter` | Select menu item |
+| `Esc` | Close menus |
+| `Mod+Shift+Enter` | Accept Copilot changes |
+
+## Usage Limits
+
+Copilot usage is billed per token from the underlying LLM. If you reach your usage limit, Copilot will prompt you to increase your limit. You can add usage in increments ($50, $100) from your current base.
- Model prices are per million tokens. The calculation divides by 1,000,000 to get the actual cost. See the Cost Calculation page for background and examples.
+ See the [Cost Calculation page](/execution/costs) for billing details.
-
diff --git a/apps/docs/content/docs/en/keyboard-shortcuts/index.mdx b/apps/docs/content/docs/en/keyboard-shortcuts/index.mdx
index 604883c42..94cc831ee 100644
--- a/apps/docs/content/docs/en/keyboard-shortcuts/index.mdx
+++ b/apps/docs/content/docs/en/keyboard-shortcuts/index.mdx
@@ -34,6 +34,8 @@ Speed up your workflow building with these keyboard shortcuts and mouse controls
| `Mod` + `V` | Paste blocks |
| `Delete` or `Backspace` | Delete selected blocks or edges |
| `Shift` + `L` | Auto-layout canvas |
+| `Mod` + `Shift` + `F` | Fit to view |
+| `Mod` + `Shift` + `Enter` | Accept Copilot changes |
## Panel Navigation
diff --git a/apps/docs/content/docs/en/meta.json b/apps/docs/content/docs/en/meta.json
index 52213b66a..b934947a3 100644
--- a/apps/docs/content/docs/en/meta.json
+++ b/apps/docs/content/docs/en/meta.json
@@ -3,6 +3,7 @@
"pages": [
"./introduction/index",
"./getting-started/index",
+ "./quick-reference/index",
"triggers",
"blocks",
"tools",
diff --git a/apps/docs/content/docs/en/quick-reference/index.mdx b/apps/docs/content/docs/en/quick-reference/index.mdx
new file mode 100644
index 000000000..02126a624
--- /dev/null
+++ b/apps/docs/content/docs/en/quick-reference/index.mdx
@@ -0,0 +1,136 @@
+---
+title: Quick Reference
+description: Essential actions for navigating and using the Sim workflow editor
+---
+
+import { Callout } from 'fumadocs-ui/components/callout'
+
+A quick lookup for everyday actions in the Sim workflow editor. For keyboard shortcuts, see [Keyboard Shortcuts](/keyboard-shortcuts).
+
+
+ **Mod** refers to `Cmd` on macOS and `Ctrl` on Windows/Linux.
+
+
+## Workspaces
+
+| Action | How |
+|--------|-----|
+| Create a workspace | Click workspace dropdown in sidebar → **New Workspace** |
+| Rename a workspace | Workspace settings → Edit name |
+| Switch workspaces | Click workspace dropdown in sidebar → Select workspace |
+| Invite team members | Workspace settings → **Team** → **Invite** |
+
+## Workflows
+
+| Action | How |
+|--------|-----|
+| Create a workflow | Click **New Workflow** button or `Mod+Shift+A` |
+| Rename a workflow | Double-click workflow name in sidebar, or right-click → **Rename** |
+| Duplicate a workflow | Right-click workflow → **Duplicate** |
+| Reorder workflows | Drag workflow up/down in the sidebar list |
+| Import a workflow | Sidebar menu → **Import** → Select file |
+| Create a folder | Right-click in sidebar → **New Folder** |
+| Rename a folder | Right-click folder → **Rename** |
+| Delete a folder | Right-click folder → **Delete** |
+| Collapse/expand folder | Click folder arrow, or double-click folder |
+| Move workflow to folder | Drag workflow onto folder in sidebar |
+| Delete a workflow | Right-click workflow → **Delete** |
+| Export a workflow | Right-click workflow → **Export** |
+| Assign workflow color | Right-click workflow → **Change Color** |
+| Multi-select workflows | `Mod+Click` or `Shift+Click` workflows in sidebar |
+| Open in new tab | Right-click workflow → **Open in New Tab** |
+
+## Blocks
+
+| Action | How |
+|--------|-----|
+| Add a block | Drag from Toolbar panel, or right-click canvas → **Add Block** |
+| Select a block | Click on the block |
+| Multi-select blocks | `Mod+Click` additional blocks, or right-drag to draw selection box |
+| Move blocks | Drag selected block(s) to new position |
+| Copy blocks | `Mod+C` with blocks selected |
+| Paste blocks | `Mod+V` to paste copied blocks |
+| Duplicate blocks | Right-click → **Duplicate** |
+| Delete blocks | `Delete` or `Backspace` key, or right-click → **Delete** |
+| Rename a block | Click block name in header, or edit in the Editor panel |
+| Enable/Disable a block | Right-click → **Enable/Disable** |
+| Toggle handle orientation | Right-click → **Toggle Handles** |
+| Toggle trigger mode | Right-click trigger block → **Toggle Trigger Mode** |
+| Configure a block | Select block → use Editor panel on right |
+
+## Connections
+
+| Action | How |
+|--------|-----|
+| Create a connection | Drag from output handle to input handle |
+| Delete a connection | Click edge to select → `Delete` key |
+| Use output in another block | Drag connection tag into input field |
+
+## Canvas Navigation
+
+| Action | How |
+|--------|-----|
+| Pan/move canvas | Left-drag on empty space, or scroll/trackpad |
+| Zoom in/out | Scroll wheel or pinch gesture |
+| Auto-layout | `Shift+L` |
+| Draw selection box | Right-drag on empty canvas area |
+
+## Panels & Views
+
+| Action | How |
+|--------|-----|
+| Open Copilot tab | Press `C` or click Copilot tab |
+| Open Toolbar tab | Press `T` or click Toolbar tab |
+| Open Editor tab | Press `E` or click Editor tab |
+| Search toolbar | `Mod+F` |
+| Toggle advanced mode | Click toggle button on input fields |
+| Resize panels | Drag panel edge |
+| Collapse/expand sidebar | Click collapse button on sidebar |
+
+## Running & Testing
+
+| Action | How |
+|--------|-----|
+| Run workflow | Click Play button or `Mod+Enter` |
+| Stop workflow | Click Stop button or `Mod+Enter` while running |
+| Test with chat | Use Chat panel on the right side |
+| Select output to view | Click dropdown in Chat panel → Select block output |
+| Clear chat history | Click clear button in Chat panel |
+| View execution logs | Open terminal panel at bottom, or `Mod+L` |
+| Filter logs by block | Click block filter in terminal |
+| Filter logs by status | Click status filter in terminal |
+| Search logs | Use search field in terminal |
+| Copy log entry | Right-click log entry → **Copy** |
+| Clear terminal | `Mod+D` |
+
+## Deployment
+
+| Action | How |
+|--------|-----|
+| Deploy a workflow | Click **Deploy** button in Deploy tab |
+| Update deployment | Click **Update** when changes are detected |
+| View deployment status | Check status indicator (Live/Update/Deploy) in Deploy tab |
+| Revert deployment | Access previous versions in Deploy tab |
+| Copy webhook URL | Deploy tab → Copy webhook URL |
+| Copy API endpoint | Deploy tab → Copy API endpoint URL |
+| Set up a schedule | Add Schedule trigger block → Configure interval |
+
+## Variables
+
+| Action | How |
+|--------|-----|
+| Add workflow variable | Variables tab → **Add Variable** |
+| Edit workflow variable | Variables tab → Click variable to edit |
+| Delete workflow variable | Variables tab → Click delete icon on variable |
+| Add environment variable | Settings → **Environment Variables** → **Add** |
+| Reference a variable | Use `{{variableName}}` syntax in block inputs |
+
+## Credentials
+
+| Action | How |
+|--------|-----|
+| Add API key | Block credential field → **Add Credential** → Enter API key |
+| Connect OAuth account | Block credential field → **Connect** → Authorize with provider |
+| Manage credentials | Settings → **Credentials** |
+| Remove credential | Settings → **Credentials** → Delete credential |
+
diff --git a/packages/python-sdk/README.md b/packages/python-sdk/README.md
index efcf91df7..e193e951c 100644
--- a/packages/python-sdk/README.md
+++ b/packages/python-sdk/README.md
@@ -43,24 +43,30 @@ SimStudioClient(api_key: str, base_url: str = "https://sim.ai")
#### Methods
-##### execute_workflow(workflow_id, input_data=None, timeout=30.0)
+##### execute_workflow(workflow_id, input=None, *, timeout=30.0, stream=None, selected_outputs=None, async_execution=None)
Execute a workflow with optional input data.
```python
-result = client.execute_workflow(
- "workflow-id",
- input_data={"message": "Hello, world!"},
- timeout=30.0 # 30 seconds
-)
+# With dict input (spread at root level of request body)
+result = client.execute_workflow("workflow-id", {"message": "Hello, world!"})
+
+# With primitive input (wrapped as { input: value })
+result = client.execute_workflow("workflow-id", "NVDA")
+
+# With options (keyword-only arguments)
+result = client.execute_workflow("workflow-id", {"message": "Hello"}, timeout=60.0)
```
**Parameters:**
- `workflow_id` (str): The ID of the workflow to execute
-- `input_data` (dict, optional): Input data to pass to the workflow. File objects are automatically converted to base64.
-- `timeout` (float): Timeout in seconds (default: 30.0)
+- `input` (any, optional): Input data to pass to the workflow. Dicts are spread at the root level, primitives/lists are wrapped in `{ input: value }`. File objects are automatically converted to base64.
+- `timeout` (float, keyword-only): Timeout in seconds (default: 30.0)
+- `stream` (bool, keyword-only): Enable streaming responses
+- `selected_outputs` (list, keyword-only): Block outputs to stream (e.g., `["agent1.content"]`)
+- `async_execution` (bool, keyword-only): Execute asynchronously and return execution ID
-**Returns:** `WorkflowExecutionResult`
+**Returns:** `WorkflowExecutionResult` or `AsyncExecutionResult`
##### get_workflow_status(workflow_id)
@@ -92,24 +98,89 @@ if is_ready:
**Returns:** `bool`
-##### execute_workflow_sync(workflow_id, input_data=None, timeout=30.0)
+##### execute_workflow_sync(workflow_id, input=None, *, timeout=30.0, stream=None, selected_outputs=None)
-Execute a workflow and poll for completion (useful for long-running workflows).
+Execute a workflow synchronously (ensures non-async mode).
```python
-result = client.execute_workflow_sync(
+result = client.execute_workflow_sync("workflow-id", {"data": "some input"}, timeout=60.0)
+```
+
+**Parameters:**
+- `workflow_id` (str): The ID of the workflow to execute
+- `input` (any, optional): Input data to pass to the workflow
+- `timeout` (float, keyword-only): Timeout in seconds (default: 30.0)
+- `stream` (bool, keyword-only): Enable streaming responses
+- `selected_outputs` (list, keyword-only): Block outputs to stream (e.g., `["agent1.content"]`)
+
+**Returns:** `WorkflowExecutionResult`
+
+##### get_job_status(task_id)
+
+Get the status of an async job.
+
+```python
+status = client.get_job_status("task-id-from-async-execution")
+print("Job status:", status)
+```
+
+**Parameters:**
+- `task_id` (str): The task ID returned from async execution
+
+**Returns:** `dict`
+
+##### execute_with_retry(workflow_id, input=None, *, timeout=30.0, stream=None, selected_outputs=None, async_execution=None, max_retries=3, initial_delay=1.0, max_delay=30.0, backoff_multiplier=2.0)
+
+Execute a workflow with automatic retry on rate limit errors.
+
+```python
+result = client.execute_with_retry(
"workflow-id",
- input_data={"data": "some input"},
- timeout=60.0
+ {"message": "Hello"},
+ timeout=30.0,
+ max_retries=3,
+ initial_delay=1.0,
+ max_delay=30.0,
+ backoff_multiplier=2.0
)
```
**Parameters:**
- `workflow_id` (str): The ID of the workflow to execute
-- `input_data` (dict, optional): Input data to pass to the workflow
-- `timeout` (float): Timeout for the initial request in seconds
+- `input` (any, optional): Input data to pass to the workflow
+- `timeout` (float, keyword-only): Timeout in seconds (default: 30.0)
+- `stream` (bool, keyword-only): Enable streaming responses
+- `selected_outputs` (list, keyword-only): Block outputs to stream
+- `async_execution` (bool, keyword-only): Execute asynchronously
+- `max_retries` (int, keyword-only): Maximum retry attempts (default: 3)
+- `initial_delay` (float, keyword-only): Initial delay in seconds (default: 1.0)
+- `max_delay` (float, keyword-only): Maximum delay in seconds (default: 30.0)
+- `backoff_multiplier` (float, keyword-only): Backoff multiplier (default: 2.0)
-**Returns:** `WorkflowExecutionResult`
+**Returns:** `WorkflowExecutionResult` or `AsyncExecutionResult`
+
+##### get_rate_limit_info()
+
+Get current rate limit information from the last API response.
+
+```python
+rate_info = client.get_rate_limit_info()
+if rate_info:
+ print("Remaining requests:", rate_info.remaining)
+```
+
+**Returns:** `RateLimitInfo` or `None`
+
+##### get_usage_limits()
+
+Get current usage limits and quota information.
+
+```python
+limits = client.get_usage_limits()
+print("Current usage:", limits.usage)
+```
+
+**Returns:** `UsageLimits`
##### set_api_key(api_key)
@@ -171,6 +242,39 @@ class SimStudioError(Exception):
self.status = status
```
+### AsyncExecutionResult
+
+```python
+@dataclass
+class AsyncExecutionResult:
+ success: bool
+ task_id: str
+ status: str # 'queued'
+ created_at: str
+ links: Dict[str, str]
+```
+
+### RateLimitInfo
+
+```python
+@dataclass
+class RateLimitInfo:
+ limit: int
+ remaining: int
+ reset: int
+ retry_after: Optional[int] = None
+```
+
+### UsageLimits
+
+```python
+@dataclass
+class UsageLimits:
+ success: bool
+ rate_limit: Dict[str, Any]
+ usage: Dict[str, Any]
+```
+
## Examples
### Basic Workflow Execution
@@ -191,7 +295,7 @@ def run_workflow():
# Execute the workflow
result = client.execute_workflow(
"my-workflow-id",
- input_data={
+ {
"message": "Process this data",
"user_id": "12345"
}
@@ -298,7 +402,7 @@ client = SimStudioClient(api_key=os.getenv("SIM_API_KEY"))
with open('document.pdf', 'rb') as f:
result = client.execute_workflow(
'workflow-id',
- input_data={
+ {
'documents': [f], # Must match your workflow's "files" field name
'instructions': 'Analyze this document'
}
@@ -308,7 +412,7 @@ with open('document.pdf', 'rb') as f:
with open('doc1.pdf', 'rb') as f1, open('doc2.pdf', 'rb') as f2:
result = client.execute_workflow(
'workflow-id',
- input_data={
+ {
'attachments': [f1, f2], # Must match your workflow's "files" field name
'query': 'Compare these documents'
}
@@ -327,14 +431,14 @@ def execute_workflows_batch(workflow_data_pairs):
"""Execute multiple workflows with different input data."""
results = []
- for workflow_id, input_data in workflow_data_pairs:
+ for workflow_id, workflow_input in workflow_data_pairs:
try:
# Validate workflow before execution
if not client.validate_workflow(workflow_id):
print(f"Skipping {workflow_id}: not deployed")
continue
- result = client.execute_workflow(workflow_id, input_data)
+ result = client.execute_workflow(workflow_id, workflow_input)
results.append({
"workflow_id": workflow_id,
"success": result.success,
diff --git a/packages/ts-sdk/README.md b/packages/ts-sdk/README.md
index 04582aeda..44d21d0c9 100644
--- a/packages/ts-sdk/README.md
+++ b/packages/ts-sdk/README.md
@@ -47,24 +47,35 @@ new SimStudioClient(config: SimStudioConfig)
#### Methods
-##### executeWorkflow(workflowId, options?)
+##### executeWorkflow(workflowId, input?, options?)
Execute a workflow with optional input data.
```typescript
+// With object input (spread at root level of request body)
const result = await client.executeWorkflow('workflow-id', {
- input: { message: 'Hello, world!' },
- timeout: 30000 // 30 seconds
+ message: 'Hello, world!'
+});
+
+// With primitive input (wrapped as { input: value })
+const result = await client.executeWorkflow('workflow-id', 'NVDA');
+
+// With options
+const result = await client.executeWorkflow('workflow-id', { message: 'Hello' }, {
+ timeout: 60000
});
```
**Parameters:**
- `workflowId` (string): The ID of the workflow to execute
+- `input` (any, optional): Input data to pass to the workflow. Objects are spread at the root level, primitives/arrays are wrapped in `{ input: value }`. File objects are automatically converted to base64.
- `options` (ExecutionOptions, optional):
- - `input` (any): Input data to pass to the workflow. File objects are automatically converted to base64.
- `timeout` (number): Timeout in milliseconds (default: 30000)
+ - `stream` (boolean): Enable streaming responses
+ - `selectedOutputs` (string[]): Block outputs to stream (e.g., `["agent1.content"]`)
+ - `async` (boolean): Execute asynchronously and return execution ID
-**Returns:** `Promise`
+**Returns:** `Promise`
##### getWorkflowStatus(workflowId)
@@ -96,25 +107,89 @@ if (isReady) {
**Returns:** `Promise`
-##### executeWorkflowSync(workflowId, options?)
+##### executeWorkflowSync(workflowId, input?, options?)
Execute a workflow and poll for completion (useful for long-running workflows).
```typescript
-const result = await client.executeWorkflowSync('workflow-id', {
- input: { data: 'some input' },
+const result = await client.executeWorkflowSync('workflow-id', { data: 'some input' }, {
timeout: 60000
});
```
**Parameters:**
- `workflowId` (string): The ID of the workflow to execute
+- `input` (any, optional): Input data to pass to the workflow
- `options` (ExecutionOptions, optional):
- - `input` (any): Input data to pass to the workflow
- `timeout` (number): Timeout for the initial request in milliseconds
**Returns:** `Promise`
+##### getJobStatus(taskId)
+
+Get the status of an async job.
+
+```typescript
+const status = await client.getJobStatus('task-id-from-async-execution');
+console.log('Job status:', status);
+```
+
+**Parameters:**
+- `taskId` (string): The task ID returned from async execution
+
+**Returns:** `Promise`
+
+##### executeWithRetry(workflowId, input?, options?, retryOptions?)
+
+Execute a workflow with automatic retry on rate limit errors.
+
+```typescript
+const result = await client.executeWithRetry('workflow-id', { message: 'Hello' }, {
+ timeout: 30000
+}, {
+ maxRetries: 3,
+ initialDelay: 1000,
+ maxDelay: 30000,
+ backoffMultiplier: 2
+});
+```
+
+**Parameters:**
+- `workflowId` (string): The ID of the workflow to execute
+- `input` (any, optional): Input data to pass to the workflow
+- `options` (ExecutionOptions, optional): Execution options
+- `retryOptions` (RetryOptions, optional):
+ - `maxRetries` (number): Maximum retry attempts (default: 3)
+ - `initialDelay` (number): Initial delay in ms (default: 1000)
+ - `maxDelay` (number): Maximum delay in ms (default: 30000)
+ - `backoffMultiplier` (number): Backoff multiplier (default: 2)
+
+**Returns:** `Promise`
+
+##### getRateLimitInfo()
+
+Get current rate limit information from the last API response.
+
+```typescript
+const rateInfo = client.getRateLimitInfo();
+if (rateInfo) {
+ console.log('Remaining requests:', rateInfo.remaining);
+}
+```
+
+**Returns:** `RateLimitInfo | null`
+
+##### getUsageLimits()
+
+Get current usage limits and quota information.
+
+```typescript
+const limits = await client.getUsageLimits();
+console.log('Current usage:', limits.usage);
+```
+
+**Returns:** `Promise`
+
##### setApiKey(apiKey)
Update the API key.
@@ -170,6 +245,81 @@ class SimStudioError extends Error {
}
```
+### AsyncExecutionResult
+
+```typescript
+interface AsyncExecutionResult {
+ success: boolean;
+ taskId: string;
+ status: 'queued';
+ createdAt: string;
+ links: {
+ status: string;
+ };
+}
+```
+
+### RateLimitInfo
+
+```typescript
+interface RateLimitInfo {
+ limit: number;
+ remaining: number;
+ reset: number;
+ retryAfter?: number;
+}
+```
+
+### UsageLimits
+
+```typescript
+interface UsageLimits {
+ success: boolean;
+ rateLimit: {
+ sync: {
+ isLimited: boolean;
+ limit: number;
+ remaining: number;
+ resetAt: string;
+ };
+ async: {
+ isLimited: boolean;
+ limit: number;
+ remaining: number;
+ resetAt: string;
+ };
+ authType: string;
+ };
+ usage: {
+ currentPeriodCost: number;
+ limit: number;
+ plan: string;
+ };
+}
+```
+
+### ExecutionOptions
+
+```typescript
+interface ExecutionOptions {
+ timeout?: number;
+ stream?: boolean;
+ selectedOutputs?: string[];
+ async?: boolean;
+}
+```
+
+### RetryOptions
+
+```typescript
+interface RetryOptions {
+ maxRetries?: number;
+ initialDelay?: number;
+ maxDelay?: number;
+ backoffMultiplier?: number;
+}
+```
+
## Examples
### Basic Workflow Execution
@@ -191,10 +341,8 @@ async function runWorkflow() {
// Execute the workflow
const result = await client.executeWorkflow('my-workflow-id', {
- input: {
- message: 'Process this data',
- userId: '12345'
- }
+ message: 'Process this data',
+ userId: '12345'
});
if (result.success) {
@@ -298,22 +446,18 @@ const file = new File([fileBuffer], 'document.pdf', { type: 'application/pdf' })
// Include files under the field name from your API trigger's input format
const result = await client.executeWorkflow('workflow-id', {
- input: {
- documents: [file], // Field name must match your API trigger's file input field
- instructions: 'Process this document'
- }
+ documents: [file], // Field name must match your API trigger's file input field
+ instructions: 'Process this document'
});
// Browser: From file input
const handleFileUpload = async (event: Event) => {
- const input = event.target as HTMLInputElement;
- const files = Array.from(input.files || []);
+ const inputEl = event.target as HTMLInputElement;
+ const files = Array.from(inputEl.files || []);
const result = await client.executeWorkflow('workflow-id', {
- input: {
- attachments: files, // Field name must match your API trigger's file input field
- query: 'Analyze these files'
- }
+ attachments: files, // Field name must match your API trigger's file input field
+ query: 'Analyze these files'
});
};
```