@signalhousellc/sdk 1.0.66 → 1.0.68

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
@@ -55,3 +55,13 @@ For full API reference and advanced usage, visit https://api.signalhouse.io
55
55
 
56
56
  License
57
57
  ISC © Signal House
58
+
59
+
60
+ ### Geographic availability search
61
+
62
+ The availability path supports optional `city` as a case-insensitive prefix within an explicit `country` (`CA` or `US`) and `state` (province/state code). City must be supplied with both country and state. Example: `getAvailablePhoneNumbers({ country: "CA", state: "QC", city: "Charny", npa: "367", nxx: "883", limit: 10 })`. Canadian province, city, NPA and NXX matches are checked before the result limit; unrelated substring matches are excluded. Availability may change before purchase.
63
+
64
+
65
+ Canadian message estimates return per-recipient `phoneNumber`, `rate`, `amount` and `fallback`, plus segment count and total in microdollars. They use cached carrier information without exposing carrier names or making a paid lookup. Rates remain 75,500 for standard carriers and 81,000 for Ice Wireless/Iristel or unresolved carriers; MMS/group MMS use one segment per recipient.
66
+
67
+ Available-number searches return `{ numbers, numberCount? }`. `numberCount` is omitted when the total is unknown, including Canadian geographic and US city searches; the page length is not a total. These filtered searches have a 20-second discovery deadline and return HTTP 503 when incomplete. Narrow the location/NPA/NXX or retry later. Successful Infobip samples may be cached for 15 seconds across pages; purchase rechecks availability.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signalhousellc/sdk",
3
- "version": "1.0.66",
3
+ "version": "1.0.68",
4
4
  "description": "Signal House SDK for use with the Signal House platform",
5
5
  "type": "module",
6
6
  "main": "src/SignalHouseSDK.js",
@@ -19,7 +19,9 @@
19
19
  },
20
20
  "scripts": {
21
21
  "postinstall": "node scripts/install-skills.mjs",
22
- "sync-skills": "node scripts/sync-skills.mjs"
22
+ "sync-skills": "node scripts/sync-skills.mjs",
23
+ "build:types": "tsc -p tsconfig.json",
24
+ "check:types": "tsc -p tsconfig.json --noEmit"
23
25
  },
24
26
  "agents": {
25
27
  "skills": "./skills"
@@ -36,5 +38,10 @@
36
38
  "jssip": {
37
39
  "optional": true
38
40
  }
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "^22.20.3",
44
+ "jssip": "^3.13.8",
45
+ "typescript": "^5.9.3"
39
46
  }
40
47
  }
@@ -42,13 +42,10 @@ Two distinct real causes share this code.
42
42
 
43
43
  **`Invalid sub-usecases: SOCIAL`.** `SOCIAL` is not a valid sub-use-case under any parent,
44
44
  neither `LOW_VOLUME` nor `MIXED`. Valid sub-use-cases for `LOW_VOLUME` are
45
- `ACCOUNT_NOTIFICATION`, `CUSTOMER_CARE`, `DELIVERY_NOTIFICATION`, `MARKETING`. Resubmit with
46
- `SOCIAL` removed.
47
-
48
- ⚠️ **Known platform bug, tracked as SHGHL-2943.** Signal House validates `subUsecases` against
49
- the *use-case* enum, so `SOCIAL` is selectable as a sub-use-case even though the registry always
50
- rejects it. **Delete this subsection when SHGHL-2943 ships.** It documents a defect, and a
51
- workaround left in a skill becomes permanent.
45
+ `ACCOUNT_NOTIFICATION`, `CUSTOMER_CARE`, `DELIVERY_NOTIFICATION`, `MARKETING`. Signal House's own
46
+ validation now rejects `SOCIAL` as a `subUsecases` value with an immediate 400 before the request
47
+ ever reaches TCR (SHGHL-2943), so this specific 501 should no longer be reachable through the
48
+ API — `SOCIAL` is still a valid top-level `usecase`, just never a sub-use-case.
52
49
 
53
50
  **Punctuation in a tag.** A tag of `maria-answers` was rejected for containing a hyphen. The
54
51
  campaign content was fine. Fix the tag (`mariaanswers`), then the campaign has to be
@@ -6,6 +6,19 @@ import axios from "axios";
6
6
  * @property {object} [headers] - Additional headers to include in the request
7
7
  */
8
8
 
9
+ /**
10
+ * @typedef {Object} SignalHouseSDKConfig
11
+ * @property {string} apiKey - The API key for authenticating requests to the SignalHouse API
12
+ * @property {string} baseUrl - The base URL for the SignalHouse API (e.g., "https://api.signalhouse.com")
13
+ * @property {boolean} [enableAdmin=false] - Enable admin-scoped behaviors on domains that support them
14
+ */
15
+
16
+ /**
17
+ * The envelope every domain method resolves to. Non-2xx responses never reject; check `success` first.
18
+ * @template T
19
+ * @typedef {{ success: true, data: T, status: number } | { success: false, error: string|Object, status: number|null }} SdkResponse
20
+ */
21
+
9
22
  // Main SDK Class (SignalHouseSDK.js)
10
23
  import { Auth } from "./domains/Auth.js";
11
24
  import { Billing } from "./domains/Billing.js";
@@ -24,23 +37,20 @@ import { Users } from "./domains/Users.js";
24
37
  import { Notifications } from "./domains/Notifications.js";
25
38
  import { Webhooks } from "./domains/Webhooks.js";
26
39
  import { Voice } from "./domains/Voice.js";
40
+ import { Agents } from "./domains/Agents.js";
27
41
 
28
42
  export class SignalHouseSDK {
29
43
  /**
30
44
  * Initialize the SignalHouseSDK with the required configuration
31
- * @param {Object} config - The configuration object for initializing the SDK
32
- * @param {string} config.apiKey - The API key for authenticating requests to the SignalHouse API
33
- * @param {string} config.baseUrl - The base URL for the SignalHouse API (e.g., "https://api.signalhouse.com")
34
- * @param {boolean} [config.enableAdmin=false] - Enable admin-scoped behaviors on domains that support them.
45
+ * @param {SignalHouseSDKConfig} config - The configuration object for initializing the SDK
35
46
  * @throws {Error} Throws an error if the API key or base URL is missing from the configuration
36
- * @returns {SignalHouseSDK} An instance of the SignalHouseSDK
37
47
  */
38
- constructor(config = {}) {
48
+ constructor(config) {
39
49
  // Validate required config parameters
40
- if (!config.apiKey) {
50
+ if (!config?.apiKey) {
41
51
  throw new Error("API key is required to initialize SignalHouseSDK");
42
52
  }
43
- if (!config.baseUrl) {
53
+ if (!config?.baseUrl) {
44
54
  throw new Error("Base URL is required to initialize SignalHouseSDK");
45
55
  }
46
56
 
@@ -73,6 +83,8 @@ export class SignalHouseSDK {
73
83
  // Voice domain targets the voice-backend service under /voice. Available
74
84
  // like any other domain; gating (if any) will be decided later.
75
85
  this.voice = new Voice(client, this.enableAdmin);
86
+ // AI Agents domain — customer-facing agent config under /agent.
87
+ this.agents = new Agents(client, this.enableAdmin);
76
88
  }
77
89
 
78
90
  /**
@@ -87,19 +99,21 @@ export class SignalHouseSDK {
87
99
  const instance = axios.create({ baseURL: this.baseUrl, headers: isMultipart ? {} : { "Content-Type": "application/json" } });
88
100
 
89
101
  // Add a request interceptor to include the API key in the Authorization header
90
- instance.interceptors.request.use((config) => {
102
+ instance.interceptors.request.use((/** @type {import('axios').InternalAxiosRequestConfig & { token?: string }} */ config) => {
91
103
  const token = config.token || this.apiKey;
92
104
  config.headers.Authorization = `Bearer ${token}`;
93
105
  delete config.token; // Remove token from config to avoid sending it as a header
94
106
  return config;
95
107
  });
96
108
 
97
- // Standardize responses
109
+ // Standardize responses. The fulfilled handler deliberately replaces the AxiosResponse with the
110
+ // SdkResponse envelope, which axios's interceptor typing does not model; the cast keeps that intent visible.
98
111
  instance.interceptors.response.use(
99
112
  // Standard 2xx responses
100
- (response) => {
113
+ /** @type {(response: import('axios').AxiosResponse) => any} */
114
+ ((response) => {
101
115
  return { success: true, data: response.data, status: response.status };
102
- },
116
+ }),
103
117
 
104
118
  // Non-2xx responses
105
119
  (error) => {
@@ -153,7 +167,7 @@ export class SignalHouseSDK {
153
167
  _require(fields) {
154
168
  for (const [name, value] of Object.entries(fields)) {
155
169
  if (value === undefined || value === null || value === "") {
156
- const error = new Error(`Missing required parameter: ${name}`);
170
+ const error = /** @type {Error & { status?: number }} */ (new Error(`Missing required parameter: ${name}`));
157
171
  error.name = "SignalHouseValidationError";
158
172
  error.status = 400; // Match API validation code
159
173
  throw error;