Skip to content

fix(worker): preserve explicit option defaults#1798

Open
rosetta-livekit-bot[bot] wants to merge 1 commit into
1.5.0from
evincing-smear-pardon
Open

fix(worker): preserve explicit option defaults#1798
rosetta-livekit-bot[bot] wants to merge 1 commit into
1.5.0from
evincing-smear-pardon

Conversation

@rosetta-livekit-bot

@rosetta-livekit-bot rosetta-livekit-bot Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Testing

  • pnpm build:agents

Ported from livekit/agents#6121

Original PR description

This PR fixes update_options to use NotGivenOr[float] defaults for timeouts, ensuring they are not reset to default values if not explicitly specified. It also adds the missing assignment for initialize_process_timeout in the update_options function body.

@changeset-bot

changeset-bot Bot commented Jun 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 106e78b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 35 packages
Name Type
@livekit/agents Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-assemblyai Patch
@livekit/agents-plugin-baseten Patch
@livekit/agents-plugin-bey Patch
@livekit/agents-plugin-cartesia Patch
@livekit/agents-plugin-cerebras Patch
@livekit/agents-plugin-deepgram Patch
@livekit/agents-plugin-did Patch
@livekit/agents-plugin-elevenlabs Patch
@livekit/agents-plugin-fishaudio Patch
@livekit/agents-plugin-google Patch
@livekit/agents-plugin-hedra Patch
@livekit/agents-plugin-hume Patch
@livekit/agents-plugin-inworld Patch
@livekit/agents-plugin-lemonslice Patch
@livekit/agents-plugin-liveavatar Patch
@livekit/agents-plugin-livekit Patch
@livekit/agents-plugin-minimax Patch
@livekit/agents-plugin-mistral Patch
@livekit/agents-plugin-mistralai Patch
@livekit/agents-plugin-neuphonic Patch
@livekit/agents-plugin-openai Patch
@livekit/agents-plugin-perplexity Patch
@livekit/agents-plugin-phonic Patch
@livekit/agents-plugin-resemble Patch
@livekit/agents-plugin-rime Patch
@livekit/agents-plugin-runway Patch
@livekit/agents-plugin-sarvam Patch
@livekit/agents-plugin-silero Patch
@livekit/agents-plugin-soniox Patch
@livekit/agents-plugin-tavus Patch
@livekit/agents-plugins-test Patch
@livekit/agents-plugin-trugen Patch
@livekit/agents-plugin-xai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@rosetta-livekit-bot rosetta-livekit-bot Bot requested a review from longcw June 16, 2026 07:38

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

Open in Devin Review

Comment thread agents/src/worker.ts
Comment on lines 243 to +246
this.apiSecret = apiSecret;
this.workerToken = workerToken;
this.host = host;
this.port = port || Default.port(production);
this.port = port ?? Default.port(production);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 CLI production mode gets dev defaults for numIdleProcesses and port due to ||?? change

When a user runs their agent with cli.runApp(new ServerOptions({ agent: '...' })) and uses the start command (production mode), the CLI re-constructs ServerOptions at agents/src/cli.ts:31-32 by spreading the already-resolved options and overriding production to true. The development-mode defaults numIdleProcesses=0 and port=0 (resolved during the first construction with production=false) are now non-nullish values, so ?? preserves them instead of re-evaluating the production defaults.

Trace of the regression
  1. User code: new ServerOptions({ agent: '...' })production=falsenumIdleProcesses = undefined ?? Default.numIdleProcesses(false) = 0, port = undefined ?? Default.port(false) = 0
  2. CLI start: runServer({ opts, production: true }) → at cli.ts:32: new ServerOptions({ production: true, ...opts }) where opts has numIdleProcesses: 0, port: 0
  3. Second construction: 0 ?? Default.numIdleProcesses(true) = 0 (wrong, should be min(parallelism, 4)), 0 ?? Default.port(true) = 0 (wrong, should be 8081)
  4. Old || behavior: 0 || Default.numIdleProcesses(true) = 4, 0 || Default.port(true) = 8081 — worked by accident because 0 is falsy

This means all production deployments via the standard CLI path get no pre-warmed processes (numIdleProcesses=0, causing latency for every job) and a random health-check port (port=0, breaking production health probes that expect port 8081).

(Refers to lines 222-246)

Prompt for agents
The root cause is that the CLI re-constructs ServerOptions with a changed `production` flag by spreading the already-resolved instance (cli.ts:31-32), making it impossible to distinguish 'user explicitly passed 0' from 'resolved to 0 from dev default'. The fix from || to ?? is correct for preserving explicit values, but needs a mechanism to handle the re-construction case.

Possible approaches:
1. Track which fields were explicitly set vs defaulted (e.g. store the raw constructor args, or use sentinel values/symbols for 'not explicitly provided').
2. In the CLI re-construction path (cli.ts:31-32), strip out fields that equal their dev-mode defaults before spreading, so the new constructor re-evaluates them with the correct production flag.
3. Instead of re-constructing ServerOptions in cli.ts, mutate the production field on the existing instance and have a method to re-evaluate production-dependent defaults.
4. Use undefined as the representation for 'use the default' and only resolve to concrete values lazily (e.g. in AgentServer constructor), keeping ServerOptions fields as `number | undefined`.

Files involved: agents/src/worker.ts (ServerOptions constructor, lines 222-246), agents/src/cli.ts (runServer function, lines 30-32).
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread agents/src/worker.ts
this.loadFunc = loadFunc;
this.loadThreshold = loadThreshold || Default.loadThreshold(production);
this.numIdleProcesses = numIdleProcesses || Default.numIdleProcesses(production);
this.loadThreshold = loadThreshold ?? Default.loadThreshold(production);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Pre-existing bug: loadThreshold also not re-evaluated for production in CLI path

The loadThreshold field has the same re-construction problem as numIdleProcesses and port, but it was already broken before this PR. The dev default is Infinity (truthy), so even the old || code would keep Infinity when the CLI switches to production: true (since Infinity || 0.7 = Infinity). This is partially mitigated for Cloud deployments by the guard at agents/src/worker.ts:322-328 in the AgentServer constructor which forces the production default when workerToken is set. However, self-hosted production deployments (no workerToken) would still get loadThreshold = Infinity, meaning the worker never reports as full. This is pre-existing and not introduced by this PR.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants