@teamlearners/clawops 0.21.0 → 0.23.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 +31 -14
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +21 -1
- package/dist/agent/index.d.ts +21 -1
- package/dist/agent/index.js +23 -6
- package/dist/agent/index.js.map +1 -1
- package/dist/{chunk-MSQH3MCJ.js → chunk-JU36ASTU.js} +3 -3
- package/dist/{chunk-MSQH3MCJ.js.map → chunk-JU36ASTU.js.map} +1 -1
- package/dist/{chunk-TRLJ6I3F.cjs → chunk-NXMTLS2U.cjs} +3 -3
- package/dist/{chunk-TRLJ6I3F.cjs.map → chunk-NXMTLS2U.cjs.map} +1 -1
- package/dist/index.cjs +35 -35
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/dist/agent/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkNXMTLS2U_cjs = require('../chunk-NXMTLS2U.cjs');
|
|
4
4
|
var pino = require('pino');
|
|
5
5
|
var fs = require('fs');
|
|
6
6
|
var path = require('path');
|
|
@@ -1079,7 +1079,7 @@ var MAX_ERROR_MESSAGE_LENGTH = 200;
|
|
|
1079
1079
|
function getSdkInfo() {
|
|
1080
1080
|
return {
|
|
1081
1081
|
name: "clawops-node",
|
|
1082
|
-
version:
|
|
1082
|
+
version: chunkNXMTLS2U_cjs.VERSION,
|
|
1083
1083
|
runtime: `node/${process.versions.node}`,
|
|
1084
1084
|
os: `${process.platform}/${os__default.default.arch()}`
|
|
1085
1085
|
};
|
|
@@ -1274,13 +1274,22 @@ var CallSession = class {
|
|
|
1274
1274
|
}
|
|
1275
1275
|
}
|
|
1276
1276
|
}
|
|
1277
|
-
/**
|
|
1277
|
+
/**
|
|
1278
|
+
* Transfer the call to a phone number or SIP endpoint.
|
|
1279
|
+
*
|
|
1280
|
+
* destinationType='pstn' (default): `to` is a phone number dialed via carrier.
|
|
1281
|
+
* destinationType='sip': `to` is a SIP URI (e.g. `sip:user@host`) connected
|
|
1282
|
+
* directly to a SIP endpoint without going through the PSTN carrier. Requires the
|
|
1283
|
+
* account to have an active `sip_trunk` add-on; otherwise the transfer fails and
|
|
1284
|
+
* the call continues with the AI (result `{ status: 'failed', ... }`).
|
|
1285
|
+
*/
|
|
1278
1286
|
async transfer(to, options) {
|
|
1279
1287
|
if (!this._transferFn) {
|
|
1280
1288
|
throw new Error("transfer not available");
|
|
1281
1289
|
}
|
|
1282
1290
|
return this._transferFn({
|
|
1283
1291
|
to,
|
|
1292
|
+
destinationType: options?.destinationType ?? "pstn",
|
|
1284
1293
|
mode: options?.mode ?? "blind",
|
|
1285
1294
|
afterTransfer: options?.afterTransfer ?? "terminate",
|
|
1286
1295
|
holdMedia: options?.holdMedia ?? "ringback",
|
|
@@ -1764,10 +1773,12 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1764
1773
|
/** prewarm 세션이 실제 CallSession 에 attach 완료된 callId. attached 이후의 stop() 은 정상 종료 경로가 책임진다. */
|
|
1765
1774
|
_prewarmAttached = /* @__PURE__ */ new Set();
|
|
1766
1775
|
_prewarmEnabled;
|
|
1776
|
+
/** 모든 발신에 적용되는 AMD default. call() 인자로 호출별 override 가능. */
|
|
1777
|
+
_machineDetection;
|
|
1767
1778
|
constructor(options) {
|
|
1768
1779
|
this._apiKey = options.apiKey ?? process.env["CLAWOPS_API_KEY"] ?? "";
|
|
1769
1780
|
this._accountId = options.accountId ?? process.env["CLAWOPS_ACCOUNT_ID"] ?? "";
|
|
1770
|
-
this._baseUrl = options.baseUrl ??
|
|
1781
|
+
this._baseUrl = options.baseUrl ?? chunkNXMTLS2U_cjs.DEFAULT_BASE_URL;
|
|
1771
1782
|
this._fromNumber = options.from;
|
|
1772
1783
|
this._session = options.session;
|
|
1773
1784
|
this._recording = options.recording ?? false;
|
|
@@ -1778,6 +1789,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1778
1789
|
this._rxGain = _ClawOpsAgent._validateGain("rxGain", options.rxGain ?? 1);
|
|
1779
1790
|
this._txGain = _ClawOpsAgent._validateGain("txGain", options.txGain ?? 1);
|
|
1780
1791
|
this._prewarmEnabled = options.prewarmEnabled ?? true;
|
|
1792
|
+
this._machineDetection = options.machineDetection;
|
|
1781
1793
|
if (options.tracing) {
|
|
1782
1794
|
setTracingConfig(options.tracing);
|
|
1783
1795
|
}
|
|
@@ -1790,7 +1802,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1790
1802
|
}
|
|
1791
1803
|
static _validateGain(name, gain) {
|
|
1792
1804
|
if (typeof gain !== "number" || !Number.isFinite(gain) || gain < 0) {
|
|
1793
|
-
throw new
|
|
1805
|
+
throw new chunkNXMTLS2U_cjs.AgentError(`${name}=${gain} must be a finite number >= 0`);
|
|
1794
1806
|
}
|
|
1795
1807
|
return gain;
|
|
1796
1808
|
}
|
|
@@ -1804,7 +1816,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1804
1816
|
tool(nameOrTool, description, parameters, handler) {
|
|
1805
1817
|
if (typeof nameOrTool === "string") {
|
|
1806
1818
|
if (!description || !parameters || !handler) {
|
|
1807
|
-
throw new
|
|
1819
|
+
throw new chunkNXMTLS2U_cjs.AgentError(
|
|
1808
1820
|
"tool(name, description, parameters, handler) requires all arguments."
|
|
1809
1821
|
);
|
|
1810
1822
|
}
|
|
@@ -1840,10 +1852,10 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1840
1852
|
async connect() {
|
|
1841
1853
|
if (this._controlWs) return;
|
|
1842
1854
|
if (!this._apiKey) {
|
|
1843
|
-
throw new
|
|
1855
|
+
throw new chunkNXMTLS2U_cjs.AgentError("API key is required. Set CLAWOPS_API_KEY or pass apiKey option.");
|
|
1844
1856
|
}
|
|
1845
1857
|
if (!this._accountId) {
|
|
1846
|
-
throw new
|
|
1858
|
+
throw new chunkNXMTLS2U_cjs.AgentError(
|
|
1847
1859
|
"Account ID is required. Set CLAWOPS_ACCOUNT_ID or pass accountId option."
|
|
1848
1860
|
);
|
|
1849
1861
|
}
|
|
@@ -1867,7 +1879,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1867
1879
|
} catch {
|
|
1868
1880
|
}
|
|
1869
1881
|
} catch (err) {
|
|
1870
|
-
throw new
|
|
1882
|
+
throw new chunkNXMTLS2U_cjs.AgentConnectionError(
|
|
1871
1883
|
`Failed to connect to ClawOps: ${err instanceof Error ? err.message : String(err)}`
|
|
1872
1884
|
);
|
|
1873
1885
|
}
|
|
@@ -1906,6 +1918,8 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1906
1918
|
*
|
|
1907
1919
|
* @param options.machineDetection 자동응답기/음성사서함 감지(AMD).
|
|
1908
1920
|
* `'Enable'`=감지 후 `AnsweredBy` 통보(통화 계속), `'Hangup'`=음성사서함 감지 시 자동 종료.
|
|
1921
|
+
* 미지정 시 인스턴스 default(생성자의 `machineDetection`)를 따른다.
|
|
1922
|
+
* 우선순위: 호출 인자 > 인스턴스 default > 비활성.
|
|
1909
1923
|
*/
|
|
1910
1924
|
async call(to, options) {
|
|
1911
1925
|
await this.connect();
|
|
@@ -1915,8 +1929,9 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1915
1929
|
From: this._fromNumber,
|
|
1916
1930
|
Timeout: options?.timeout ?? 60
|
|
1917
1931
|
};
|
|
1918
|
-
|
|
1919
|
-
|
|
1932
|
+
const effectiveMd = options?.machineDetection ?? this._machineDetection;
|
|
1933
|
+
if (effectiveMd) {
|
|
1934
|
+
body["MachineDetection"] = effectiveMd;
|
|
1920
1935
|
}
|
|
1921
1936
|
const resp = await fetch(url, {
|
|
1922
1937
|
method: "POST",
|
|
@@ -1928,7 +1943,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
|
|
|
1928
1943
|
});
|
|
1929
1944
|
if (resp.status !== 201) {
|
|
1930
1945
|
const error = await resp.json();
|
|
1931
|
-
throw new
|
|
1946
|
+
throw new chunkNXMTLS2U_cjs.AgentError(`\uBC1C\uC2E0 \uC2E4\uD328 (${resp.status}): ${error["error"] ?? ""}`);
|
|
1932
1947
|
}
|
|
1933
1948
|
const data = await resp.json();
|
|
1934
1949
|
const callSession = new CallSession({
|
|
@@ -2361,11 +2376,12 @@ var SEND_DTMF = {
|
|
|
2361
2376
|
};
|
|
2362
2377
|
var TRANSFER_CALL = {
|
|
2363
2378
|
name: "transfer_call",
|
|
2364
|
-
description: "Transfer the current call to another phone number. Use for blind transfer (direct handoff) or warm transfer (with whisper message to the target).",
|
|
2379
|
+
description: "Transfer the current call to another phone number or SIP endpoint. Use for blind transfer (direct handoff) or warm transfer (with whisper message to the target).",
|
|
2365
2380
|
parameters: {
|
|
2366
2381
|
type: "object",
|
|
2367
2382
|
properties: {
|
|
2368
|
-
to: { type: "string", description: "
|
|
2383
|
+
to: { type: "string", description: "Transfer destination. A phone number when destination_type is 'pstn', or a SIP URI (e.g. 'sip:user@host') when destination_type is 'sip'." },
|
|
2384
|
+
destination_type: { type: "string", enum: ["pstn", "sip"], description: "pstn: dial a phone number via carrier (default). sip: connect directly to a SIP endpoint (no carrier/PSTN)." },
|
|
2369
2385
|
mode: { type: "string", enum: ["blind", "warm"], description: "blind: direct transfer (default), warm: play whisper to target first" },
|
|
2370
2386
|
after_transfer: { type: "string", enum: ["terminate", "return"], description: "terminate: end AI session (default), return: AI resumes after transfer ends" },
|
|
2371
2387
|
whisper: { type: "string", description: "Message to speak to transfer target before connecting customer (warm mode only)" },
|
|
@@ -2455,6 +2471,7 @@ async function executeBuiltinTool(funcName, args, call) {
|
|
|
2455
2471
|
if (funcName === "transfer_call") {
|
|
2456
2472
|
try {
|
|
2457
2473
|
call.transfer(args["to"], {
|
|
2474
|
+
destinationType: args["destination_type"] ?? void 0,
|
|
2458
2475
|
mode: args["mode"] ?? void 0,
|
|
2459
2476
|
afterTransfer: args["after_transfer"] ?? void 0,
|
|
2460
2477
|
whisper: args["whisper"] ?? void 0,
|