This commit is contained in:
1 parent
63e15b6023
commit
b1643b635d
2 files changed
+38
-1
No files matched your search
@@ -758,6 +758,17 @@ async def handle_job(ctx: JobContext) -> None:
|
||||
)
|
||||
|
||||
await ctx.connect()
|
||||
# The participant can appear in the browser slightly before AgentSession is
|
||||
# ready to accept lk.chat streams. Explicitly signal readiness so the first
|
||||
# typed message is never raced against session startup.
|
||||
try:
|
||||
await ctx.room.local_participant.publish_data(
|
||||
json.dumps({"type": "agent_ready"}),
|
||||
reliable=True,
|
||||
topic="conversation-control",
|
||||
)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
logger.warning("failed to publish agent readiness: %s", exc)
|
||||
logger.info("Agent connected to room %s", ctx.room.name)
|
||||
|
||||
|
||||
|
||||
+27
-1
@@ -31,6 +31,7 @@ const MODE_KEY = "hope_conversation_mode";
|
||||
// ── State ───────────────────────────────────────────────────────────────────
|
||||
let room = null;
|
||||
let agentParticipant = null;
|
||||
let agentReady = false;
|
||||
let uiState = "idle"; // idle | connecting | listening | thinking | speaking
|
||||
let micLevel = 0; // 0..1, smoothed
|
||||
let agentAudioLevel = 0; // 0..1, smoothed
|
||||
@@ -518,7 +519,9 @@ function registerTranscriptionStream(rm) {
|
||||
function handleDataPacket(payload, participant, topic) {
|
||||
try {
|
||||
const msg = JSON.parse(new TextDecoder().decode(payload));
|
||||
if (msg.type === "transcript") {
|
||||
if (msg.type === "agent_ready") {
|
||||
agentReady = true;
|
||||
} else if (msg.type === "transcript") {
|
||||
addMessage(msg.role || "agent", msg.text);
|
||||
if (conversationMode === "text" && (msg.role || "agent") === "agent") {
|
||||
setState("listening");
|
||||
@@ -721,6 +724,7 @@ function createRoom(token) {
|
||||
startBtn.disabled = false;
|
||||
stopBtn.disabled = true;
|
||||
agentParticipant = null;
|
||||
agentReady = false;
|
||||
});
|
||||
|
||||
return newRoom.connect(LIVEKIT_URL, token, {
|
||||
@@ -733,6 +737,22 @@ function createRoom(token) {
|
||||
});
|
||||
}
|
||||
|
||||
function waitForAgentReady(timeoutMs) {
|
||||
return new Promise((resolve) => {
|
||||
if (agentReady) return resolve(true);
|
||||
const deadline = Date.now() + timeoutMs;
|
||||
const timer = setInterval(() => {
|
||||
if (agentReady) {
|
||||
clearInterval(timer);
|
||||
resolve(true);
|
||||
} else if (Date.now() > deadline) {
|
||||
clearInterval(timer);
|
||||
resolve(false);
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
|
||||
function waitForAgent(timeoutMs) {
|
||||
return new Promise((resolve) => {
|
||||
if (findAgent(room)) return resolve(true);
|
||||
@@ -773,6 +793,7 @@ async function connectConversation() {
|
||||
const stale = room;
|
||||
room = null;
|
||||
agentParticipant = null;
|
||||
agentReady = false;
|
||||
await stale.disconnect();
|
||||
const freshToken = await fetchToken(ROOM_NAME);
|
||||
room = await createRoom(freshToken);
|
||||
@@ -780,6 +801,10 @@ async function connectConversation() {
|
||||
throw new Error("Assistant did not join — reload the page and try again");
|
||||
}
|
||||
}
|
||||
statusEl.textContent = "Hope joined · Finishing setup…";
|
||||
if (!(await waitForAgentReady(10000))) {
|
||||
throw new Error("Assistant joined but was not ready — try again");
|
||||
}
|
||||
|
||||
sendModeMessage(conversationMode);
|
||||
if (conversationMode === "voice") {
|
||||
@@ -870,6 +895,7 @@ stopBtn.addEventListener("click", () => {
|
||||
room.disconnect();
|
||||
room = null;
|
||||
agentParticipant = null;
|
||||
agentReady = false;
|
||||
}
|
||||
teardownAudio();
|
||||
stopVisualLoop();
|
||||
|
||||
Reference in new issue
Block a user