Commit Graph
100 Commits
Author SHA1 Message Date
Hoan Luu HuuandClaude Opus 5 6cc3dc45f2 Fix/siprec survives fs transfer (#1586)
* fix: carry siprec recording state across a feature server transfer

transferCallToFeatureServer() stored the application, callInfo and remaining tasks,
but not the SIPREC recording state, so the receiving session started at
RecordingOff while the SBC was still recording. From there every live call control
on the recording was rejected locally before an INFO was ever sent: stop and pause
fail the guards in notifyRecordOptions, and a fresh startCallRecording is refused
by the SBC as a duplicate.

Carry recordOptions and the record state through the transfer and restore both on
the receiving session, which also keeps propagateAnswer from issuing a second
startCallRecording for a call that is already being recorded.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test: add standalone smoke test for siprec across a feature server transfer

Drives the failing flow end to end - answer, start SIPREC, enqueue, create the
agent call on a different feature server, dequeue by callSid - while acting as
the SIPREC recorder, so it can tell whether the recording kept receiving media
across the REFER and whether it was BYEd when the call ended.

Needs two or more feature servers and a real inbound call, so it lives outside
the mocha suite and is run by hand; npm test does not pick it up.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test: let the siprec smoke test originate both call legs itself

Waiting for a human to dial in with music playing made the test hard to run and
easy to make meaningless (a muted caller sends no RTP, so "the recording is
silent" proves nothing). Add a built-in SIP endpoint that answers and streams a
PCMU tone, and have the test place both legs through createCall, so a run needs
only an account_sid and no carrier, DID or softphone.

That makes the default mode exercise the transfer path in sbc-outbound; the
previous flow is kept as SMOKE_MODE=inbound for the sbc-inbound path.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: hand the inherited recording state to one session only

Review of the previous commit turned up two ways the carried state leaks, both
because it was read off the shared application object and left there:

  - a call transferred twice kept a stale siprecRecording from the first hop.
    transferCallToFeatureServer copies cs.application, and the new guard only
    wrote the key, so a call recorded FS1->FS2, stopped there, then moved to FS3
    arrived believing it was still recording: startCallRecording rejected as
    "already started", stopCallRecording sent an INFO for a session that was
    gone.
  - child legs got it too. dial passes cs.application straight to
    ConfirmCallSession and place-outdial spreads it for the adulting session, so
    those sessions came up with recordState=recording_on and the parent's SRS
    options while their own dialog had no siprec session at all.

The transferred session now takes the state off the application as it adopts it,
so exactly one session owns it.

Also fixes the smoke test's silence measurement, which was computed per stream
and reported a whole quiet window as a gap - a legitimately silent second stream
failed the run - and splits the README's requirements by mode, since the default
rest mode needs no portal application and no external caller.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test: drop the standalone smoke script, the harness test covers it

smoke-tests/siprec-fs-transfer was a self-contained driver for the cross-feature
-server SIPREC flow, written before the same scenario landed in the smoke-tester
harness as TestVerb_Siprec_SurvivesFeatureServerTransfer (plus a REST-leg
variant for the sbc-outbound path). The harness version is the one that runs in
CI, asserts the recorded audio with Deepgram rather than counting packets, and
is what proved both fixes on a real cluster - keeping a second implementation of
the same flow here only invites the two to drift.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 07:45:30 +01:00
Hoan Luu HuuandClaude Opus 5 db18b558ce add sip_reason_header to status Callback- #178 (#1579)
* feat: surface the SIP Reason header on call status events

Carriers fronting ISDN/E1 PRI trunks put the authoritative disconnect cause in
an RFC 3326 Reason header rather than in the SIP status line, e.g.

    SIP/2.0 408 Request Timeout
    Reason: Q.850 ;cause=18

Q.850 cause 18 is "no user responding" - nobody answered, not a platform fault.
Different causes also arrive under the same SIP status (503 with cause=38
network out of order, or cause=41 temporary failure), so the status code alone
cannot classify the outcome of the call.

drachtio relays the header intact and it is present on the response object, but
the feature server only read the status line from it, so the cause was lost at
the application boundary and never reached the call status webhook.

Rather than extract the header at each emit site, carry the SIP message that
caused the status change on the callStatusChange event and derive from it in one
place, so provisional responses, the 200, final failures, BYE and CANCEL are all
covered by the same code and future headers cost one line.

Note this partly overlaps the existing _extractCustomHeaders/sip_headers
passthrough: that already exposes a Reason header arriving on a BYE, but it only
runs on the hangup path, so nothing covered the outbound INVITE failure
responses where a Q.850 cause matters most.  sip_reason_header is a dedicated,
documented field that behaves the same on every status event.

sip_reason keeps meaning the status line phrase, and no key is added when there
is no Reason header, so existing consumers see an unchanged payload.

Adds a test:unit script so the smoke test runs without the docker testbed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: note that the Reason header arrives re-serialized, not verbatim

Verified live end-to-end against a cluster, capturing both the external leg and
the leg into the feature server:

    14.226.234.142 -> 10.0.197.31:5060   Reason: Q.850 ;cause=31   (as sent)
    10.0.197.31:5060 -> :5070            Reason: Q.850;cause=31    (to fs)

Proxying re-serializes the header, normalizing the optional whitespace RFC 3326
permits around ';'. The same normalization appears in customer captures from an
unrelated deployment, so this is drachtio behaviour, not cluster-specific.

sip_reason_header is therefore the header as this process received it, not the
carrier's exact bytes - worth stating outright, since the spacing inconsistency
is exactly what consumers ask about, and a consumer who string-matches on the
spaced form would silently never match.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: clear a stale Reason header in redis, pass it on the alloc path, run the tests in CI

Three problems found reviewing the earlier commits.

1. The redis call record kept a stale header forever. updateCallStatus assigns
   unconditionally, but toJSON only emits truthy values, and the same object is
   written to the redis hash with hmset - a MERGE. An absent key therefore left
   the previous status change's header in place, readable via GET /Calls/:sid:
   a leg that got 183 + "Reason: Q.850;cause=31", then answered on a clean 200
   and completed on a plain BYE, reported a Q.850 temporary-failure cause for a
   call that ended normally. The webhooks were right; only the call record was
   wrong. Storing absence as '' overwrites it. The existing "does not linger"
   test passed throughout because it only exercised toJSON in memory, so this
   adds one that pins what survives the redis filter (verified: it fails
   without the fix).

2. The endpoint-allocation failure path already extracted the Reason header and
   relayed it to the SBC, but called _notifyCallStatusChange without it - so a
   FreeSWITCH 488 with "Reason: Q.850;cause=88 INCOMPATIBLE_DESTINATION" told
   the SBC the cause and the application nothing, which is exactly the case
   this feature exists to expose. That error is an fsmrf object rather than a
   SipMessage, so it cannot go through msg (the guard in
   reasonHeaderFromSipMessage would silently return undefined); the event now
   takes an explicit sipReasonHeader for callers holding the value already.

3. The test:unit script added with these tests was never wired into CI - the
   workflow runs jslint and npm test, and npm test enumerates its files
   explicitly and skips test/unit entirely, so the suite would have rotted
   unnoticed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: clear the stale header on the CallSession path too, and keep the CANCEL

Both from PR review.

1. The previous fix only worked for SingleDialer. Storing '' on the instance is
   enough for callers that write the instance itself, but CallSession writes
   toJSON(), and toJSON() drops falsy values on purpose so the key stays out of
   the webhook payload - so '' never reached hmset and the stale header
   survived. Reproduced:

       after 183, toJSON has: Q.850;cause=31
       raw instance value:    ""
       instance   -> redis has key: true    (SingleDialer, clears)
       toJSON()   -> redis has key: false   (CallSession, stale persists)

   The split is by session class, not call direction: place-outdial is required
   only by dial.js, so SingleDialer covers dial-verb child legs while inbound,
   REST-created and adulting all inherit CallSession._notifyCallStatusChange -
   including the REST outdial path this feature was written for.

   Adds CallInfo.toRedisJSON(), a named projection for the merge-semantics
   store, so the divergence from toJSON() lives in one documented place rather
   than being rediscovered at each call site. The unit test asserted against the
   raw instance, which is why it passed while the real path was broken; it now
   goes through both writers and fails if either regresses.

2. The caller-abandoned race dropped the CANCEL. middleware.js had it in hand
   and discarded it, so the constructor's _onCancel() passed nothing whenever
   the CANCEL beat the application fetch - the header landed or not depending on
   timing. Worth closing because the 487 and its 'Request Terminated' phrase are
   both ours, so every abandoned inbound call looks identical: a
   Reason: SIP;cause=200;text="Call completed elsewhere" is what separates a
   forked branch losing the race from a caller who gave up, and today both are
   just no-answer.

   Confirmed on a deployed srf (5.0.27) that this is not a no-op:
   copyUASHeaderToUACForOnlyCancel forwards a hardcoded ['Reason', 'X-Reason']
   when proxying a CANCEL, so the header does reach us.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* refactor: keep the Reason header out of the redis call record

Reversing the earlier approach after a closer look at who reads what.

The header was reaching the redis call record simply because CallInfo feeds two
sinks with opposite semantics: the status webhook is an EVENT (each POST is
independent, an absent key means "not in this event") while the redis record is
STATE written with hmset, a MERGE (an absent key means "keep what was there").
sipReasonHeader is the first field here that can legitimately go from set back
to unset - sipStatus and sipReason are only ever overwritten - so it was the
first to expose the mismatch, and two rounds of fixes had to chase it because
the two writers project from different bases.

Rather than keep managing that, exclude it: redis holds calls that are still
live, where there is usually no interesting cause yet, and by the time there is
one the call is over. Call history is served from RecentCalls (the CDR), which
is what the webapp reads - not GET /Calls. So the field earned very little there
while costing an invariant that has to be remembered forever.

Worth being explicit that this is NOT simply a revert: dropping the '' would
only have stopped the empty value being written. When the header is PRESENT it
still reached redis through both writers - toJSON includes it, and SingleDialer
writes the instance's own properties - and was then never cleared. Keeping it out
takes the same machinery as clearing it, just inverted, so this is a choice about
where the field belongs rather than a saving.

WEBHOOK_ONLY_FIELDS names that intent in one place, with the reasoning, so the
next field with the same property has somewhere obvious to go. The test asserts
both writers, since they project from different bases and checking one would
pass while the other still wrote the field (verified: it fails if the exclusion
is removed).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: apply the redis projection at the boundary, and drop dead adulting plumbing

From PR review.

1. There was a THIRD call-record writer. Asking each call site to remember the
   projection was the wrong shape, and review found the proof: this class writes
   the record from the status change, the recording flag AND (private only)
   _persistConferenceState, and the last one still passed toJSON() straight
   through. A conferenced caller whose BYE carried Reason: Q.850;cause=16 would
   have that written into the call hash on the next conference-state persist,
   where hmset merges and nothing can ever clear it.

   Fixed by wrapping updateCallStatus once where it is bound, so every write is
   projected and a newly added writer cannot bypass it by forgetting to ask. The
   call sites go back to passing plain shapes. This is a class of miss that a
   unit test cannot catch - the contract test passed the whole time - so the fix
   is structural rather than another assertion.

2. The msg/byeReq parameters added to AdultingCallSession were dead code. The
   only path that reacts to the far-end BYE there is the inline
   sd.dlg.on('destroy') handler, which calls _callReleased() and discards the
   request; _hangup is reachable only from CallSession.hangup() (LCC), which
   passes nothing. The Reason header on that leg does reach the webhook, via
   SingleDialer's own destroy handler - so the plumbing was not just unused but
   misleading about which path carries it. Removed, with a comment at the handler
   recording where the event actually comes from so it does not get re-added.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: correct the projection comment in SingleDialer

Copied verbatim from CallSession, where the list of writers (status change,
recording flag, conference state) is accurate. SingleDialer has one writer, so
the comment described code that is not there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 07:35:38 -04:00
Hoan Luu Huu f35b694877 update speech utils v1.0.10 (#1574) 2026-07-29 07:15:51 -04:00
Hoan Luu HuuandClaude Opus 4.8 cdc9070488 feat: support srtpEncryption on dial verb for sip URI targets (#1568)
* feat: support srtpEncryption on dial verb for sip URI targets

Reads the new dial.srtpEncryption option and, for sip: URI targets,
forwards it to sbc-outbound as an X-Jambonz-SRTP header so the outbound
leg negotiates encrypted media (SRTP) — e.g. to a sips:/TLS endpoint
such as LiveKit. No behavior change when the option is unset.

Requires @jambonz/verb-specifications with the srtpEncryption spec
(dependency bump to follow once published) and sbc-outbound honoring
the X-Jambonz-SRTP header.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* update verb specification

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 07:23:48 -04:00
Hoan Luu Huu 81601a290d update realtimedb-helper (#1555)
* update realtimedb-helper

* update realtimedb-helper
2026-06-15 21:24:29 -04:00
Hoan Luu Huu 44fbd91053 fixed listern verb terminated due to background task listen failure,teardown wrong handler as well (#1554) 2026-06-05 07:48:44 -04:00
Hoan Luu Huu c1a7f1146a sync google s2s from jambonz version 10 (#1551) 2026-05-20 20:50:15 -04:00
Hoan Luu Huu cb581f9be7 support recognizer.googleOptions.parentPath (#1546)
* support recognizer.googleOptions.parentPath

* update vẻb specification

* wip
2026-05-13 08:33:51 -04:00
Hoan Luu Huu 423c070900 fixed HTTP llm.toolHook does not support openAI (#1547) 2026-05-06 08:47:04 -07:00
Hoan Luu Huu 4b8fc65cdb support houndify ws (#1540) 2026-04-23 07:19:39 -04:00
Hoan Luu Huu 570641fe07 update drachtio srf 5.0.21 (#1537) 2026-04-13 21:52:14 -04:00
Hoan Luu HuuandDave Horton d7beaa1b7b Feat/dialogflow cx (#7) (#1516)
* wip

* wip

* wip

* wip

* logging

* wip

* wip

* wip

* update docker env to latest freeswitch

* wip

* lint

* wip

* support dialogflowcx

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

---------

Co-authored-by: Dave Horton <daveh@beachdognet.com>
2026-02-12 07:46:36 -05:00
Hoan Luu Huu 6120dcbe96 support openai transcribe turn_detection.eagerness (#1496) 2026-01-28 08:09:01 -05:00
Hoan Luu Huu 96d72216e2 support google s2s host, version, sessionResumption (#1498) 2026-01-28 08:01:53 -05:00
Hoan Luu Huu faee30278b support mod_google_tts_streaming (#1409)
* support mod_google_tts_streaming

* wip

* wip
2026-01-27 08:18:47 -05:00
Hoan Luu Huu 325af42946 speechmatics support end_of_utterance_silence_trigger (#1499)
* speechmatics support end_of_utterance_silence_trigger

* wip
2026-01-23 10:11:58 -05:00
Hoan Luu Huu 9848152d5b support google gemini tts (#1491)
* support google gemini tts

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* update speech utils version

* wip
2026-01-22 10:12:06 -05:00
Hoan Luu Huu e4ec0025c3 Fix/gladia multi sessions (#1487)
* support gladia transcribe multi channels

* wip
2026-01-07 10:46:33 -05:00
Hoan Luu Huu e007e0e2d3 fixed callsession cannot close tts streaming (#1472) 2025-12-16 07:58:54 -05:00
Hoan Luu Huu c5cd488fdf fixed gather should ignore transcription if task is killed/resolved. (#1465)
* fixed gather should ignore transcription if task is killed/resolved.

* wip
2025-12-12 09:03:08 -05:00
Hoan Luu Huu 5cea91e18a add support for sending DTMF to ultravox (#1471) 2025-12-11 07:53:59 -05:00
Hoan Luu Huu 7802822773 fixed dial verb cannot bridge 2 leg endpoints due to transcoding (#1457)
* fixed dial verb cannot bridge 2 leg endpoints due to transcoding

* wip
2025-12-03 07:16:25 -05:00
Hoan Luu Huu edb4d21ce1 fixed undefine issue when setting tts streaming channel vars (#1456) 2025-12-02 19:46:28 -05:00
Hoan Luu Huu 83955ba972 SoundHound support audio endpoint from speech credential (#1446)
* SoundHound support audio endpoint from speech credential

* add requestInfo and sampleRate to houndify channel variable

* add requestInfo and sampleRate to houndify channel variable

* wip

* wip

* wip

* wip

* wip

* wip

* wip
2025-11-30 11:55:20 -05:00
Hoan Luu Huu a5fa5fce5b Fixed transcribe 2 legs cannot fallback (#1451)
* fixed transcribe cannot fallback for specific endpoint

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip
2025-11-28 21:43:05 -05:00
Hoan Luu Huu 1984b6d3ea allow say verb failed as NonFatalTaskError for File Not Found (#1443)
* allow say verb failed as NonFatalTaskError for File Not Found

* wip
2025-11-20 07:22:28 -05:00
Hoan Luu Huu 769b66f57e fixed playbackIds is not in correct order compare with say.text array (#1439)
* fixed playbackIds is not in correct order compare with say.text array

* wip

* wip
2025-11-19 19:00:44 -05:00
Hoan Luu Huu 98b845f489 fix say verb does not close streaming when finish say (#1412)
* fix say verb does not close streaming when finish say

* wip

* wip

* ttsStreamingBuffer reset eventHandlerCount after remove listeners

* only send tokens to module if connected

* wip

* sent stream_open when successfully connected to vendor
2025-11-17 08:56:09 -05:00
Hoan Luu HuuandDave Horton 2de24af169 fixed gather does not start timeout on bargin (#1421)
* fixed gather does not start timeout on bargin

* with previous change, no need to emit playDone since no where in the code are we listening for it

---------

Co-authored-by: Dave Horton <daveh@beachdognet.com>
2025-11-03 13:11:59 -05:00
Hoan Luu Huu 77bd11dd47 update speech util 0.2.26 (#1416) 2025-10-31 07:14:38 -04:00
Hoan Luu Huu 46d56fe546 fd_1574: should not send only whitespace to streaming tts engine (#1415) 2025-10-30 20:59:25 -04:00
Hoan Luu Huu 30ab281ea2 support disableTtsCache from config verb (#1410) 2025-10-28 08:19:03 -04:00
Hoan Luu Huu 89cc39f726 support gladia stt (#1397)
* support gladia stt

* wip

* wip

* update verb specification
2025-10-20 04:56:39 -04:00
Hoan Luu Huu a00703a067 support houndify stt (#1364)
* support houndify stt

* wip

* wip

* wip

* update houndify stt parameters

* wip

* wip
2025-10-14 00:55:21 -04:00
Hoan Luu Huu 89c985b564 fixed does not send final status call back if call canceled quickly (#1393)
* fixed callsession should cleanup resource if call was canceled while fetching app

* wip

* wip

* wip

* wip

* wip
2025-10-11 03:44:42 -04:00
Hoan Luu Huu 581d309f36 support elevenlabs different endpoint (#1387)
* support elevenlabs different endpoint

* wip

* wip
2025-10-09 08:19:40 -04:00
Hoan Luu Huu 854c26db11 support deepgramflux (#1373)
* support deepgramflux

* wip

* wip

* wip

* wip

* update verb scpecification
2025-10-03 10:38:39 -04:00
Hoan Luu Huu 057f52e56c speech_util v0.2.23 (#1358) 2025-09-11 01:30:31 -04:00
Hoan Luu Huu b46be57eba singleDialer should create ConfirmCallSession with correct tmpFiles (#1357) 2025-09-10 22:37:41 -04:00
Hoan Luu Huu f950d19d1c fix ConfirmCallSession in placeCall does not have access to tmpFiles for removing tmp file later (#1356) 2025-09-10 19:39:43 -04:00
Hoan Luu Huu add8d63e8e tts stream should not print speech credential (#1352) 2025-09-09 19:18:49 -04:00
Hoan Luu Huu 96aa705378 update speech util verbsion (#1323) 2025-08-14 08:39:12 -04:00
Hoan Luu Huu 44f69fa76d Support resemble tts (#1322)
* support resemble tts

* update speech utils version
2025-08-13 08:15:29 -04:00
Hoan Luu Huu 6b8d0fe1a8 update db-helper 0.9.16 (#1316) 2025-08-08 10:43:59 -04:00
Hoan Luu HuuandDave Horton eb449e9169 support deepgram river (#1273)
* support deepgram river

* wip

* rebase

* fix review comment

---------

Co-authored-by: Dave Horton <daveh@beachdognet.com>
2025-07-29 13:49:43 -04:00
Hoan Luu Huu 158d9d7d25 support stt latency metrics (#1252)
* support stt latency metrics

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* enable stt latency calculator by config verb

* wip

* wip

* wip

* fix jslint

* fixed gather timeout does not have latency calculation

* upadte verb specification to use notifySttLatency

* move stt latency metric from call session to stt-latency calculator

* wip
2025-07-29 09:56:37 -04:00
Hoan Luu Huu 5886d1d945 allow pause/resume background listen with silence/blank (#1300)
* allow pause/resume background listen with silence/blank

* wip

* wip

* wip

* wip

* update drachtio-fsmrf version
2025-07-28 07:58:30 -04:00
Hoan Luu Huu 352106ec0c support referTo with tel: prefix (#1297)
* support referTo with tel: prefix

* fix review comment
2025-07-23 10:52:10 -04:00
Hoan Luu Huu e0e2ade289 fixed gather cannot timeout if listenDuringPrompt is true (#1276)
* fixed gather cannot timeout if listenDuringPrompt is true

* wip

* wip

* wip
2025-07-15 22:53:22 -04:00
Hoan Luu Huu 337c1cded0 fixed transcription is not received when call is terminated (#1259)
* fixed transcription is not received when call is terminated

* wip

* fixed failing testcases

* wip

* wip

* wip

* wip

* should not do gracefulshutdown on stopAmd
2025-07-09 10:20:09 -04:00
Hoan Luu Huu c82a835e70 FD_1079: tts modules response_code = 0 should make say fail to exec. (#1269)
* FD_1079: tts modules response_code = 0 should make say fail to exec.

* fixed tts azure does not have response code

* fixed tts error does not raise alarm

* wip

* fixed
2025-07-07 07:59:29 -04:00
Hoan Luu Huu 3c185d4bd2 consistent assemblyAiOptions name (#1267)
* consistent assemblyAiOptions  name

* update verb specification version
2025-07-03 08:05:56 -04:00
Hoan Luu Huu ba2049b705 support assemblyai v3 (#1265)
* support assemblyai v3

* wip

* wip

* wip

* wip

* wip

* wip
2025-07-01 15:46:19 -04:00
Hoan Luu Huu ab83b21979 support inworld tts (#1262)
* support inworld tts

* wip

* wip
2025-06-27 10:05:18 -04:00
Hoan Luu Huu f18b62e165 support ultravox agent id (#1254)
* support ultravox agent id

* wip
2025-06-23 09:37:10 -04:00
Hoan Luu Huu 8c67c05d87 fixed bargin task loop forever (#1253) 2025-06-22 06:20:24 +02:00
Hoan Luu Huu 3f11ee58a7 fixed dub playOnTrack loop forever (#1247) 2025-06-18 21:37:32 +02:00
Hoan Luu Huu 5be6c54339 support mod_cartesia_transcribe (#1245) 2025-06-17 20:54:26 +02:00
Hoan Luu Huu b0b74871e7 support say stream with text (#1227)
* support say stream with text

* wip

* wip

* wip

* wip

* update verb  specification
2025-06-10 16:56:44 +02:00
Hoan Luu Huu 29708a1f7c clear log from ws-requestor (#1238)
* clear log from ws-requestor

* wip

* wip
2025-06-10 10:34:33 +02:00
Hoan Luu Huu 4386df993c add retry for http/ws requestor (#1210)
* add retry for http requestor

* fix failing testcase

* wip

* update ws-requestor

* wip

* wip

* wip
2025-05-29 10:17:49 -04:00
Hoan Luu Huu 4990b1fb68 fix mod dub throw undefined reference (#1209) 2025-05-28 09:58:33 -04:00
Hoan Luu Huu 3475f39b1d support deepgram model_id in speechCredential (#1213) 2025-05-28 08:00:56 -04:00
Hoan Luu Huu 690a7fcd55 add ws msgid to telemetry span if it's ws requestor (#1215)
* add ws msgid to telemetry span if it's ws requestor

* wip
2025-05-28 07:51:59 -04:00
Hoan Luu Huu b92a9c700e fixed google s2s mcp initiate wrong functionDeclarations (#1203)
* fixed google s2s mcp initiate wrong functionDeclarations

* populate model from llm verb to google setup message
2025-05-18 20:15:26 -04:00
Hoan Luu Huu 9585018147 support whisper instructions (#1198)
* support whisper instructions

* wip

* update speech utils and verb specification
2025-05-13 09:44:00 -04:00
Hoan Luu Huu d7884a837a update deepgram voice agent (#1191)
* update deepgram voice agent

* fix lint

* wip

* wip
2025-05-13 07:43:48 -04:00
Hoan Luu Huu 8b18532f31 fixed tts streaming buffer cannot reset timeoutwhen lastUpdateTime is short (#1184)
* fixed tts streaming buffer cannot reset timeoutwhen lastUpdateTime is short

* wip
2025-05-07 10:26:11 -04:00
Hoan Luu Huu 14295dcebc support google s2s (#1169)
* support google s2s

* wip
2025-05-07 07:20:33 -04:00
Hoan Luu Huu 4d68c179ea sip_decline release callSession if ws requestor is used (#1182) 2025-05-06 10:01:36 -04:00
Hoan Luu Huu 6205959f53 fix microsoft stt max client buffer size error for transcribe verb (#1173) 2025-04-29 09:41:24 -04:00
Hoan Luu Huu ed92cb2632 update speech utils 0.2.7 (#1177)
* update speech utils 0.2.7

* wip
2025-04-29 08:26:09 -04:00
Hoan Luu Huu 7e2fe72b6c fix say verb cannot failover if tts_response-code != 2xx (#1174) 2025-04-28 08:46:08 -04:00
Hoan Luu Huu c2666b7a09 fixed deepgram gather cannot be timeout on empty transcription with continueAsr (#1171) 2025-04-28 08:36:31 -04:00
Hoan Luu Huu 9d54ca8116 Jambonz support Model context protocol (MCP) (#1150)
* Jambonz support Model context protocol (MCP)

* merged mcp tools with existing llmOptions.tools

* support list of mcp servers

* wip

* wip

* wip

* fix voice agent

* fix open-ai

* fix review comment

* fix deepgram voice agent

* update verb specification version
2025-04-24 06:50:53 -04:00
Hoan Luu Huu 63899d0091 update speech utils version 0.2.6 (#1172) 2025-04-23 08:22:47 -04:00
Hoan Luu Huu 15b583ef2c only connect to drachtio server if connected to freeswitch (#1123)
* only connect to drachtio server if connected to freeswitch

* wip

* wip
2025-04-22 09:55:39 -04:00
Hoan Luu Huu 77f0fc85a3 ell tts support speech and pronunciation_dictionary_locators (#1137) 2025-04-09 12:32:06 -04:00
Hoan Luu Huu 343b382373 fixed ws-requestor missing hook for dial:confirm (#1143) 2025-04-09 07:29:08 -04:00
Hoan Luu Huu 3f2744f032 fixed replaceEndpoint offer single codec that callee does not support (#1131) 2025-04-03 07:58:39 -04:00
Hoan Luu Huu acdb8695a0 allow cartesia model_id is override from synthesizer option (#1130) 2025-03-27 13:37:57 -04:00
Hoan Luu Huu f33f197e8d gather say support ttstream (#1128) 2025-03-27 07:19:19 -04:00
Hoan Luu Huu 8b8283e603 ws requestor should store initial sessionData when sending session:adulting (#1110) 2025-03-06 07:42:47 -05:00
Hoan Luu Huu af4e17f447 fixed dial transcribe is not able to receive final transcribe when closing the call (#1073)
* fixed dial transcribe is not able to received final transcribe when close call.

* wip

* fix review comment

* support call session delay detroy ep when current task is transcribe

* wip

* wip

* fixed review comments

* fixed review comments
2025-02-27 07:25:01 -05:00
Hoan Luu Huu cd2563ce17 support ultravox send user_input_message (#1100) 2025-02-26 19:50:09 -05:00
Hoan Luu HuuandMatt Hertogs 4bf2f42f33 support ultravox sends createCall response to app (#1091)
* support ultravox sends createCall response to app

* update type issue

Co-authored-by: Matt Hertogs <matthertogs@gmail.com>

---------

Co-authored-by: Matt Hertogs <matthertogs@gmail.com>
2025-02-20 07:07:03 -05:00
Hoan Luu Huu 33bca8e67c tts stream should save tts.response_time metric (#1086)
* tts stream should save tts.response_time metric

* wip
2025-02-18 08:45:21 -05:00
Hoan Luu Huu 9c05fd3deb fix dialMusic keep running in infinity loop (#1085) 2025-02-18 07:08:19 -05:00
Hoan Luu Huu 7fa0041f6b support deepgram options noDelay (#1083)
* support deepgram options noDelay

* update verb specification version
2025-02-15 16:39:30 -05:00
Hoan Luu Huu 59d9c62cbe support create call with target.proxy (#1075) 2025-02-11 09:24:04 -05:00
Hoan Luu Huu f241faa871 update speech utils version (#1070) 2025-02-07 08:00:33 -05:00
Hoan Luu Huu dbdc1cd43d support voxist stt (#1066)
* support voxist stt

* wip
2025-02-05 08:33:35 -05:00
Hoan Luu Huu 7105453d81 support caching tts audio with model/model_id (#1062)
* support caching tts audio with model/model_id

* update speech utils version
2025-02-03 08:47:44 -05:00
Hoan Luu Huu 8487a4be68 support elevenlabs private agent (#1063) 2025-02-02 22:10:51 -05:00
Hoan Luu Huu 2ddcd53d6b support elevenlabs s2s (#1052)
* support elevenlabs s2s

* wip

* wip

* wip
2025-02-02 10:29:48 -05:00
Hoan Luu Huu ba282d775d support rimelabs tts streaming (#1047) 2025-01-18 08:17:33 -05:00
Hoan Luu Huu ca8cace284 support custom tts streaming (#1023)
* support custom tts streaming

* wip

* wip

* wip

* wip

* wip

* wip

* fix review comments
2025-01-14 07:24:06 -05:00
Hoan Luu Huu 499c800213 Feat/ultravox s2s (#1032)
* support ultravox_s2s

* support ultravox_s2s

* support ultravox_s2s

* wip

* wip

* wip

* wip

* fix ultravox toolcall

* wip
2025-01-14 07:11:55 -05:00
Hoan Luu Huu f4e68d0ea1 fix openai_s2s is using wrong model (#1031)
* fix openai_s2s is using wrong model

* wip

* wip
2025-01-11 08:38:14 -05:00
Hoan Luu Huu fcefa1ff31 fix inband dtmf does not work in dial verb (#1018) 2025-01-08 18:29:43 -05:00