@elevasis/sdk 1.53.0 → 1.54.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.
@@ -1,31 +1,43 @@
1
1
  ---
2
2
  title: When to Reach for the define* Builders
3
- description: defineWorkflow, defineStep, defineContract, defineResource, and defineTopology exist for two different reasons -- this page teaches which reason applies before you pick a builder over a plain object literal.
3
+ description: defineSingleStepWorkflow, defineContract, defineResource, and defineTopology exist for three different reasons -- this page teaches which reason applies before you pick a builder over a plain object literal.
4
4
  ---
5
5
 
6
- `@elevasis/sdk`'s root export includes a family of `define*` functions: `defineWorkflow`, `defineStep`, `defineContract`, `defineWorkflowConfig`, `defineResource`, `defineResources`, `defineResourceOntology`, `defineTopology`, `defineTopologyRelationship`, plus the `topologyRelationship` / `topologyRef` helpers. Every existing recipe in this bundle teaches the plain object-literal shape instead (a `WorkflowDefinition` written out by hand with a `: WorkflowDefinition` annotation), which is completely valid TypeScript -- but it means the builders are never actually demonstrated, so there is nothing here to tell you when reaching for one buys you something real versus when it is just a different way to write the same object. This page is that judgment call. For the full list of what `@elevasis/sdk` exports, see the [Export Catalog](exports.mdx).
6
+ `@elevasis/sdk`'s root export includes a family of `define*` functions: `defineSingleStepWorkflow`, `defineContract`, `defineWorkflowConfig`, `defineResource`, `defineResources`, `defineResourceOntology`, `defineTopology`, `defineTopologyRelationship`, plus the `topologyRelationship` / `topologyRef` helpers. Most recipes in this bundle teach the plain object-literal shape instead (a `WorkflowDefinition` written out by hand with a `: WorkflowDefinition` annotation), which is completely valid TypeScript -- but it means the builders are rarely demonstrated, so there is nothing to tell you when reaching for one buys you something real versus when it is just a different way to write the same object. This page is that judgment call. For the full list of what `@elevasis/sdk` exports, see the [Export Catalog](exports.mdx).
7
7
 
8
- The family splits into two groups that do genuinely different things, and the judgment call is different for each.
8
+ The family splits into groups that do genuinely different things, and the judgment call is different for each.
9
9
 
10
- ## Group 1: Workflow Builders Are Type Inference, Not Validation
10
+ ## Group 1: `defineSingleStepWorkflow` Removes Real Ceremony
11
11
 
12
- `defineWorkflow`, `defineStep`, and `defineContract` do nothing at runtime. Their entire implementation is an identity function constrained by a generic:
12
+ A workflow with exactly one step pays about eighteen lines to say something the shape already implies: the step's schemas are the contract's schemas, `entryPoint` is the step's own id, and `next` is `null` because there is nowhere else for a single step to go. `defineSingleStepWorkflow` takes the parts that vary and assembles the rest:
13
13
 
14
- {/* doc-snippet:skip: source excerpt (WorkflowDefinition intentionally unimported), not a standalone compilable file */}
14
+ {/* doc-snippet:skip: illustrative excerpt (EchoInput/EchoOutput intentionally undefined), not a standalone compilable file */}
15
15
 
16
16
  ```typescript
17
- export function defineWorkflow<TWorkflow extends WorkflowDefinition>(workflow: TWorkflow): TWorkflow {
18
- return workflow
19
- }
17
+ import { defineSingleStepWorkflow, type WorkflowDefinition } from '@elevasis/sdk'
18
+
19
+ export const echo: WorkflowDefinition = defineSingleStepWorkflow({
20
+ config: echoConfig,
21
+ inputSchema: EchoInput,
22
+ outputSchema: EchoOutput,
23
+ step: {
24
+ id: 'echo',
25
+ name: 'Echo',
26
+ description: 'Returns the input unchanged',
27
+ handler: async (input, context) => ({ message: input.message })
28
+ }
29
+ })
20
30
  ```
21
31
 
22
- `defineStep` and `defineContract` are the same three lines against `WorkflowStep` and `Contract`. Calling one of these does not validate, transform, or check anything beyond what TypeScript's structural typing already does on the argument you pass it.
32
+ Two things it does that a literal cannot. It threads the input type through to the handler, so `handler` receives the value already typed as `z.infer<typeof inputSchema>` rather than `unknown` -- the `rawInput as EchoInput` cast every hand-written single-step handler carries is absorbed once by the factory instead of being repeated per workflow. And it guarantees the contract and the step share one pair of schemas, which a hand-written workflow has to keep in sync by hand and can silently get wrong.
33
+
34
+ The emitted `WorkflowDefinition` is structurally identical to the hand-written form -- same `config`, `contract`, `steps` map, and `entryPoint`. Keep the explicit `: WorkflowDefinition` annotation on the export: `pnpm check:workflow-assembly` pattern-matches that annotation rather than the right-hand side, so dropping it makes the gate stop seeing the workflow.
23
35
 
24
- What it buys you is narrower inference. Annotate a literal `const echo: WorkflowDefinition = { ... }` and TypeScript widens every field to the interface's declared type -- `config.resourceId` becomes `string`, not `'echo'`. Pass the same object to `defineWorkflow({ ... })` with no annotation and `TWorkflow` is inferred from the literal you wrote, so `defineWorkflow(...).config.resourceId` keeps the literal type `'echo'`. That distinction only matters if something downstream reads the value back and wants the narrower type -- a test asserting on `resourceId`, a lookup table keyed by it, a second resource that imports the first and needs its literal id. A workflow file that is only ever consumed by the deploy pipeline, which just needs it to satisfy `WorkflowDefinition`, gets nothing extra from the wrapper.
36
+ Reach for it whenever a workflow has exactly one step. Write the literal form when it has two or more, or when the step's input and output schemas genuinely differ from the workflow contract's.
25
37
 
26
- That is a real, but narrow, upside -- and it is honestly reflected in what ships. The scaffolded template's own workflow files (`example/echo.ts`, `email-notification/index.ts`) use the plain annotated-literal form, not `defineWorkflow`. The builder is real, exported, and demonstrated in the SDK's own test fixtures with exactly the calling convention above -- it is simply not the house style the template ships with. Use the annotated literal by default, matching what a scaffolded project already contains; reach for `defineWorkflow` / `defineStep` / `defineContract` specifically when you want the object's literal types preserved past its own definition.
38
+ `defineContract` is the one survivor of the old identity-function group -- three lines returning their argument, buying narrower inference and nothing else. Annotate a literal `const c: Contract = { ... }` and TypeScript widens every field to the interface's declared type; pass the same object to `defineContract({ ... })` with no annotation and the literal types survive. That only matters if something downstream reads the value back and wants the narrower type. Use the annotated literal by default.
27
39
 
28
- `defineWorkflowConfig` is a different kind of helper in this same group -- it derives `config` fields from an Organization Model resource descriptor instead of preserving literal types. It has its own page: see [The Deployment Spec Pattern](project-deployment-spec.mdx#defineworkflowconfig-deriving-config-from-one-om-descriptor).
40
+ `defineWorkflowConfig` is a different kind of helper again -- it derives `config` fields from an Organization Model resource descriptor. It has its own page: see [The Deployment Spec Pattern](project-deployment-spec.mdx#defineworkflowconfig-deriving-config-from-one-om-descriptor).
29
41
 
30
42
  ## Group 2: Resource and Topology Builders Do Real Work
31
43
 
@@ -63,8 +75,9 @@ For this group, reaching for the builder is not a style preference -- it is the
63
75
 
64
76
  ## Quick Decision Guide
65
77
 
66
- - Writing a workflow, step, or contract, and nothing downstream needs the literal types back -- use the plain annotated object literal. This is what the scaffolded template ships.
67
- - Writing a workflow, step, or contract, and something downstream reads the value back and needs its literal types preserved -- wrap it in `defineWorkflow` / `defineStep` / `defineContract`.
78
+ - Writing a workflow with exactly one step -- use `defineSingleStepWorkflow`, and keep the `: WorkflowDefinition` annotation on the export.
79
+ - Writing a workflow with two or more steps -- use the plain annotated object literal. This is what the scaffolded template ships.
80
+ - Writing a contract, and something downstream reads the value back and needs its literal types preserved -- wrap it in `defineContract`. Otherwise annotate the literal.
68
81
  - Deriving a workflow's `config` from an OM resource descriptor that already has `ontology.primaryAction` set -- use `defineWorkflowConfig`.
69
82
  - Authoring an Organization Model resource, resource ontology binding, or topology relationship directly (Elevasis's own workspace-internal model, or inside the tooling `/om` itself runs) -- always use `defineResource` / `defineResourceOntology` / `defineTopology` / `defineTopologyRelationship`, never the raw parsed shape.
70
83
  - Authoring a tenant project's own Organization Model -- go through `/om`; you generally will not call the Group 2 builders yourself.
@@ -8,7 +8,7 @@ description: "Auto-generated catalog of all published @elevasis/sdk subpath expo
8
8
 
9
9
  | Import | Title | Group | Description |
10
10
  | --- | --- | --- | --- |
11
- | `@elevasis/sdk` | SDK | Getting Started | Default entry: defineWorkflow, defineStep, defineContract, contract-ref resolution, shared types, and workflow utilities. |
11
+ | `@elevasis/sdk` | SDK | Getting Started | Default entry: defineSingleStepWorkflow, defineContract, contract-ref resolution, shared types, and workflow utilities. |
12
12
  | `@elevasis/sdk/worker` | Worker Runtime | Runtime | worker_threads runtime plus the typed platform and integration adapters a step handler calls at execution time. |
13
13
  | `@elevasis/sdk/test-utils` | Test Utils | Testing | Workflow test harness, resource registry helpers, and mock adapters for unit-testing definitions without the platform. |
14
14
  | `@elevasis/sdk/node` | Node Build Tooling | Tooling | Node-only build-time codegen for knowledge nodes and bodies. Requires fs/path/process -- not browser-safe. |
@@ -50,7 +50,7 @@ See [Platform Tools](platform-tools/index.mdx) for the full catalog, adapter ref
50
50
  - [Credential Security](platform-tools/index.mdx#credential-security) - Three-layer credential model, HTTP tool patterns, and credential management
51
51
  - [Human-in-the-Loop Workflows](human-in-the-loop.mdx) - The full HITL story: approval adapter, checkpoint metadata, and queue resolution
52
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
53
+ - [When to Reach for the define\* Builders](define-builders.mdx) - Judgment guide for defineSingleStepWorkflow, defineResource, defineTopology, and friends
54
54
 
55
55
  ### Reference
56
56
 
@@ -17,7 +17,7 @@ Platform adapters are singletons — import them directly, no credential require
17
17
  | AcqDb | `acqDb` | `listLists`, `createList`, `updateList`, `deleteList`, `addContactsToList`, `addCompaniesToList`, `updateCompanyStage`, `updateContactStage`, `clearCompanyStages`, `clearContactStages`, `createCompany`, `upsertCompany`, `updateCompany`, `getCompany`, `listCompanies`, `deleteCompany`, `createContact`, `upsertContact`, `updateContact`, `getContact`, `getContactByEmail`, `listContacts`, `deleteContact`, `bulkImportContacts`, `bulkImportCompanies`, `deactivateContactsByCompany`, `upsertDeal`, `getDealByEmail`, `getDealByEnvelopeId`, `updateDealEnvelopeId`, `getDealById`, `getContactById`, `getCompanyById`, `listDeals`, `getDealPipelineAnalytics`, `updateDiscoveryData`, `updateProposalData`, `markProposalSent`, `markProposalReviewed`, `updateCloseLostReason`, `updateFees`, `cacheInstantlyThreadIds`, `transitionItem`, `setContactNurture`, `cancelSchedulesAndHitlByEmail`, `cancelHitlByDealId`, `clearDealFields`, `deleteDeal`, `recordDealActivity`, `setDealStateKey`, `transitionDeal`, `loadDeal`, `createDealNote`, `listDealNotes`, `createDealTask`, `listDealTasks`, `listDealTasksDue`, `completeDealTask`, `mergeEnrichmentData`, `upsertSocialPosts` | AcqDb — full acquisition database: lists, companies, contacts, deals, notes, tasks, and enrichment. |
18
18
  | Projects | `projects` | `listProjects`, `getProject`, `createProject`, `updateProject`, `deleteProject`, `listMilestones`, `createMilestone`, `updateMilestone`, `deleteMilestone`, `listTasks`, `getTask`, `createTask`, `updateTask`, `deleteTask`, `mergeTaskResumeContext`, `listNotes`, `createNote`, `updateNote`, `deleteNote` | Projects — manage delivery projects, milestones, tasks, notes, and resume context. |
19
19
  | Crm | `crm` | `getRecentActivity`, `listDeals`, `getDeal`, `getDealByEmail`, `createDealNote`, `listDealNotes`, `createDealTask`, `listDealTasks`, `listDealTasksDue`, `completeDealTask`, `recordActivity`, `deleteDeal` | CRM — read and update deals, notes, tasks, activity, and stage transitions. |
20
- | List | `list` | `getConfig`, `recordExecution`, `updateCompanyStage`, `updateContactStage`, `clearCompanyStages`, `clearContactStages`, `listPendingCompanyIds`, `listPendingContactIds` | List — list-scoped workflow execution tracking and stage updates. |
20
+ | List | `list` | `getConfig`, `recordExecution`, `updateCompanyStage`, `updateContactStage`, `bulkUpdateCompanyStage`, `bulkUpdateContactStage`, `clearCompanyStages`, `clearContactStages`, `listPendingCompanyIds`, `listPendingContactIds` | List — list-scoped workflow execution tracking and stage updates. |
21
21
  | Pdf | `pdf` | `render`, `renderToBuffer` | PDF — render PDF documents from structured page definitions. |
22
22
  | Approval | `approval` | `create`, `deleteByMetadata` | Approval — create and manage HITL (human-in-the-loop) tasks. |
23
23
  | Execution | `execution` | `trigger`, `triggerAsync` | Execution — trigger other workflows or agents within the same organization. |
@@ -54,6 +54,8 @@ Four things are doing work here that the minimal literal example does not show:
54
54
 
55
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
56
 
57
+ It also overrides `config.name` and `config.description` from the descriptor's `title` / `description` -- see [The OM Descriptor Owns Display Identity](#the-om-descriptor-owns-display-identity) below.
58
+
57
59
  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
60
 
59
61
  The three resolver functions are required or optional depending on what you're deploying:
@@ -109,7 +111,21 @@ export const echo: WorkflowDefinition = {
109
111
 
110
112
  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
113
 
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.
114
+ Note that `config.resource`, the final `config.resourceId` / `config.type`, and `config.name` / `config.description` are all overwritten by `projectDeploymentSpec` at assembly time regardless of which of the two you use here. `defineWorkflowConfig` and the manual fallback save you from retyping the strings, not from the projection step below.
115
+
116
+ ## The OM Descriptor Owns Display Identity
117
+
118
+ A resource's `name` and `description` in its `operations/src/**` config are **not** what the platform shows. At deploy time the projected spec takes `title` and `description` from that resource's OM descriptor in `core/config/organization-model.ts` and overrides the locally declared strings, for both workflows and agents. The descriptor is what Command Center's action surfaces render; a config string only ever reached the execution log.
119
+
120
+ Deploy warns per resource when the two disagree:
121
+
122
+ ```text
123
+ [deployment-spec] "<resource-id>" name disagrees with its OM descriptor -- using the OM title.
124
+ ```
125
+
126
+ The warning does not fail the deploy. Fix it by editing the OM descriptor when the descriptor is wrong, or the config when the config is. **Editing only the config and redeploying changes nothing a user sees.**
127
+
128
+ A descriptor that omits `title` or `description` leaves the config value in place, so the override is a preference rather than a hard requirement. `config.name` and `config.description` themselves stay required by `WorkflowConfig`, so you still author them.
113
129
 
114
130
  ## `triggers`, `integrations`, `humanCheckpoints`: `metadata.ts`
115
131