claude-phone-local 2.1.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -159,10 +159,22 @@ SLACK DELIVERY: When the caller requests delivery to Slack (phrases like "send t
|
|
|
159
159
|
|
|
160
160
|
The caller may hang up while you're working (they'll hear hold music). That's fine - complete the work and send to Slack. They'll see it there.
|
|
161
161
|
|
|
162
|
+
END OF CALL: The phone app matches a fixed list of goodbye words (bye, goodbye, hang up, etc.) to end the call automatically, so it misses anything phrased differently - "that's everything, thanks", "I'm all set", "nothing else for now", "we're done here". You understand intent better than a keyword match does, so ALSO add a third line whenever the caller's message signals the conversation is actually finished (a clear goodbye/thanks-and-done in any wording, in any language) - not for a mid-conversation pause, not for "give me a second", not merely because their immediate question was answered:
|
|
163
|
+
|
|
164
|
+
🔚 END_CALL: true
|
|
165
|
+
|
|
166
|
+
Omit this line entirely (do not write "false") on every turn that isn't a real goodbye - most turns won't have it.
|
|
167
|
+
|
|
162
168
|
Example query: "What's the weather in Royce City?"
|
|
163
169
|
Example response:
|
|
164
170
|
🗣️ VOICE_RESPONSE: It's 65 degrees and partly cloudy in Royce City right now. Great weather for being outside!
|
|
165
171
|
🎯 COMPLETED: Weather lookup for Royce City done.
|
|
172
|
+
|
|
173
|
+
Example query: "Great, that's everything, thanks!"
|
|
174
|
+
Example response:
|
|
175
|
+
🗣️ VOICE_RESPONSE: You're welcome! Have a great day.
|
|
176
|
+
🎯 COMPLETED: Caller signed off, no further requests.
|
|
177
|
+
🔚 END_CALL: true
|
|
166
178
|
[END VOICE CONTEXT]
|
|
167
179
|
|
|
168
180
|
`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-phone-local",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Local/offline fork of NetworkChuck's claude-phone: talk to Claude Code over 3CX/SIP with faster-whisper STT + Piper TTS in one Docker container.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -162,6 +162,17 @@ function extractVoiceLine(response) {
|
|
|
162
162
|
return response.substring(0, 500).trim();
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Whether Claude's raw response signals the conversation is actually over.
|
|
167
|
+
* Complements isGoodbye()'s fixed phrase match on the caller's own words -
|
|
168
|
+
* Claude sees the full exchange and can recognize a sign-off phrased in ways
|
|
169
|
+
* the keyword list doesn't cover ("that's everything, thanks", "I'm all
|
|
170
|
+
* set"), in any language, without maintaining a growing keyword list.
|
|
171
|
+
*/
|
|
172
|
+
function hasEndCallMarker(response) {
|
|
173
|
+
return /🔚\s*END_CALL:\s*true/i.test(response);
|
|
174
|
+
}
|
|
175
|
+
|
|
165
176
|
/**
|
|
166
177
|
* Play a clip the caller is allowed to interrupt.
|
|
167
178
|
*
|
|
@@ -443,6 +454,13 @@ async function conversationLoop(endpoint, dialog, callUuid, options, deviceConfi
|
|
|
443
454
|
const responseBarge = await playInterruptible(endpoint, session, responseUrl);
|
|
444
455
|
if (responseBarge) {
|
|
445
456
|
pendingUtterance = responseBarge;
|
|
457
|
+
} else if (hasEndCallMarker(claudeResponse)) {
|
|
458
|
+
// Claude judged this a real sign-off from the caller's own words
|
|
459
|
+
// (not just isGoodbye()'s fixed phrase match) - she already said
|
|
460
|
+
// her goodbye as part of the normal response above, so just end
|
|
461
|
+
// the call rather than waiting for another turn.
|
|
462
|
+
console.log('[' + new Date().toISOString() + '] CONVERSATION Claude signaled end of call');
|
|
463
|
+
break;
|
|
446
464
|
}
|
|
447
465
|
}
|
|
448
466
|
|