Skip to content
Open
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
122 changes: 122 additions & 0 deletions .github/workflows/deploy-examples.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# SPDX-FileCopyrightText: 2026 LiveKit, Inc.
#
# SPDX-License-Identifier: Apache-2.0

name: Deploy Examples

on:
workflow_dispatch:
inputs:
ref:
description: 'Branch or ref to deploy from (default: main)'
type: string
required: false
default: 'main'
workflow_call:
inputs:
ref:
type: string
required: false

permissions:
contents: read

jobs:
deploy:
name: Deploy ${{ matrix.example }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- example: frontdesk
entry: ./frontdesk/frontdesk_agent.js
agent_id_secret: LIVEKIT_EXAMPLES_FRONTDESK_AGENT_ID
- example: survey
entry: ./survey_agent.js
agent_id_secret: LIVEKIT_EXAMPLES_SURVEY_AGENT_ID
- example: drive-thru
entry: ./drive-thru/drivethru_agent.js
agent_id_secret: LIVEKIT_EXAMPLES_DRIVE_THRU_AGENT_ID
- example: avatar
entry: ./lemonslice_realtime_avatar.js
agent_id_secret: LIVEKIT_EXAMPLES_AVATAR_AGENT_ID
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
ref: ${{ inputs.ref || 'main' }}

- name: Install LiveKit CLI
run: |
curl -sSL https://get.livekit.io/cli | bash
lk --version

- name: Add LiveKit Cloud project
env:
LIVEKIT_URL: ${{ secrets.LIVEKIT_EXAMPLES_URL }}
LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_EXAMPLES_API_KEY }}
LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_EXAMPLES_API_SECRET }}
run: |
lk project add examples \
--url "$LIVEKIT_URL" \
--api-key "$LIVEKIT_API_KEY" \
--api-secret "$LIVEKIT_API_SECRET" \
--default

- name: Prepare deploy directory
env:
AGENT_ID: ${{ secrets[matrix.agent_id_secret] }}

Check warning

Code scanning / CodeQL

Excessive Secrets Exposure Medium

All organization and repository secrets are passed to the workflow runner in
secrets[matrix.agent_id_secret]
run: |
if [ -z "$AGENT_ID" ]; then
echo "::error::${{ matrix.agent_id_secret }} is required"
exit 1
fi

deploy_dir="deploy/${{ matrix.example }}"
mkdir -p "$deploy_dir"
cp -R examples/. "$deploy_dir"
cp "$deploy_dir/src/Dockerfile-example" "$deploy_dir/Dockerfile"
cat > "$deploy_dir/src/agent.ts" <<'EOF'
import '${{ matrix.entry }}';
EOF
cat > "$deploy_dir/livekit.toml" <<EOF
[project]
subdomain = "examples-wfxyig8v"

[agent]
id = "$AGENT_ID"
EOF

- name: Build secrets file
working-directory: deploy/${{ matrix.example }}
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LEMONSLICE_API_KEY: ${{ secrets.LEMONSLICE_API_KEY }}
run: |
: > .env.deploy
# Register the agent under a deterministic name so the playground can
# dispatch to it explicitly.
echo "LIVEKIT_AGENT_NAME=${{ matrix.example }}" >> .env.deploy
case "${{ matrix.example }}" in
avatar)
keys="LEMONSLICE_API_KEY"
;;
*)
keys=""
;;
esac
Comment on lines +100 to +107
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.

🟡 OPENAI_API_KEY pulled into env but never written to secrets file for any example

The Build secrets file step maps OPENAI_API_KEY from GitHub secrets into the shell environment (line 93), but the case statement (lines 100-107) never adds it to .env.deploy for any example — the wildcard *) branch sets keys="". The frontdesk and drive-thru examples directly instantiate new openai.LLM(...) (examples/src/frontdesk/frontdesk_agent.ts:225 and examples/src/drive-thru/drivethru_agent.ts:389), which reads OPENAI_API_KEY from the environment at runtime. Unless this key is separately configured at the LiveKit Cloud project level, those deployed agents will fail when attempting OpenAI API calls. At minimum, OPENAI_API_KEY in env: is dead code if intentionally managed elsewhere, or a missing case entry if it was intended to be passed through the secrets file.

Prompt for agents
In the 'Build secrets file' step of deploy-examples.yml, the OPENAI_API_KEY is pulled from GitHub secrets into the env block (line 93) but never written to .env.deploy. The case statement at lines 100-107 only adds LEMONSLICE_API_KEY for the avatar example and sets keys to empty for all others.

The frontdesk example (examples/src/frontdesk/frontdesk_agent.ts) and drive-thru example (examples/src/drive-thru/drivethru_agent.ts) both directly instantiate openai.LLM, deepgram.STT, and elevenlabs.TTS plugins, which require OPENAI_API_KEY, DEEPGRAM_API_KEY, and ELEVENLABS_API_KEY respectively in the runtime environment.

Either:
1. Add appropriate case entries for frontdesk and drive-thru to include OPENAI_API_KEY (and potentially DEEPGRAM_API_KEY, ELEVENLABS_API_KEY) in keys, or
2. If these are managed at the LiveKit Cloud project level, remove the unused OPENAI_API_KEY from the env block to avoid confusion, or
3. Refactor frontdesk and drive-thru examples to use inference gateway strings (like survey_agent.ts does) so they don't need local API keys.
Open in Devin Review

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

for k in $keys; do
val="${!k}"
if [ -n "$val" ]; then
echo "${k}=${val}" >> .env.deploy
fi
done

- name: Deploy ${{ matrix.example }}
working-directory: deploy/${{ matrix.example }}
run: |
args=()
if [ -s .env.deploy ]; then
args+=(--secrets-file .env.deploy)
fi
lk agent deploy "${args[@]}" .
Loading