fix: unique room names per session, JT_ROOM dispatch, dispatch-first prompt

- token_server: generate voice-{uuid8} room name per request so each
  browser session creates a fresh room and triggers agent dispatch
- token claim: add jobType JT_ROOM to roomConfig.agents
- livekit.yaml: revert empty_timeout to default (300s)
- agent.py: system prompt now mandates dispatch_task for all non-trivial
  tasks (not just research); removed inline web_search instructions;
  added tool_call logging in _ReasoningFallbackWrapper
This commit is contained in:
Shane
2026-08-23 07:05:03 -04:00
parent 98168f2876
commit f80b9ebe3d
3 changed files with 29 additions and 24 deletions
+24 -16
View File
@@ -63,15 +63,6 @@ SYSTEM_PROMPT = textwrap.dedent("""\
- Never write more than three sentences in a row.
- Never read back URLs, file paths, or technical identifiers.
# Web access
You have web_search and web_scrape tools. Use them when the user asks about
current events, recent news, prices, sports scores, or anything
that may have changed since your training data. Search first, then scrape
a result only if you need more detail. Answer from what you find, in your
normal conversational style — don't cite sources formally, just mention the
source naturally ("according to..."). If a search comes up empty, say so
briefly and move on.
# Weather & Time
You can check the weather for any location. Use get_weather when the user
asks about current conditions, temperature, or forecasts. It returns a
@@ -79,6 +70,27 @@ SYSTEM_PROMPT = textwrap.dedent("""\
Use get_time when the user asks what time or day it is. If they mention
a city, pass it as the location argument.
# Background Tasks (dispatch_task) — USE FOR ALL NON-TRIVIAL TASKS
For ANY task that is not a simple one-sentence answer from your own
knowledge, you MUST call dispatch_task. This includes: looking up news,
researching topics, checking current events, prices, sports scores,
writing something, summarizing, comparing options, planning, or anything
that takes more than a couple seconds to think through. Do NOT use
web_search or web_scrape directly; always dispatch instead.
The only things you answer inline are: weather (get_weather), time
(get_time), memory operations, and trivial facts you already know.
Examples:
- User says "what's the latest news?" → CALL dispatch_task with
description="Find the top 5 international news headlines today"
- User says "look up the price of a PS5" → CALL dispatch_task with
description="Find the current retail price of a PlayStation 5"
- User says "plan a weekend trip to Denver" → CALL dispatch_task with
description="Plan a two-day weekend trip to Denver including activities"
After calling dispatch_task, tell the user "I'll get on that for you"
and keep the conversation going. The result comes back automatically — when
you receive it, share the findings naturally in your conversational style.
You can have multiple tasks running at once.
# Memory (CRITICAL — always use these tools)
You MUST call memory_save whenever the user tells you something to remember,
shares a preference, or says "remember that...". Do NOT just say "okay I'll
@@ -99,13 +111,6 @@ SYSTEM_PROMPT = textwrap.dedent("""\
use skill_save to record it so you can follow it next time. Be selective: only
save skills for repeatable tasks, not one-off facts (those go in memory).
# Background Tasks (dispatch_task)
When the user asks you to research something, look up news, or do anything
that will take more than a few seconds, CALL dispatch_task with a clear
description of what to investigate. Tell the user "I'll take a look at that
for you" and keep talking. The result comes back automatically — when you
receive it, share the findings naturally. You can have multiple tasks running
at once.
""")
@@ -165,6 +170,9 @@ class _ReasoningFallbackWrapper:
self._last_reasoning = reasoning
if chunk.has_response():
self._has_content = True
tc = getattr(delta, "tool_calls", None)
if tc:
logger.info("LLM tool_call: %s", [t.function.name for t in tc])
return chunk
async def collect(self):