Scene Builder
Fluent API for composing scenes
const builder = rodeo.scenes.build();All methods return this for chaining except create().
intention(id)
builder.intention("intention-uuid")audience(id)
builder.audience("audience-uuid")arc(type)
builder.arc("approach")
// "approach" | "surround" | "crescendo" | "slow_burn" | "single_strike" | "siege" | "gift"constraints(c)
builder.constraints({
maxDuration: "4h",
maxBeats: 6,
budget: 100,
})pacing(p)
builder.pacing({ interval: "30m" })beat(b)
Call multiple times for multiple beats.
builder
.beat({
sequence: 1,
channel_id: "uuid",
content: { body: "First message" },
tone: { warmth: "warm", urgency: "none", ask: "implicit" },
timing: { mode: "absolute", at: "2025-01-15T08:00:00Z" },
})
.beat({
sequence: 2,
channel_id: "uuid",
content: { body: "Follow up" },
tone: { warmth: "warm", urgency: "gentle", ask: "soft" },
timing: { mode: "relative", after: "30m", anchor: "beat:1" },
})rule(r)
Call multiple times for multiple rules.
builder
.rule({
condition: { type: "response", metric: "replied", sentiment: "positive" },
action: "accelerate",
params: { factor: 2 },
})
.rule({
condition: { type: "sentiment", metric: "hostile" },
action: "terminate",
})Signal handlers
builder
.onDecline("terminate")
.onPositive("continue")
.onNeutral("continue")
.onNegative("decelerate")create()
Submits the scene. Returns a promise.
const result = await builder.create();
// result.scene (status: "draft"), result.beatsFull example
const result = await rodeo.scenes
.build()
.intention(intention.id)
.audience(audience.id)
.arc("surround")
.constraints({ maxBeats: 4, maxDuration: "2h", budget: 50 })
.onDecline("terminate")
.onPositive("accelerate")
.onNegative("decelerate")
.rule({
condition: { type: "response", metric: "replied", sentiment: "positive" },
action: "accelerate",
params: { factor: 2 },
})
.beat({
sequence: 1,
channel_id: sms.id,
content: { body: "Hey — heard you're the best." },
tone: { warmth: "warm", urgency: "none", ask: "implicit" },
timing: { mode: "absolute", at: "2025-01-15T08:00:00Z" },
})
.beat({
sequence: 2,
channel_id: email.id,
content: { subject: "Opportunity", body: "Full details..." },
tone: { warmth: "warm", urgency: "gentle", ask: "soft" },
timing: { mode: "relative", after: "40m", anchor: "beat:1" },
})
.beat({
sequence: 3,
channel_id: referral.id,
content: { brief: "Mention us naturally" },
tone: { warmth: "familiar", urgency: "none", ask: "none" },
timing: { mode: "relative", after: "4m", anchor: "beat:2" },
})
.beat({
sequence: 4,
channel_id: phone.id,
content: { script: "Closing call" },
tone: { warmth: "familiar", urgency: "present", ask: "direct" },
timing: { mode: "relative", after: "6m", anchor: "beat:3" },
})
.create();
await rodeo.scenes.declare(result.scene.id);