@elevasis/sdk 0.5.11 → 0.5.13
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/dist/cli.cjs +276 -298
- package/dist/index.d.ts +13 -256
- package/dist/index.js +10 -38
- package/dist/templates.js +193 -187
- package/dist/types/worker/adapters/index.d.ts +0 -1
- package/dist/worker/index.js +126 -75
- package/package.json +1 -1
- package/reference/_navigation.md +13 -57
- package/reference/concepts.mdx +203 -0
- package/reference/deployment/{command-center-ui.mdx → command-center.mdx} +229 -151
- package/reference/deployment/index.mdx +158 -153
- package/reference/framework/agent.mdx +168 -151
- package/reference/framework/index.mdx +182 -103
- package/reference/framework/memory.mdx +347 -347
- package/reference/framework/project-structure.mdx +3 -13
- package/reference/framework/tutorial-system.mdx +253 -0
- package/reference/{getting-started/index.mdx → getting-started.mdx} +6 -7
- package/reference/index.mdx +117 -114
- package/reference/platform-tools/adapters.mdx +175 -32
- package/reference/platform-tools/index.mdx +354 -195
- package/reference/resources/index.mdx +5 -0
- package/reference/{roadmap/index.mdx → roadmap.mdx} +1 -1
- package/reference/{runtime/index.mdx → runtime.mdx} +196 -141
- package/dist/types/worker/adapters/trello.d.ts +0 -14
- package/reference/concepts/index.mdx +0 -203
- package/reference/deployment/command-view.mdx +0 -154
- package/reference/framework/documentation.mdx +0 -92
- package/reference/platform-tools/examples.mdx +0 -170
- package/reference/runtime/limits.mdx +0 -75
- package/reference/security/credentials.mdx +0 -141
- /package/reference/{cli/index.mdx → cli.mdx} +0 -0
- /package/reference/{developer → framework}/interaction-guidance.mdx +0 -0
- /package/reference/{troubleshooting/common-errors.mdx → troubleshooting.mdx} +0 -0
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Command View
|
|
3
|
-
description: How the Command View graph works -- node types, relationships, what is enforced vs decorative, and what the platform needs to render your resource graph
|
|
4
|
-
loadWhen: "Deploying resources or building resources that invoke other resources"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
The Command View is a visual graph in the Elevasis command center that shows how your organization's resources connect. Nodes are resources (workflows, agents, integrations). Edges are relationships you declare between them. The graph helps operators understand how automation flows through the system at a glance.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Node Types
|
|
12
|
-
|
|
13
|
-
Every resource you deploy becomes a node in the Command View. Some nodes are executable (the platform runs them); others are visual-only (they exist for the graph but have no runtime behavior).
|
|
14
|
-
|
|
15
|
-
### Executable Nodes
|
|
16
|
-
|
|
17
|
-
| Type | What It Does | Deployed By |
|
|
18
|
-
| ---- | ------------ | ----------- |
|
|
19
|
-
| Workflow | Runs step handlers in sequence or branching paths | `elevasis-sdk deploy` |
|
|
20
|
-
| Agent | Autonomous LLM-powered resource with tools | `elevasis-sdk deploy` |
|
|
21
|
-
|
|
22
|
-
### Visual-Only Nodes
|
|
23
|
-
|
|
24
|
-
These exist solely for the Command View graph. They have no runtime behavior -- the platform does not execute them.
|
|
25
|
-
|
|
26
|
-
| Type | What It Represents | Why It Exists |
|
|
27
|
-
| ---- | ------------------ | ------------- |
|
|
28
|
-
| Trigger | A webhook or schedule that starts a workflow | Shows how executions begin |
|
|
29
|
-
| Integration | A credential reference (provider + credential name) | Shows which external services a resource uses |
|
|
30
|
-
| External Resource | A third-party automation (n8n, Make, Zapier) | Documents automations outside the platform |
|
|
31
|
-
| Human Checkpoint | A point where a human makes a decision | Shows where HITL approval gates exist |
|
|
32
|
-
|
|
33
|
-
Visual-only nodes are declarations. A `TriggerDefinition` does not set up actual trigger routing -- the webhook gateway routes independently. An `IntegrationDefinition` does not configure or connect to anything -- it is a visual node referencing a credential.
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Relationships
|
|
38
|
-
|
|
39
|
-
Relationships are edges in the Command View graph. You declare them in `OrganizationResources` to tell the platform how resources connect.
|
|
40
|
-
|
|
41
|
-
### Declaring Relationships
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
const org: OrganizationResources = {
|
|
45
|
-
workflows: {
|
|
46
|
-
'score-lead': scoreLeadWorkflow,
|
|
47
|
-
'send-proposal': sendProposalWorkflow,
|
|
48
|
-
},
|
|
49
|
-
agents: {
|
|
50
|
-
'research-agent': researchAgent,
|
|
51
|
-
},
|
|
52
|
-
relationships: {
|
|
53
|
-
'score-lead': {
|
|
54
|
-
triggers: {
|
|
55
|
-
workflows: ['send-proposal'], // score-lead triggers send-proposal
|
|
56
|
-
agents: ['research-agent'], // score-lead triggers research-agent
|
|
57
|
-
},
|
|
58
|
-
uses: {
|
|
59
|
-
integrations: ['attio-integration'], // score-lead uses Attio
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### Relationship Fields
|
|
67
|
-
|
|
68
|
-
| Field | Type | Meaning |
|
|
69
|
-
| ----- | ---- | ------- |
|
|
70
|
-
| `triggers.workflows` | `string[]` | Workflows this resource starts |
|
|
71
|
-
| `triggers.agents` | `string[]` | Agents this resource starts |
|
|
72
|
-
| `uses.integrations` | `string[]` | Integrations this resource depends on |
|
|
73
|
-
|
|
74
|
-
All referenced IDs must exist in the same organization. Missing targets cause a validation error at deploy time.
|
|
75
|
-
|
|
76
|
-
### Relationships Are Declarations, Not Routing
|
|
77
|
-
|
|
78
|
-
Relationships tell the Command View what edges to draw. They do **not** create execution paths. If you declare that workflow A triggers workflow B, the platform does not automatically route A's output to B. Your handler code must explicitly invoke B using the `execution` adapter or `platform.call()`.
|
|
79
|
-
|
|
80
|
-
This means the graph can drift from reality:
|
|
81
|
-
|
|
82
|
-
- If your code invokes resource B but you forgot to declare the relationship, the edge is **missing** from the graph
|
|
83
|
-
- If you declared a relationship to resource B but your code never invokes it, the edge is **stale** in the graph
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
## What Is Enforced vs Decorative
|
|
88
|
-
|
|
89
|
-
| Category | Validated at Deploy | Matches Runtime | Status |
|
|
90
|
-
| -------- | ------------------- | --------------- | ------ |
|
|
91
|
-
| Resource IDs unique | Yes | Yes | **Enforced** |
|
|
92
|
-
| Input schema matches execution interface | Yes | Yes | **Enforced** |
|
|
93
|
-
| Relationship targets exist | Yes | No -- invocations are hardcoded strings in handlers | **Decorative** |
|
|
94
|
-
| Trigger routing | No | No -- webhook handlers route independently | **Decorative** |
|
|
95
|
-
| Tool availability per agent | No | No -- tools built dynamically at runtime | **Decorative** |
|
|
96
|
-
| Model config | Yes (provider + model valid) | No -- runtime uses environment config | **Decorative** |
|
|
97
|
-
| Integration usage | Partial (IDs checked) | No -- credentials resolved at runtime | **Decorative** |
|
|
98
|
-
|
|
99
|
-
**Enforced** means the platform rejects invalid state. **Decorative** means the platform trusts your declaration but does not verify it matches what the code actually does.
|
|
100
|
-
|
|
101
|
-
### What This Means for You
|
|
102
|
-
|
|
103
|
-
- Keep relationships in sync with your handler code. When you add an `execution.trigger('other-resource')` call, add the corresponding relationship declaration.
|
|
104
|
-
- When you remove an invocation, remove the relationship.
|
|
105
|
-
- The Command View is only as accurate as your declarations.
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## Deploy-Time Validation
|
|
110
|
-
|
|
111
|
-
When you run `elevasis-sdk deploy` or `elevasis-sdk check`, the SDK validates your resource definitions locally using the same `ResourceRegistry` the platform uses.
|
|
112
|
-
|
|
113
|
-
### What Gets Checked
|
|
114
|
-
|
|
115
|
-
- **Duplicate resource IDs** -- two resources with the same key in `workflows` or `agents`
|
|
116
|
-
- **Relationship targets exist** -- every ID in `triggers` and `uses` must match a resource or integration in the same `OrganizationResources`
|
|
117
|
-
- **Model configuration** -- agent model params (provider, model name, temperature bounds) are valid
|
|
118
|
-
- **Step chains** -- `next.target` values in multi-step workflows point to existing step names
|
|
119
|
-
|
|
120
|
-
### What Does Not Get Checked
|
|
121
|
-
|
|
122
|
-
- Whether your handler code actually invokes the resources you declared in relationships
|
|
123
|
-
- Whether your handler code invokes resources you did **not** declare in relationships
|
|
124
|
-
- Whether triggers route to the workflows you declared
|
|
125
|
-
- Whether agents use the tools you expect
|
|
126
|
-
|
|
127
|
-
These are the decorative gaps listed above. The graph is a best-effort representation that depends on you keeping declarations in sync with code.
|
|
128
|
-
|
|
129
|
-
### Validation Error Examples
|
|
130
|
-
|
|
131
|
-
```
|
|
132
|
-
ERROR Relationship target 'send-proposal' not found in organization resources
|
|
133
|
-
Resource: score-lead
|
|
134
|
-
Field: relationships.triggers.workflows
|
|
135
|
-
|
|
136
|
-
ERROR Duplicate resource ID 'score-lead' in organization
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
Fix relationship errors by checking that the target resource ID is spelled correctly and exists in your `OrganizationResources` export. If the resource was renamed or removed, update the relationship to match.
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
## Graph Serialization
|
|
144
|
-
|
|
145
|
-
The platform converts your resource definitions and relationships into a visual graph using two data structures:
|
|
146
|
-
|
|
147
|
-
- **`CommandViewNode`** -- one per resource (workflow, agent, trigger, integration, etc.). Contains the resource ID, type, name, status, and metadata.
|
|
148
|
-
- **`CommandViewEdge`** -- one per relationship. Contains source node, target node, and edge type (triggers, uses).
|
|
149
|
-
|
|
150
|
-
The `buildEdges()` function in the platform registry reads your `relationships` declarations and produces `CommandViewEdge[]`. This is a pure transformation -- it does not add or remove edges based on runtime behavior.
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
|
|
154
|
-
**Last Updated:** 2026-03-02
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Resource Documentation
|
|
3
|
-
description: Write and deploy MDX documentation alongside your Elevasis resources
|
|
4
|
-
loadWhen: "Writing or updating project documentation"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
`elevasis-sdk deploy` ships your code and your documentation atomically -- one command, no version drift. Documentation files live in a `docs/` directory at your project root and render in the Elevasis platform UI for operators using your resources.
|
|
8
|
-
|
|
9
|
-
## Directory Structure
|
|
10
|
-
|
|
11
|
-
Create `.mdx` files inside a `docs/` directory at your project root. `elevasis-sdk init` scaffolds a starter structure:
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
my-project/
|
|
15
|
-
├── docs/
|
|
16
|
-
│ └── index.mdx # Resource overview (scaffolded by init)
|
|
17
|
-
├── src/
|
|
18
|
-
│ └── index.ts # Resource definitions
|
|
19
|
-
├── elevasis.config.ts
|
|
20
|
-
└── ...
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
A missing `docs/` directory is silently ignored -- documentation is optional. If the directory exists, its contents are included in the deploy payload alongside resource schemas.
|
|
24
|
-
|
|
25
|
-
## Frontmatter Schema
|
|
26
|
-
|
|
27
|
-
Every documentation file supports a frontmatter block at the top:
|
|
28
|
-
|
|
29
|
-
```yaml
|
|
30
|
-
---
|
|
31
|
-
title: string # Page title (required)
|
|
32
|
-
description: string # Short description (optional)
|
|
33
|
-
order: number # Sort order within directory (optional, default: 0)
|
|
34
|
-
---
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Naming Conventions
|
|
38
|
-
|
|
39
|
-
- `docs/index.mdx` is the root documentation page and is always rendered first
|
|
40
|
-
- Nested directories create sections: `docs/guides/getting-started.mdx`
|
|
41
|
-
- File names become URL slugs: `setup-guide.mdx` renders at `/docs/setup-guide`
|
|
42
|
-
- Arbitrary nesting is supported -- there is no depth limit
|
|
43
|
-
|
|
44
|
-
## Size Limits
|
|
45
|
-
|
|
46
|
-
- 100KB per file
|
|
47
|
-
- 1MB total across all files in a deployment
|
|
48
|
-
|
|
49
|
-
These limits are enforced by the CLI before the deploy request is sent. Validation errors include the file name and size.
|
|
50
|
-
|
|
51
|
-
## Starter Template
|
|
52
|
-
|
|
53
|
-
`elevasis-sdk init` writes this starter file to `docs/index.mdx`:
|
|
54
|
-
|
|
55
|
-
```mdx
|
|
56
|
-
---
|
|
57
|
-
title: Overview
|
|
58
|
-
description: Documentation for this Elevasis project
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
# Overview
|
|
62
|
-
|
|
63
|
-
Welcome to the documentation for this project.
|
|
64
|
-
|
|
65
|
-
## Resources
|
|
66
|
-
|
|
67
|
-
Describe your workflows and agents here. This documentation is deployed alongside your
|
|
68
|
-
code and rendered in the Elevasis platform UI.
|
|
69
|
-
|
|
70
|
-
## Getting Started
|
|
71
|
-
|
|
72
|
-
\`\`\`bash
|
|
73
|
-
elevasis-sdk check # Validate resources
|
|
74
|
-
elevasis-sdk deploy # Deploy to platform
|
|
75
|
-
elevasis-sdk exec <resourceId> --input '{"key": "value"}'
|
|
76
|
-
\`\`\`
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Deploy Behavior
|
|
80
|
-
|
|
81
|
-
When you run `elevasis-sdk deploy`:
|
|
82
|
-
|
|
83
|
-
1. The CLI scans `docs/` recursively for `.mdx` files
|
|
84
|
-
2. Each file's frontmatter (title, description, order) is parsed and stripped from the content
|
|
85
|
-
3. Total size is validated against the 1MB limit and individual files against 100KB
|
|
86
|
-
4. The documentation array is included in the deploy metadata alongside your resource schemas
|
|
87
|
-
|
|
88
|
-
Documentation and code ship in the same transaction. There is no separate upload step and no way for documentation to drift out of sync with the deployed version.
|
|
89
|
-
|
|
90
|
-
---
|
|
91
|
-
|
|
92
|
-
**Last Updated:** 2026-02-25
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Integration Examples
|
|
3
|
-
description: Working code examples for email, CRM, PDF, LLM inference, resource triggering, and storage using typed adapters and platform.call()
|
|
4
|
-
loadWhen: "Implementing a platform tool call in a workflow step"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Working code examples for common tool integrations. All tools shown here have [typed adapters](adapters.mdx) that provide full autocomplete and compile-time checking -- prefer adapters in new code. The `platform.call()` patterns below are kept as reference and for tools without adapters yet (supabase).
|
|
8
|
-
|
|
9
|
-
## Sending Email via Resend
|
|
10
|
-
|
|
11
|
-
Send a transactional email through your Resend account. Store your Resend API key as a credential named `resend` using the [Elevasis CLI](../cli/index.mdx).
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
import { createResendAdapter } from '@elevasis/sdk/worker'
|
|
15
|
-
|
|
16
|
-
const resend = createResendAdapter('resend')
|
|
17
|
-
const result = await resend.sendEmail({
|
|
18
|
-
from: 'hello@yourapp.com',
|
|
19
|
-
to: 'customer@example.com',
|
|
20
|
-
subject: 'Your order is confirmed',
|
|
21
|
-
html: '\<p\>Thank you for your order!\</p\>',
|
|
22
|
-
})
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
The `credential` value must match the name you used when storing the API key. Resend supports `{ apiKey }` as its credential shape.
|
|
26
|
-
|
|
27
|
-
## Creating a CRM Record via Attio
|
|
28
|
-
|
|
29
|
-
Create a contact or company record in Attio. Store your Attio API key as a credential named `attio`.
|
|
30
|
-
|
|
31
|
-
```typescript
|
|
32
|
-
import { createAttioAdapter } from '@elevasis/sdk/worker'
|
|
33
|
-
|
|
34
|
-
const attio = createAttioAdapter('attio')
|
|
35
|
-
const result = await attio.createRecord({
|
|
36
|
-
object: 'people',
|
|
37
|
-
values: {
|
|
38
|
-
name: [{ full_name: 'Jane Smith' }],
|
|
39
|
-
email_addresses: [{ email_address: 'jane@example.com' }],
|
|
40
|
-
},
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
const recordId = result.data.id
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Attio exposes 12 methods covering CRUD operations, schema inspection, and notes. See the [typed adapter reference](adapters.mdx#attio-crm-adapter) for the full method list.
|
|
47
|
-
|
|
48
|
-
## Generating a PDF
|
|
49
|
-
|
|
50
|
-
Render a PDF from a document structure or template. No credential required -- PDF generation is a built-in platform service.
|
|
51
|
-
|
|
52
|
-
```typescript
|
|
53
|
-
import { pdf, storage } from '@elevasis/sdk/worker'
|
|
54
|
-
|
|
55
|
-
// Render to storage directly
|
|
56
|
-
const result = await pdf.render({
|
|
57
|
-
document: proposalDocument,
|
|
58
|
-
storage: { bucket: 'invoices', path: 'invoice-1042.pdf' },
|
|
59
|
-
})
|
|
60
|
-
console.log(result.pdfUrl)
|
|
61
|
-
|
|
62
|
-
// Or render to buffer for inline processing
|
|
63
|
-
const { buffer } = await pdf.renderToBuffer({
|
|
64
|
-
document: proposalDocument,
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
// Then upload manually if needed
|
|
68
|
-
await storage.upload({
|
|
69
|
-
bucket: 'invoices',
|
|
70
|
-
path: 'invoice-1042.pdf',
|
|
71
|
-
content: buffer,
|
|
72
|
-
contentType: 'application/pdf',
|
|
73
|
-
})
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## Making an LLM Call with Structured Output
|
|
77
|
-
|
|
78
|
-
Use the `llm` adapter to call any supported model with a JSON Schema for structured output. No API keys are needed in your code -- keys are resolved server-side.
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
import { llm } from '@elevasis/sdk/worker'
|
|
82
|
-
|
|
83
|
-
interface TicketClassification {
|
|
84
|
-
priority: 'low' | 'medium' | 'high' | 'critical'
|
|
85
|
-
category: 'billing' | 'technical' | 'account' | 'other'
|
|
86
|
-
sentiment: 'positive' | 'neutral' | 'negative'
|
|
87
|
-
summary: string
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const response = await llm.generate\<TicketClassification\>({
|
|
91
|
-
provider: 'anthropic',
|
|
92
|
-
model: 'claude-sonnet-4-5',
|
|
93
|
-
messages: [
|
|
94
|
-
{ role: 'system', content: 'You extract structured data from support tickets.' },
|
|
95
|
-
{ role: 'user', content: ticketText },
|
|
96
|
-
],
|
|
97
|
-
responseSchema: {
|
|
98
|
-
type: 'object',
|
|
99
|
-
properties: {
|
|
100
|
-
priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },
|
|
101
|
-
category: { type: 'string', enum: ['billing', 'technical', 'account', 'other'] },
|
|
102
|
-
sentiment: { type: 'string', enum: ['positive', 'neutral', 'negative'] },
|
|
103
|
-
summary: { type: 'string' },
|
|
104
|
-
},
|
|
105
|
-
required: ['priority', 'category', 'sentiment', 'summary'],
|
|
106
|
-
},
|
|
107
|
-
temperature: 0.1,
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
// response.output is typed as TicketClassification
|
|
111
|
-
const { priority, category, summary } = response.output
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Supported providers: `google`, `openai`, `anthropic`, `openrouter`. See [Platform Tools](index.mdx) for the full model list.
|
|
115
|
-
|
|
116
|
-
## Triggering Another Resource
|
|
117
|
-
|
|
118
|
-
Trigger a separate workflow or agent as a nested child execution. The call is synchronous -- your workflow waits for the child to complete and receives its output.
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
import { execution } from '@elevasis/sdk/worker'
|
|
122
|
-
|
|
123
|
-
const outcome = await execution.trigger({
|
|
124
|
-
resourceId: 'send-welcome-sequence',
|
|
125
|
-
input: {
|
|
126
|
-
userId: newUser.id,
|
|
127
|
-
email: newUser.email,
|
|
128
|
-
plan: 'pro',
|
|
129
|
-
},
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
if (!outcome.success) {
|
|
133
|
-
throw new Error(`Child workflow failed: ${outcome.error}`)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// outcome = { success: true, executionId: '...', output: { emailsSent: 3 }, error: undefined }
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
Nested executions are tracked with depth up to a maximum of 5 levels. Both the calling workflow and the child must belong to the same organization.
|
|
140
|
-
|
|
141
|
-
## Uploading to Storage
|
|
142
|
-
|
|
143
|
-
Upload a file to Elevasis-managed storage and generate a signed URL for temporary access. No credential required.
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
import { storage } from '@elevasis/sdk/worker'
|
|
147
|
-
|
|
148
|
-
// Upload a processed file
|
|
149
|
-
const reportPath = `exports/report-${Date.now()}.csv`
|
|
150
|
-
await storage.upload({
|
|
151
|
-
bucket: 'exports',
|
|
152
|
-
path: reportPath,
|
|
153
|
-
content: csvContent,
|
|
154
|
-
contentType: 'text/csv',
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
// Generate a signed URL valid for 1 hour (3600 seconds)
|
|
158
|
-
const { signedUrl } = await storage.createSignedUrl({
|
|
159
|
-
bucket: 'exports',
|
|
160
|
-
path: reportPath,
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
// Share signedUrl with the user or include in an email
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
Storage also supports `download`, `delete`, and `list` operations. Use `list` to enumerate files under a path prefix.
|
|
167
|
-
|
|
168
|
-
---
|
|
169
|
-
|
|
170
|
-
**Last Updated:** 2026-03-02
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Resource Limits & Quotas
|
|
3
|
-
description: Memory limits, execution timeouts, scale quotas, networking constraints, and v1 platform limitations for SDK resources
|
|
4
|
-
loadWhen: "Hitting resource limits or planning for scale"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
This page documents the hard limits enforced on all SDK resources running on the Elevasis platform. These limits exist to ensure platform stability and fair resource usage across all organizations.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Resource Limits
|
|
12
|
-
|
|
13
|
-
Limits enforced per worker thread at runtime:
|
|
14
|
-
|
|
15
|
-
| Resource | Value |
|
|
16
|
-
| -------- | ----- |
|
|
17
|
-
| Memory (V8 heap) | 256MB per worker |
|
|
18
|
-
| Disk | Bundle file only (ephemeral, not persistent across deploys) |
|
|
19
|
-
|
|
20
|
-
- **Memory:** Enforced by the platform. Exceeding 256MB crashes the worker. The platform catches the error; other tenants are unaffected. If your workflow processes large datasets, consider streaming or batching to stay within the limit.
|
|
21
|
-
- **Disk:** Your bundle is written to disk during deploy and available to the worker at execution time. It is not a persistent write surface -- do not write files to disk from within your handler expecting them to persist.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Scale Limits & Quotas
|
|
26
|
-
|
|
27
|
-
Hard limits to prevent abuse and ensure platform stability:
|
|
28
|
-
|
|
29
|
-
| Limit | Value |
|
|
30
|
-
| ----- | ----- |
|
|
31
|
-
| Max execution duration (workflows) | 300s (5 min) |
|
|
32
|
-
| Max execution duration (agents) | 600s (10 min) |
|
|
33
|
-
| Max log volume | 100MB/day |
|
|
34
|
-
| Max deploy frequency | 60/day |
|
|
35
|
-
|
|
36
|
-
- **Execution duration:** Executions exceeding the timeout are terminated by the platform. The execution is marked failed with a timeout reason.
|
|
37
|
-
- **Log volume:** Total log output across all executions is capped at 100MB per day. Logs beyond this threshold may be truncated.
|
|
38
|
-
- **Deploy frequency:** 60 deploys per day is generous for normal development. This limit prevents accidental deploy loops (for example, a CI pipeline misconfigured to deploy on every commit).
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## Networking
|
|
43
|
-
|
|
44
|
-
- **Outbound:** Unrestricted. Your handlers can call any external API (OpenAI, Twilio, Stripe, etc.) from within the worker.
|
|
45
|
-
- **Inbound:** Workers receive input from the platform coordinator via internal message passing -- they are not exposed to the network directly.
|
|
46
|
-
- **No ports:** Workers communicate with the platform via zero-network-overhead message passing. No port allocation occurs.
|
|
47
|
-
- **Isolation:** Workers have no access to other organizations' data or platform credentials by default. Supabase credentials are not present in the worker environment.
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## Platform Maintenance
|
|
52
|
-
|
|
53
|
-
- **Rolling updates:** Platform upgrades re-register all active deployments on startup. No executions are lost.
|
|
54
|
-
- **Node.js updates:** When the server's Node.js version is updated, worker threads pick up the new version on the next execution with no action required from you.
|
|
55
|
-
- **Advance notice:** 24-hour advance notice is provided for breaking maintenance windows. These are rare and reserved for major infrastructure changes.
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## v1 Limitations
|
|
60
|
-
|
|
61
|
-
| Limitation | Reason | Future path |
|
|
62
|
-
| ---------- | ------ | ----------- |
|
|
63
|
-
| **No nested execution from external resources** | External resources cannot call back to the platform's execution coordinator to trigger other resources as sub-executions. | A callback API endpoint that external processes can call to trigger nested executions (requires auth token forwarding). |
|
|
64
|
-
| **No streaming logs** | Execution logs are returned in the response body after completion. There is no real-time SSE streaming from within the worker. | SSE/WebSocket push from external processes to the platform log system. |
|
|
65
|
-
| **Static resource priority conflicts** | If your organization has a static (monorepo) resource with the same ID as a resource in your SDK bundle, the deploy will fail. Static definitions always take priority and cannot be overridden. | Conflict detection is surfaced in the CLI with a clear error message. |
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## Organization Provisioning
|
|
70
|
-
|
|
71
|
-
Organization creation is currently admin-only. If you need a new organization provisioned for SDK access, contact the Elevasis team. Self-serve organization creation and API key generation is on the roadmap.
|
|
72
|
-
|
|
73
|
-
---
|
|
74
|
-
|
|
75
|
-
**Last Updated:** 2026-03-03
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Credential Security"
|
|
3
|
-
description: "Three-layer credential model: platform tools (server-side injection), http tool (arbitrary APIs), getCredential() (explicit opt-in raw access) -- .env scope and security boundaries"
|
|
4
|
-
loadWhen: "Setting up integrations or configuring tool access"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
This reference covers the Elevasis credential security model. Read it when helping a user connect to an external service, set up platform tools, or understand why environment variables are not used in workflows.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## The Core Rule
|
|
12
|
-
|
|
13
|
-
Integration credentials are never stored in `.env` and never available via `process.env` inside worker threads.
|
|
14
|
-
|
|
15
|
-
Credentials live in the platform credential system, created via the command center UI. Worker threads access credentials only through controlled channels: `platform.call()` (server-side injection) or `platform.getCredential()` (explicit opt-in).
|
|
16
|
-
|
|
17
|
-
`.env` contains only `ELEVASIS_API_KEY`, used by the CLI for authentication. It is never uploaded to the platform and never injected into workers.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Three-Layer Model
|
|
22
|
-
|
|
23
|
-
### Layer 1: Platform Tools (Default)
|
|
24
|
-
|
|
25
|
-
All platform tools resolve credentials server-side. The tool dispatcher in the API process looks up the credential by name, injects it into the service call, and returns only the result. Credential values never cross the postMessage boundary into the worker.
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
// Credential 'my-gmail' is resolved server-side -- value never enters worker memory
|
|
29
|
-
const result = await platform.call({
|
|
30
|
-
tool: 'gmail',
|
|
31
|
-
method: 'sendEmail',
|
|
32
|
-
credential: 'my-gmail',
|
|
33
|
-
params: { to: '...', subject: '...', body: '...' },
|
|
34
|
-
})
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
This is the default pattern for all integrations that have a platform adapter (Gmail, Attio, Stripe, Resend, etc.).
|
|
38
|
-
|
|
39
|
-
### Layer 2: HTTP Platform Tool
|
|
40
|
-
|
|
41
|
-
For APIs without a dedicated platform adapter, use the `http` platform tool. Credentials are resolved and injected server-side before the outgoing HTTP request.
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
const result = await platform.call({
|
|
45
|
-
tool: 'http',
|
|
46
|
-
method: 'request',
|
|
47
|
-
credential: 'my-custom-api',
|
|
48
|
-
params: {
|
|
49
|
-
url: 'https://api.example.com/v1/data',
|
|
50
|
-
method: 'GET',
|
|
51
|
-
headers: { 'Content-Type': 'application/json' },
|
|
52
|
-
},
|
|
53
|
-
})
|
|
54
|
-
// result = { status: 200, headers: {...}, body: {...} }
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**Supported credential injection patterns:**
|
|
58
|
-
|
|
59
|
-
| Pattern | Credential Config | How Injected |
|
|
60
|
-
| --- | --- | --- |
|
|
61
|
-
| Bearer token | `{ type: 'bearer', token: 'sk_...' }` | `Authorization: Bearer sk_...` header |
|
|
62
|
-
| API key header | `{ type: 'api-key-header', header: 'X-API-Key', key: 'ak_...' }` | Custom header with key value |
|
|
63
|
-
| Basic auth | `{ type: 'basic', username: '...', password: '...' }` | `Authorization: Basic base64(user:pass)` header |
|
|
64
|
-
| Query parameter | `{ type: 'query-param', param: 'api_key', value: 'ak_...' }` | Appended to URL query string |
|
|
65
|
-
| Body field | `{ type: 'body-field', field: 'apiKey', value: 'ak_...' }` | Merged into JSON request body |
|
|
66
|
-
| Custom header | `{ type: 'custom-header', header: 'X-Custom', value: '...' }` | Arbitrary header with value |
|
|
67
|
-
|
|
68
|
-
The credential type is selected when creating the credential in the command center UI.
|
|
69
|
-
|
|
70
|
-
### Layer 3: getCredential() (Explicit Opt-In)
|
|
71
|
-
|
|
72
|
-
For cases where a third-party SDK must be initialized with a raw key (e.g., `new Stripe(key)`), use `platform.getCredential()`. This is an explicit opt-in that causes the credential value to enter worker memory.
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
import { platform } from '@elevasis/sdk/worker'
|
|
76
|
-
|
|
77
|
-
// Explicit opt-in -- secret enters worker memory for duration of execution
|
|
78
|
-
const cred = await platform.getCredential('my-stripe-key')
|
|
79
|
-
const stripe = new Stripe(cred.credentials.secretKey)
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
`getCredential()` returns `{ provider: string, credentials: Record<string, string> }`. The fields in `credentials` depend on the credential type stored in the command center.
|
|
83
|
-
|
|
84
|
-
**Security guardrails:**
|
|
85
|
-
|
|
86
|
-
- All `getCredential()` calls are logged with credential name, deployment ID, and execution ID
|
|
87
|
-
- Workers are ephemeral (destroyed after each execution) -- no credential persistence
|
|
88
|
-
- Use `platform.call()` with the `http` tool instead when possible
|
|
89
|
-
|
|
90
|
-
---
|
|
91
|
-
|
|
92
|
-
## Credential Setup
|
|
93
|
-
|
|
94
|
-
Credentials are created in the command center UI:
|
|
95
|
-
|
|
96
|
-
1. Open the Elevasis command center
|
|
97
|
-
2. Navigate to Credentials
|
|
98
|
-
3. Click "Add Credential"
|
|
99
|
-
4. Enter a name (e.g., `my-gmail`, `production-attio`, `custom-api`)
|
|
100
|
-
5. Select the credential type (bearer, api-key-header, basic, etc.)
|
|
101
|
-
6. Enter the secret values
|
|
102
|
-
7. Save
|
|
103
|
-
|
|
104
|
-
The credential name is what you pass as `credential: 'my-gmail'` in `platform.call()`.
|
|
105
|
-
|
|
106
|
-
Credential names are case-sensitive. A mismatch causes a `PlatformToolError` with the message "credential not found."
|
|
107
|
-
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
## .env Scope
|
|
111
|
-
|
|
112
|
-
`.env` in your workspace contains only:
|
|
113
|
-
|
|
114
|
-
```
|
|
115
|
-
ELEVASIS_API_KEY=sk_your_key_here
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
This key authenticates CLI operations (`elevasis-sdk deploy`, `elevasis-sdk check`, `elevasis-sdk exec`). It is never uploaded to the platform and never injected into workers.
|
|
119
|
-
|
|
120
|
-
Do not put integration API keys in `.env`. They will not be available inside workflows.
|
|
121
|
-
|
|
122
|
-
---
|
|
123
|
-
|
|
124
|
-
## Choosing a Credential Pattern
|
|
125
|
-
|
|
126
|
-
| Situation | Pattern |
|
|
127
|
-
| --- | --- |
|
|
128
|
-
| Using a supported platform tool (Gmail, Attio, Stripe, etc.) | `platform.call()` with the tool name |
|
|
129
|
-
| Calling an API not in the tool catalog | `platform.call()` with `tool: 'http'` |
|
|
130
|
-
| Third-party SDK that requires a raw key | `platform.getCredential()` |
|
|
131
|
-
| CLI authentication | `ELEVASIS_API_KEY` in `.env` only |
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
## Migrating from elevasis-sdk env
|
|
136
|
-
|
|
137
|
-
If you previously set integration credentials via `elevasis-sdk env set`, that command no longer exists. Use `elevasis-sdk env list` to see what was set, then recreate each entry as a platform credential in the command center. Update workflow code from `process.env.KEY` to `platform.call({ tool: 'http', credential: '...', ... })` or `platform.getCredential('...')`, then redeploy. The `.env` file remains but is scoped to `ELEVASIS_API_KEY` only.
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
**Last Updated:** 2026-02-26
|
|
File without changes
|
|
File without changes
|
|
File without changes
|