Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion autocomplete/fish_autocomplete
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,16 @@ complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_s
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l num-simulations -s n -r -d 'Number of scenarios to generate'
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l concurrency -r -d 'Max simulations running in parallel (default: server-side limit)'
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l scenarios -r -d 'Path to a scenarios `FILE` (yaml). If omitted, scenarios are generated from the agent\'s source'
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l audio -d 'Simulate speech-to-speech interactions using the agent\'s full audio pipeline. By default, simulations run in text-only mode.'
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l yes -s y -d 'Skip the source-upload confirmation prompt (required for non-interactive runs that generate from source)'
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l view -r -d 'Open a pre-existing simulation'
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l export -r -d 'Print the run with run `ID` and its exact per-job chat contexts as JSON. Nothing is run or polled: the run must already be finished'
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l agent-name -r -d 'Run against an already-running agent instead of spawning one locally. Pass the registered `NAME`, or "" to target the project\'s default agent (the one that auto-joins every room). Requires --scenarios.'
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l help -s h -d 'show help'
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate; and not __fish_seen_subcommand_from audio' -a 'audio' -d 'Simulate speech-to-speech interactions using the agent\'s full audio pipeline'
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate; and __fish_seen_subcommand_from audio' -f -l background-noise -d 'Mix ambient noise into the simulated user\'s audio'
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate; and __fish_seen_subcommand_from audio' -f -l low-quality-microphone -d 'Publish the simulated user\'s audio as a low-quality microphone would capture it'
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate; and __fish_seen_subcommand_from audio' -f -l packet-loss -d 'Drop packets from the simulated user\'s audio track'
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate; and __fish_seen_subcommand_from audio' -f -l help -s h -d 'show help'
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy promote status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console daemon simulate help h' -a 'help' -d 'Shows a list of commands or help for one command'
complete -c lk -n '__fish_seen_subcommand_from analytics' -f -l experimental -d 'Enable experimental features'
complete -c lk -n '__fish_seen_subcommand_from analytics' -f -l help -s h -d 'show help'
Expand Down
65 changes: 51 additions & 14 deletions cmd/lk/simulate.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ var simulateCommand = &cli.Command{
simulateProjectConfig = pc
return nil, nil
},
Action: runSimulate,
Action: func(ctx context.Context, cmd *cli.Command) error {
return runSimulate(ctx, cmd, livekit.SimulationMode_SIMULATION_MODE_TEXT)
},
Commands: []*cli.Command{simulateAudioCommand},
Flags: []cli.Flag{
&cli.IntFlag{
Name: "num-simulations",
Expand All @@ -85,10 +88,6 @@ var simulateCommand = &cli.Command{
Name: "scenarios",
Usage: "Path to a scenarios `FILE` (yaml). If omitted, scenarios are generated from the agent's source",
},
&cli.BoolFlag{
Name: "audio",
Usage: "Simulate speech-to-speech interactions using the agent's full audio pipeline. By default, simulations run in text-only mode.",
},
&cli.BoolFlag{
Name: "yes",
Aliases: []string{"y"},
Expand All @@ -109,6 +108,34 @@ var simulateCommand = &cli.Command{
},
}

// simulateAudioCommand inherits every flag on `simulate`: flags there are
// persistent (cli.FlagBase.Local defaults to false), so they parse on either
// side of the subcommand name.
var simulateAudioCommand = &cli.Command{
Name: "audio",
Usage: "Simulate speech-to-speech interactions using the agent's full audio pipeline",
Description: "Options on lk agent simulate apply here too, e.g. --scenarios and --agent-name.",
ArgsUsage: "[entrypoint]",
HideHelpCommand: true,
Action: func(ctx context.Context, cmd *cli.Command) error {
return runSimulate(ctx, cmd, livekit.SimulationMode_SIMULATION_MODE_AUDIO)
},
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "background-noise",
Usage: "Mix ambient noise into the simulated user's audio",
},
&cli.BoolFlag{
Name: "low-quality-microphone",
Usage: "Publish the simulated user's audio as a low-quality microphone would capture it",
},
&cli.BoolFlag{
Name: "packet-loss",
Usage: "Drop packets from the simulated user's audio track",
},
},
}

// writeGeneratedScenariosTemp writes a generated run's scenarios to a temp
// scenarios.yaml; "" when the run carries none.
func writeGeneratedScenariosTemp(run *livekit.SimulationRun) (string, error) {
Expand Down Expand Up @@ -189,6 +216,12 @@ type simulateConfig struct {
viewModeRunID string // non-empty when --view opens a pre-existing run
liveAgent bool // --agent-name: run against an already-running agent, don't spawn one
warnings []string // config-level warnings surfaced at setup (e.g. ignored flags)

// impairments on the simulated user's audio, set only in SIMULATION_MODE_AUDIO
backgroundNoise bool
lowQualityMicrophone bool
packetLoss bool

// TODO (steveyoon): add agent deployment support
// agentDeployment string
}
Expand Down Expand Up @@ -273,7 +306,7 @@ func buildTaskExists(projectDir string) (bool, error) {
return ok, nil
}

func runSimulate(ctx context.Context, cmd *cli.Command) error {
func runSimulate(ctx context.Context, cmd *cli.Command, simulationMode livekit.SimulationMode) error {
pc := simulateProjectConfig

// --export is a one-shot read of a finished run, so it short-circuits
Expand Down Expand Up @@ -368,11 +401,6 @@ func runSimulate(ctx context.Context, cmd *cli.Command) error {

simClient := lksdk.NewAgentSimulationClient(serverURL, pc.APIKey, pc.APISecret)

simulationMode := livekit.SimulationMode_SIMULATION_MODE_TEXT
if cmd.Bool("audio") {
simulationMode = livekit.SimulationMode_SIMULATION_MODE_AUDIO
}

simCfg := &simulateConfig{
ctx: ctx,
client: simClient,
Expand All @@ -392,6 +420,12 @@ func runSimulate(ctx context.Context, cmd *cli.Command) error {
warnings: simulateConfigWarnings(mode, numSimulations),
}

if simulationMode == livekit.SimulationMode_SIMULATION_MODE_AUDIO {
simCfg.backgroundNoise = cmd.Bool("background-noise")
simCfg.lowQualityMicrophone = cmd.Bool("low-quality-microphone")
simCfg.packetLoss = cmd.Bool("packet-loss")
}

if !isInteractive() {
return runSimulateCI(ctx, simCfg)
}
Expand Down Expand Up @@ -522,9 +556,12 @@ func startSimulationAgent(c *simulateConfig, forwardOutput io.Writer) (*AgentPro

func createSimulationRun(ctx context.Context, c *simulateConfig) (string, *livekit.PresignedPostRequest, error) {
req := &livekit.SimulationRun_Create_Request{
AgentName: c.agentName,
NumSimulations: c.numSimulations,
Mode: c.simulationMode,
AgentName: c.agentName,
NumSimulations: c.numSimulations,
Mode: c.simulationMode,
BackgroundNoise: c.backgroundNoise,
LowQualityMicrophone: c.lowQualityMicrophone,
PacketLoss: c.packetLoss,
}
if c.concurrency > 0 {
req.Concurrency = &c.concurrency
Expand Down
Loading
Loading