fix: route voice wake to main
parent
066a2828c4
commit
cf96ad8ef9
|
|
@ -38,8 +38,7 @@ final class NodeAppModel {
|
||||||
init() {
|
init() {
|
||||||
self.voiceWake.configure { [weak self] cmd in
|
self.voiceWake.configure { [weak self] cmd in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
let nodeId = UserDefaults.standard.string(forKey: "node.instanceId") ?? "ios-node"
|
let sessionKey = "main"
|
||||||
let sessionKey = "node-\(nodeId)"
|
|
||||||
do {
|
do {
|
||||||
try await self.sendVoiceTranscript(text: cmd, sessionKey: sessionKey)
|
try await self.sendVoiceTranscript(text: cmd, sessionKey: sessionKey)
|
||||||
} catch {
|
} catch {
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ actor BridgeServer {
|
||||||
guard !text.isEmpty else { return }
|
guard !text.isEmpty else { return }
|
||||||
|
|
||||||
let sessionKey = payload.sessionKey?.trimmingCharacters(in: .whitespacesAndNewlines).nonEmpty
|
let sessionKey = payload.sessionKey?.trimmingCharacters(in: .whitespacesAndNewlines).nonEmpty
|
||||||
?? "node-\(nodeId)"
|
?? "main"
|
||||||
|
|
||||||
_ = await GatewayConnection.shared.sendAgent(GatewayAgentInvocation(
|
_ = await GatewayConnection.shared.sendAgent(GatewayAgentInvocation(
|
||||||
message: text,
|
message: text,
|
||||||
|
|
|
||||||
|
|
@ -2793,6 +2793,54 @@ describe("gateway server", () => {
|
||||||
await server.close();
|
await server.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("bridge voice transcript defaults to main session", async () => {
|
||||||
|
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdis-gw-"));
|
||||||
|
testSessionStorePath = path.join(dir, "sessions.json");
|
||||||
|
await fs.writeFile(
|
||||||
|
testSessionStorePath,
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
main: {
|
||||||
|
sessionId: "sess-main",
|
||||||
|
updatedAt: Date.now(),
|
||||||
|
lastChannel: "whatsapp",
|
||||||
|
lastTo: "+1555",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
"utf-8",
|
||||||
|
);
|
||||||
|
|
||||||
|
const port = await getFreePort();
|
||||||
|
const server = await startGatewayServer(port);
|
||||||
|
const bridgeCall = bridgeStartCalls.at(-1);
|
||||||
|
expect(bridgeCall?.onEvent).toBeDefined();
|
||||||
|
|
||||||
|
const spy = vi.mocked(agentCommand);
|
||||||
|
const beforeCalls = spy.mock.calls.length;
|
||||||
|
|
||||||
|
await bridgeCall?.onEvent?.("ios-node", {
|
||||||
|
event: "voice.transcript",
|
||||||
|
payloadJSON: JSON.stringify({ text: "hello" }),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(spy.mock.calls.length).toBe(beforeCalls + 1);
|
||||||
|
const call = spy.mock.calls.at(-1)?.[0] as Record<string, unknown>;
|
||||||
|
expect(call.sessionId).toBe("sess-main");
|
||||||
|
expect(call.deliver).toBe(false);
|
||||||
|
expect(call.surface).toBe("Node");
|
||||||
|
|
||||||
|
const stored = JSON.parse(
|
||||||
|
await fs.readFile(testSessionStorePath, "utf-8"),
|
||||||
|
) as Record<string, { sessionId?: string } | undefined>;
|
||||||
|
expect(stored.main?.sessionId).toBe("sess-main");
|
||||||
|
expect(stored["node-ios-node"]).toBeUndefined();
|
||||||
|
|
||||||
|
await server.close();
|
||||||
|
});
|
||||||
|
|
||||||
test("bridge chat.abort cancels while saving the session store", async () => {
|
test("bridge chat.abort cancels while saving the session store", async () => {
|
||||||
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdis-gw-"));
|
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdis-gw-"));
|
||||||
testSessionStorePath = path.join(dir, "sessions.json");
|
testSessionStorePath = path.join(dir, "sessions.json");
|
||||||
|
|
|
||||||
|
|
@ -1800,8 +1800,10 @@ export async function startGatewayServer(
|
||||||
if (text.length > 20_000) return;
|
if (text.length > 20_000) return;
|
||||||
const sessionKeyRaw =
|
const sessionKeyRaw =
|
||||||
typeof obj.sessionKey === "string" ? obj.sessionKey.trim() : "";
|
typeof obj.sessionKey === "string" ? obj.sessionKey.trim() : "";
|
||||||
|
const mainKey =
|
||||||
|
(loadConfig().inbound?.session?.mainKey ?? "main").trim() || "main";
|
||||||
const sessionKey =
|
const sessionKey =
|
||||||
sessionKeyRaw.length > 0 ? sessionKeyRaw : `node-${nodeId}`;
|
sessionKeyRaw.length > 0 ? sessionKeyRaw : mainKey;
|
||||||
const { storePath, store, entry } = loadSessionEntry(sessionKey);
|
const { storePath, store, entry } = loadSessionEntry(sessionKey);
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const sessionId = entry?.sessionId ?? randomUUID();
|
const sessionId = entry?.sessionId ?? randomUUID();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue