Repository navigation
Conversation
A connect-only LiveKit job is dispatched by config.agent_name, authored from the pasted target_system_prompt, and may claim the customer's LiveKit secrets. Closes TH-8481
6 of 17 tasks
cdileep23
requested review from
hadarishav and
khushalsonawat
and removed request for
hadarishav
October 8, 2026 12:54
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lets the harness run against a LiveKit agent that is already deployed (hosted,
connect_only), not only one it starts from source. A hosted LiveKit job carries the agent's registered name and a pasted system prompt; the call runner dispatches that name into a room on the customer's LiveKit project, and authoring builds the agent profile from the prompt.Pairs with the platform PR: future-agi/future-agi#3402
Why the changes are done (what is the problem)
A hosted LiveKit job could never complete:
_dispatch_agent_nameread the agent name only fromruntime.metadata["livekit_agent_name"], which is set only when ALK starts the agent from source and reads itsLIVEKIT_AGENT_NAME. A hosted agent has no such process, so every call aborted withvoice_dispatch_identity_unavailable.target_providersecrets only for Vapi and Retell, so the LiveKit key and secret failed withsecret_unclaimed.AgentConnectionacceptedlivekit+connect_onlywith no required fields, so a bad job only failed at dispatch.What changed
src/fi/alk/harness/job.py
A
livekit+connect_onlyAgentConnectionrequiresconfig.agent_nameand atarget_system_prompt(max 65,536 chars), mirroring the phone branch. Fails withlivekit_connect_only_requires_agent_name/livekit_connect_only_requires_target_system_prompt.src/fi/alk/harness/authoring_entrypoint.py
_load_provider_import_profilereturns{"provider": "livekit", "modality": "voice", "agent_name", "system_prompt", "tools": []}for hosted LiveKit, and deletes the one-shot target-secrets file if one was passed (it exists only for read-only provider inspection).src/fi/alk/harness/call_runner.py
_dispatch_agent_name(runtime, job)readsjob.agent.config["agent_name"]forconnect_onlyjobs and keeps readingruntime.metadata["livekit_agent_name"]otherwise. The call site passes the job.src/fi/alk/harness/process_preflight.py
livekitjoinsvapi,retell,retell_chatin the connect-only set that may claim customer target-provider secrets. Phone stays out: it dials with platform SIP credentials.src/fi/alk/harness/sandbox_server.py
The local sandbox server's
provider_onlyrequests acceptlivekit.src/fi/alk/harness/sources.py
The provider briefing tells the authoring model that a phone or LiveKit connection may contain only the user-supplied prompt.
Known limitations (follow-ups)
Tools are empty for hosted LiveKit. Vapi and Retell tools are fetched from their APIs (
inspect_provider_target:GET /assistant/{id}+/tool/{id},get-agent+get-retell-llm/get-conversation-flow). A LiveKit agent's tools are functions in the customer's code and LiveKit exposes no API for them, so the profile has"tools": [], the same as phone targets. Scenarios are generated from the prompt alone. Follow-up options: read tools from the agent repository (the hosted form already has an optional GitHub repo field) or accept pasted tool schemas.Agent check happens in platform preflight. The platform PR adds a preflight probe that dispatches the agent into a throwaway room and waits up to 8s for it to join, because LiveKit accepts a dispatch for any name. It starts a short real session of the customer's agent (billed to their LiveKit and AI provider accounts) and a wrong name costs the full 8s. Planned follow-up: pass once the dispatch has an accepted job instead of waiting for the join, after testing against a real project.
Tests included (what each scenario covers)
test_livekit_connect_only_requires_agent_name_and_prompt(3 cases)AgentConnectionlivekit + connect_onlytest_livekit_connect_only_authoring_uses_the_pasted_prompt_and_drops_secrets_load_provider_import_profiletest_livekit_connect_only_dispatches_the_configured_agent_nameagent-from-sourcereturns-agentfrom config, on the customer's URLtest_connect_only_provider_claims_the_customer_target_secret(vapi, retell, retell_chat, livekit)preflight_bundletest_connect_only_phone_does_not_claim_a_customer_target_secretpreflight_bundlesecret_unclaimedtest_provider_only_accepts_a_connect_only_livekit_agentLocalSandboxRequestEach test was checked to fail with its source change reverted.
Commands to run tests
# from the repo root uv sync --frozen --all-extras .venv/bin/python -m pytest -q tests/harness/test_call_runner.py tests/harness/test_process_preflight.py tests/test_harness_sandbox_server.pyLocal verification results
The 2 failures (
test_public_github_branch_url_populates_job_ref,test_private_github_submission_becomes_hosted_job) fail the same way on untouchedorigin/dev.End to end on a local stack with an E2B template built from this branch (
alk-hosted-local:f8aeae48-d44b-4283-8276-645e9c3a0b2b): a hosted LiveKit environment built (contract, world, 10 scenarios) and a run completed all 10 calls, dispatching the deployed agent by name.Local end-to-end run
Distributed dev stack, runner wheel and E2B template built from agent-learning-kit#146 (
alk-hosted-local:f8aeae48-d44b-4283-8276-645e9c3a0b2b), hosted LiveKit agent on a LiveKit Cloud project.41f39d82-f7d4-412a-8050-b36d6dbf9dac: completed on attempt 3 (contract, world, 10 scenarios). Attempts 1 and 2 failed on local setup (AI gateway proxy route, missing storage buckets), not on the LiveKit codee95a2d0f-0d1b-410a-ab77-b82be697aafd, execution02f694fd-aece-42fb-ad85-eb9278d204d7simulator_end_call), 4 loop detector ended a repetitive closing (closing_loop)Video
None.
Screenshot of test suit run
None.
Backwards compatibility
No schema change. Behaviour changes only for
connector: livekitwithmode: connect_only, which previously could not complete.modeunset)config.agent_nameManual verification (UI)
Type of change
Checklist
Backout / rollback
Revert this PR. Hosted LiveKit jobs go back to failing at dispatch; nothing else is affected. Release order: ship this ALK change (new version, runner wheel and E2B template) before the platform PR enables the LiveKit tile.
Linear
Closes TH-8481
🤖 Generated with Claude Code