@teamlearners/clawops 0.20.2 → 0.22.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/README.md CHANGED
@@ -280,6 +280,19 @@ const numbers = await client.numbers.list();
280
280
  // 웹훅 URL 변경
281
281
  await client.numbers.update('07012340001', { webhookUrl: 'https://my-app.com/webhook' });
282
282
 
283
+ // 인바운드 소프트폰 착신으로 라우팅 변경 (sip_trunk 부가서비스 + 등록 단말 필요)
284
+ // 1) 등록된 SIP 단말(credential) 목록에서 id 조회
285
+ const creds = await client.sipCredentials.list({ status: 'active' });
286
+ // 2) 그 id 로 라우팅 설정
287
+ await client.numbers.update('07012340001', {
288
+ routingType: 'softphone',
289
+ sipCredentialId: creds[0].id,
290
+ });
291
+
292
+ // (sip 라우팅의 경우) SIP 엔드포인트 id 조회
293
+ const endpoints = await client.sipEndpoints.list({ status: 'active' });
294
+ await client.numbers.update('07012340001', { routingType: 'sip', sipEndpointId: endpoints[0].id });
295
+
283
296
  // 번호 해제
284
297
  await client.numbers.delete('07012340001');
285
298
  ```
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkVFSF6CKS_cjs = require('../chunk-VFSF6CKS.cjs');
3
+ var chunkCJ2LJZDQ_cjs = require('../chunk-CJ2LJZDQ.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: chunkVFSF6CKS_cjs.VERSION,
1082
+ version: chunkCJ2LJZDQ_cjs.VERSION,
1083
1083
  runtime: `node/${process.versions.node}`,
1084
1084
  os: `${process.platform}/${os__default.default.arch()}`
1085
1085
  };
@@ -1274,13 +1274,20 @@ var CallSession = class {
1274
1274
  }
1275
1275
  }
1276
1276
  }
1277
- /** Transfer the call to another destination. */
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.
1283
+ */
1278
1284
  async transfer(to, options) {
1279
1285
  if (!this._transferFn) {
1280
1286
  throw new Error("transfer not available");
1281
1287
  }
1282
1288
  return this._transferFn({
1283
1289
  to,
1290
+ destinationType: options?.destinationType ?? "pstn",
1284
1291
  mode: options?.mode ?? "blind",
1285
1292
  afterTransfer: options?.afterTransfer ?? "terminate",
1286
1293
  holdMedia: options?.holdMedia ?? "ringback",
@@ -1767,7 +1774,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
1767
1774
  constructor(options) {
1768
1775
  this._apiKey = options.apiKey ?? process.env["CLAWOPS_API_KEY"] ?? "";
1769
1776
  this._accountId = options.accountId ?? process.env["CLAWOPS_ACCOUNT_ID"] ?? "";
1770
- this._baseUrl = options.baseUrl ?? chunkVFSF6CKS_cjs.DEFAULT_BASE_URL;
1777
+ this._baseUrl = options.baseUrl ?? chunkCJ2LJZDQ_cjs.DEFAULT_BASE_URL;
1771
1778
  this._fromNumber = options.from;
1772
1779
  this._session = options.session;
1773
1780
  this._recording = options.recording ?? false;
@@ -1790,7 +1797,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
1790
1797
  }
1791
1798
  static _validateGain(name, gain) {
1792
1799
  if (typeof gain !== "number" || !Number.isFinite(gain) || gain < 0) {
1793
- throw new chunkVFSF6CKS_cjs.AgentError(`${name}=${gain} must be a finite number >= 0`);
1800
+ throw new chunkCJ2LJZDQ_cjs.AgentError(`${name}=${gain} must be a finite number >= 0`);
1794
1801
  }
1795
1802
  return gain;
1796
1803
  }
@@ -1804,7 +1811,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
1804
1811
  tool(nameOrTool, description, parameters, handler) {
1805
1812
  if (typeof nameOrTool === "string") {
1806
1813
  if (!description || !parameters || !handler) {
1807
- throw new chunkVFSF6CKS_cjs.AgentError(
1814
+ throw new chunkCJ2LJZDQ_cjs.AgentError(
1808
1815
  "tool(name, description, parameters, handler) requires all arguments."
1809
1816
  );
1810
1817
  }
@@ -1840,10 +1847,10 @@ var ClawOpsAgent = class _ClawOpsAgent {
1840
1847
  async connect() {
1841
1848
  if (this._controlWs) return;
1842
1849
  if (!this._apiKey) {
1843
- throw new chunkVFSF6CKS_cjs.AgentError("API key is required. Set CLAWOPS_API_KEY or pass apiKey option.");
1850
+ throw new chunkCJ2LJZDQ_cjs.AgentError("API key is required. Set CLAWOPS_API_KEY or pass apiKey option.");
1844
1851
  }
1845
1852
  if (!this._accountId) {
1846
- throw new chunkVFSF6CKS_cjs.AgentError(
1853
+ throw new chunkCJ2LJZDQ_cjs.AgentError(
1847
1854
  "Account ID is required. Set CLAWOPS_ACCOUNT_ID or pass accountId option."
1848
1855
  );
1849
1856
  }
@@ -1867,7 +1874,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
1867
1874
  } catch {
1868
1875
  }
1869
1876
  } catch (err) {
1870
- throw new chunkVFSF6CKS_cjs.AgentConnectionError(
1877
+ throw new chunkCJ2LJZDQ_cjs.AgentConnectionError(
1871
1878
  `Failed to connect to ClawOps: ${err instanceof Error ? err.message : String(err)}`
1872
1879
  );
1873
1880
  }
@@ -1928,7 +1935,7 @@ var ClawOpsAgent = class _ClawOpsAgent {
1928
1935
  });
1929
1936
  if (resp.status !== 201) {
1930
1937
  const error = await resp.json();
1931
- throw new chunkVFSF6CKS_cjs.AgentError(`\uBC1C\uC2E0 \uC2E4\uD328 (${resp.status}): ${error["error"] ?? ""}`);
1938
+ throw new chunkCJ2LJZDQ_cjs.AgentError(`\uBC1C\uC2E0 \uC2E4\uD328 (${resp.status}): ${error["error"] ?? ""}`);
1932
1939
  }
1933
1940
  const data = await resp.json();
1934
1941
  const callSession = new CallSession({
@@ -2361,11 +2368,12 @@ var SEND_DTMF = {
2361
2368
  };
2362
2369
  var TRANSFER_CALL = {
2363
2370
  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).",
2371
+ 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
2372
  parameters: {
2366
2373
  type: "object",
2367
2374
  properties: {
2368
- to: { type: "string", description: "Phone number to transfer to" },
2375
+ 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'." },
2376
+ 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
2377
  mode: { type: "string", enum: ["blind", "warm"], description: "blind: direct transfer (default), warm: play whisper to target first" },
2370
2378
  after_transfer: { type: "string", enum: ["terminate", "return"], description: "terminate: end AI session (default), return: AI resumes after transfer ends" },
2371
2379
  whisper: { type: "string", description: "Message to speak to transfer target before connecting customer (warm mode only)" },
@@ -2455,6 +2463,7 @@ async function executeBuiltinTool(funcName, args, call) {
2455
2463
  if (funcName === "transfer_call") {
2456
2464
  try {
2457
2465
  call.transfer(args["to"], {
2466
+ destinationType: args["destination_type"] ?? void 0,
2458
2467
  mode: args["mode"] ?? void 0,
2459
2468
  afterTransfer: args["after_transfer"] ?? void 0,
2460
2469
  whisper: args["whisper"] ?? void 0,