@rymi/node 1.0.1 → 2.1.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/index.mjs CHANGED
@@ -12,6 +12,7 @@ var RymiError = class extends Error {
12
12
  var RymiClient = class {
13
13
  apiKey;
14
14
  baseURL;
15
+ fetchImpl;
15
16
  constructor(options) {
16
17
  const key = options?.apiKey || (typeof process !== "undefined" ? process.env.RYMI_API_KEY : void 0);
17
18
  if (!key) {
@@ -19,6 +20,7 @@ var RymiClient = class {
19
20
  }
20
21
  this.apiKey = key;
21
22
  this.baseURL = options?.baseURL || "https://api.rymi.live/v1";
23
+ this.fetchImpl = options?.fetch ?? globalThis.fetch;
22
24
  if (this.baseURL.endsWith("/")) {
23
25
  this.baseURL = this.baseURL.slice(0, -1);
24
26
  }
@@ -39,7 +41,7 @@ var RymiClient = class {
39
41
  init.body = JSON.stringify(body);
40
42
  }
41
43
  try {
42
- const response = await fetch(url, init);
44
+ const response = await this.fetchImpl(url, init);
43
45
  const isJson = response.headers.get("content-type")?.includes("application/json");
44
46
  const data = isJson ? await response.json() : await response.text();
45
47
  if (!response.ok) {
@@ -147,6 +149,15 @@ var AgentsResource = class {
147
149
  async validatePublish(params) {
148
150
  return this.client.post("/agents/validate-publish", params);
149
151
  }
152
+ /**
153
+ * Publish an agent: validate its persisted config and freeze it into the
154
+ * published snapshot the harness/review pipeline reads as the baseline.
155
+ * Returns `{ published: false, blockers }` (HTTP 200) when blockers remain —
156
+ * inspect `blockers` rather than relying on a thrown error.
157
+ */
158
+ async publish(agentId) {
159
+ return this.client.post(`/agents/${agentId}/publish`, {});
160
+ }
150
161
  /**
151
162
  * Validate and apply a flat-diff change-set against the AgentConfig field registry.
152
163
  * Does NOT persist — callers must follow up with update().
@@ -162,9 +173,8 @@ var AgentsResource = class {
162
173
  }
163
174
  /**
164
175
  * Preview the resolved per-language model stack (STT/LLM/TTS), blockers,
165
- * warnings, model diffs, and any required role upgrades for a set of
166
- * supported languages — without persisting anything. Note: the concierge
167
- * (realtime) role is not supported by this endpoint.
176
+ * warnings, and model diffs for a set of supported languages — without
177
+ * persisting anything.
168
178
  */
169
179
  async previewStack(params) {
170
180
  return this.client.post("/agents/stack-preview", params);
@@ -187,6 +197,26 @@ var AgentsResource = class {
187
197
  async deleteKnowledgeSource(agentId, sourceId) {
188
198
  return this.client.delete(`/agents/${agentId}/knowledge-sources/${sourceId}`);
189
199
  }
200
+ /**
201
+ * Get the agent's public share link, or `link: null` if none exists.
202
+ * `link_feature: false` means share links are disabled on this deployment.
203
+ */
204
+ async getShareLink(agentId) {
205
+ const res = await this.client.get(`/agents/${agentId}/testers`);
206
+ return { link_feature: res.link_feature, link: res.link };
207
+ }
208
+ /**
209
+ * Create the agent's public share link, or update its settings if one exists.
210
+ */
211
+ async setShareLink(agentId, settings = {}) {
212
+ return this.client.put(`/agents/${agentId}/share-link`, settings);
213
+ }
214
+ /**
215
+ * Issue a new URL for the share link. The old URL stops working immediately.
216
+ */
217
+ async regenerateShareLink(agentId) {
218
+ return this.client.post(`/agents/${agentId}/share-link/regenerate`, {});
219
+ }
190
220
  /**
191
221
  * List the recorded configuration changes for an agent (most recent first).
192
222
  * Optionally pass an ISO timestamp to only return changes since then.
@@ -207,8 +237,20 @@ var AgentsResource = class {
207
237
  * the offline scorer; mode="live" runs the model-driven runner.
208
238
  */
209
239
  async runEvals(agentId, params = {}) {
210
- const query = params.mode ? `?mode=${params.mode}` : "";
211
- return this.client.post(`/agents/${agentId}/evals/run${query}`, {});
240
+ const query = new URLSearchParams();
241
+ if (params.mode) query.set("mode", params.mode);
242
+ if (params.judge) query.set("judge", "1");
243
+ const qs = query.toString();
244
+ return this.client.post(`/agents/${agentId}/evals/run${qs ? `?${qs}` : ""}`, {});
245
+ }
246
+ /**
247
+ * Run the eval SUITE across many agents at once (agents × seeded scenarios),
248
+ * bounded by the optional concurrency cap. One eval run is persisted per
249
+ * agent; the aggregate EvalSuiteReport is returned. Pass `judge: true` to
250
+ * supplement the heuristics with the opt-in LLM judge (needs a Gemini key).
251
+ */
252
+ async runEvalSuite(params) {
253
+ return this.client.post("/agents/evals/suite", params);
212
254
  }
213
255
  /**
214
256
  * List previous evaluation runs for an agent.
@@ -264,7 +306,16 @@ var CallsResource = class {
264
306
  return this.client.post("/calls", data);
265
307
  }
266
308
  /**
267
- * Queue up to 500 outbound PSTN recipients in one request.
309
+ * Group call fanout: dial up to 500 PSTN participants into a single call room.
310
+ * Every recipient joins the same call. For independent per-recipient attempts,
311
+ * retries, and reports, use `campaigns` instead.
312
+ */
313
+ async fanout(data) {
314
+ return this.client.post("/calls/fanout", data);
315
+ }
316
+ /**
317
+ * Compatibility alias for {@link fanout}. Creates one call room with multiple
318
+ * PSTN participants. Queue up to 500 outbound PSTN recipients in one request.
268
319
  */
269
320
  async batch(data) {
270
321
  return this.client.post("/calls/batch", data);
@@ -350,6 +401,14 @@ var NumbersResource = class {
350
401
  async attach(number, agentId) {
351
402
  return this.client.post(`/numbers/${encodeURIComponent(number)}/attach`, { agent_id: agentId });
352
403
  }
404
+ /** Clear the agent association without deregistering the number. */
405
+ async detach(number) {
406
+ return this.client.post(`/numbers/${encodeURIComponent(number)}/detach`);
407
+ }
408
+ /** Re-run carrier inbound-webhook auto-provisioning for a number. */
409
+ async provisionWebhook(number) {
410
+ return this.client.post(`/numbers/${encodeURIComponent(number)}/webhook`);
411
+ }
353
412
  async remove(number) {
354
413
  return this.client.delete(`/numbers/${encodeURIComponent(number)}`);
355
414
  }
@@ -473,7 +532,7 @@ var BillingResource = class {
473
532
  async usageSummary() {
474
533
  return this.client.get("/billing/usage-summary");
475
534
  }
476
- /** Estimate the cost of a call for a given tier and duration. */
535
+ /** Estimate the cost of a call for a custom model stack and duration. */
477
536
  async estimate(data = {}) {
478
537
  return this.client.post("/billing/estimate", data);
479
538
  }
@@ -501,6 +560,228 @@ var TemplatesResource = class {
501
560
  }
502
561
  };
503
562
 
563
+ // src/resources/campaigns.ts
564
+ function buildQuery4(params) {
565
+ const sp = new URLSearchParams();
566
+ for (const [k, v] of Object.entries(params)) {
567
+ if (v !== void 0 && v !== null) sp.set(k, String(v));
568
+ }
569
+ const q = sp.toString();
570
+ return q ? `?${q}` : "";
571
+ }
572
+ var CampaignMembersResource = class {
573
+ constructor(client) {
574
+ this.client = client;
575
+ }
576
+ /** List a campaign's members, paginated. */
577
+ async list(campaignId, params = {}) {
578
+ return this.client.get(`/campaigns/${campaignId}/members${buildQuery4(params)}`);
579
+ }
580
+ /** Attach existing contacts to a campaign as members. */
581
+ async add(campaignId, data) {
582
+ return this.client.post(`/campaigns/${campaignId}/members`, data);
583
+ }
584
+ /** Import inline contact rows (JSON or CSV): creates/merges contacts and attaches members in one call. */
585
+ async import(campaignId, data) {
586
+ return this.client.post(`/campaigns/${campaignId}/members/import`, data);
587
+ }
588
+ /** Update a campaign member (status, variables, next attempt time). */
589
+ async update(campaignId, memberId, data) {
590
+ return this.client.patch(`/campaigns/${campaignId}/members/${memberId}`, data);
591
+ }
592
+ /** Remove a member from a campaign. */
593
+ async remove(campaignId, memberId) {
594
+ return this.client.delete(`/campaigns/${campaignId}/members/${memberId}`);
595
+ }
596
+ };
597
+ var CampaignRoutesResource = class {
598
+ constructor(client) {
599
+ this.client = client;
600
+ }
601
+ /** List a campaign's inbound routing rules. */
602
+ async list(campaignId, params = {}) {
603
+ return this.client.get(`/campaigns/${campaignId}/routes${buildQuery4(params)}`);
604
+ }
605
+ /** Bind an owned phone number to this campaign for inbound routing. Only one active route per number is allowed. */
606
+ async create(campaignId, data) {
607
+ return this.client.post(`/campaigns/${campaignId}/routes`, data);
608
+ }
609
+ /** Update an inbound route's schedule or active flag. */
610
+ async update(campaignId, routeId, data) {
611
+ return this.client.patch(`/campaigns/${campaignId}/routes/${routeId}`, data);
612
+ }
613
+ /** Delete an inbound route. */
614
+ async delete(campaignId, routeId) {
615
+ return this.client.delete(`/campaigns/${campaignId}/routes/${routeId}`);
616
+ }
617
+ };
618
+ var CampaignsResource = class {
619
+ constructor(client) {
620
+ this.client = client;
621
+ this.members = new CampaignMembersResource(client);
622
+ this.routes = new CampaignRoutesResource(client);
623
+ }
624
+ members;
625
+ routes;
626
+ /** List campaigns for the authenticated tenant, paginated. */
627
+ async list(params = {}) {
628
+ return this.client.get(`/campaigns${buildQuery4(params)}`);
629
+ }
630
+ /** Create a new campaign in draft status against a published agent. */
631
+ async create(data) {
632
+ return this.client.post("/campaigns", data);
633
+ }
634
+ /** Retrieve a single campaign by id. */
635
+ async get(campaignId) {
636
+ return this.client.get(`/campaigns/${campaignId}`);
637
+ }
638
+ /** Update campaign policy/goal fields. Status and lifecycle fields are not writable here. */
639
+ async update(campaignId, data) {
640
+ return this.client.patch(`/campaigns/${campaignId}`, data);
641
+ }
642
+ /**
643
+ * Launch a campaign: validates launch blockers, then stamps
644
+ * `launched_at` + `agent_snapshot_id`, flips members to `ready`, and
645
+ * transitions status to `running`.
646
+ */
647
+ async launch(campaignId) {
648
+ return this.client.post(`/campaigns/${campaignId}/launch`);
649
+ }
650
+ /** Evaluate launch blockers without launching (dry run). Safe from any status. */
651
+ async launchBlockers(campaignId) {
652
+ return this.client.get(`/campaigns/${campaignId}/launch-blockers`);
653
+ }
654
+ /** Pause a running campaign. In-flight calls finish naturally. */
655
+ async pause(campaignId) {
656
+ return this.client.post(`/campaigns/${campaignId}/pause`);
657
+ }
658
+ /** Resume a paused campaign. */
659
+ async resume(campaignId) {
660
+ return this.client.post(`/campaigns/${campaignId}/resume`);
661
+ }
662
+ /** Archive a campaign. Terminal — the scheduler never selects work for it again. */
663
+ async archive(campaignId) {
664
+ return this.client.post(`/campaigns/${campaignId}/archive`);
665
+ }
666
+ /** Read the campaign report: `stat_*` summary counters + outcome/sentiment/hourly/snapshot distributions. */
667
+ async report(campaignId) {
668
+ return this.client.get(`/campaigns/${campaignId}/report`);
669
+ }
670
+ /** List a campaign's dial attempts, paginated. */
671
+ async attempts(campaignId, params = {}) {
672
+ return this.client.get(`/campaigns/${campaignId}/attempts${buildQuery4(params)}`);
673
+ }
674
+ /** List a campaign's sweep-claim batches, paginated. */
675
+ async batches(campaignId, params = {}) {
676
+ return this.client.get(`/campaigns/${campaignId}/batches${buildQuery4(params)}`);
677
+ }
678
+ /** List a campaign's follow-up jobs, paginated. */
679
+ async followups(campaignId, params = {}) {
680
+ return this.client.get(`/campaigns/${campaignId}/followups${buildQuery4(params)}`);
681
+ }
682
+ /** Run the improve engine: detectors gate an LLM proposal writer, persisting new `campaign_suggestions`. */
683
+ async improve(campaignId) {
684
+ return this.client.post(`/campaigns/${campaignId}/improve`);
685
+ }
686
+ /** List a campaign's improvement suggestions, paginated. */
687
+ async suggestions(campaignId, params = {}) {
688
+ return this.client.get(`/campaigns/${campaignId}/suggestions${buildQuery4(params)}`);
689
+ }
690
+ /** Accept a suggestion: agent-editing suggestions create an agent-changes draft; campaign-policy suggestions patch the campaign. */
691
+ async acceptSuggestion(campaignId, suggestionId) {
692
+ return this.client.post(`/campaigns/${campaignId}/suggestions/${suggestionId}/accept`);
693
+ }
694
+ /** Dismiss a suggestion without applying it. */
695
+ async dismissSuggestion(campaignId, suggestionId) {
696
+ return this.client.post(`/campaigns/${campaignId}/suggestions/${suggestionId}/dismiss`);
697
+ }
698
+ };
699
+
700
+ // src/resources/contacts.ts
701
+ function buildQuery5(params) {
702
+ const sp = new URLSearchParams();
703
+ for (const [k, v] of Object.entries(params)) {
704
+ if (v !== void 0 && v !== null) sp.set(k, String(v));
705
+ }
706
+ const q = sp.toString();
707
+ return q ? `?${q}` : "";
708
+ }
709
+ var ContactsResource = class {
710
+ constructor(client) {
711
+ this.client = client;
712
+ }
713
+ /** List tenant-level contacts, paginated. */
714
+ async list(params = {}) {
715
+ return this.client.get(`/contacts${buildQuery5(params)}`);
716
+ }
717
+ /**
718
+ * Create a tenant-level contact. If a contact with the same
719
+ * (tenant, phone) already exists, the existing row is returned instead
720
+ * of creating a duplicate — check `deduped` in the response.
721
+ */
722
+ async create(data) {
723
+ return this.client.post("/contacts", data);
724
+ }
725
+ /** Retrieve a single tenant-scoped contact by id. */
726
+ async get(contactId) {
727
+ return this.client.get(`/contacts/${contactId}`);
728
+ }
729
+ /** Update an existing tenant-scoped contact. Only provided fields change. */
730
+ async update(contactId, data) {
731
+ return this.client.patch(`/contacts/${contactId}`, data);
732
+ }
733
+ /** Delete a tenant-scoped contact. */
734
+ async delete(contactId) {
735
+ return this.client.delete(`/contacts/${contactId}`);
736
+ }
737
+ /**
738
+ * Bulk import contacts from JSON rows or CSV text. Each row's phone is
739
+ * normalized to E.164 and upserted on (tenant_id, phone); rows with
740
+ * unparseable phones are skipped and reported in `invalid`.
741
+ */
742
+ async import(data) {
743
+ return this.client.post("/contacts/import", data);
744
+ }
745
+ /** Record a consent grant or revoke for one channel, with evidence. Also
746
+ * appends an immutable row to the consent_events proof log. */
747
+ async setConsent(contactId, data) {
748
+ return this.client.patch(`/contacts/${contactId}/consent`, data);
749
+ }
750
+ };
751
+
752
+ // src/resources/compliance.ts
753
+ var ComplianceResource = class {
754
+ constructor(client) {
755
+ this.client = client;
756
+ }
757
+ /** Record a compliance attestation (append-only). Campaign launch blockers
758
+ * in `attested` mode read the most recent one of the matching `kind`. */
759
+ async attest(data) {
760
+ return this.client.post("/compliance/attestations", data);
761
+ }
762
+ /** List the tenant's 50 most recent compliance attestations, newest first. */
763
+ async listAttestations() {
764
+ return this.client.get("/compliance/attestations");
765
+ }
766
+ };
767
+
768
+ // src/resources/toolSecrets.ts
769
+ var ToolSecretsResource = class {
770
+ constructor(client) {
771
+ this.client = client;
772
+ }
773
+ async list() {
774
+ return this.client.get("/tool-secrets");
775
+ }
776
+ /** Create or replace. `name` is UPPER_SNAKE_CASE; `host` is a public hostname. */
777
+ async set(name, data) {
778
+ return this.client.put(`/tool-secrets/${encodeURIComponent(name)}`, data);
779
+ }
780
+ async delete(name) {
781
+ return this.client.delete(`/tool-secrets/${encodeURIComponent(name)}`);
782
+ }
783
+ };
784
+
504
785
  // src/index.ts
505
786
  export * from "@rymi/sdk-types";
506
787
  var Rymi = class {
@@ -514,6 +795,10 @@ var Rymi = class {
514
795
  telephony;
515
796
  billing;
516
797
  templates;
798
+ campaigns;
799
+ contacts;
800
+ compliance;
801
+ toolSecrets;
517
802
  constructor(options) {
518
803
  this.client = new RymiClient(options);
519
804
  this.agents = new AgentsResource(this.client);
@@ -525,6 +810,10 @@ var Rymi = class {
525
810
  this.telephony = new TelephonyResource(this.client);
526
811
  this.billing = new BillingResource(this.client);
527
812
  this.templates = new TemplatesResource(this.client);
813
+ this.campaigns = new CampaignsResource(this.client);
814
+ this.contacts = new ContactsResource(this.client);
815
+ this.compliance = new ComplianceResource(this.client);
816
+ this.toolSecrets = new ToolSecretsResource(this.client);
528
817
  }
529
818
  };
530
819
  var index_default = Rymi;
@@ -532,6 +821,9 @@ export {
532
821
  AgentsResource,
533
822
  BillingResource,
534
823
  CallsResource,
824
+ CampaignsResource,
825
+ ComplianceResource,
826
+ ContactsResource,
535
827
  DncResource,
536
828
  KeysResource,
537
829
  NumbersResource,
@@ -540,6 +832,7 @@ export {
540
832
  RymiError,
541
833
  TelephonyResource,
542
834
  TemplatesResource,
835
+ ToolSecretsResource,
543
836
  WebhooksResource,
544
837
  index_default as default
545
838
  };