Sales & Recruitment
Multi-channel outreach with tone adjustment and response handling
SR-1 recruits a mobile butcher across 4 channels with real-time adjustment.
Channels
import { Rodeo } from "@rodeo/sdk";
const rodeo = new Rodeo({ apiKey: process.env.RODEO_API_KEY! });
const sms = await rodeo.channels.create({
name: "sms-main",
type: "direct",
tone: { register: "casual", voice: "peer", awareness: "cold", deniability: "none" },
provider: "twilio",
provider_config: { from: "+15551234567" },
signal_capabilities: ["delivery", "response"],
});
const email = await rodeo.channels.create({
name: "email-formal",
type: "direct",
tone: { register: "formal", voice: "authority", awareness: "warm", deniability: "none" },
provider: "sendgrid",
signal_capabilities: ["delivery", "engagement"],
});
const referral = await rodeo.channels.create({
name: "referral-network",
type: "proxy",
tone: { register: "casual", voice: "peer", awareness: "warm", deniability: "plausible" },
provider: "internal",
coordination_config: { role: "peer-referral", region: "TX-Hill-Country" },
});
const phone = await rodeo.channels.create({
name: "phone-direct",
type: "direct",
tone: { register: "professional", voice: "peer", awareness: "warm", deniability: "none" },
provider: "twilio-voice",
});Audience
const butcher = await rodeo.audiences.create({
type: "individual",
context: {
name: "Jordan",
role: "mobile butcher",
region: "TX-Hill-Country",
timezone: "America/Chicago",
notes: "Works 6am-2pm. Prefers text over email. Competitive offers from other networks.",
},
bounds: { maxTouchesPerDay: 3, maxTouchesPerWeek: 8, cooldownMinutes: 60 },
rhythm: { preferredTimes: ["08:00-10:00", "17:00-19:00"], timezone: "America/Chicago" },
});Intention
const intention = await rodeo.intentions.create({
type: "recruit",
description: "Recruit mobile butcher for ranch processing network",
success_condition: { contractSigned: true, startDate: "within 14 days" },
alignment: {
audienceBenefit: "Guaranteed weekly volume, premium pricing ($0.85/lb vs market $0.65/lb), flexible scheduling",
mutuality: "Butcher gets stable income and premium rates, network gets reliable processing capacity in Hill Country region",
},
});Scene
const result = await rodeo.scenes
.build()
.intention(intention.id)
.audience(butcher.id)
.arc("surround")
.constraints({ maxTouches: 4, maxDuration: "2h", budget: 50 })
.onDecline("terminate")
.onNegative("decelerate")
.rule({
condition: { type: "response", metric: "replied", sentiment: "positive" },
action: "accelerate",
params: { factor: 2 },
})
.rule({
condition: { type: "sentiment", metric: "hostile" },
action: "terminate",
})
.touch({
sequence: 1,
channel_id: sms.id,
content: { body: "Hey Jordan — heard you do the best custom cuts in the Hill Country. We're building something that might interest you." },
tone: { warmth: "warm", urgency: "none", ask: "implicit" },
timing: { mode: "absolute", at: "2025-01-15T08:00:00-06:00" },
})
.touch({
sequence: 2,
channel_id: email.id,
content: {
subject: "Processing Network — Hill Country",
body: "Formal introduction with volume projections, pricing structure, and contract terms...",
},
tone: { warmth: "warm", urgency: "gentle", ask: "soft" },
timing: { mode: "relative", after: "40m", anchor: "touch:1" },
})
.touch({
sequence: 3,
channel_id: referral.id,
content: { brief: "Mention the processing network naturally in conversation. Share your own experience." },
tone: { warmth: "familiar", urgency: "none", ask: "none" },
timing: { mode: "relative", after: "4m", anchor: "touch:2" },
})
.touch({
sequence: 4,
channel_id: phone.id,
content: { script: "Call to discuss terms, answer questions, close if ready." },
tone: { warmth: "familiar", urgency: "present", ask: "direct" },
timing: { mode: "relative", after: "6m", anchor: "touch:3" },
})
.create();
await rodeo.scenes.declare(result.scene.id);Signals
await rodeo.signals.report({
signalId: "twilio-delivery", touchId: result.touches[0].id,
sceneId: result.scene.id, type: "delivery", metric: "delivered", value: true,
});
await rodeo.signals.report({
signalId: "twilio-response", touchId: result.touches[0].id,
sceneId: result.scene.id, type: "response", metric: "replied",
value: "Yeah I've been looking for something like this. What's the volume?",
});
await rodeo.signals.report({
signalId: "sentiment-analyzer", touchId: result.touches[0].id,
sceneId: result.scene.id, type: "sentiment", metric: "positive",
value: 0.92, confidence: 0.78,
});Ledger
const entries = await rodeo.ledger.query({ intentionType: "recruit" });
const profile = await rodeo.ledger.agentProfile(agentId);