Skip to main content

Registering Services

Services group your functions and connect them to the Daemo Engine. This page shows you how to set up and run your service.

The DaemoBuilder

Use DaemoBuilder to configure and create your Daemo instance:

src/index.ts
import { DaemoBuilder } from 'daemo-engine';

const daemo = new DaemoBuilder()
.withApiKey(process.env.DAEMO_AGENT_API_KEY!)
.withServiceName("MyService")
.build();

Required Configuration

MethodDescription
.withApiKey(key)Your DAEMO_AGENT_API_KEY from the dashboard
.withServiceName(name)A unique name for this service
.build()Creates the Daemo instance

Optional Configuration

MethodDescription
.withSystemPrompt(prompt)Instructions for the AI on how to use this service

Registering Functions

After building, register your function classes:

src/index.ts
import { CalculatorFunctions } from './services/calculator';
import { CRMFunctions } from './services/crm';

// Register one class
await daemo.registerService(CalculatorFunctions);

// Or register an instance (if you have constructor dependencies)
const db = new Database(connectionString);
const crmFuncs = new CRMFunctions(db);
await daemo.registerService(crmFuncs);

Starting the Service

Once registered, start the service:

src/index.ts
await daemo.start();

This:

  1. Connects to the Daemo Engine via secure tunnel
  2. Sends your function metadata (names, descriptions, types)
  3. Listens for incoming function calls
  4. Keeps the connection alive

Complete Example

Here's a full src/index.ts:

src/index.ts
import 'dotenv/config';
import "reflect-metadata";
import { DaemoBuilder } from 'daemo-engine';
import { CalculatorFunctions } from './services/calculator';

async function main() {
// 1. Build the Daemo instance
const daemo = new DaemoBuilder()
.withApiKey(process.env.DAEMO_AGENT_API_KEY!)
.withServiceName("CalculatorService")
.build();

// 2. Register your functions
await daemo.registerService(CalculatorFunctions);

// 3. Start the service
console.log("🚀 Starting Daemo service...");
await daemo.start();
console.log("✅ Service is online!");
}

main().catch(console.error);

Alternative: DaemoHostedConnection

For more control over the connection, use DaemoHostedConnection directly:

src/manual-connect.ts
import 'dotenv/config';
import "reflect-metadata";
import { DaemoBuilder, DaemoHostedConnection } from 'daemo-engine';
import { MyApiService } from './myApiService';

async function main() {
const myApiService = new MyApiService();

// Build the session data
const sessionData = new DaemoBuilder()
.withServiceName("api_service")
.registerService(myApiService)
.build();

// Connect to the Daemo Gateway
const connection = new DaemoHostedConnection(
{
daemoGatewayUrl: process.env.DAEMO_GATEWAY_URL, // Optional: custom gateway
agentApiKey: process.env.DAEMO_AGENT_API_KEY,
},
sessionData,
);

await connection.start();
console.log("🚀 Daemo service connected!");
}

main().catch(console.error);

This pattern is useful when you need to:

  • Specify a custom gateway URL
  • Have more control over connection lifecycle
  • Separate configuration from registration

Adding a System Prompt

The system prompt guides the AI on how to use your service. It appears in the dashboard and influences how the AI responds:

src/index.ts
const daemo = new DaemoBuilder()
.withApiKey(process.env.DAEMO_AGENT_API_KEY!)
.withServiceName("CRMService")
.withSystemPrompt(`
You are a helpful CRM assistant with access to a customer relationship management system.

You can help users:
- Manage contacts (create, read, update, delete)
- Manage deals (create, read, update, delete, change stages)
- Manage notes (create, read, search with semantic similarity)

Important guidelines:
- When creating contacts, deals, or notes, ensure all required fields are provided
- Email addresses must be unique for contacts
- Deal stages follow this pipeline: Lead Identified → Meeting Scheduled → Demo Completed → Proposal Sent → Follow-Up → Contract Sent → Closed Won/Lost
- Always validate IDs before operations
- Provide clear error messages if operations fail
`)
.build();
Tip

System prompts appear in the dashboard. When you view your service in app.daemo.ai, you'll see this prompt displayed. It helps you and your team understand what each service does.

Info

📦 Real-World Example: The SF 311 Agent has an excellent system prompt (~80 lines) that teaches the LLM query strategies, performance rules, and schema details. See daemoService.ts in the repo for a production-quality prompt template.

Multiple Services

You can register multiple services to the same agent:

src/index.ts
// Option 1: Multiple registrations to one instance
const daemo = new DaemoBuilder()
.withApiKey(process.env.DAEMO_AGENT_API_KEY!)
.withServiceName("MultiService")
.build();

await daemo.registerService(CalculatorFunctions);
await daemo.registerService(CRMFunctions);
await daemo.registerService(NotificationFunctions);
await daemo.start();

// Option 2: Run separate services (different processes)
// service-a/index.ts
const daemoA = new DaemoBuilder()
.withApiKey(process.env.DAEMO_AGENT_API_KEY!)
.withServiceName("CalculatorService")
.build();
await daemoA.registerService(CalculatorFunctions);
await daemoA.start();

// service-b/index.ts
const daemoB = new DaemoBuilder()
.withApiKey(process.env.DAEMO_AGENT_API_KEY!)
.withServiceName("CRMService")
.build();
await daemoB.registerService(CRMFunctions);
await daemoB.start();

All services connected to the same agent will appear in the dashboard and be available to the AI.

Running Your Service

Development

Terminal
# With ts-node
npx ts-node src/index.ts

# Or add to package.json scripts
# "scripts": { "dev": "ts-node src/index.ts" }
npm run dev

Production

Compile and run:

Terminal
# Compile
npx tsc

# Run
node dist/index.js

Or use a process manager:

Terminal
# With PM2
pm2 start dist/index.js --name "my-daemo-service"

# Keep running after terminal closes
pm2 save

Keeping the Service Running

Your service needs to stay running for the AI to call your functions. Options:

EnvironmentSolution
Local devKeep terminal open, use nodemon for auto-restart
ServerUse PM2, systemd, or Docker
CloudAWS Lambda, Google Cloud Run, Azure Functions
ServerlessVercel, Railway, Render

Auto-restart on Changes (Development)

Terminal
npm install -D nodemon

# Add to package.json
# "scripts": { "dev": "nodemon --exec ts-node src/index.ts" }
npm run dev

What Happens When You Start

When you run daemo.start():

  1. Connection — Secure tunnel established to Daemo Engine
  2. Registration — Function metadata sent to the platform
  3. Online — Service shows as "online" in dashboard
  4. Waiting — Service listens for function calls

You'll see your service and functions appear in the dashboard within seconds.

Note

Service must be running. If your service stops, the AI won't be able to call your functions. The dashboard will show the service as "offline."

Troubleshooting

"Connection refused" or timeout

  • Check your internet connection
  • Verify your API key is correct
  • Ensure no firewall is blocking outbound connections

"Invalid API key"

  • Copy the key again from the dashboard
  • Check for extra spaces or newlines
  • Make sure you're using DAEMO_AGENT_API_KEY, not a different key type

Functions not appearing in dashboard

  • Ensure @DaemoTool() decorator is present on each function
  • Check that registerService() was called before start()
  • Verify the service is running (check console output)

Next Steps

Your service is running! Let's see it in action: