@teamlearners/clawops 0.36.0 → 0.37.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.
- package/dist/agent/index.cjs +78 -409
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +2 -2
- package/dist/agent/index.d.ts +2 -2
- package/dist/agent/index.js +5 -340
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/livekit/index.cjs +9 -8
- package/dist/agent/livekit/index.cjs.map +1 -1
- package/dist/agent/livekit/index.d.cts +1 -1
- package/dist/agent/livekit/index.d.ts +1 -1
- package/dist/agent/livekit/index.js +2 -1
- package/dist/agent/livekit/index.js.map +1 -1
- package/dist/{base-C3yzF1e0.d.cts → base-BalWsEyb.d.cts} +31 -2
- package/dist/{base-C3yzF1e0.d.ts → base-BalWsEyb.d.ts} +31 -2
- package/dist/{chunk-4YLSDMLL.js → chunk-2OGQSWTW.js} +372 -3
- package/dist/chunk-2OGQSWTW.js.map +1 -0
- package/dist/{chunk-XL2VWU36.js → chunk-35XJNMFU.js} +3 -6
- package/dist/chunk-35XJNMFU.js.map +1 -0
- package/dist/{chunk-QD2ZY4UP.cjs → chunk-7TEOYLZI.cjs} +375 -2
- package/dist/chunk-7TEOYLZI.cjs.map +1 -0
- package/dist/chunk-CKPVV6SZ.js +6 -0
- package/dist/chunk-CKPVV6SZ.js.map +1 -0
- package/dist/chunk-EYI3ULDU.cjs +8 -0
- package/dist/chunk-EYI3ULDU.cjs.map +1 -0
- package/dist/{chunk-LKFNV2GI.cjs → chunk-LLPMUDNE.cjs} +2 -6
- package/dist/chunk-LLPMUDNE.cjs.map +1 -0
- package/dist/index.cjs +12 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-4YLSDMLL.js.map +0 -1
- package/dist/chunk-LKFNV2GI.cjs.map +0 -1
- package/dist/chunk-QD2ZY4UP.cjs.map +0 -1
- package/dist/chunk-XL2VWU36.js.map +0 -1
package/dist/agent/index.cjs
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkLLPMUDNE_cjs = require('../chunk-LLPMUDNE.cjs');
|
|
4
4
|
var chunkIYSPOOKH_cjs = require('../chunk-IYSPOOKH.cjs');
|
|
5
|
-
var
|
|
5
|
+
var chunk7TEOYLZI_cjs = require('../chunk-7TEOYLZI.cjs');
|
|
6
|
+
require('../chunk-EYI3ULDU.cjs');
|
|
6
7
|
var fs = require('fs');
|
|
7
8
|
var path = require('path');
|
|
8
|
-
var os = require('os');
|
|
9
|
-
|
|
10
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
9
|
|
|
12
10
|
function _interopNamespace(e) {
|
|
13
11
|
if (e && e.__esModule) return e;
|
|
@@ -29,7 +27,6 @@ function _interopNamespace(e) {
|
|
|
29
27
|
|
|
30
28
|
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
31
29
|
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
32
|
-
var os__default = /*#__PURE__*/_interopDefault(os);
|
|
33
30
|
|
|
34
31
|
// src/agent/control-ws.ts
|
|
35
32
|
var INITIAL_RECONNECT_DELAY = 1e3;
|
|
@@ -60,7 +57,7 @@ var ControlWebSocket = class {
|
|
|
60
57
|
_closed = false;
|
|
61
58
|
_connectedResolve = null;
|
|
62
59
|
_connectedPromise;
|
|
63
|
-
_log =
|
|
60
|
+
_log = chunk7TEOYLZI_cjs.NOOP_LOGGER;
|
|
64
61
|
_pingTimer = null;
|
|
65
62
|
setLogger(logger) {
|
|
66
63
|
this._log = logger;
|
|
@@ -225,7 +222,7 @@ var ControlWebSocket = class {
|
|
|
225
222
|
var MCPClient = class {
|
|
226
223
|
_servers = /* @__PURE__ */ new Map();
|
|
227
224
|
_clients = /* @__PURE__ */ new Map();
|
|
228
|
-
_log =
|
|
225
|
+
_log = chunk7TEOYLZI_cjs.NOOP_LOGGER;
|
|
229
226
|
setLogger(logger) {
|
|
230
227
|
this._log = logger;
|
|
231
228
|
}
|
|
@@ -367,7 +364,7 @@ var MediaWebSocket = class {
|
|
|
367
364
|
_onClose = null;
|
|
368
365
|
_onDtmf = null;
|
|
369
366
|
_markWaiters = /* @__PURE__ */ new Map();
|
|
370
|
-
_log =
|
|
367
|
+
_log = chunk7TEOYLZI_cjs.NOOP_LOGGER;
|
|
371
368
|
setLogger(logger) {
|
|
372
369
|
this._log = logger;
|
|
373
370
|
}
|
|
@@ -593,7 +590,7 @@ var AudioRecorder = class {
|
|
|
593
590
|
_started = false;
|
|
594
591
|
_baseTs = null;
|
|
595
592
|
_outCursor = 0;
|
|
596
|
-
_log =
|
|
593
|
+
_log = chunk7TEOYLZI_cjs.NOOP_LOGGER;
|
|
597
594
|
setLogger(logger) {
|
|
598
595
|
this._log = logger;
|
|
599
596
|
}
|
|
@@ -724,341 +721,6 @@ var AudioRecorder = class {
|
|
|
724
721
|
}
|
|
725
722
|
}
|
|
726
723
|
};
|
|
727
|
-
var MAX_ERRORS = 20;
|
|
728
|
-
var MAX_ERROR_MESSAGE_LENGTH = 200;
|
|
729
|
-
function getSdkInfo() {
|
|
730
|
-
return {
|
|
731
|
-
name: "clawops-node",
|
|
732
|
-
version: chunkLKFNV2GI_cjs.VERSION,
|
|
733
|
-
runtime: `node/${process.versions.node}`,
|
|
734
|
-
os: `${process.platform}/${os__default.default.arch()}`
|
|
735
|
-
};
|
|
736
|
-
}
|
|
737
|
-
function createCallMetrics() {
|
|
738
|
-
return {
|
|
739
|
-
firstResponseMs: null,
|
|
740
|
-
turnCount: 0,
|
|
741
|
-
toolCallCount: 0,
|
|
742
|
-
toolErrorCount: 0,
|
|
743
|
-
bargeInCount: 0,
|
|
744
|
-
endReason: null,
|
|
745
|
-
errors: []
|
|
746
|
-
};
|
|
747
|
-
}
|
|
748
|
-
function addMetricError(metrics, err) {
|
|
749
|
-
metrics.toolErrorCount++;
|
|
750
|
-
if (metrics.errors.length < MAX_ERRORS) {
|
|
751
|
-
metrics.errors.push({
|
|
752
|
-
type: err.name || "Error",
|
|
753
|
-
message: (err.message || "").slice(0, MAX_ERROR_MESSAGE_LENGTH)
|
|
754
|
-
});
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
// src/agent/session.ts
|
|
759
|
-
var CallSession = class {
|
|
760
|
-
callId;
|
|
761
|
-
fromNumber;
|
|
762
|
-
toNumber;
|
|
763
|
-
accountId;
|
|
764
|
-
direction;
|
|
765
|
-
startTime;
|
|
766
|
-
metadata;
|
|
767
|
-
_status;
|
|
768
|
-
_endedStatus = null;
|
|
769
|
-
_endedDuration = null;
|
|
770
|
-
_sendAudioFn = null;
|
|
771
|
-
_clearAudioFn = null;
|
|
772
|
-
_hangupFn = null;
|
|
773
|
-
/** @internal */
|
|
774
|
-
_sendDtmfFn = null;
|
|
775
|
-
/** @internal */
|
|
776
|
-
_transferFn = null;
|
|
777
|
-
/** @internal */
|
|
778
|
-
_isTransportConnected = null;
|
|
779
|
-
/**
|
|
780
|
-
* @internal Media WS playout 마커 훅. LiveKit(`ClawOpsAudioOutput`)이 재생 완료
|
|
781
|
-
* 판정(mark echo)과 barge-in 절단 위치 계산에 쓴다. 다른 세션 타입은 읽지 않는다.
|
|
782
|
-
* prewarm 중(BufferingCall)에는 바인딩되지 않아 null 이다.
|
|
783
|
-
*/
|
|
784
|
-
/** @internal */
|
|
785
|
-
_sendMark = null;
|
|
786
|
-
/** @internal */
|
|
787
|
-
_waitForMark = null;
|
|
788
|
-
/** @internal */
|
|
789
|
-
_flushTransport = null;
|
|
790
|
-
_dtmfCollectorActive = false;
|
|
791
|
-
_dtmfResolvers = [];
|
|
792
|
-
_dtmfBuffer = [];
|
|
793
|
-
_log = chunkQD2ZY4UP_cjs.NOOP_LOGGER;
|
|
794
|
-
_handlers = /* @__PURE__ */ new Map();
|
|
795
|
-
_endedPromise;
|
|
796
|
-
_resolveEnded;
|
|
797
|
-
_metrics = createCallMetrics();
|
|
798
|
-
_firstResponseSent = false;
|
|
799
|
-
constructor(options) {
|
|
800
|
-
this.callId = options.callId;
|
|
801
|
-
this.fromNumber = options.fromNumber;
|
|
802
|
-
this.toNumber = options.toNumber;
|
|
803
|
-
this.accountId = options.accountId;
|
|
804
|
-
this.direction = options.direction;
|
|
805
|
-
this.metadata = options.metadata ?? {};
|
|
806
|
-
this._status = "ringing";
|
|
807
|
-
this.startTime = /* @__PURE__ */ new Date();
|
|
808
|
-
this._endedPromise = new Promise((resolve) => {
|
|
809
|
-
this._resolveEnded = resolve;
|
|
810
|
-
});
|
|
811
|
-
}
|
|
812
|
-
setLogger(logger) {
|
|
813
|
-
this._log = logger;
|
|
814
|
-
}
|
|
815
|
-
get status() {
|
|
816
|
-
return this._status;
|
|
817
|
-
}
|
|
818
|
-
/**
|
|
819
|
-
* 서버가 통보한 최종 종료 상태. 통화가 끝나기 전에는 null.
|
|
820
|
-
*
|
|
821
|
-
* `completed`(성사) / `no-answer`(벨은 울렸으나 무응답) / `busy`(통화중) /
|
|
822
|
-
* `rejected`(수신 거절) / `canceled`(응답 전 발신 측 취소) / `failed`(시스템·망 오류).
|
|
823
|
-
* `status` 는 SDK 내부 수명주기(ringing→active→ended)이므로 통화 성사 여부는
|
|
824
|
-
* 이 값이나 `call_failed` 이벤트로 판단한다.
|
|
825
|
-
*/
|
|
826
|
-
get endedStatus() {
|
|
827
|
-
return this._endedStatus;
|
|
828
|
-
}
|
|
829
|
-
/**
|
|
830
|
-
* 서버가 확정한 통화 시간(초). 통화가 끝나기 전에는 `null`.
|
|
831
|
-
*
|
|
832
|
-
* ⚠️ `duration` 과 다르다 — 그쪽은 SDK 가 로컬 시계로 재는 **경과 시간**이라 통화 중에도
|
|
833
|
-
* 읽히고, 세션이 붙기 전후의 오차를 포함한다. 기록·정산에 쓸 값은 이쪽이다.
|
|
834
|
-
*/
|
|
835
|
-
get endedDuration() {
|
|
836
|
-
return this._endedDuration;
|
|
837
|
-
}
|
|
838
|
-
get duration() {
|
|
839
|
-
return (Date.now() - this.startTime.getTime()) / 1e3;
|
|
840
|
-
}
|
|
841
|
-
/** @internal 서버가 통보한 통화 시간을 확정한다. */
|
|
842
|
-
_setEndedDuration(seconds) {
|
|
843
|
-
this._endedDuration = seconds;
|
|
844
|
-
}
|
|
845
|
-
get metrics() {
|
|
846
|
-
return this._metrics;
|
|
847
|
-
}
|
|
848
|
-
recordFirstResponse() {
|
|
849
|
-
if (!this._firstResponseSent) {
|
|
850
|
-
this._firstResponseSent = true;
|
|
851
|
-
this._metrics.firstResponseMs = Date.now() - this.startTime.getTime();
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
recordTurn() {
|
|
855
|
-
this._metrics.turnCount++;
|
|
856
|
-
}
|
|
857
|
-
recordToolCall() {
|
|
858
|
-
this._metrics.toolCallCount++;
|
|
859
|
-
}
|
|
860
|
-
recordToolError(err) {
|
|
861
|
-
addMetricError(this._metrics, err);
|
|
862
|
-
}
|
|
863
|
-
recordBargeIn() {
|
|
864
|
-
this._metrics.bargeInCount++;
|
|
865
|
-
}
|
|
866
|
-
recordEndReason(reason) {
|
|
867
|
-
this._metrics.endReason = reason;
|
|
868
|
-
}
|
|
869
|
-
/** Bind transport functions (called internally by the agent). */
|
|
870
|
-
_bindTransport(send, clear, hangup, sendDtmf, isConnected) {
|
|
871
|
-
this._sendAudioFn = send;
|
|
872
|
-
this._clearAudioFn = clear;
|
|
873
|
-
this._hangupFn = hangup;
|
|
874
|
-
if (sendDtmf) this._sendDtmfFn = sendDtmf;
|
|
875
|
-
if (isConnected) this._isTransportConnected = isConnected;
|
|
876
|
-
this._status = "active";
|
|
877
|
-
}
|
|
878
|
-
/**
|
|
879
|
-
* Send G.711 μ-law audio (8kHz, mono) to the caller.
|
|
880
|
-
*
|
|
881
|
-
* NOT PCM16. The transport applies μ-law gain and forwards the bytes as-is,
|
|
882
|
-
* so PCM16 input is reinterpreted as μ-law and plays as noise. Convert first.
|
|
883
|
-
*/
|
|
884
|
-
sendAudio(audio) {
|
|
885
|
-
if (this._sendAudioFn) {
|
|
886
|
-
this._sendAudioFn(audio);
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
/** Clear any queued outbound audio. */
|
|
890
|
-
clearAudio() {
|
|
891
|
-
if (this._clearAudioFn) {
|
|
892
|
-
this._clearAudioFn();
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
/** Hang up the call, waiting for pending audio to finish. */
|
|
896
|
-
async hangup() {
|
|
897
|
-
if (this._hangupFn) {
|
|
898
|
-
await this._hangupFn();
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
/** @internal Route a received DTMF digit to an active collector or buffer. */
|
|
902
|
-
_routeDtmf(digit) {
|
|
903
|
-
if (this._dtmfCollectorActive && this._dtmfResolvers.length > 0) {
|
|
904
|
-
const resolve = this._dtmfResolvers.shift();
|
|
905
|
-
resolve(digit);
|
|
906
|
-
} else {
|
|
907
|
-
this._dtmfBuffer.push(digit);
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
/** Collect DTMF digits from the caller. */
|
|
911
|
-
async collectDtmf(options) {
|
|
912
|
-
if (this._dtmfCollectorActive) {
|
|
913
|
-
throw new Error("\uC774\uBBF8 DTMF \uC218\uC9D1 \uC911\uC785\uB2C8\uB2E4");
|
|
914
|
-
}
|
|
915
|
-
const { maxDigits, finishOnKey = "#", timeout = 5 } = options;
|
|
916
|
-
this._dtmfCollectorActive = true;
|
|
917
|
-
const collected = [];
|
|
918
|
-
try {
|
|
919
|
-
while (collected.length < maxDigits) {
|
|
920
|
-
if (this._dtmfBuffer.length > 0) {
|
|
921
|
-
const digit2 = this._dtmfBuffer.shift();
|
|
922
|
-
if (digit2 === finishOnKey) break;
|
|
923
|
-
collected.push(digit2);
|
|
924
|
-
continue;
|
|
925
|
-
}
|
|
926
|
-
const digit = await Promise.race([
|
|
927
|
-
new Promise((resolve) => {
|
|
928
|
-
this._dtmfResolvers.push(resolve);
|
|
929
|
-
}),
|
|
930
|
-
new Promise((resolve) => {
|
|
931
|
-
setTimeout(() => resolve(null), timeout * 1e3);
|
|
932
|
-
})
|
|
933
|
-
]);
|
|
934
|
-
if (digit === null) break;
|
|
935
|
-
if (digit === finishOnKey) break;
|
|
936
|
-
collected.push(digit);
|
|
937
|
-
}
|
|
938
|
-
} finally {
|
|
939
|
-
this._dtmfCollectorActive = false;
|
|
940
|
-
this._dtmfResolvers = [];
|
|
941
|
-
this._dtmfBuffer = [];
|
|
942
|
-
}
|
|
943
|
-
const result = collected.join("");
|
|
944
|
-
this._log.info("DTMF collected: %s", result);
|
|
945
|
-
return result;
|
|
946
|
-
}
|
|
947
|
-
/** Send a sequence of DTMF digits. */
|
|
948
|
-
async sendDtmfSequence(digits) {
|
|
949
|
-
if (!this._sendDtmfFn) {
|
|
950
|
-
throw new Error("DTMF \uC804\uC1A1 \uD568\uC218\uAC00 \uBC14\uC778\uB529\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
951
|
-
}
|
|
952
|
-
for (const ch of digits) {
|
|
953
|
-
if (this._isTransportConnected && !this._isTransportConnected()) {
|
|
954
|
-
throw new Error("DTMF \uC804\uC1A1 \uC911 \uC5F0\uACB0\uC774 \uB04A\uC5B4\uC84C\uC2B5\uB2C8\uB2E4");
|
|
955
|
-
}
|
|
956
|
-
if (ch === "w") {
|
|
957
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
958
|
-
} else if (ch === "W") {
|
|
959
|
-
await new Promise((r) => setTimeout(r, 1e3));
|
|
960
|
-
} else if ("0123456789*#".includes(ch)) {
|
|
961
|
-
if (this._sendDtmfFn) {
|
|
962
|
-
await this._sendDtmfFn(ch);
|
|
963
|
-
}
|
|
964
|
-
} else {
|
|
965
|
-
throw new Error(`\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 DTMF \uBB38\uC790: ${ch}`);
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
/**
|
|
970
|
-
* Transfer the call to a phone number or SIP endpoint.
|
|
971
|
-
*
|
|
972
|
-
* destinationType='pstn' (default): `to` is a phone number dialed via carrier.
|
|
973
|
-
* destinationType='sip': `to` is a SIP URI (e.g. `sip:user@host`) connected
|
|
974
|
-
* directly to a SIP endpoint without going through the PSTN carrier. Requires the
|
|
975
|
-
* account to have an active `sip_trunk` add-on; otherwise the transfer fails and
|
|
976
|
-
* the call continues with the AI (result `{ status: 'failed', ... }`).
|
|
977
|
-
*
|
|
978
|
-
* 전환받는 쪽에 표시되는 발신번호는 기본이 **계정 보유번호**(인바운드면 착신 070)다.
|
|
979
|
-
*
|
|
980
|
-
* `callerIdMode: 'original'` 은 인바운드 통화의 **원 발신자 번호를 승계하려는 선호**다.
|
|
981
|
-
* 승계할 수 없는 통화(KCT 직결 인입이 아니거나 국내 번호로 정규화되지 않는 발신번호)면
|
|
982
|
-
* 조용히 계정 보유번호로 내려앉고 **전환은 그대로 성사된다**.
|
|
983
|
-
*
|
|
984
|
-
* `callerId` 는 번호를 직접 주는 **지시**라 성격이 다르다. 허용 범위(계정 보유번호 또는
|
|
985
|
-
* KCT 직결 인입의 원 발신자)를 벗어나면 전환 자체가 실패한다. 둘 다 주면 `callerId` 가
|
|
986
|
-
* 이기고 `callerIdMode` 는 무시된다 — 우선순위 판단은 서버가 한다.
|
|
987
|
-
*/
|
|
988
|
-
async transfer(to, options) {
|
|
989
|
-
if (!this._transferFn) {
|
|
990
|
-
throw new Error("transfer not available");
|
|
991
|
-
}
|
|
992
|
-
const callerIdMode = options?.callerIdMode;
|
|
993
|
-
if (callerIdMode !== void 0 && callerIdMode !== "account" && callerIdMode !== "original") {
|
|
994
|
-
throw new Error(
|
|
995
|
-
`callerIdMode must be 'account' or 'original', got ${JSON.stringify(callerIdMode)}`
|
|
996
|
-
);
|
|
997
|
-
}
|
|
998
|
-
return this._transferFn({
|
|
999
|
-
to,
|
|
1000
|
-
destinationType: options?.destinationType ?? "pstn",
|
|
1001
|
-
mode: options?.mode ?? "blind",
|
|
1002
|
-
afterTransfer: options?.afterTransfer ?? "terminate",
|
|
1003
|
-
holdMedia: options?.holdMedia ?? "ringback",
|
|
1004
|
-
whisper: options?.whisper ?? null,
|
|
1005
|
-
context: options?.context ?? null,
|
|
1006
|
-
callerId: options?.callerId ?? null,
|
|
1007
|
-
timeout: options?.timeout ?? 30,
|
|
1008
|
-
// 안 주면 키를 붙이지 않는다 — 구 서버와 기존 동작을 그대로 둔다(additive).
|
|
1009
|
-
...callerIdMode !== void 0 ? { callerIdMode } : {}
|
|
1010
|
-
});
|
|
1011
|
-
}
|
|
1012
|
-
/** Register an event handler. */
|
|
1013
|
-
on(event, handler) {
|
|
1014
|
-
let list = this._handlers.get(event);
|
|
1015
|
-
if (!list) {
|
|
1016
|
-
list = [];
|
|
1017
|
-
this._handlers.set(event, list);
|
|
1018
|
-
}
|
|
1019
|
-
list.push(handler);
|
|
1020
|
-
}
|
|
1021
|
-
/** Wait for the call to end. */
|
|
1022
|
-
async wait() {
|
|
1023
|
-
return this._endedPromise;
|
|
1024
|
-
}
|
|
1025
|
-
/**
|
|
1026
|
-
* Mark the session as ended (called internally).
|
|
1027
|
-
*
|
|
1028
|
-
* @param status 서버가 통보한 최종 상태(completed/no-answer/busy/rejected/canceled/
|
|
1029
|
-
* failed). 주어지면 `endedStatus` 로 확정한다 — 상대가 받지 않은 통화를 성사된 통화와
|
|
1030
|
-
* 구분하기 위함이다. 생략하면 미디어 세션 정리 경로에서의 호출이므로, 아직 종료 전일
|
|
1031
|
-
* 때만 'completed' 로 채우고 이미 확정된 서버 상태는 덮어쓰지 않는다.
|
|
1032
|
-
*/
|
|
1033
|
-
_markEnded(status) {
|
|
1034
|
-
if (status !== void 0) {
|
|
1035
|
-
this._endedStatus = status;
|
|
1036
|
-
} else if (this._status !== "ended") {
|
|
1037
|
-
this._endedStatus = "completed";
|
|
1038
|
-
}
|
|
1039
|
-
this._status = "ended";
|
|
1040
|
-
this._resolveEnded();
|
|
1041
|
-
}
|
|
1042
|
-
/** Emit an event to registered handlers. Matches Python SDK: _emit(event, ...args) */
|
|
1043
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1044
|
-
_emit(event, ...args) {
|
|
1045
|
-
const handlers = this._handlers.get(event);
|
|
1046
|
-
if (handlers) {
|
|
1047
|
-
for (const handler of handlers) {
|
|
1048
|
-
try {
|
|
1049
|
-
const result = handler(this, ...args);
|
|
1050
|
-
if (result && typeof result.catch === "function") {
|
|
1051
|
-
result.catch((err) => {
|
|
1052
|
-
this._log.error({ err }, "CallSession handler error: %s", event);
|
|
1053
|
-
});
|
|
1054
|
-
}
|
|
1055
|
-
} catch (err) {
|
|
1056
|
-
this._log.error({ err }, "CallSession handler error: %s", event);
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
};
|
|
1062
724
|
var CHUNK_SIZE = 160;
|
|
1063
725
|
var SAMPLE_RATE2 = 8e3;
|
|
1064
726
|
var BELL_PARTIALS = [
|
|
@@ -1143,7 +805,7 @@ function generateComfortTone(volume = 0.12) {
|
|
|
1143
805
|
}
|
|
1144
806
|
}
|
|
1145
807
|
const pcm = int16ArrayToBuffer(concatInt16Arrays(...parts));
|
|
1146
|
-
const ulaw =
|
|
808
|
+
const ulaw = chunk7TEOYLZI_cjs.pcm16ToUlaw(pcm);
|
|
1147
809
|
const chunks = [];
|
|
1148
810
|
for (let i = 0; i < ulaw.length; i += CHUNK_SIZE) {
|
|
1149
811
|
chunks.push(ulaw.subarray(i, i + CHUNK_SIZE));
|
|
@@ -1200,9 +862,9 @@ function loadHoldAudio(source) {
|
|
|
1200
862
|
pcmData = mono;
|
|
1201
863
|
}
|
|
1202
864
|
if (sampleRate !== SAMPLE_RATE2) {
|
|
1203
|
-
pcmData =
|
|
865
|
+
pcmData = chunk7TEOYLZI_cjs.resamplePcm16(pcmData, sampleRate, SAMPLE_RATE2);
|
|
1204
866
|
}
|
|
1205
|
-
const ulaw =
|
|
867
|
+
const ulaw = chunk7TEOYLZI_cjs.pcm16ToUlaw(pcmData);
|
|
1206
868
|
const chunks = [];
|
|
1207
869
|
for (let i = 0; i < ulaw.length; i += CHUNK_SIZE) {
|
|
1208
870
|
chunks.push(ulaw.subarray(i, i + CHUNK_SIZE));
|
|
@@ -1474,13 +1136,13 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1474
1136
|
constructor(options) {
|
|
1475
1137
|
this._apiKey = options.apiKey ?? process.env["CLAWOPS_API_KEY"] ?? "";
|
|
1476
1138
|
this._accountId = options.accountId ?? process.env["CLAWOPS_ACCOUNT_ID"] ?? "";
|
|
1477
|
-
this._baseUrl = options.baseUrl ??
|
|
1139
|
+
this._baseUrl = options.baseUrl ?? chunkLLPMUDNE_cjs.DEFAULT_BASE_URL;
|
|
1478
1140
|
this._fromNumber = options.from;
|
|
1479
1141
|
this._session = options.session;
|
|
1480
1142
|
this._recording = options.recording ?? false;
|
|
1481
1143
|
this._recordingPath = options.recordingPath ?? "./recordings";
|
|
1482
1144
|
this._mcpServers = options.mcpServers ?? [];
|
|
1483
|
-
this._builtinTools =
|
|
1145
|
+
this._builtinTools = chunk7TEOYLZI_cjs.resolveBuiltinTools(options.builtinTools ?? "all" /* ALL */);
|
|
1484
1146
|
this._passiveDtmfDebounceMs = options.passiveDtmfDebounceMs ?? 500;
|
|
1485
1147
|
this._rxGain = _ClawOpsAgent._validateGain("rxGain", options.rxGain ?? 1);
|
|
1486
1148
|
this._txGain = _ClawOpsAgent._validateGain("txGain", options.txGain ?? 1);
|
|
@@ -1489,8 +1151,8 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1489
1151
|
if (options.tracing) {
|
|
1490
1152
|
setTracingConfig(options.tracing);
|
|
1491
1153
|
}
|
|
1492
|
-
this._log =
|
|
1493
|
-
this._pipelineLog =
|
|
1154
|
+
this._log = chunk7TEOYLZI_cjs.createAgentLogger(options.logger);
|
|
1155
|
+
this._pipelineLog = chunk7TEOYLZI_cjs.createPipelineLogger(this._log);
|
|
1494
1156
|
this._isPipelineSession = "_stt" in this._session && "_llm" in this._session;
|
|
1495
1157
|
if (options.toolConfig?.holdAudio) {
|
|
1496
1158
|
this._holdAudioChunks = loadHoldAudio(options.toolConfig.holdAudio);
|
|
@@ -1571,7 +1233,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1571
1233
|
await this._controlWs.connect();
|
|
1572
1234
|
await this._controlWs.waitConnected();
|
|
1573
1235
|
try {
|
|
1574
|
-
this._controlWs.send({ event: "agent.hello", sdk: getSdkInfo() });
|
|
1236
|
+
this._controlWs.send({ event: "agent.hello", sdk: chunk7TEOYLZI_cjs.getSdkInfo() });
|
|
1575
1237
|
} catch {
|
|
1576
1238
|
}
|
|
1577
1239
|
} catch (err) {
|
|
@@ -1643,7 +1305,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1643
1305
|
throw new chunkIYSPOOKH_cjs.AgentError(`\uBC1C\uC2E0 \uC2E4\uD328 (${resp.status}): ${error["error"] ?? ""}`);
|
|
1644
1306
|
}
|
|
1645
1307
|
const data = await resp.json();
|
|
1646
|
-
const callSession = new CallSession({
|
|
1308
|
+
const callSession = new chunk7TEOYLZI_cjs.CallSession({
|
|
1647
1309
|
callId: data["callId"],
|
|
1648
1310
|
fromNumber: this._fromNumber,
|
|
1649
1311
|
toNumber: to,
|
|
@@ -1667,7 +1329,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1667
1329
|
const callId = event["callId"];
|
|
1668
1330
|
const fromNumber = event["from"] ?? "";
|
|
1669
1331
|
const mediaUrl = event["mediaUrl"] ?? "";
|
|
1670
|
-
const session = new CallSession({
|
|
1332
|
+
const session = new chunk7TEOYLZI_cjs.CallSession({
|
|
1671
1333
|
callId,
|
|
1672
1334
|
fromNumber,
|
|
1673
1335
|
toNumber: this._fromNumber,
|
|
@@ -1768,7 +1430,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1768
1430
|
const mediaUrl = event["mediaUrl"] ?? "";
|
|
1769
1431
|
let session = this._activeSessions.get(callId);
|
|
1770
1432
|
if (!session) {
|
|
1771
|
-
session = new CallSession({
|
|
1433
|
+
session = new chunk7TEOYLZI_cjs.CallSession({
|
|
1772
1434
|
callId,
|
|
1773
1435
|
fromNumber: this._fromNumber,
|
|
1774
1436
|
toNumber: event["to"] ?? "",
|
|
@@ -1970,9 +1632,9 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1970
1632
|
let latestMediaTs = 0;
|
|
1971
1633
|
session._bindTransport(
|
|
1972
1634
|
(audio) => {
|
|
1973
|
-
const gained =
|
|
1635
|
+
const gained = chunk7TEOYLZI_cjs.applyUlawGain(audio, this._txGain);
|
|
1974
1636
|
if (recorder) {
|
|
1975
|
-
recorder.writeOutbound(
|
|
1637
|
+
recorder.writeOutbound(chunk7TEOYLZI_cjs.ulawToPcm16(gained), latestMediaTs);
|
|
1976
1638
|
}
|
|
1977
1639
|
mediaWs.sendAudio(gained.toString("base64"));
|
|
1978
1640
|
session.recordFirstResponse();
|
|
@@ -2002,9 +1664,9 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
2002
1664
|
this._callSessions.set(session.callId, sessionHandler);
|
|
2003
1665
|
mediaWs.onAudio((ulawAudio, timestamp) => {
|
|
2004
1666
|
latestMediaTs = timestamp;
|
|
2005
|
-
const gained =
|
|
1667
|
+
const gained = chunk7TEOYLZI_cjs.applyUlawGain(ulawAudio, this._rxGain);
|
|
2006
1668
|
if (recorder) {
|
|
2007
|
-
recorder.writeInbound(
|
|
1669
|
+
recorder.writeInbound(chunk7TEOYLZI_cjs.ulawToPcm16(gained), timestamp);
|
|
2008
1670
|
}
|
|
2009
1671
|
if (sessionHandler) {
|
|
2010
1672
|
sessionHandler.feedAudio(gained, timestamp);
|
|
@@ -2120,7 +1782,7 @@ var PipelineSession = class {
|
|
|
2120
1782
|
_speaking = false;
|
|
2121
1783
|
_builtinTools = null;
|
|
2122
1784
|
_holdAudioChunks = null;
|
|
2123
|
-
_log =
|
|
1785
|
+
_log = chunk7TEOYLZI_cjs.NOOP_LOGGER;
|
|
2124
1786
|
constructor(options) {
|
|
2125
1787
|
this._stt = options.stt;
|
|
2126
1788
|
this._llm = options.llm;
|
|
@@ -2182,7 +1844,7 @@ var PipelineSession = class {
|
|
|
2182
1844
|
*/
|
|
2183
1845
|
async prewarm(tools) {
|
|
2184
1846
|
if (tools) this._tools = tools;
|
|
2185
|
-
this._callSession = new
|
|
1847
|
+
this._callSession = new chunk7TEOYLZI_cjs.BufferingCall();
|
|
2186
1848
|
this._running = true;
|
|
2187
1849
|
this._conversation = [];
|
|
2188
1850
|
this._log.info("PipelineSession prewarmed");
|
|
@@ -2205,7 +1867,7 @@ var PipelineSession = class {
|
|
|
2205
1867
|
async attach(callSession) {
|
|
2206
1868
|
const prev = this._callSession;
|
|
2207
1869
|
this._callSession = callSession;
|
|
2208
|
-
|
|
1870
|
+
chunk7TEOYLZI_cjs.attachBuffered(prev, callSession);
|
|
2209
1871
|
}
|
|
2210
1872
|
async start(callSession, tools) {
|
|
2211
1873
|
this._tools = tools ?? null;
|
|
@@ -2252,8 +1914,8 @@ var PipelineSession = class {
|
|
|
2252
1914
|
while (this._running) {
|
|
2253
1915
|
if (this._audioBuffer.length > 0) {
|
|
2254
1916
|
const ulaw = this._audioBuffer.shift();
|
|
2255
|
-
const pcm8k =
|
|
2256
|
-
const pcm16k =
|
|
1917
|
+
const pcm8k = chunk7TEOYLZI_cjs.ulawToPcm16(ulaw);
|
|
1918
|
+
const pcm16k = chunk7TEOYLZI_cjs.resamplePcm16(pcm8k, 8e3, 16e3);
|
|
2257
1919
|
yield pcm16k;
|
|
2258
1920
|
} else {
|
|
2259
1921
|
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
@@ -2269,7 +1931,7 @@ var PipelineSession = class {
|
|
|
2269
1931
|
await this._respond();
|
|
2270
1932
|
}
|
|
2271
1933
|
_buildEffectiveTools() {
|
|
2272
|
-
const builtinSchemas =
|
|
1934
|
+
const builtinSchemas = chunk7TEOYLZI_cjs.getBuiltinToolSchemas(this._builtinTools, "chat");
|
|
2273
1935
|
const dtmfSchemas = builtinSchemas.filter((s) => {
|
|
2274
1936
|
const name = s["function"]?.["name"];
|
|
2275
1937
|
return name === "collect_dtmf" || name === "send_dtmf";
|
|
@@ -2318,8 +1980,8 @@ var PipelineSession = class {
|
|
|
2318
1980
|
const { id, name, arguments: argsStr } = chunk.toolCall;
|
|
2319
1981
|
try {
|
|
2320
1982
|
const args = JSON.parse(argsStr);
|
|
2321
|
-
if (
|
|
2322
|
-
const result2 = await
|
|
1983
|
+
if (chunk7TEOYLZI_cjs.BUILTIN_TOOL_NAMES.has(name) && this._callSession && !(this._callSession instanceof chunk7TEOYLZI_cjs.BufferingCall)) {
|
|
1984
|
+
const result2 = await chunk7TEOYLZI_cjs.executeBuiltinTool(name, args, this._callSession);
|
|
2323
1985
|
if (result2 !== null) {
|
|
2324
1986
|
if (name === "hang_up") return;
|
|
2325
1987
|
this._conversation.push({ role: "tool", content: result2, tool_call_id: id, name });
|
|
@@ -2327,11 +1989,11 @@ var PipelineSession = class {
|
|
|
2327
1989
|
return;
|
|
2328
1990
|
}
|
|
2329
1991
|
}
|
|
2330
|
-
if (
|
|
1992
|
+
if (chunk7TEOYLZI_cjs.BUILTIN_TOOL_NAMES.has(name) && this._callSession instanceof chunk7TEOYLZI_cjs.BufferingCall) {
|
|
2331
1993
|
this._log.warn("Builtin tool %s called before answer \u2014 deferring", name);
|
|
2332
1994
|
this._conversation.push({
|
|
2333
1995
|
role: "tool",
|
|
2334
|
-
content:
|
|
1996
|
+
content: chunk7TEOYLZI_cjs.CALL_NOT_READY_RESULT,
|
|
2335
1997
|
tool_call_id: id,
|
|
2336
1998
|
name
|
|
2337
1999
|
});
|
|
@@ -2340,7 +2002,7 @@ var PipelineSession = class {
|
|
|
2340
2002
|
}
|
|
2341
2003
|
if (!this._tools) return;
|
|
2342
2004
|
this._callSession?.recordToolCall();
|
|
2343
|
-
const player = this._holdAudioChunks && this._callSession && !(this._callSession instanceof
|
|
2005
|
+
const player = this._holdAudioChunks && this._callSession && !(this._callSession instanceof chunk7TEOYLZI_cjs.BufferingCall) ? new HoldAudioPlayer(this._callSession, this._holdAudioChunks) : null;
|
|
2344
2006
|
player?.start();
|
|
2345
2007
|
let result;
|
|
2346
2008
|
try {
|
|
@@ -2391,8 +2053,8 @@ var PipelineSession = class {
|
|
|
2391
2053
|
sampleRate: this._sampleRate
|
|
2392
2054
|
})) {
|
|
2393
2055
|
if (!this._running || !this._speaking) break;
|
|
2394
|
-
const pcm8k =
|
|
2395
|
-
const ulaw =
|
|
2056
|
+
const pcm8k = chunk7TEOYLZI_cjs.resamplePcm16(audioChunk, this._sampleRate, 8e3);
|
|
2057
|
+
const ulaw = chunk7TEOYLZI_cjs.pcm16ToUlaw(pcm8k);
|
|
2396
2058
|
for (let off = 0; off < ulaw.length; off += 160) {
|
|
2397
2059
|
let chunk = ulaw.subarray(off, off + 160);
|
|
2398
2060
|
if (chunk.length < 160) {
|
|
@@ -2419,7 +2081,7 @@ var OpenAIRealtime = class {
|
|
|
2419
2081
|
_language;
|
|
2420
2082
|
_turnDetection;
|
|
2421
2083
|
_greeting;
|
|
2422
|
-
_log =
|
|
2084
|
+
_log = chunk7TEOYLZI_cjs.NOOP_LOGGER;
|
|
2423
2085
|
_builtinTools = null;
|
|
2424
2086
|
/**
|
|
2425
2087
|
* 마지막 session.update 로 LLM 에 알린 tool 이름들. attach() 가 이 값과 현재
|
|
@@ -2496,7 +2158,7 @@ var OpenAIRealtime = class {
|
|
|
2496
2158
|
/** Open WS + session.update + (optional) response.create without a CallSession. */
|
|
2497
2159
|
async prewarm(tools) {
|
|
2498
2160
|
if (tools) this._tools = tools;
|
|
2499
|
-
this._call = new
|
|
2161
|
+
this._call = new chunk7TEOYLZI_cjs.BufferingCall();
|
|
2500
2162
|
this._closed = false;
|
|
2501
2163
|
this._playback = null;
|
|
2502
2164
|
this._latestMediaTs = 0;
|
|
@@ -2538,7 +2200,7 @@ var OpenAIRealtime = class {
|
|
|
2538
2200
|
this._resyncTools();
|
|
2539
2201
|
const prev = this._call;
|
|
2540
2202
|
this._call = callSession;
|
|
2541
|
-
|
|
2203
|
+
chunk7TEOYLZI_cjs.attachBuffered(prev, callSession);
|
|
2542
2204
|
}
|
|
2543
2205
|
async start(callSession, tools) {
|
|
2544
2206
|
if (tools) this._tools = tools;
|
|
@@ -2599,7 +2261,7 @@ var OpenAIRealtime = class {
|
|
|
2599
2261
|
/** Current tool schemas: user tools + builtin tools (flat realtime format). */
|
|
2600
2262
|
_currentToolSchemas() {
|
|
2601
2263
|
const toolSchemas = this._tools ? this._tools.toOpenAITools().map((t) => ({ type: "function", ...t.function })) : [];
|
|
2602
|
-
toolSchemas.push(...
|
|
2264
|
+
toolSchemas.push(...chunk7TEOYLZI_cjs.getBuiltinToolSchemas(this._builtinTools, "realtime"));
|
|
2603
2265
|
return toolSchemas;
|
|
2604
2266
|
}
|
|
2605
2267
|
/**
|
|
@@ -2770,9 +2432,9 @@ var OpenAIRealtime = class {
|
|
|
2770
2432
|
const controller = new AbortController();
|
|
2771
2433
|
this._pendingToolCalls.set(callId, controller);
|
|
2772
2434
|
try {
|
|
2773
|
-
if (
|
|
2435
|
+
if (chunk7TEOYLZI_cjs.BUILTIN_TOOL_NAMES.has(funcName) && this._call && !(this._call instanceof chunk7TEOYLZI_cjs.BufferingCall)) {
|
|
2774
2436
|
const args = JSON.parse(item["arguments"] ?? "{}");
|
|
2775
|
-
const result2 = await
|
|
2437
|
+
const result2 = await chunk7TEOYLZI_cjs.executeBuiltinTool(funcName, args, this._call);
|
|
2776
2438
|
if (result2 !== null) {
|
|
2777
2439
|
if (funcName === "hang_up") return;
|
|
2778
2440
|
if (controller.signal.aborted) return;
|
|
@@ -2789,7 +2451,7 @@ var OpenAIRealtime = class {
|
|
|
2789
2451
|
return;
|
|
2790
2452
|
}
|
|
2791
2453
|
}
|
|
2792
|
-
if (
|
|
2454
|
+
if (chunk7TEOYLZI_cjs.BUILTIN_TOOL_NAMES.has(funcName) && this._call instanceof chunk7TEOYLZI_cjs.BufferingCall) {
|
|
2793
2455
|
this._log.warn("Builtin tool %s called before answer \u2014 deferring", funcName);
|
|
2794
2456
|
await this._waitForResponseDone();
|
|
2795
2457
|
this._send({
|
|
@@ -2797,7 +2459,7 @@ var OpenAIRealtime = class {
|
|
|
2797
2459
|
item: {
|
|
2798
2460
|
type: "function_call_output",
|
|
2799
2461
|
call_id: callId,
|
|
2800
|
-
output:
|
|
2462
|
+
output: chunk7TEOYLZI_cjs.CALL_NOT_READY_RESULT
|
|
2801
2463
|
}
|
|
2802
2464
|
});
|
|
2803
2465
|
this._send({ type: "response.create" });
|
|
@@ -2818,7 +2480,7 @@ var OpenAIRealtime = class {
|
|
|
2818
2480
|
return;
|
|
2819
2481
|
}
|
|
2820
2482
|
let result;
|
|
2821
|
-
const player = this._holdAudioChunks && this._call && !(this._call instanceof
|
|
2483
|
+
const player = this._holdAudioChunks && this._call && !(this._call instanceof chunk7TEOYLZI_cjs.BufferingCall) ? new HoldAudioPlayer(this._call, this._holdAudioChunks) : null;
|
|
2822
2484
|
player?.start();
|
|
2823
2485
|
try {
|
|
2824
2486
|
const args = JSON.parse(item["arguments"] ?? "{}");
|
|
@@ -2967,7 +2629,7 @@ var GeminiRealtime = class _GeminiRealtime {
|
|
|
2967
2629
|
_toolDrainTimer = null;
|
|
2968
2630
|
_lastAudioTime = 0;
|
|
2969
2631
|
_holdAudioChunks = null;
|
|
2970
|
-
_log =
|
|
2632
|
+
_log = chunk7TEOYLZI_cjs.NOOP_LOGGER;
|
|
2971
2633
|
constructor(options = {}) {
|
|
2972
2634
|
this._apiKey = options.apiKey ?? process.env["GOOGLE_API_KEY"] ?? "";
|
|
2973
2635
|
this._systemPrompt = options.systemPrompt ?? "";
|
|
@@ -3013,7 +2675,7 @@ var GeminiRealtime = class _GeminiRealtime {
|
|
|
3013
2675
|
/** Open Live session (no CallSession). Audio deltas accumulate into BufferingCall until attach(). */
|
|
3014
2676
|
async prewarm(tools) {
|
|
3015
2677
|
if (tools) this._tools = tools;
|
|
3016
|
-
this._call = new
|
|
2678
|
+
this._call = new chunk7TEOYLZI_cjs.BufferingCall();
|
|
3017
2679
|
this._closed = false;
|
|
3018
2680
|
this._sentAudioChunks = 0;
|
|
3019
2681
|
this._audioRemainder = Buffer.alloc(0);
|
|
@@ -3070,7 +2732,7 @@ var GeminiRealtime = class _GeminiRealtime {
|
|
|
3070
2732
|
async attach(callSession) {
|
|
3071
2733
|
const prev = this._call;
|
|
3072
2734
|
this._call = callSession;
|
|
3073
|
-
|
|
2735
|
+
chunk7TEOYLZI_cjs.attachBuffered(prev, callSession);
|
|
3074
2736
|
}
|
|
3075
2737
|
async start(callSession, tools) {
|
|
3076
2738
|
if (tools) this._tools = tools;
|
|
@@ -3079,8 +2741,8 @@ var GeminiRealtime = class _GeminiRealtime {
|
|
|
3079
2741
|
}
|
|
3080
2742
|
feedAudio(audio) {
|
|
3081
2743
|
if (this._session && !this._closed) {
|
|
3082
|
-
const pcm8k =
|
|
3083
|
-
const pcm16k =
|
|
2744
|
+
const pcm8k = chunk7TEOYLZI_cjs.ulawToPcm16(audio);
|
|
2745
|
+
const pcm16k = chunk7TEOYLZI_cjs.resamplePcm16(pcm8k, 8e3, 16e3);
|
|
3084
2746
|
this._session.sendRealtimeInput({
|
|
3085
2747
|
audio: {
|
|
3086
2748
|
data: Buffer.from(pcm16k).toString("base64"),
|
|
@@ -3124,7 +2786,7 @@ var GeminiRealtime = class _GeminiRealtime {
|
|
|
3124
2786
|
t.function.parameters ?? { type: "object", properties: {} }
|
|
3125
2787
|
)
|
|
3126
2788
|
})) : [];
|
|
3127
|
-
toolDefs.push(...
|
|
2789
|
+
toolDefs.push(...chunk7TEOYLZI_cjs.getBuiltinToolSchemas(this._builtinTools, "gemini"));
|
|
3128
2790
|
return toolDefs;
|
|
3129
2791
|
}
|
|
3130
2792
|
_handleMessage(msg) {
|
|
@@ -3184,8 +2846,8 @@ var GeminiRealtime = class _GeminiRealtime {
|
|
|
3184
2846
|
_handleAudioData(b64Data) {
|
|
3185
2847
|
if (!this._call) return;
|
|
3186
2848
|
const pcm24k = Buffer.from(b64Data, "base64");
|
|
3187
|
-
const pcm8k =
|
|
3188
|
-
const ulaw =
|
|
2849
|
+
const pcm8k = chunk7TEOYLZI_cjs.resamplePcm16(pcm24k, 24e3, 8e3);
|
|
2850
|
+
const ulaw = chunk7TEOYLZI_cjs.pcm16ToUlaw(pcm8k);
|
|
3189
2851
|
const combined = Buffer.concat([this._audioRemainder, ulaw]);
|
|
3190
2852
|
const chunkSize = 160;
|
|
3191
2853
|
const fullEnd = Math.floor(combined.length / chunkSize) * chunkSize;
|
|
@@ -3228,7 +2890,7 @@ var GeminiRealtime = class _GeminiRealtime {
|
|
|
3228
2890
|
const functionCalls = toolCall.functionCalls;
|
|
3229
2891
|
if (!functionCalls) return;
|
|
3230
2892
|
const responses = [];
|
|
3231
|
-
const player = this._holdAudioChunks && this._call && !(this._call instanceof
|
|
2893
|
+
const player = this._holdAudioChunks && this._call && !(this._call instanceof chunk7TEOYLZI_cjs.BufferingCall) ? new HoldAudioPlayer(this._call, this._holdAudioChunks) : null;
|
|
3232
2894
|
player?.start();
|
|
3233
2895
|
try {
|
|
3234
2896
|
for (const fc of functionCalls) {
|
|
@@ -3236,8 +2898,8 @@ var GeminiRealtime = class _GeminiRealtime {
|
|
|
3236
2898
|
const fcId = fc.id ?? "";
|
|
3237
2899
|
const args = fc.args ?? {};
|
|
3238
2900
|
this._log.info({ tool: name, args }, "Tool call: %s", name);
|
|
3239
|
-
if (
|
|
3240
|
-
const result = await
|
|
2901
|
+
if (chunk7TEOYLZI_cjs.BUILTIN_TOOL_NAMES.has(name) && this._call && !(this._call instanceof chunk7TEOYLZI_cjs.BufferingCall)) {
|
|
2902
|
+
const result = await chunk7TEOYLZI_cjs.executeBuiltinTool(
|
|
3241
2903
|
name,
|
|
3242
2904
|
args,
|
|
3243
2905
|
this._call
|
|
@@ -3252,9 +2914,9 @@ var GeminiRealtime = class _GeminiRealtime {
|
|
|
3252
2914
|
continue;
|
|
3253
2915
|
}
|
|
3254
2916
|
}
|
|
3255
|
-
if (
|
|
2917
|
+
if (chunk7TEOYLZI_cjs.BUILTIN_TOOL_NAMES.has(name) && this._call instanceof chunk7TEOYLZI_cjs.BufferingCall) {
|
|
3256
2918
|
this._log.warn("Builtin tool %s called before answer \u2014 deferring", name);
|
|
3257
|
-
responses.push({ id: fcId, name, response: { result:
|
|
2919
|
+
responses.push({ id: fcId, name, response: { result: chunk7TEOYLZI_cjs.CALL_NOT_READY_RESULT } });
|
|
3258
2920
|
continue;
|
|
3259
2921
|
}
|
|
3260
2922
|
if (!this._tools || !this._tools.has(name)) {
|
|
@@ -3299,7 +2961,7 @@ var GeminiRealtime = class _GeminiRealtime {
|
|
|
3299
2961
|
// src/agent/pipeline/stt/deepgram-stt.ts
|
|
3300
2962
|
var DeepgramSTT = class {
|
|
3301
2963
|
_options;
|
|
3302
|
-
_log =
|
|
2964
|
+
_log = chunk7TEOYLZI_cjs.NOOP_LOGGER;
|
|
3303
2965
|
get provider() {
|
|
3304
2966
|
return "deepgram";
|
|
3305
2967
|
}
|
|
@@ -3426,7 +3088,7 @@ var DeepgramSTT = class {
|
|
|
3426
3088
|
// src/agent/pipeline/tts/elevenlabs-tts.ts
|
|
3427
3089
|
var ElevenLabsTTS = class {
|
|
3428
3090
|
_options;
|
|
3429
|
-
_log =
|
|
3091
|
+
_log = chunk7TEOYLZI_cjs.NOOP_LOGGER;
|
|
3430
3092
|
get provider() {
|
|
3431
3093
|
return "elevenlabs";
|
|
3432
3094
|
}
|
|
@@ -4172,51 +3834,58 @@ function mcpServerHTTP(options) {
|
|
|
4172
3834
|
|
|
4173
3835
|
Object.defineProperty(exports, "BUILTIN_TOOL_NAMES", {
|
|
4174
3836
|
enumerable: true,
|
|
4175
|
-
get: function () { return
|
|
3837
|
+
get: function () { return chunk7TEOYLZI_cjs.BUILTIN_TOOL_NAMES; }
|
|
4176
3838
|
});
|
|
4177
3839
|
Object.defineProperty(exports, "BuiltinTool", {
|
|
4178
3840
|
enumerable: true,
|
|
4179
|
-
get: function () { return
|
|
3841
|
+
get: function () { return chunk7TEOYLZI_cjs.BuiltinTool; }
|
|
3842
|
+
});
|
|
3843
|
+
Object.defineProperty(exports, "CallSession", {
|
|
3844
|
+
enumerable: true,
|
|
3845
|
+
get: function () { return chunk7TEOYLZI_cjs.CallSession; }
|
|
4180
3846
|
});
|
|
4181
3847
|
Object.defineProperty(exports, "DECODE_TABLE", {
|
|
4182
3848
|
enumerable: true,
|
|
4183
|
-
get: function () { return
|
|
3849
|
+
get: function () { return chunk7TEOYLZI_cjs.DECODE_TABLE; }
|
|
3850
|
+
});
|
|
3851
|
+
Object.defineProperty(exports, "DtmfCollectorBusyError", {
|
|
3852
|
+
enumerable: true,
|
|
3853
|
+
get: function () { return chunk7TEOYLZI_cjs.DtmfCollectorBusyError; }
|
|
4184
3854
|
});
|
|
4185
3855
|
Object.defineProperty(exports, "createAgentLogger", {
|
|
4186
3856
|
enumerable: true,
|
|
4187
|
-
get: function () { return
|
|
3857
|
+
get: function () { return chunk7TEOYLZI_cjs.createAgentLogger; }
|
|
4188
3858
|
});
|
|
4189
3859
|
Object.defineProperty(exports, "createPipelineLogger", {
|
|
4190
3860
|
enumerable: true,
|
|
4191
|
-
get: function () { return
|
|
3861
|
+
get: function () { return chunk7TEOYLZI_cjs.createPipelineLogger; }
|
|
4192
3862
|
});
|
|
4193
3863
|
Object.defineProperty(exports, "executeBuiltinTool", {
|
|
4194
3864
|
enumerable: true,
|
|
4195
|
-
get: function () { return
|
|
3865
|
+
get: function () { return chunk7TEOYLZI_cjs.executeBuiltinTool; }
|
|
4196
3866
|
});
|
|
4197
3867
|
Object.defineProperty(exports, "getBuiltinToolSchemas", {
|
|
4198
3868
|
enumerable: true,
|
|
4199
|
-
get: function () { return
|
|
3869
|
+
get: function () { return chunk7TEOYLZI_cjs.getBuiltinToolSchemas; }
|
|
4200
3870
|
});
|
|
4201
3871
|
Object.defineProperty(exports, "isBuiltinTool", {
|
|
4202
3872
|
enumerable: true,
|
|
4203
|
-
get: function () { return
|
|
3873
|
+
get: function () { return chunk7TEOYLZI_cjs.isBuiltinTool; }
|
|
4204
3874
|
});
|
|
4205
3875
|
Object.defineProperty(exports, "pcm16ToUlaw", {
|
|
4206
3876
|
enumerable: true,
|
|
4207
|
-
get: function () { return
|
|
3877
|
+
get: function () { return chunk7TEOYLZI_cjs.pcm16ToUlaw; }
|
|
4208
3878
|
});
|
|
4209
3879
|
Object.defineProperty(exports, "resamplePcm16", {
|
|
4210
3880
|
enumerable: true,
|
|
4211
|
-
get: function () { return
|
|
3881
|
+
get: function () { return chunk7TEOYLZI_cjs.resamplePcm16; }
|
|
4212
3882
|
});
|
|
4213
3883
|
Object.defineProperty(exports, "ulawToPcm16", {
|
|
4214
3884
|
enumerable: true,
|
|
4215
|
-
get: function () { return
|
|
3885
|
+
get: function () { return chunk7TEOYLZI_cjs.ulawToPcm16; }
|
|
4216
3886
|
});
|
|
4217
3887
|
exports.AnthropicLLM = AnthropicLLM;
|
|
4218
3888
|
exports.AudioRecorder = AudioRecorder;
|
|
4219
|
-
exports.CallSession = CallSession;
|
|
4220
3889
|
exports.ClawOpsAgent = ClawOpsAgent;
|
|
4221
3890
|
exports.ControlWebSocket = ControlWebSocket;
|
|
4222
3891
|
exports.DeepSeekLLM = DeepSeekLLM;
|