@elevasis/sdk 1.44.2 → 1.45.0
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 +1001 -652
- package/dist/index.d.ts +1045 -509
- package/dist/index.js +748 -690
- package/dist/node/index.d.ts +105 -97
- package/dist/test-utils/index.d.ts +42 -28
- package/dist/test-utils/index.js +549 -732
- package/dist/worker/index.d.ts +12112 -0
- package/dist/worker/index.js +211 -186
- package/package.json +6 -9
- package/reference/_navigation.md +151 -21
- package/reference/_reference-manifest.json +186 -4
- package/reference/claude-config.md +8 -0
- package/reference/core/index.mdx +3 -3
- package/reference/examples/organization-model.ts +117 -111
- package/reference/index.mdx +4 -4
- package/reference/rules/active-change-index.md +40 -54
- package/reference/rules/agent-runtime.md +81 -0
- package/reference/rules/agent-start-here.md +71 -163
- package/reference/rules/deployment.md +33 -10
- package/reference/rules/error-handling.md +26 -0
- package/reference/rules/execution.md +13 -0
- package/reference/rules/frontend.md +10 -3
- package/reference/rules/observability.md +9 -1
- package/reference/rules/operations.md +26 -17
- package/reference/rules/organization-model.md +74 -88
- package/reference/rules/organization-os.md +71 -88
- package/reference/rules/package-taxonomy.md +11 -2
- package/reference/rules/platform.md +13 -7
- package/reference/rules/shared-types.md +15 -0
- package/reference/rules/task-tracking.md +30 -5
- package/reference/rules/ui.md +145 -3
- package/reference/rules/vibe-intents.md +271 -0
- package/reference/rules/vibe.md +17 -243
- package/reference/scaffold/core/organization-graph.mdx +111 -97
- package/reference/scaffold/core/organization-model.mdx +234 -214
- package/reference/scaffold/operations/propagation-pipeline.md +1 -1
- package/reference/scaffold/operations/scaffold-maintenance.md +19 -18
- package/reference/scaffold/operations/workflow-recipes.md +71 -19
- package/reference/scaffold/recipes/add-a-feature.md +156 -146
- package/reference/scaffold/recipes/add-a-resource.md +123 -117
- package/reference/scaffold/recipes/customize-crm-actions.md +25 -10
- package/reference/scaffold/recipes/customize-knowledge-browser.md +52 -117
- package/reference/scaffold/recipes/customize-organization-model.md +161 -149
- package/reference/scaffold/recipes/extend-a-base-entity.md +156 -140
- package/reference/scaffold/recipes/extend-crm.md +16 -11
- package/reference/scaffold/recipes/extend-lead-gen.md +25 -7
- package/reference/scaffold/recipes/gate-by-feature-or-admin.md +160 -118
- package/reference/scaffold/recipes/index.md +2 -2
- package/reference/scaffold/recipes/query-the-knowledge-graph.md +23 -23
- package/reference/scaffold/reference/contracts.md +12 -1
- package/reference/scaffold/reference/glossary.md +3 -3
- package/reference/scaffold/reference/system-interface-capabilities.md +5 -4
- package/reference/scaffold/ui/composition-extensibility.mdx +271 -232
- package/reference/scaffold/ui/feature-flags-and-gating.md +14 -6
- package/reference/scaffold/ui/feature-shell.mdx +279 -62
- package/reference/scaffold/ui/recipes.md +229 -197
- package/reference/sdk/cli-management.mdx +77 -29
- package/reference/sdk/concepts.mdx +2 -0
- package/reference/sdk/define-builders.mdx +76 -0
- package/reference/sdk/deployment/command-center.mdx +6 -2
- package/reference/sdk/deployment/execution-reference.mdx +64 -186
- package/reference/sdk/deployment/index.mdx +2 -0
- package/reference/sdk/exports.mdx +4 -4
- package/reference/sdk/framework/agent.mdx +49 -119
- package/reference/sdk/framework/index.mdx +46 -65
- package/reference/sdk/framework/project-structure.mdx +150 -205
- package/reference/sdk/framework/tutorial-system.mdx +2 -2
- package/reference/sdk/human-in-the-loop.mdx +152 -0
- package/reference/sdk/index.mdx +6 -7
- package/reference/sdk/platform-tools/index.mdx +12 -0
- package/reference/sdk/platform-tools/type-safety.mdx +4 -0
- package/reference/sdk/project-deployment-spec.mdx +131 -0
- package/reference/sdk/resources/index.mdx +23 -7
- package/reference/sdk/resources/patterns.mdx +54 -24
- package/reference/sdk/resources/types.mdx +7 -4
- package/reference/sdk/templates/data-enrichment.mdx +7 -3
- package/reference/sdk/templates/email-sender.mdx +139 -135
- package/reference/sdk/templates/lead-scorer.mdx +5 -1
- package/reference/sdk/templates/pdf-generator.mdx +155 -151
- package/reference/sdk/templates/recurring-job.mdx +195 -189
- package/reference/sdk/templates/text-classifier.mdx +4 -0
- package/reference/sdk/templates/web-scraper.mdx +139 -135
- package/reference/spine/spine-primer.md +135 -96
- package/reference/ui/index.mdx +14 -7
- package/dist/types/worker/adapters/anymailfinder.d.ts +0 -14
- package/dist/types/worker/adapters/apify.d.ts +0 -14
- package/dist/types/worker/adapters/approval.d.ts +0 -23
- package/dist/types/worker/adapters/attio.d.ts +0 -22
- package/dist/types/worker/adapters/clickup.d.ts +0 -22
- package/dist/types/worker/adapters/create-adapter.d.ts +0 -41
- package/dist/types/worker/adapters/crm.d.ts +0 -20
- package/dist/types/worker/adapters/dropbox.d.ts +0 -14
- package/dist/types/worker/adapters/email.d.ts +0 -25
- package/dist/types/worker/adapters/execution.d.ts +0 -22
- package/dist/types/worker/adapters/gmail.d.ts +0 -14
- package/dist/types/worker/adapters/google-sheets.d.ts +0 -14
- package/dist/types/worker/adapters/index.d.ts +0 -33
- package/dist/types/worker/adapters/instantly.d.ts +0 -14
- package/dist/types/worker/adapters/lead.d.ts +0 -28
- package/dist/types/worker/adapters/list.d.ts +0 -9
- package/dist/types/worker/adapters/llm.d.ts +0 -45
- package/dist/types/worker/adapters/millionverifier.d.ts +0 -14
- package/dist/types/worker/adapters/notification.d.ts +0 -28
- package/dist/types/worker/adapters/pdf.d.ts +0 -22
- package/dist/types/worker/adapters/projects.d.ts +0 -20
- package/dist/types/worker/adapters/resend.d.ts +0 -14
- package/dist/types/worker/adapters/scheduler.d.ts +0 -25
- package/dist/types/worker/adapters/signature-api.d.ts +0 -14
- package/dist/types/worker/adapters/storage.d.ts +0 -33
- package/dist/types/worker/adapters/stripe.d.ts +0 -14
- package/dist/types/worker/adapters/tomba.d.ts +0 -14
- package/dist/types/worker/index.d.ts +0 -60
- package/dist/types/worker/platform.d.ts +0 -90
- package/dist/types/worker/utils.d.ts +0 -9
- package/reference/claude-config/Overview.md +0 -230
- package/reference/claude-config/hooks/post-edit-validate.mjs +0 -98
- package/reference/claude-config/hooks/scaffold-registry-reminder.mjs +0 -187
- package/reference/claude-config/hooks/tool-failure-recovery.mjs +0 -73
- package/reference/claude-config/registries/graph-skills.json +0 -4
- package/reference/claude-config/registries/knowledge-flags.json +0 -154
- package/reference/claude-config/registries/skill-coverage.json +0 -20
- package/reference/claude-config/rules/active-change-index.md +0 -22
- package/reference/claude-config/rules/agent-start-here.md +0 -22
- package/reference/claude-config/rules/deployment.md +0 -22
- package/reference/claude-config/rules/error-handling.md +0 -22
- package/reference/claude-config/rules/execution.md +0 -22
- package/reference/claude-config/rules/frontend.md +0 -22
- package/reference/claude-config/rules/observability.md +0 -22
- package/reference/claude-config/rules/operations.md +0 -22
- package/reference/claude-config/rules/organization-model.md +0 -22
- package/reference/claude-config/rules/organization-os.md +0 -22
- package/reference/claude-config/rules/package-taxonomy.md +0 -22
- package/reference/claude-config/rules/platform.md +0 -22
- package/reference/claude-config/rules/shared-types.md +0 -22
- package/reference/claude-config/rules/task-tracking.md +0 -22
- package/reference/claude-config/rules/topbar-actions.md +0 -70
- package/reference/claude-config/rules/ui.md +0 -22
- package/reference/claude-config/rules/vibe.md +0 -22
- package/reference/claude-config/scripts/statusline-command.js +0 -18
- package/reference/claude-config/settings.json +0 -30
- package/reference/claude-config/skills/client/SKILL.md +0 -201
- package/reference/claude-config/skills/deploy/SKILL.md +0 -159
- package/reference/claude-config/skills/dsp/SKILL.md +0 -66
- package/reference/claude-config/skills/elevasis/SKILL.md +0 -251
- package/reference/claude-config/skills/explore/SKILL.md +0 -78
- package/reference/claude-config/skills/git-sync/SKILL.md +0 -166
- package/reference/claude-config/skills/om/SKILL.md +0 -475
- package/reference/claude-config/skills/om/operations/build.md +0 -237
- package/reference/claude-config/skills/om/operations/codify-level-a.md +0 -109
- package/reference/claude-config/skills/om/operations/codify-level-b.md +0 -159
- package/reference/claude-config/skills/om/operations/customers.md +0 -114
- package/reference/claude-config/skills/om/operations/features.md +0 -88
- package/reference/claude-config/skills/om/operations/goals.md +0 -123
- package/reference/claude-config/skills/om/operations/identity.md +0 -97
- package/reference/claude-config/skills/om/operations/labels.md +0 -110
- package/reference/claude-config/skills/om/operations/offerings.md +0 -114
- package/reference/claude-config/skills/om/operations/roles.md +0 -104
- package/reference/claude-config/skills/om/operations/scaffold.md +0 -163
- package/reference/claude-config/skills/om/operations/techStack.md +0 -38
- package/reference/claude-config/skills/project/SKILL.md +0 -1114
- package/reference/claude-config/skills/run-ui/SKILL.md +0 -73
- package/reference/claude-config/skills/save/SKILL.md +0 -183
- package/reference/claude-config/skills/setup/SKILL.md +0 -290
- package/reference/claude-config/skills/status/SKILL.md +0 -59
- package/reference/claude-config/skills/submit-request/SKILL.md +0 -180
- package/reference/claude-config/skills/sync/SKILL.md +0 -47
- package/reference/claude-config/skills/tutorial/SKILL.md +0 -259
- package/reference/claude-config/skills/tutorial/progress-template.md +0 -74
- package/reference/claude-config/skills/tutorial/technical.md +0 -1303
- package/reference/claude-config/skills/tutorial/vibe-coder.md +0 -890
- package/reference/claude-config/sync-notes/2026-04-22-git-sync-and-sync-notes.md +0 -27
- package/reference/claude-config/sync-notes/2026-04-22-lead-gen-deliverability-removal.md +0 -30
- package/reference/claude-config/sync-notes/2026-04-24-test-utils-and-template-tests.md +0 -73
- package/reference/claude-config/sync-notes/2026-04-24-ui-consolidation-and-sdk-cli-train.md +0 -86
- package/reference/claude-config/sync-notes/2026-04-25-auth-role-system-and-settings-roles.md +0 -55
- package/reference/claude-config/sync-notes/2026-04-27-crm-hitl-action-layer-cutover.md +0 -97
- package/reference/claude-config/sync-notes/2026-04-27-lead-gen-substrate-train.md +0 -112
- package/reference/claude-config/sync-notes/2026-04-29-crm-state-and-lead-gen-processing-status.md +0 -93
- package/reference/claude-config/sync-notes/2026-05-02-crm-ownership-next-action.md +0 -58
- package/reference/claude-config/sync-notes/2026-05-02-template-hardcode-workos-config.md +0 -56
- package/reference/claude-config/sync-notes/2026-05-04-elevasis-workspace.md +0 -71
- package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +0 -83
- package/reference/claude-config/sync-notes/2026-05-04-template-skills-run-ui-and-tutorial.md +0 -59
- package/reference/claude-config/sync-notes/2026-05-05-list-builder.md +0 -42
- package/reference/claude-config/sync-notes/2026-05-06-crm-spine.md +0 -60
- package/reference/claude-config/sync-notes/2026-05-06-sdk-changes-release-train.md +0 -37
- package/reference/claude-config/sync-notes/2026-05-07-sdk-changes-release-train.md +0 -34
- package/reference/claude-config/sync-notes/2026-05-08-resource-governance-scaffold-guidance.md +0 -38
- package/reference/claude-config/sync-notes/2026-05-09-clients-domain.md +0 -32
- package/reference/claude-config/sync-notes/2026-05-09-command-system.md +0 -33
- package/reference/claude-config/sync-notes/2026-05-09-resource-governance-and-misc.md +0 -69
- package/reference/claude-config/sync-notes/2026-05-12-sdk-ready-release-train.md +0 -30
- package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +0 -45
- package/reference/claude-config/sync-notes/2026-05-15-om-skill-rename-and-write-family.md +0 -52
- package/reference/claude-config/sync-notes/2026-05-17-sdk-boundary-consolidation.md +0 -33
- package/reference/claude-config/sync-notes/2026-05-20-om-define-helpers.md +0 -32
- package/reference/claude-config/sync-notes/2026-05-22-access-model-and-right-panel.md +0 -43
- package/reference/claude-config/sync-notes/2026-05-22-lead-gen-tenant-config.md +0 -40
- package/reference/claude-config/sync-notes/2026-05-22-org-model-multi-file-split.md +0 -61
- package/reference/claude-config/sync-notes/2026-05-23-branding-names-to-identity.md +0 -49
- package/reference/claude-config/sync-notes/2026-05-23-lead-gen-manage-access.md +0 -31
- package/reference/claude-config/sync-notes/2026-05-23-om-deployment-drift-detection.md +0 -42
- package/reference/claude-config/sync-notes/2026-05-23-om-full-model-deploy-contract.md +0 -33
- package/reference/claude-config/sync-notes/2026-05-23-ui-sdk-package-fixes.md +0 -37
- package/reference/claude-config/sync-notes/2026-05-24-platform-invite-router-core-baseline.md +0 -28
- package/reference/claude-config/sync-notes/2026-05-24-system-interface-readiness.md +0 -43
- package/reference/claude-config/sync-notes/2026-05-25-invitation-login-loader.md +0 -26
- package/reference/claude-config/sync-notes/2026-05-25-om-topbar-requests.md +0 -33
- package/reference/claude-config/sync-notes/2026-05-25-system-interface-profile-registry-and-substrate.md +0 -35
- package/reference/claude-config/sync-notes/2026-05-25-tenant-om-scaffold-cli.md +0 -49
- package/reference/claude-config/sync-notes/2026-05-25-vibe-operate-intent.md +0 -47
- package/reference/claude-config/sync-notes/2026-05-28-om-snapshot-sdk-workflow-config.md +0 -33
- package/reference/claude-config/sync-notes/2026-05-30-client-source-and-om-profiles.md +0 -39
- package/reference/claude-config/sync-notes/2026-06-02-knowledge-nested-group-routing.md +0 -27
- package/reference/claude-config/sync-notes/2026-06-02-nest-projects-under-platform.md +0 -45
- package/reference/claude-config/sync-notes/2026-06-03-skill-autogen-and-client-skill.md +0 -34
- package/reference/claude-config/sync-notes/2026-06-04-scaffold-registry-lane-severity.md +0 -34
- package/reference/claude-config/sync-notes/2026-06-05-appearance-app-mode-decouple.md +0 -29
- package/reference/claude-config/sync-notes/2026-06-05-ontology-endpoint-rename-and-knowledge-browser-ui.md +0 -86
- package/reference/claude-config/sync-notes/2026-06-06-om-build-systems-scaffold.md +0 -47
- package/reference/claude-config/sync-notes/2026-06-06-om-item-copy-references.md +0 -50
- package/reference/claude-config/sync-notes/2026-06-08-knowledge-base-page-not-found-fix.md +0 -76
- package/reference/claude-config/sync-notes/2026-06-09-agent-sessions-public-agent-chat-route.md +0 -75
- package/reference/claude-config/sync-notes/2026-06-09-sdk-cli-load-org-model-resolution.md +0 -42
- package/reference/claude-config/sync-notes/2026-06-12-agent-grants-visualizer-operations.md +0 -30
- package/reference/claude-config/sync-notes/2026-06-14-session-ux-and-project-cli-json.md +0 -33
- package/reference/claude-config/sync-notes/2026-06-14-shared-session-conversation-view.md +0 -26
- package/reference/claude-config/sync-notes/2026-06-15-session-chat-zero-wiring.md +0 -46
- package/reference/claude-config/sync-notes/2026-06-17-agent-session-ux-features.md +0 -34
- package/reference/claude-config/sync-notes/2026-06-25-shared-page-scroll-contract-guard.md +0 -52
- package/reference/claude-config/sync-notes/2026-06-26-leadgen-overview-om-telemetry.md +0 -47
- package/reference/claude-config/sync-notes/2026-07-21-agent-scaffold-hardening.md +0 -75
- package/reference/claude-config/sync-notes/2026-07-23-agent-session-memory.md +0 -49
- package/reference/claude-config/sync-notes/2026-07-23-workos-org-marker.md +0 -50
- package/reference/claude-config/sync-notes/2026-07-24-claude-5-models-and-session-surface-fixes.md +0 -116
- package/reference/claude-config/sync-notes/2026-07-27-agent-strict-output-and-turn-drift.md +0 -73
- package/reference/claude-config/sync-notes/2026-07-28-agent-reply-is-its-own-field.md +0 -84
- package/reference/claude-config/sync-notes/2026-07-30-login-screen-and-member-provisioning-state.md +0 -114
- package/reference/claude-config/sync-notes/2026-08-02-auth-guard-defaults-and-truncation-fix.md +0 -122
- package/reference/claude-config/sync-notes/2026-08-03-cli-gateway-errors-and-request-timeout.md +0 -120
- package/reference/claude-config/sync-notes/README.md +0 -43
- package/reference/sdk/framework/interaction-guidance.mdx +0 -182
- package/reference/sdk/framework/memory.mdx +0 -326
- package/reference/sdk/framework/resource-documentation.mdx +0 -90
- package/reference/sdk/roadmap.mdx +0 -164
package/reference/sdk/index.mdx
CHANGED
|
@@ -48,6 +48,9 @@ See [Platform Tools](platform-tools/index.mdx) for the full catalog, adapter ref
|
|
|
48
48
|
- [Resources](resources/index.mdx) - Workflow and agent definition patterns, Zod schemas, step types, and routing
|
|
49
49
|
- [Platform Tools](platform-tools/index.mdx) - Full catalog of 25 adapters (13 integration + 12 platform), integration adapters, and credential management
|
|
50
50
|
- [Credential Security](platform-tools/index.mdx#credential-security) - Three-layer credential model, HTTP tool patterns, and credential management
|
|
51
|
+
- [Human-in-the-Loop Workflows](human-in-the-loop.mdx) - The full HITL story: approval adapter, checkpoint metadata, and queue resolution
|
|
52
|
+
- [The Deployment Spec Pattern](project-deployment-spec.mdx) - projectDeploymentSpec and defineWorkflowConfig, the shape the template actually ships
|
|
53
|
+
- [When to Reach for the define\* Builders](define-builders.mdx) - Judgment guide for defineWorkflow, defineResource, defineTopology, and friends
|
|
51
54
|
|
|
52
55
|
### Reference
|
|
53
56
|
|
|
@@ -65,13 +68,10 @@ See [Platform Tools](platform-tools/index.mdx) for the full catalog, adapter ref
|
|
|
65
68
|
|
|
66
69
|
### Framework
|
|
67
70
|
|
|
68
|
-
- [Development Framework](framework/index.mdx) - How Claude Code helps you build: project structure, agent integration,
|
|
71
|
+
- [Development Framework](framework/index.mdx) - How Claude Code helps you build: project structure, agent integration, and the skill surface
|
|
69
72
|
- [Project Structure](framework/project-structure.mdx) - Scaffolded file layout, domain barrels, src/index.ts entry point, and config files
|
|
70
|
-
- [Agent Configuration](framework/agent.mdx) -
|
|
71
|
-
- [
|
|
72
|
-
- [Interaction Guidance](framework/interaction-guidance.mdx) - Skill dimension adaptation rules for platform navigation, API integration, and automation concepts
|
|
73
|
-
- [Tutorial System](framework/tutorial-system.mdx) - Two-track onboarding (8 vibe-coder + 19 technical lessons), skill-adaptive lesson variants, progress tracking, and module contents
|
|
74
|
-
- [Resource Documentation](framework/resource-documentation.mdx) - Docs directory structure, frontmatter schema, size limits, deploy behavior, and /docs command reference
|
|
73
|
+
- [Agent Configuration](framework/agent.mdx) - The shipped skill inventory, project context via `project:*`, upgrades via `/git-sync`, and the ambient vibe layer
|
|
74
|
+
- [Tutorial System](framework/tutorial-system.mdx) - Two-track onboarding: 8 vibe-coder lessons and 19 technical lessons across 5 sections, with track choice persisted to `profile.md`
|
|
75
75
|
|
|
76
76
|
### Resources Subpages
|
|
77
77
|
|
|
@@ -87,7 +87,6 @@ See [Platform Tools](platform-tools/index.mdx) for the full catalog, adapter ref
|
|
|
87
87
|
|
|
88
88
|
- [Export Catalog](exports.mdx) - Auto-generated catalog of all published @elevasis/sdk subpath exports
|
|
89
89
|
- [Troubleshooting](troubleshooting.mdx) - Static error catalog for CLI, deployment, schema, and runtime failures
|
|
90
|
-
- [Roadmap](roadmap.mdx) - Planned features including error taxonomy, retry semantics, circuit breaker, and metrics
|
|
91
90
|
|
|
92
91
|
---
|
|
93
92
|
|
|
@@ -11,6 +11,8 @@ Your SDK workflows have access to 25 adapters (13 integration + 12 platform) --
|
|
|
11
11
|
|
|
12
12
|
**Preferred: Typed adapters** (available for all integration tools + key platform services)
|
|
13
13
|
|
|
14
|
+
{/* doc-snippet:skip: illustrative excerpt with `...` elisions, not a standalone compilable file */}
|
|
15
|
+
|
|
14
16
|
```typescript
|
|
15
17
|
import { createResendAdapter, scheduler, llm } from '@elevasis/sdk/worker'
|
|
16
18
|
|
|
@@ -25,6 +27,8 @@ const result = await llm.generate({ messages: [...] })
|
|
|
25
27
|
|
|
26
28
|
**Fallback: `platform.call()`** (for tools without typed adapters)
|
|
27
29
|
|
|
30
|
+
{/* doc-snippet:skip: illustrative excerpt with `...` elisions, not a standalone compilable file */}
|
|
31
|
+
|
|
28
32
|
```typescript
|
|
29
33
|
import { platform } from '@elevasis/sdk/worker'
|
|
30
34
|
|
|
@@ -51,6 +55,8 @@ Integration credentials are never stored in `.env` and never available via `proc
|
|
|
51
55
|
|
|
52
56
|
All platform tools resolve credentials server-side. The credential value never crosses the postMessage boundary into the worker.
|
|
53
57
|
|
|
58
|
+
{/* doc-snippet:skip: continues from the `import { platform } from '@elevasis/sdk/worker'` shown in Usage above */}
|
|
59
|
+
|
|
54
60
|
```typescript
|
|
55
61
|
// Credential 'my-gmail' is resolved server-side -- value never enters worker memory
|
|
56
62
|
const result = await platform.call({
|
|
@@ -65,6 +71,8 @@ const result = await platform.call({
|
|
|
65
71
|
|
|
66
72
|
For APIs without a dedicated adapter, use the `http` platform tool. Credentials are injected server-side before the outgoing request.
|
|
67
73
|
|
|
74
|
+
{/* doc-snippet:skip: continues from the `import { platform } from '@elevasis/sdk/worker'` shown in Usage above */}
|
|
75
|
+
|
|
68
76
|
```typescript
|
|
69
77
|
const result = await platform.call({
|
|
70
78
|
tool: 'http',
|
|
@@ -93,6 +101,8 @@ const result = await platform.call({
|
|
|
93
101
|
|
|
94
102
|
For third-party SDKs that require a raw key (e.g., `new Stripe(key)`), use `platform.getCredential()`. This explicitly causes the credential value to enter worker memory.
|
|
95
103
|
|
|
104
|
+
{/* doc-snippet:skip: illustrative composition with the third-party `stripe` npm package -- that package is not installed in this doc-check project and is not an @elevasis import */}
|
|
105
|
+
|
|
96
106
|
```typescript
|
|
97
107
|
import { platform } from '@elevasis/sdk/worker'
|
|
98
108
|
|
|
@@ -152,6 +162,8 @@ Supabase is a first-class integration adapter for persistent storage. Pass the `
|
|
|
152
162
|
|
|
153
163
|
**Methods:** `insert`, `select`, `update`, `delete`, `upsert`, `rpc`, `count`
|
|
154
164
|
|
|
165
|
+
{/* doc-snippet:skip: continues from the `import { platform } from '@elevasis/sdk/worker'` shown in Usage above */}
|
|
166
|
+
|
|
155
167
|
```typescript
|
|
156
168
|
const qualified = await platform.call({
|
|
157
169
|
tool: 'supabase',
|
|
@@ -15,6 +15,8 @@ The approach: tighten types where misconfiguration is a realistic foot-gun, and
|
|
|
15
15
|
|
|
16
16
|
`provider` and `model` are required on `SDKLLMGenerateParams` in `packages/sdk/src/worker/adapters/llm.ts`. They were previously optional because the server-side `modelConfig` fallback in `tool-dispatcher.ts` would fill them in -- but that fallback is a foot-gun, not a feature. Omitting them silently selects a default model that may not be appropriate for the call site.
|
|
17
17
|
|
|
18
|
+
{/* doc-snippet:skip: illustrative excerpt with `...` elisions, not a standalone compilable file */}
|
|
19
|
+
|
|
18
20
|
```typescript
|
|
19
21
|
// Required -- both fields must be specified inline
|
|
20
22
|
await llm.generate({
|
|
@@ -54,6 +56,8 @@ The `never` pattern on sibling fields causes TypeScript to error if you pass two
|
|
|
54
56
|
|
|
55
57
|
`ApprovalToolMap.create.params` uses `context: Record<string, unknown>` instead of `context: unknown`. This prevents passing primitives (strings, numbers) as context -- approval tasks always expect a structured key-value object.
|
|
56
58
|
|
|
59
|
+
{/* doc-snippet:skip: illustrative excerpt with `...` elisions, not a standalone compilable file */}
|
|
60
|
+
|
|
57
61
|
```typescript
|
|
58
62
|
// Correct
|
|
59
63
|
await approval.create({
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: The Deployment Spec Pattern
|
|
3
|
+
description: How projectDeploymentSpec and defineWorkflowConfig assemble the DeploymentSpec a scaffolded project actually ships, using operations/src/index.ts as the reference.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
[Resources](resources/index.mdx#deploymentspec) shows the minimal shape of a `DeploymentSpec`: a hand-built object literal with `version`, `organizationModel`, `workflows`, and `agents`. That shape type-checks, but it is not what a scaffolded project ships. The real `operations/src/index.ts` -- the file every agent is pointed at to register a new resource -- is built on two exports this bundle otherwise only mentions in passing: `projectDeploymentSpec` and `defineWorkflowConfig`. This page teaches that shape, using the shipped file as the reference point.
|
|
7
|
+
|
|
8
|
+
## The Real File
|
|
9
|
+
|
|
10
|
+
`external/_template/operations/src/index.ts` (the file `pnpm dlx @elevasis/sdk init` scaffolds for you) looks like this, trimmed to the parts that matter:
|
|
11
|
+
|
|
12
|
+
{/* doc-snippet:skip: real-file excerpt with project-local path aliases, not a standalone compilable file */}
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
import { projectDeploymentSpec, type DeploymentSpec } from '@elevasis/sdk'
|
|
16
|
+
import {
|
|
17
|
+
canonicalOrganizationModel,
|
|
18
|
+
getTemplateAgentResourceDescriptor,
|
|
19
|
+
getTemplateWorkflowResourceDescriptor
|
|
20
|
+
} from '@core/config/organization-model'
|
|
21
|
+
import * as example from './example/index.js'
|
|
22
|
+
import * as emailNotification from './email-notification/exports.js'
|
|
23
|
+
import { triggers, integrations, humanCheckpoints } from './metadata.js'
|
|
24
|
+
|
|
25
|
+
function getTemplateIntegrationResourceDescriptor(resourceId: string): never {
|
|
26
|
+
throw new Error(`No integration OM Resource descriptor for "${resourceId}".`)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type TemplateDeploymentSpec = DeploymentSpec & {
|
|
30
|
+
organizationModel: typeof canonicalOrganizationModel
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const deploymentSpec: TemplateDeploymentSpec = {
|
|
34
|
+
...projectDeploymentSpec({
|
|
35
|
+
version: '0.1.0',
|
|
36
|
+
organizationModel: canonicalOrganizationModel,
|
|
37
|
+
workflows: [...example.workflows, ...emailNotification.workflows],
|
|
38
|
+
agents: [...example.agents, ...emailNotification.agents],
|
|
39
|
+
triggers,
|
|
40
|
+
integrations,
|
|
41
|
+
humanCheckpoints,
|
|
42
|
+
getWorkflowResourceDescriptor: getTemplateWorkflowResourceDescriptor,
|
|
43
|
+
getAgentResourceDescriptor: getTemplateAgentResourceDescriptor,
|
|
44
|
+
getIntegrationResourceDescriptor: getTemplateIntegrationResourceDescriptor
|
|
45
|
+
}),
|
|
46
|
+
organizationModel: canonicalOrganizationModel
|
|
47
|
+
}
|
|
48
|
+
export default deploymentSpec
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Four things are doing work here that the minimal literal example does not show: `projectDeploymentSpec` itself, the descriptor resolver functions passed into it, the feature-group `exports.ts` files being spread into `workflows`/`agents`, and `metadata.ts` supplying `triggers`/`integrations`/`humanCheckpoints`. Each is below.
|
|
52
|
+
|
|
53
|
+
## `projectDeploymentSpec`: What It Actually Does
|
|
54
|
+
|
|
55
|
+
`projectDeploymentSpec` takes your bare `WorkflowDefinition[]` / `AgentDefinition[]` / `IntegrationDefinition[]` arrays and, for every entry, injects `config.resource`, `config.resourceId`, and `config.type` from the matching Organization Model resource descriptor -- looked up through the resolver functions you pass in. You never write those three fields into a workflow's `config` by hand under this pattern; the workflow file only needs a `resourceId` that exists in the OM.
|
|
56
|
+
|
|
57
|
+
It also computes `relationships` for you, by projecting `organizationModel.topology.relationships` into the `triggers` / `uses` edges the Command Center graph reads. The minimal `DeploymentSpec` recipe has you author `relationships` manually; under `projectDeploymentSpec`, that field is derived, not authored -- edit topology in the OM (via `/om`) rather than adding a `relationships` entry to `index.ts` by hand.
|
|
58
|
+
|
|
59
|
+
The three resolver functions are required or optional depending on what you're deploying:
|
|
60
|
+
|
|
61
|
+
- `getWorkflowResourceDescriptor` -- required. Looks up a workflow's `resourceId` in the OM `resources` map and throws if it is missing or not `kind: 'workflow'`.
|
|
62
|
+
- `getIntegrationResourceDescriptor` -- required by the function signature, even if you have zero integrations. The template satisfies this with a function that always throws, since `integrations` starts empty -- it is never invoked while the array stays empty, and it fails loudly the moment someone wires an integration without first adding its OM descriptor.
|
|
63
|
+
- `getAgentResourceDescriptor` -- optional. Omit it and your `agents` array passes through unresolved.
|
|
64
|
+
|
|
65
|
+
These resolvers are why a workflow you write must have a matching OM resource descriptor before it deploys -- `projectDeploymentSpec` is the point where that requirement is enforced, not a validation step bolted on afterward.
|
|
66
|
+
|
|
67
|
+
## Feature-Group Exports
|
|
68
|
+
|
|
69
|
+
Each feature folder under `operations/src/` owns an `exports.ts` (or, for a single-workflow group, folds the same two arrays into its `index.ts`) that lists its own workflows and agents:
|
|
70
|
+
|
|
71
|
+
{/* doc-snippet:skip: real-file excerpt with a relative import, not a standalone compilable file */}
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// email-notification/exports.ts
|
|
75
|
+
import { emailNotification } from './index.js'
|
|
76
|
+
import type { WorkflowDefinition } from '@elevasis/sdk'
|
|
77
|
+
|
|
78
|
+
export const workflows: WorkflowDefinition[] = [emailNotification]
|
|
79
|
+
export const agents: never[] = []
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`index.ts` at the project root spreads every group's arrays together: `workflows: [...example.workflows, ...emailNotification.workflows]`. Adding a new workflow to an existing feature means adding it to that feature's array; adding a new feature means adding a new `import * as myFeature from './my-feature/exports.js'` line and spreading its arrays alongside the others.
|
|
83
|
+
|
|
84
|
+
## `defineWorkflowConfig`: Deriving `config` From One OM Descriptor
|
|
85
|
+
|
|
86
|
+
`defineWorkflowConfig(resourceId, descriptors, actionRegistry?)` is a second, smaller helper for the common case where a workflow's `config.name`, `config.description`, `config.actions`, and `config.primaryAction` should all come from the same OM resource descriptor instead of being retyped by hand. `echo.ts` uses it:
|
|
87
|
+
|
|
88
|
+
{/* doc-snippet:skip: real-file excerpt with project-local path aliases, not a standalone compilable file */}
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { defineWorkflowConfig, type WorkflowDefinition } from '@elevasis/sdk'
|
|
92
|
+
import { templateResourceDescriptors } from '@core/config/organization-model'
|
|
93
|
+
import { echoInputSchema, echoOutputSchema } from '@core/types'
|
|
94
|
+
|
|
95
|
+
export const echo: WorkflowDefinition = {
|
|
96
|
+
config: {
|
|
97
|
+
...defineWorkflowConfig('echo', templateResourceDescriptors),
|
|
98
|
+
type: 'workflow',
|
|
99
|
+
version: '1.0.0',
|
|
100
|
+
status: 'dev'
|
|
101
|
+
},
|
|
102
|
+
contract: { inputSchema: echoInputSchema, outputSchema: echoOutputSchema },
|
|
103
|
+
steps: {
|
|
104
|
+
/* ... */
|
|
105
|
+
},
|
|
106
|
+
entryPoint: 'echo'
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
It throws if the descriptor is missing, if it is not `kind: 'workflow'`, or if the descriptor's `ontology.primaryAction` is unset -- `defineWorkflowConfig` requires a resource that has already been given an ontology binding. A workflow whose OM descriptor has no `ontology.primaryAction` yet cannot use this helper. `email-notification.ts`, in the same shipped template, is that case: it reads `templateResourceDescriptors['email-notification']` directly and builds `config.resourceId` / `config.name` / `config.type` / `config.description` off the descriptor's own fields by hand, because that resource's ontology binding was not authored. Both are valid, verified-shipping patterns -- reach for `defineWorkflowConfig` once the descriptor has a `primaryAction`, and fall back to manual descriptor field access until it does.
|
|
111
|
+
|
|
112
|
+
Note that `config.resource` and the final `config.resourceId` / `config.type` are still overwritten by `projectDeploymentSpec` at assembly time regardless of which of the two you use here -- `defineWorkflowConfig` and the manual fallback both only save you from retyping `name` and `description`, not from the resolver-injection step above.
|
|
113
|
+
|
|
114
|
+
## `triggers`, `integrations`, `humanCheckpoints`: `metadata.ts`
|
|
115
|
+
|
|
116
|
+
These three arrays are deployment mechanics, not OM identity, and live in `operations/src/metadata.ts`. All three start empty in a freshly scaffolded project -- add entries as you adopt webhook triggers, third-party credentials, or HITL checkpoints. See [Human-in-the-Loop Workflows](human-in-the-loop.mdx) for the `humanCheckpoints` shape in context.
|
|
117
|
+
|
|
118
|
+
## Adding a Workflow Under This Pattern
|
|
119
|
+
|
|
120
|
+
1. Write the workflow file (`config`, `contract`, `steps`, `entryPoint`), using `defineWorkflowConfig` if the resource already has an `ontology.primaryAction`, otherwise deriving `config` fields from the descriptor by hand.
|
|
121
|
+
2. Make sure the resource exists in your OM -- for a tenant project this goes through the `/om` ceremony, not a direct edit to `core/config/organization-model.ts`.
|
|
122
|
+
3. Export it from its feature group's `workflows` array (`exports.ts` or `index.ts`).
|
|
123
|
+
4. Confirm the top-level `operations/src/index.ts` spreads that group into the `workflows` list passed to `projectDeploymentSpec` -- existing groups already do; a brand-new group needs the import and spread added once.
|
|
124
|
+
5. Run `pnpm -C operations run check` (not `deploy` without `run` -- `pnpm -C operations deploy` without the `run` keyword is parsed as pnpm's own builtin `deploy` command, not your project's `deploy` script).
|
|
125
|
+
6. Deploy with `pnpm -C operations run deploy`.
|
|
126
|
+
|
|
127
|
+
## Documentation
|
|
128
|
+
|
|
129
|
+
- [Resources](resources/index.mdx) -- the `WorkflowDefinition` / `AgentDefinition` shape these helpers assemble
|
|
130
|
+
- [Human-in-the-Loop Workflows](human-in-the-loop.mdx) -- the `humanCheckpoints` entry in `metadata.ts`, in context
|
|
131
|
+
- [Deployment](deployment/index.mdx) -- what happens after `deploy` runs
|
|
@@ -23,7 +23,7 @@ A complete workflow definition has four required properties:
|
|
|
23
23
|
```typescript
|
|
24
24
|
import { z } from 'zod';
|
|
25
25
|
import type { WorkflowDefinition } from '@elevasis/sdk';
|
|
26
|
-
import {
|
|
26
|
+
import { templateResourceDescriptors } from '@core/config/organization-model';
|
|
27
27
|
|
|
28
28
|
const echoInput = z.object({
|
|
29
29
|
message: z.string(),
|
|
@@ -37,10 +37,10 @@ type EchoInput = z.infer<typeof echoInput>;
|
|
|
37
37
|
|
|
38
38
|
const echoWorkflow: WorkflowDefinition = {
|
|
39
39
|
config: {
|
|
40
|
-
resource:
|
|
41
|
-
resourceId:
|
|
40
|
+
resource: templateResourceDescriptors.echo,
|
|
41
|
+
resourceId: templateResourceDescriptors.echo.id,
|
|
42
42
|
name: 'Echo',
|
|
43
|
-
type:
|
|
43
|
+
type: templateResourceDescriptors.echo.kind,
|
|
44
44
|
description: 'Returns the input message unchanged',
|
|
45
45
|
version: '1.0.0',
|
|
46
46
|
status: 'dev',
|
|
@@ -88,6 +88,8 @@ The `contract` block defines the Zod schemas for input and output. The platform
|
|
|
88
88
|
|
|
89
89
|
Always use `z.object()` for both schemas. Use `z.infer` to derive TypeScript types -- this keeps types and runtime validation in sync automatically.
|
|
90
90
|
|
|
91
|
+
{/* doc-snippet:skip: illustrative excerpt -- shows the contract shape in isolation, omits the `import { z } from 'zod'` shown in the Minimal Example above */}
|
|
92
|
+
|
|
91
93
|
```typescript
|
|
92
94
|
const contract = {
|
|
93
95
|
inputSchema: z.object({
|
|
@@ -105,6 +107,8 @@ const contract = {
|
|
|
105
107
|
|
|
106
108
|
The `steps` record maps step IDs to step objects. Each step has metadata (`id`, `name`, `description`), a `handler` function, Zod schemas for its own input and output, and a `next` property that controls routing.
|
|
107
109
|
|
|
110
|
+
{/* doc-snippet:skip: illustrative excerpt -- MyInput/myInputSchema/ValidatedData are placeholder names for types you define yourself, not a standalone compilable file */}
|
|
111
|
+
|
|
108
112
|
```typescript
|
|
109
113
|
const steps = {
|
|
110
114
|
validate: {
|
|
@@ -136,6 +140,8 @@ const steps = {
|
|
|
136
140
|
|
|
137
141
|
`entryPoint` is the name of the first step. For single-step workflows it is always the only step name. For multi-step workflows it is the name of the first step in the chain.
|
|
138
142
|
|
|
143
|
+
{/* doc-snippet:skip: illustrative excerpt with a `// ...` elision, not a standalone compilable file */}
|
|
144
|
+
|
|
139
145
|
```typescript
|
|
140
146
|
const workflow: WorkflowDefinition = {
|
|
141
147
|
// ...
|
|
@@ -153,6 +159,8 @@ For workflows with more than one step, import `StepType` from `@elevasis/sdk` to
|
|
|
153
159
|
|
|
154
160
|
Use `StepType.LINEAR` to connect steps in a fixed sequence. Each step declares a `next` property pointing to the next step name.
|
|
155
161
|
|
|
162
|
+
{/* doc-snippet:skip: illustrative excerpt -- fetchSomething/transform/pipelineInput/pipelineOutput are placeholder names for your own helpers and schemas, not a standalone compilable file */}
|
|
163
|
+
|
|
156
164
|
```typescript
|
|
157
165
|
import { z } from 'zod';
|
|
158
166
|
import type { WorkflowDefinition, WorkflowStep } from '@elevasis/sdk';
|
|
@@ -201,6 +209,8 @@ const pipeline: WorkflowDefinition = {
|
|
|
201
209
|
|
|
202
210
|
Use `StepType.CONDITIONAL` to route to different steps based on output values. Each route has a `condition` function and a `target` step name. The first condition that returns `true` wins. A `default` fallback step is required.
|
|
203
211
|
|
|
212
|
+
{/* doc-snippet:skip: illustrative excerpt -- `evaluate` is a placeholder name for your own scoring logic, not a standalone compilable file */}
|
|
213
|
+
|
|
204
214
|
```typescript
|
|
205
215
|
import { z } from 'zod';
|
|
206
216
|
import type { WorkflowStep } from '@elevasis/sdk';
|
|
@@ -246,7 +256,7 @@ import type { StepHandler } from '@elevasis/sdk';
|
|
|
246
256
|
const myStep: StepHandler = async (input, context) => {
|
|
247
257
|
const { executionId, organizationId, resourceId, logger, store } = context;
|
|
248
258
|
|
|
249
|
-
logger.info(
|
|
259
|
+
logger.info(`Starting step for execution ${executionId}`);
|
|
250
260
|
|
|
251
261
|
// store is a simple key-value store scoped to this execution
|
|
252
262
|
await store.set('progress', '50%');
|
|
@@ -328,19 +338,25 @@ const myAgent: AgentDefinition = {
|
|
|
328
338
|
|
|
329
339
|
`contract.inputSchema` is required, same as a workflow. `contract.outputSchema` is what a **non-session** (single-shot) agent like the example above returns — there is no conversational reply to read a structured answer from otherwise. A `sessionCapable: true` agent typically omits `outputSchema` and speaks through its conversational `message` instead.
|
|
330
340
|
|
|
341
|
+
The framework normalizes literal escape sequences out of that conversational `message`, out of `reasoning`, and out of session-memory values before any of them are persisted, streamed, or replayed. A model sometimes writes the two characters backslash-n where a line break belongs; the result is valid JSON that satisfies the response schema, so nothing upstream can catch it, and the operator ends up reading those characters mid-sentence. Nothing is required of you — no agent definition field changes — but two consequences are worth knowing. An agent that legitimately wants to show an escape sequence in prose (explaining a regex, say) will have it converted, because the normalizer is not markdown-aware. And a memory value that is itself JSON is skipped entirely, so a stored JSON blob keeps its internal escaping intact.
|
|
342
|
+
|
|
331
343
|
---
|
|
332
344
|
|
|
333
345
|
## DeploymentSpec
|
|
334
346
|
|
|
335
347
|
All executable resources must be assembled through a `DeploymentSpec` default export from `operations/src/index.ts`. This is the entry point the platform reads when you deploy. Include the Organization Model payload so the validator can compare code-backed resources against OM descriptors.
|
|
336
348
|
|
|
349
|
+
Use the canonical (resolved) organization model here, not the `organizationModel` convenience export used for navigation/UI code -- that export reshapes the `navigation` field into a template-facing surface list and is not assignable to `DeploymentSpec['organizationModel']`.
|
|
350
|
+
|
|
351
|
+
{/* doc-snippet:skip: illustrative excerpt -- echoWorkflow and pipeline continue from the Minimal Example and Linear Steps examples earlier on this page, not a standalone compilable file */}
|
|
352
|
+
|
|
337
353
|
```typescript
|
|
338
354
|
import type { DeploymentSpec } from '@elevasis/sdk';
|
|
339
|
-
import {
|
|
355
|
+
import { canonicalOrganizationModel } from '@core/config/organization-model';
|
|
340
356
|
|
|
341
357
|
const org: DeploymentSpec = {
|
|
342
358
|
version: '0.1.0',
|
|
343
|
-
organizationModel,
|
|
359
|
+
organizationModel: canonicalOrganizationModel,
|
|
344
360
|
workflows: [echoWorkflow, pipeline],
|
|
345
361
|
agents: [
|
|
346
362
|
// myAgent,
|
|
@@ -13,6 +13,10 @@ The simplest pattern: a chain of steps where each step feeds its output into the
|
|
|
13
13
|
|
|
14
14
|
Each `WorkflowStep` requires `id`, `name`, `description`, `handler`, `inputSchema`, `outputSchema`, and `next`. There is no `type` field on a step -- `StepType` (`LINEAR` / `CONDITIONAL`) is a label for `next.type` only, not a step property.
|
|
15
15
|
|
|
16
|
+
A step's `handler` is typed `(input: unknown, context) => Promise<unknown>` -- narrowing the parameter itself (`async (input: Input) => ...`) breaks assignability under `strictFunctionTypes`. Cast inside the handler body instead, as shown below.
|
|
17
|
+
|
|
18
|
+
{/* doc-snippet:skip: illustrative excerpt -- getOrder/createShipment are placeholder names for your own domain logic, not a standalone compilable file */}
|
|
19
|
+
|
|
16
20
|
```typescript
|
|
17
21
|
import { z } from 'zod';
|
|
18
22
|
import type { WorkflowDefinition, WorkflowStep } from '@elevasis/sdk';
|
|
@@ -28,9 +32,10 @@ const validateStep: WorkflowStep = {
|
|
|
28
32
|
description: 'Checks the order exists before shipping',
|
|
29
33
|
inputSchema: z.object({ orderId: z.string() }),
|
|
30
34
|
outputSchema: z.object({ order: z.unknown() }),
|
|
31
|
-
handler: async (input
|
|
32
|
-
const
|
|
33
|
-
|
|
35
|
+
handler: async (input) => {
|
|
36
|
+
const { orderId } = input as Input;
|
|
37
|
+
const order = await getOrder(orderId);
|
|
38
|
+
if (!order) throw new Error(`Order ${orderId} not found`);
|
|
34
39
|
return { order };
|
|
35
40
|
},
|
|
36
41
|
next: { type: 'linear', target: 'ship' },
|
|
@@ -43,7 +48,8 @@ const shipStep: WorkflowStep = {
|
|
|
43
48
|
inputSchema: z.object({ order: z.unknown() }),
|
|
44
49
|
outputSchema: z.object({ shipped: z.boolean(), trackingNumber: z.string() }),
|
|
45
50
|
handler: async (input) => {
|
|
46
|
-
const
|
|
51
|
+
const { order } = input as { order: unknown };
|
|
52
|
+
const tracking = await createShipment(order);
|
|
47
53
|
return { shipped: true, trackingNumber: tracking.number };
|
|
48
54
|
},
|
|
49
55
|
next: null, // terminal -- no further steps
|
|
@@ -72,6 +78,8 @@ const fulfillOrder: WorkflowDefinition = {
|
|
|
72
78
|
|
|
73
79
|
Use a `next.type` of `'conditional'` when the next step depends on the output of the current step. The step itself still has no `type` field -- the routing decision lives entirely in `next`.
|
|
74
80
|
|
|
81
|
+
{/* doc-snippet:skip: illustrative excerpt, not a standalone compilable file */}
|
|
82
|
+
|
|
75
83
|
```typescript
|
|
76
84
|
import { z } from 'zod';
|
|
77
85
|
import type { WorkflowStep } from '@elevasis/sdk';
|
|
@@ -128,18 +136,20 @@ const sendEmailStep: WorkflowStep = {
|
|
|
128
136
|
inputSchema: z.object({ recipientEmail: z.string(), subject: z.string(), body: z.string() }),
|
|
129
137
|
outputSchema: z.object({ sent: z.boolean(), messageId: z.string() }),
|
|
130
138
|
handler: async (input, context) => {
|
|
131
|
-
const
|
|
139
|
+
const { recipientEmail, subject, body } = input as {
|
|
140
|
+
recipientEmail: string;
|
|
141
|
+
subject: string;
|
|
142
|
+
body: string;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const result = (await platform.call({
|
|
132
146
|
tool: 'email',
|
|
133
147
|
method: 'send',
|
|
134
|
-
params: {
|
|
135
|
-
to: input.recipientEmail,
|
|
136
|
-
subject: input.subject,
|
|
137
|
-
body: input.body,
|
|
138
|
-
},
|
|
148
|
+
params: { to: recipientEmail, subject, body },
|
|
139
149
|
credential: 'sendgrid', // name of the stored credential
|
|
140
|
-
});
|
|
150
|
+
})) as { messageId: string };
|
|
141
151
|
|
|
142
|
-
context.logger.info(
|
|
152
|
+
context.logger.info(`Email sent: ${result.messageId}`);
|
|
143
153
|
return { sent: true, messageId: result.messageId };
|
|
144
154
|
},
|
|
145
155
|
next: null,
|
|
@@ -149,7 +159,7 @@ const sendEmailStep: WorkflowStep = {
|
|
|
149
159
|
**Key points:**
|
|
150
160
|
|
|
151
161
|
- `platform.call()` is async and times out after 30 minutes (a worker-side safety net; real enforcement is server-side)
|
|
152
|
-
- `credential` is the name of a platform environment variable
|
|
162
|
+
- `credential` is the name of a platform environment variable created via `elevasis-sdk creds create` when the tool needs one
|
|
153
163
|
- On failure, `platform.call()` throws `PlatformToolError` (not `ToolingError`)
|
|
154
164
|
- Always log success so executions are easy to debug in the dashboard
|
|
155
165
|
|
|
@@ -164,20 +174,20 @@ Use `PlatformToolError` (from `@elevasis/sdk/worker`) to handle tool-specific fa
|
|
|
164
174
|
```typescript
|
|
165
175
|
import { platform, PlatformToolError } from '@elevasis/sdk/worker';
|
|
166
176
|
|
|
167
|
-
const step = async (input) => {
|
|
177
|
+
const step = async (input: { followUpAt?: string }) => {
|
|
168
178
|
try {
|
|
169
|
-
const deals = await platform.call({
|
|
179
|
+
const deals = (await platform.call({
|
|
170
180
|
tool: 'crm',
|
|
171
181
|
method: 'listDeals',
|
|
172
182
|
params: { stage: 'proposal', limit: 10 },
|
|
173
|
-
})
|
|
183
|
+
})) as Array<{ id: string }>;
|
|
174
184
|
|
|
175
185
|
const deal = deals[0]
|
|
176
|
-
? await platform.call({
|
|
186
|
+
? ((await platform.call({
|
|
177
187
|
tool: 'crm',
|
|
178
188
|
method: 'getDeal',
|
|
179
189
|
params: { dealId: deals[0].id },
|
|
180
|
-
})
|
|
190
|
+
})) as { id: string })
|
|
181
191
|
: null;
|
|
182
192
|
|
|
183
193
|
if (deal) {
|
|
@@ -234,6 +244,8 @@ const step = async (input) => {
|
|
|
234
244
|
|
|
235
245
|
Use `ExecutionError` when your step detects a condition that should mark the entire execution as failed:
|
|
236
246
|
|
|
247
|
+
{/* doc-snippet:skip: illustrative excerpt, not a standalone compilable file */}
|
|
248
|
+
|
|
237
249
|
```typescript
|
|
238
250
|
import { ExecutionError } from '@elevasis/sdk';
|
|
239
251
|
|
|
@@ -254,10 +266,12 @@ const validateStep = async (input) => {
|
|
|
254
266
|
|
|
255
267
|
`ToolingError` is thrown by lower-level platform operations (not `platform.call()` directly). You may encounter it in advanced scenarios:
|
|
256
268
|
|
|
269
|
+
{/* doc-snippet:skip: illustrative excerpt -- `doSomething` is a placeholder name for your own logic, not a standalone compilable file */}
|
|
270
|
+
|
|
257
271
|
```typescript
|
|
258
272
|
import { ToolingError } from '@elevasis/sdk';
|
|
259
273
|
|
|
260
|
-
const step = async (input) => {
|
|
274
|
+
const step = async (input: unknown) => {
|
|
261
275
|
try {
|
|
262
276
|
return await doSomething(input);
|
|
263
277
|
} catch (err) {
|
|
@@ -274,17 +288,20 @@ const step = async (input) => {
|
|
|
274
288
|
|
|
275
289
|
## Logging in Steps
|
|
276
290
|
|
|
277
|
-
The `context.logger` writes structured logs attached to the execution. Use it instead of `console.log` so logs appear in the dashboard alongside the execution record.
|
|
291
|
+
The `context.logger` writes structured logs attached to the execution. Use it instead of `console.log` so logs appear in the dashboard alongside the execution record. `logger.info()`'s optional second parameter is an internal engine-only context type, not a place for arbitrary metadata -- interpolate values into the message string instead.
|
|
292
|
+
|
|
293
|
+
{/* doc-snippet:skip: illustrative excerpt -- `doWork` is a placeholder name for your own logic, not a standalone compilable file */}
|
|
278
294
|
|
|
279
295
|
```typescript
|
|
280
296
|
import type { StepHandler } from '@elevasis/sdk';
|
|
281
297
|
|
|
282
298
|
const processStep: StepHandler = async (input, context) => {
|
|
283
|
-
|
|
299
|
+
const { userId } = input as { userId: string };
|
|
300
|
+
context.logger.info(`Starting process for user ${userId}`);
|
|
284
301
|
|
|
285
|
-
const result = await doWork(input);
|
|
302
|
+
const result = (await doWork(input)) as { id: string };
|
|
286
303
|
|
|
287
|
-
context.logger.info(
|
|
304
|
+
context.logger.info(`Process complete: ${result.id}`);
|
|
288
305
|
return result;
|
|
289
306
|
};
|
|
290
307
|
```
|
|
@@ -297,9 +314,14 @@ Avoid logging sensitive values (API keys, passwords, PII) since logs are stored
|
|
|
297
314
|
|
|
298
315
|
`context.store` is a simple key-value store scoped to the current execution. Use it to pass data between steps without coupling step interfaces, or to checkpoint long-running work.
|
|
299
316
|
|
|
317
|
+
{/* doc-snippet:skip: illustrative excerpt -- fetchExpensiveData/transform are placeholder names for your own logic, not a standalone compilable file */}
|
|
318
|
+
|
|
300
319
|
```typescript
|
|
320
|
+
import type { StepHandler } from '@elevasis/sdk';
|
|
321
|
+
|
|
301
322
|
const firstStep: StepHandler = async (input, context) => {
|
|
302
|
-
const
|
|
323
|
+
const { id } = input as { id: string };
|
|
324
|
+
const data = await fetchExpensiveData(id);
|
|
303
325
|
|
|
304
326
|
// Save for use by later steps
|
|
305
327
|
await context.store.set('fetchedData', JSON.stringify(data));
|
|
@@ -325,6 +347,8 @@ Store values are strings. Serialize objects with `JSON.stringify` and parse with
|
|
|
325
347
|
|
|
326
348
|
While building a resource, set `config.status` to `'dev'`:
|
|
327
349
|
|
|
350
|
+
{/* doc-snippet:skip: illustrative excerpt with a `// ...` elision, not a standalone compilable file */}
|
|
351
|
+
|
|
328
352
|
```typescript
|
|
329
353
|
const myWorkflow: WorkflowDefinition = {
|
|
330
354
|
config: {
|
|
@@ -345,6 +369,8 @@ Dev resources:
|
|
|
345
369
|
|
|
346
370
|
When you are ready to go live, change to `'prod'` and redeploy:
|
|
347
371
|
|
|
372
|
+
{/* doc-snippet:skip: illustrative excerpt, not a standalone compilable file */}
|
|
373
|
+
|
|
348
374
|
```typescript
|
|
349
375
|
config: {
|
|
350
376
|
name: 'my-workflow',
|
|
@@ -375,6 +401,8 @@ Individual resources that set their own `config.status` override this default.
|
|
|
375
401
|
|
|
376
402
|
As your project grows, organize resources by business domain. Each domain gets its own directory with an `index.ts` barrel that exports `workflows` and `agents` arrays:
|
|
377
403
|
|
|
404
|
+
{/* doc-snippet:skip: illustrative excerpt with `...` elisions, not a standalone compilable file */}
|
|
405
|
+
|
|
378
406
|
```typescript
|
|
379
407
|
// src/orders/fulfill-order.ts
|
|
380
408
|
export const fulfillOrder: WorkflowDefinition = { ... };
|
|
@@ -423,6 +451,8 @@ The platform's HITL mechanism works in two parts: your workflow code creates an
|
|
|
423
451
|
|
|
424
452
|
Call `approval.create()` from any workflow step to pause execution and emit a task to the Command Queue:
|
|
425
453
|
|
|
454
|
+
{/* doc-snippet:skip: illustrative excerpt -- dealId/proposalUrl are shorthand for values from the enclosing step handler's input, not a standalone compilable file */}
|
|
455
|
+
|
|
426
456
|
```typescript
|
|
427
457
|
import { approval } from '@elevasis/sdk/worker'
|
|
428
458
|
|
|
@@ -45,6 +45,8 @@ Zod is a peer dependency.
|
|
|
45
45
|
|
|
46
46
|
Resource metadata uses graph links:
|
|
47
47
|
|
|
48
|
+
{/* doc-snippet:skip: illustrative excerpt, not a standalone compilable file */}
|
|
49
|
+
|
|
48
50
|
```ts
|
|
49
51
|
config: {
|
|
50
52
|
resourceId: 'lead-import',
|
|
@@ -77,6 +79,8 @@ config: {
|
|
|
77
79
|
## ElevasConfig
|
|
78
80
|
|
|
79
81
|
```ts
|
|
82
|
+
import type { ResourceStatus } from '@elevasis/sdk'
|
|
83
|
+
|
|
80
84
|
export interface ElevasConfig {
|
|
81
85
|
defaultStatus?: ResourceStatus
|
|
82
86
|
dev?: { port?: number }
|
|
@@ -90,14 +94,13 @@ export interface ElevasConfig {
|
|
|
90
94
|
|
|
91
95
|
## StepHandler Context
|
|
92
96
|
|
|
97
|
+
`logger`'s optional second parameter is an internal engine-only context type, not a place for arbitrary metadata -- interpolate values into the message string instead.
|
|
98
|
+
|
|
93
99
|
```ts
|
|
94
100
|
import type { StepHandler, ExecutionContext } from '@elevasis/sdk'
|
|
95
101
|
|
|
96
102
|
const handler: StepHandler = async (input, context: ExecutionContext) => {
|
|
97
|
-
context.logger.info(
|
|
98
|
-
executionId: context.executionId,
|
|
99
|
-
resourceId: context.resourceId
|
|
100
|
-
})
|
|
103
|
+
context.logger.info(`Processing execution ${context.executionId} for resource ${context.resourceId}`)
|
|
101
104
|
|
|
102
105
|
await context.store.set('checkpoint', JSON.stringify({ step: 'started' }))
|
|
103
106
|
return { done: true }
|
|
@@ -23,10 +23,12 @@ Fetches records from a Supabase table that need enrichment, sends each record to
|
|
|
23
23
|
|
|
24
24
|
## Input Schema
|
|
25
25
|
|
|
26
|
+
{/* doc-snippet:skip: illustrative excerpt -- shows the schema shape in isolation, omits the `import { z } from 'zod'` shown in Workflow Code Pattern below */}
|
|
27
|
+
|
|
26
28
|
```typescript
|
|
27
29
|
z.object({
|
|
28
30
|
table: z.string(), // Supabase table to enrich
|
|
29
|
-
filter: z.record(z.string()).optional(), // Filter rows to enrich (PostgREST format)
|
|
31
|
+
filter: z.record(z.string(), z.string()).optional(), // Filter rows to enrich (PostgREST format)
|
|
30
32
|
sourceField: z.string(), // Field to send to the LLM as input
|
|
31
33
|
targetField: z.string(), // Field to write enriched output to
|
|
32
34
|
prompt: z.string(), // LLM prompt template (use {value} as placeholder)
|
|
@@ -36,6 +38,8 @@ z.object({
|
|
|
36
38
|
|
|
37
39
|
## Output Schema
|
|
38
40
|
|
|
41
|
+
{/* doc-snippet:skip: illustrative excerpt -- shows the schema shape in isolation, omits the `import { z } from 'zod'` shown in Workflow Code Pattern below */}
|
|
42
|
+
|
|
39
43
|
```typescript
|
|
40
44
|
z.object({
|
|
41
45
|
processed: z.number(), // Rows successfully enriched
|
|
@@ -55,7 +59,7 @@ import { z } from 'zod'
|
|
|
55
59
|
|
|
56
60
|
const inputSchema = z.object({
|
|
57
61
|
table: z.string(),
|
|
58
|
-
filter: z.record(z.string()).optional(),
|
|
62
|
+
filter: z.record(z.string(), z.string()).optional(),
|
|
59
63
|
sourceField: z.string(),
|
|
60
64
|
targetField: z.string(),
|
|
61
65
|
prompt: z.string(),
|
|
@@ -130,7 +134,7 @@ export const dataEnrichment: WorkflowDefinition = {
|
|
|
130
134
|
},
|
|
131
135
|
})
|
|
132
136
|
|
|
133
|
-
context.logger.info(
|
|
137
|
+
context.logger.info(`Enriched row ${String(row.id)}`)
|
|
134
138
|
processed++
|
|
135
139
|
} catch (err) {
|
|
136
140
|
const msg = err instanceof Error ? err.message : String(err)
|