Skip to content

Commit 277207e

Browse files
committed
feat(simulate): run audio simulations against a phone number with --to-phone-number
1 parent aec8d03 commit 277207e

1 file changed

Lines changed: 44 additions & 2 deletions

File tree

‎cmd/lk/simulate.go‎

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,18 @@ var simulateAudioCommand = &cli.Command{
175175
Name: "packet-loss",
176176
Usage: "Drop packets from the simulated user's audio track",
177177
},
178+
&cli.StringFlag{
179+
Name: "to-phone-number",
180+
Usage: "Call this `NUMBER` over SIP and simulate against whoever answers, instead of dispatching an agent. Requires --from-phone-number and --scenarios.",
181+
},
182+
&cli.StringFlag{
183+
Name: "from-trunk",
184+
Usage: "Outbound SIP trunk `ID` to place --to-phone-number calls through. Without it, calls go out from a LiveKit phone number.",
185+
},
186+
&cli.StringFlag{
187+
Name: "from-phone-number",
188+
Usage: "Caller `NUMBER` for --to-phone-number calls: a LiveKit phone number the project owns, or a number on --from-trunk",
189+
},
178190
},
179191
}
180192

@@ -410,14 +422,19 @@ type simulateConfig struct {
410422
scenarioGroup *livekit.ScenarioGroup
411423
scenariosPath string // path to the --scenarios file (empty when generating from source)
412424
viewModeRunID string // non-empty when `view` opens a pre-existing run
413-
liveAgent bool // --agent-name: run against an already-running agent, don't spawn one
425+
liveAgent bool // --agent-name or --to-phone-number: run against an already-running agent, don't spawn one
414426
warnings []string // config-level warnings surfaced at setup (e.g. ignored flags)
415427

416428
// impairments on the simulated user's audio, set only in SIMULATION_MODE_AUDIO
417429
backgroundNoise bool
418430
lowQualityMicrophone bool
419431
packetLoss bool
420432

433+
// --to-phone-number: dial this number over SIP in place of dispatching agentName
434+
sipCallTo string
435+
sipTrunkID string
436+
sipNumber string
437+
421438
// TODO (steveyoon): add agent deployment support
422439
// agentDeployment string
423440
}
@@ -522,6 +539,19 @@ func runSimulate(ctx context.Context, cmd *cli.Command, simulationMode livekit.S
522539
samples := int32(cmd.Int("samples"))
523540
passRate := cmd.Float("pass-rate")
524541
liveAgentName := cmd.String("agent-name")
542+
var phoneNumber, fromTrunk, fromPhoneNumber string
543+
if simulationMode == livekit.SimulationMode_SIMULATION_MODE_AUDIO {
544+
phoneNumber = cmd.String("to-phone-number")
545+
fromTrunk = cmd.String("from-trunk")
546+
fromPhoneNumber = cmd.String("from-phone-number")
547+
}
548+
if fromTrunk != "" && phoneNumber == "" {
549+
return fmt.Errorf("--from-trunk requires --to-phone-number")
550+
}
551+
// every call needs a caller: the number simulations are placed from
552+
if phoneNumber != "" && fromPhoneNumber == "" {
553+
return fmt.Errorf("--to-phone-number requires --from-phone-number")
554+
}
525555

526556
// never auto-discovered: an explicit --scenarios file is the source of
527557
// truth, otherwise scenarios are generated from the agent's source
@@ -547,7 +577,13 @@ func runSimulate(ctx context.Context, cmd *cli.Command, simulationMode livekit.S
547577

548578
// --agent-name (even empty) means: run against an already-running agent,
549579
// don't spawn one. https://docs.livekit.io/agents/server/agent-dispatch/#automatic
550-
if cmd.IsSet("agent-name") {
580+
if phoneNumber != "" {
581+
// nothing is spawned, so there's no source to generate scenarios from.
582+
if scenariosPath == "" {
583+
return fmt.Errorf("--to-phone-number requires --scenarios (no source to generate scenarios from when calling a number)")
584+
}
585+
liveAgent = true
586+
} else if cmd.IsSet("agent-name") {
551587
// nothing is spawned, so there's no source to generate scenarios from.
552588
if scenariosPath == "" {
553589
return fmt.Errorf("--agent-name requires --scenarios (no source to generate scenarios from when running against a live agent)")
@@ -628,6 +664,9 @@ func runSimulate(ctx context.Context, cmd *cli.Command, simulationMode livekit.S
628664
simCfg.backgroundNoise = cmd.Bool("background-noise")
629665
simCfg.lowQualityMicrophone = cmd.Bool("low-quality-microphone")
630666
simCfg.packetLoss = cmd.Bool("packet-loss")
667+
simCfg.sipCallTo = phoneNumber
668+
simCfg.sipTrunkID = fromTrunk
669+
simCfg.sipNumber = fromPhoneNumber
631670
}
632671

633672
if !isInteractive() {
@@ -801,6 +840,9 @@ func createSimulationRun(ctx context.Context, c *simulateConfig) (string, *livek
801840
BackgroundNoise: c.backgroundNoise,
802841
LowQualityMicrophone: c.lowQualityMicrophone,
803842
PacketLoss: c.packetLoss,
843+
SipCallTo: c.sipCallTo,
844+
SipTrunkId: c.sipTrunkID,
845+
SipNumber: c.sipNumber,
804846
Ci: ciFromEnv(),
805847
}
806848
if c.concurrency > 0 {

0 commit comments

Comments
 (0)