Aelio
PlatformsNode.js

ShopCo Sample SaaS

Full pipeline YAML demo — multi-stage onboarding with profile memory and tool gating.

The ShopCo sample (examples/sample-saas in the Aelio-Convox repo) is the reference integration for YAML-backed conversational pipelines.

For a step-by-step guide on creating your own YAML file and linking it in your project, see Pipeline YAML Manifest — Part 1 (create) and Part 2 (link).

What it demonstrates

FeatureImplementation
YAML pipeline manifestmanifests/shopco.pipeline.yaml
Manifest loadersrc/load-manifest.ts
Backend toolssrc/index.ts via aelio.expose()
In-memory business dataOrders, subscription, invoices Map
REST APIParallel /api/* routes
Multi-stage onboardingunverified → verified → onboarding → active
Tool gatingtool_groups block writes during onboarding
Profile memoryEmail, name, shopping preference
Widget quick repliesintent_ack, shopping_preference chips

Run the demo

From the Aelio-Convox repo root:

pnpm install
pnpm build
pnpm start
URLPurpose
http://localhost:3010/demo.htmlPipeline demo page with widget
http://localhost:3010/readyServer readiness + pipeline registration
http://localhost:8081/healthShopCo backend health

Click New user on the demo page to start a fresh pipeline for a unique customer id.

Project layout

examples/sample-saas/
├── manifests/
│   └── shopco.pipeline.yaml    # Declarative pipeline config
├── src/
│   ├── load-manifest.ts        # YAML → aelio.pipeline/attribute/flow
│   └── index.ts                # REST API + aelio.expose() tools
└── package.json

Boot sequence

import { loadShopCoManifest } from './load-manifest.js';

// 1. Load YAML manifest (stages, attributes, flows, policies)
loadShopCoManifest();

// 2. Register tools (referenced by flow steps in YAML)
aelio.expose('listOrders', async ({ status }, ctx) => { /* ... */ }, {
  description: "List the customer's orders",
  params: { status: { type: 'string', optional: true } },
  safety: 'read',
  intent: 'order_inquiry',
});

// 3. Connect to Aelio server
await aelio.listen({
  secret: process.env.AELIO_SDK_SECRET,
  url: process.env.AELIO_SERVER_URL ?? 'ws://127.0.0.1:3010',
});

Every new customerId starts at pipeline stage unverified. Stage and flow progress are stored by Aelio in SQLite — not in ShopCo's in-memory Map.

Exposed tools

ToolSafetyIntentUsed in flow
syncProfilereadonboardingshopco_onboarding.sync_profile
listOrdersreadorder_inquiryshopco_onboarding.review_orders
getSubscriptionreadsubscriptionshopco_onboarding.check_plan
listInvoicesreadbillingshopco_onboarding.view_invoices
getOrderStatusreadorder_inquiryActive stage (free chat)
cancelOrderwritecancellationActive stage only
upgradePlanwritesubscriptionActive stage only

Write tools are blocked during onboarding via:

onboarding:
  blocked_groups: [writes]

Walking through the pipeline

Unverified — Assistant delivers the ShopCo pitch. Tap Let's go (quick reply) or say yes. Flow: welcome.

Verified — Provide an email (e.g. you@example.com). Flow: verify_identity.

Onboarding — Name → preference chips → profile sync → orders → plan → invoices. Flow: shopco_onboarding.

Active — Full support. Try cancel order A-1002 or upgrade me to pro.

Adapting for your product

  1. Copy manifests/shopco.pipeline.yamlmanifests/your-product.pipeline.yaml
  2. Copy src/load-manifest.ts and rename types/helpers for your schema
  3. Update stages, attributes, and flows for your onboarding
  4. Implement tools in index.ts — reference them from YAML tool: fields
  5. Align tool intent values with your tool_groups intent lists

Attributes vs your database

Attribute values (email, name, preference) are stored in Aelio's profile memory (customer_attributes). Your tools should read business data from your own database. The sample's syncProfile tool is a checkpoint in the tour — it does not write back to the in-memory ShopCo Map.

Verify registration

curl -s http://127.0.0.1:3010/ready | jq '{
  pipeline: .sdk.pipeline != null,
  flows: .sdk.flows,
  attributes: .sdk.attributes
}'

On this page