@spekoai/sdk 0.4.1 → 0.4.2

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +31 -0
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/lib/client.d.ts +6 -0
  6. package/dist/lib/client.d.ts.map +1 -1
  7. package/dist/lib/client.js +10 -1
  8. package/dist/lib/http.d.ts +1 -0
  9. package/dist/lib/http.d.ts.map +1 -1
  10. package/dist/lib/http.js +4 -1
  11. package/dist/lib/resources/agents.d.ts +27 -10
  12. package/dist/lib/resources/agents.d.ts.map +1 -1
  13. package/dist/lib/resources/agents.js +58 -14
  14. package/dist/lib/resources/callbacks.d.ts +13 -0
  15. package/dist/lib/resources/callbacks.d.ts.map +1 -0
  16. package/dist/lib/resources/callbacks.js +26 -0
  17. package/dist/lib/resources/calls.d.ts +18 -0
  18. package/dist/lib/resources/calls.d.ts.map +1 -0
  19. package/dist/lib/resources/calls.js +33 -0
  20. package/dist/lib/resources/complete.d.ts.map +1 -1
  21. package/dist/lib/resources/complete.js +4 -1
  22. package/dist/lib/resources/phone-numbers.d.ts +20 -6
  23. package/dist/lib/resources/phone-numbers.d.ts.map +1 -1
  24. package/dist/lib/resources/phone-numbers.js +27 -5
  25. package/dist/lib/resources/synthesize.d.ts.map +1 -1
  26. package/dist/lib/resources/synthesize.js +2 -0
  27. package/dist/lib/resources/voice.d.ts +3 -4
  28. package/dist/lib/resources/voice.d.ts.map +1 -1
  29. package/dist/lib/resources/voice.js +3 -4
  30. package/dist/lib/resources/voices.d.ts +27 -0
  31. package/dist/lib/resources/voices.d.ts.map +1 -0
  32. package/dist/lib/resources/voices.js +32 -0
  33. package/dist/lib/types/index.d.ts +542 -17
  34. package/dist/lib/types/index.d.ts.map +1 -1
  35. package/package.json +1 -1
@@ -4,6 +4,8 @@ export interface SpekoClientOptions {
4
4
  apiKey: string;
5
5
  /** Base URL of the Speko API. Defaults to https://api.speko.dev */
6
6
  baseUrl?: string;
7
+ /** Alias for {@link SpekoClientOptions.baseUrl}. If both are set, `baseUrl` wins. */
8
+ baseURL?: string;
7
9
  /** Request timeout in milliseconds. Defaults to 30000. */
8
10
  timeout?: number;
9
11
  }
@@ -127,6 +129,15 @@ export type TranscribeStreamEvent = {
127
129
  export interface SynthesizeOptions extends RoutingIntent {
128
130
  /** Optional voice override. Otherwise the SDK uses each provider's default. */
129
131
  voice?: string;
132
+ /**
133
+ * Optional upstream model name to use for synthesis (e.g.
134
+ * `eleven_multilingual_v2`, `sonic-2`, `gpt-4o-mini-tts`,
135
+ * `qwen3-tts-flash`). When omitted, the router picks the best-ranked
136
+ * model for the chosen provider. When set, applies to the primary
137
+ * candidate only — failover candidates still use the selector's model
138
+ * so a model intended for provider A isn't sent to provider B.
139
+ */
140
+ model?: string;
130
141
  speed?: number;
131
142
  constraints?: PipelineConstraints;
132
143
  }
@@ -147,6 +158,36 @@ export interface SynthesizeStreamResult extends AsyncIterable<Uint8Array> {
147
158
  failoverCount: number;
148
159
  scoresRunId: string | null;
149
160
  }
161
+ export interface VoiceCatalogEntry {
162
+ /** Routing-key vendor (matches `allowedProviders.tts` entries). */
163
+ vendor: string;
164
+ /** Voice id passed through to the provider's TTS API. */
165
+ id: string;
166
+ /** Human-readable label. */
167
+ name: string;
168
+ }
169
+ export interface VoicesProviderEntry {
170
+ key: string;
171
+ name: string;
172
+ models: readonly string[];
173
+ /**
174
+ * `true` when the provider's voice library is account-scoped and must
175
+ * be fetched live from the provider (currently only ElevenLabs).
176
+ */
177
+ voicesFetchedLive: boolean;
178
+ }
179
+ export interface VoicesListResult {
180
+ voices: readonly VoiceCatalogEntry[];
181
+ providers: readonly VoicesProviderEntry[];
182
+ }
183
+ export interface VoicesListParams {
184
+ /**
185
+ * Filter to a single provider's voices. Accepts either the routing key
186
+ * (`cartesia`, `xai`, `alibaba`, `openai`, `inworld`, `elevenlabs`) or the
187
+ * catalog suffix form (`xai-tts`, `alibaba-tts`, `openai-tts`).
188
+ */
189
+ provider?: string;
190
+ }
150
191
  /**
151
192
  * One LLM-emitted tool invocation. `args` is a JSON-encoded string (LLMs may
152
193
  * stream partial JSON; the proxy guarantees a complete, parseable string).
@@ -177,14 +218,15 @@ export interface ChatMessage {
177
218
  * Speko's server-side execution: the proxy POSTs a Standard-Webhooks-
178
219
  * signed request to your URL, folds the result back into the next
179
220
  * provider turn, and only returns to you when the model emits final
180
- * text or hands back an inline tool call. `builtin` reserves a slot
181
- * for managed tools (e.g. `search_knowledge_base`) — handlers ship in
182
- * a follow-on release.
221
+ * text or hands back an inline tool call. `builtin` runs Speko-managed
222
+ * primitives (e.g. `search_knowledge_base`, `transfer_call`, `end_call`).
223
+ * `integration` runs an
224
+ * org-installed Speko app action such as Google Calendar or Slack.
183
225
  */
184
- export type ChatToolExecutionMode = 'inline' | 'webhook' | 'builtin';
226
+ export type ChatToolExecutionMode = 'inline' | 'webhook' | 'builtin' | 'integration';
185
227
  /**
186
228
  * Source-of-execution config. Required when `executionMode` is
187
- * `webhook` or `builtin`. Mirrors the SpekoTool `source` shape inside
229
+ * `webhook`, `builtin`, or `integration`. Mirrors the SpekoTool `source` shape inside
188
230
  * `@spekoai/tool-execution`.
189
231
  */
190
232
  export type ChatToolSource = {
@@ -196,10 +238,20 @@ export type ChatToolSource = {
196
238
  secretRef: string;
197
239
  headers?: Record<string, string>;
198
240
  timeoutMs?: number;
241
+ /** `async` returns `asyncAck` immediately while Speko dispatches the webhook in the background. */
242
+ responseMode?: 'sync' | 'async';
243
+ /** LLM-facing acknowledgement used when `responseMode` is `async`. */
244
+ asyncAck?: string;
199
245
  } | {
200
246
  kind: 'builtin';
201
247
  name: string;
202
248
  config?: unknown;
249
+ } | {
250
+ kind: 'integration';
251
+ installationId: string;
252
+ appKey: string;
253
+ actionKey: string;
254
+ config?: unknown;
203
255
  };
204
256
  /**
205
257
  * Tool definition exposed to the LLM. `parameters` is a JSON Schema (draft-7)
@@ -208,8 +260,8 @@ export type ChatToolSource = {
208
260
  *
209
261
  * `executionMode` and `source` are optional and back-compat: omitting
210
262
  * both preserves the v0.3 inline behavior. Set `executionMode: 'webhook'`
211
- * with a matching `source: { kind: 'webhook', ... }` to opt into
212
- * server-managed execution.
263
+ * with a matching `source: { kind: 'webhook', ... }` or
264
+ * `source: { kind: 'integration', ... }` to opt into server-managed execution.
213
265
  */
214
266
  export interface ChatTool {
215
267
  name: string;
@@ -229,6 +281,12 @@ export type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | '
229
281
  export interface CompleteParams {
230
282
  messages: ChatMessage[];
231
283
  intent: RoutingIntent;
284
+ /**
285
+ * Optional voice/session identifier forwarded as `x-session-id` for
286
+ * server-executed tools. The value is intentionally carried out-of-band
287
+ * so `/v1/complete` request bodies stay provider-shaped.
288
+ */
289
+ sessionId?: string;
232
290
  systemPrompt?: string;
233
291
  temperature?: number;
234
292
  maxTokens?: number;
@@ -284,7 +342,7 @@ export type CompleteStreamEvent = {
284
342
  error: string;
285
343
  code: string;
286
344
  };
287
- export type RealtimeProvider = 'openai' | 'google' | 'xai' | 'inworld';
345
+ export type RealtimeProvider = 'openai' | 'google' | 'xai' | 'inworld' | 'alibaba';
288
346
  export interface RealtimeToolSpec {
289
347
  name: string;
290
348
  description: string;
@@ -370,13 +428,17 @@ export interface VoiceDialParams {
370
428
  to: string;
371
429
  /** Caller ID. Falls back to the org default if omitted server-side. */
372
430
  from?: string;
431
+ /** Persisted assistant to run for this call. When supplied, `intent` can be omitted. */
432
+ agentId?: string;
373
433
  /** Routing intent — language is required, optimizeFor optional. */
374
- intent: RoutingIntent;
434
+ intent?: RoutingIntent;
375
435
  constraints?: PipelineConstraints;
376
436
  /** TTS voice id passed through to the picked TTS provider. */
377
437
  voice?: string;
378
438
  /** Agent system prompt. */
379
439
  systemPrompt?: string;
440
+ /** Optional first utterance. `null` is not accepted by phone dial; omit to use the agent default. */
441
+ firstMessage?: string;
380
442
  llm?: {
381
443
  temperature?: number;
382
444
  maxTokens?: number;
@@ -385,6 +447,17 @@ export interface VoiceDialParams {
385
447
  sampleRate?: number;
386
448
  speed?: number;
387
449
  };
450
+ sttOptions?: {
451
+ keywords?: string[];
452
+ };
453
+ /** Optional per-call SIP routing hints. Carrier AMD requires trunk/provider support. */
454
+ telephony?: {
455
+ region?: string;
456
+ amd?: {
457
+ mode?: 'agent' | 'carrier' | 'disabled';
458
+ timeoutSeconds?: number;
459
+ };
460
+ };
388
461
  /** Free-form metadata round-tripped to your webhooks. */
389
462
  metadata?: Record<string, unknown>;
390
463
  }
@@ -392,42 +465,89 @@ export interface VoiceDialResult {
392
465
  sessionId: string;
393
466
  callControlId: string;
394
467
  roomName: string;
395
- /** 'dialing' on a real call, 'dialing-stub' if Telnyx isn't configured. */
468
+ /** 'dialing' on a real call, 'dialing-stub' if managed telephony isn't configured. */
396
469
  status: 'dialing' | 'dialing-stub';
397
470
  to: string;
398
471
  from: string;
399
472
  }
400
473
  export type PhoneNumberDirection = 'inbound' | 'outbound' | 'both';
474
+ export type PhoneNumberSource = 'managed' | 'sip_trunk';
475
+ export type PhoneNumberSmsAssignmentStatus = 'FAILED_ASSIGNMENT' | 'PENDING_ASSIGNMENT' | 'ASSIGNED' | 'PENDING_UNASSIGNMENT' | 'FAILED_UNASSIGNMENT';
476
+ export interface PhoneNumberSetupStatus {
477
+ status: 'ready' | 'action_required' | 'suspended';
478
+ inboundReady: boolean;
479
+ outboundReady: boolean;
480
+ agentReady: boolean;
481
+ forwardingRequired: boolean;
482
+ sipConnectionReady: boolean;
483
+ issues: string[];
484
+ }
401
485
  export interface PhoneNumberRow {
402
486
  id: string;
403
487
  organizationId: string;
404
488
  e164: string;
489
+ source: PhoneNumberSource;
490
+ /** Platform-neutral resource id for a platform-managed number. */
491
+ providerResourceId: string | null;
492
+ /** @deprecated Use `providerResourceId`. */
405
493
  telnyxPhoneNumberId: string | null;
494
+ /** @deprecated LiveKit trunk IDs are internal and no longer exposed. */
495
+ sipTrunkId: string | null;
496
+ sipConnectionInstallationId: string | null;
497
+ sipProviderName: string | null;
406
498
  direction: PhoneNumberDirection;
407
499
  dispatchMetadataTemplate: Record<string, unknown> | null;
408
500
  label: string | null;
501
+ sms10dlcProfileId: string | null;
502
+ smsCampaignId: string | null;
503
+ smsAssignmentStatus: PhoneNumberSmsAssignmentStatus | null;
504
+ smsAssignmentUpdatedAt: string | null;
409
505
  /**
410
506
  * 1:1 link to a persisted agent. When set, inbound calls hydrate
411
507
  * pipeline config from the agent row instead of (or alongside) the
412
508
  * dispatch_metadata_template.
413
509
  */
414
510
  agentId: string | null;
511
+ setupStatus: PhoneNumberSetupStatus;
512
+ nextChargeAt: string;
513
+ lastChargedAt: string | null;
514
+ suspendedAt: string | null;
415
515
  createdAt: string;
416
516
  updatedAt: string;
417
517
  }
418
518
  export interface PhoneNumberCreateParams {
419
519
  e164: string;
420
520
  direction?: PhoneNumberDirection;
421
- /** LiveKit dispatch metadata template (variables `{{var}}` resolved at dial). */
521
+ /** Dispatch metadata template (variables `{{var}}` resolved at dial). */
422
522
  dispatchMetadataTemplate?: Record<string, unknown>;
423
523
  label?: string;
424
524
  /** 1:1 link to an agent in the same org. */
425
525
  agentId?: string;
426
526
  }
427
- export interface PhoneNumberUpdateParams {
527
+ export type PhoneNumberImportSipTrunkParams = {
528
+ e164: string;
529
+ /** Optional provider/account label for display. */
530
+ sipProviderName?: string;
428
531
  direction?: PhoneNumberDirection;
532
+ /** Dispatch metadata template (variables `{{var}}` resolved at dial). */
429
533
  dispatchMetadataTemplate?: Record<string, unknown>;
430
534
  label?: string;
535
+ /** 1:1 link to an agent in the same org. */
536
+ agentId?: string;
537
+ } & ({
538
+ /** Installed SIP connection integration id. Preferred for productized SIP connections. */
539
+ sipConnectionInstallationId: string;
540
+ /** Legacy LiveKit outbound trunk id. Ignored when `sipConnectionInstallationId` is present. */
541
+ sipTrunkId?: string;
542
+ } | {
543
+ /** Legacy LiveKit outbound trunk id. Use `sipConnectionInstallationId` for new integrations. */
544
+ sipTrunkId: string;
545
+ sipConnectionInstallationId?: string;
546
+ });
547
+ export interface PhoneNumberUpdateParams {
548
+ direction?: PhoneNumberDirection;
549
+ dispatchMetadataTemplate?: Record<string, unknown> | null;
550
+ label?: string | null;
431
551
  /** Pass `null` to unlink, a string to relink. */
432
552
  agentId?: string | null;
433
553
  }
@@ -448,9 +568,75 @@ export interface PhoneNumberSearchParams {
448
568
  areaCode?: string;
449
569
  /** Optional locality filter, e.g. "San Francisco". */
450
570
  locality?: string;
451
- /** Max results — Telnyx caps at 50. Default 10. */
571
+ /** Max results. Default 10. */
452
572
  limit?: number;
453
573
  }
574
+ export type PhoneNumberKybStatus = 'missing' | 'draft' | 'submitted' | 'approved' | 'rejected' | 'revoked';
575
+ export type PhoneNumberKybSubmissionStatus = Exclude<PhoneNumberKybStatus, 'missing'>;
576
+ export type PhoneNumberKybSlackNotificationStatus = 'not_queued' | 'queued' | 'enqueue_failed';
577
+ export interface PhoneNumberKybBusinessProfile {
578
+ legalName: string;
579
+ displayName: string;
580
+ entityType: string;
581
+ country: string;
582
+ registrationId?: string;
583
+ website: string;
584
+ address: {
585
+ street: string;
586
+ city: string;
587
+ state: string;
588
+ postalCode: string;
589
+ country: string;
590
+ };
591
+ useCase: string;
592
+ expectedUsage: string;
593
+ }
594
+ export interface PhoneNumberKybAuthorizedRepresentative {
595
+ name: string;
596
+ title: string;
597
+ email: string;
598
+ phone?: string;
599
+ }
600
+ export interface PhoneNumberKybDraftParams {
601
+ businessProfile: PhoneNumberKybBusinessProfile;
602
+ authorizedRepresentative: PhoneNumberKybAuthorizedRepresentative;
603
+ attestationAccepted?: boolean;
604
+ }
605
+ export interface PhoneNumberKybSubmitParams {
606
+ businessProfile: PhoneNumberKybBusinessProfile;
607
+ authorizedRepresentative: PhoneNumberKybAuthorizedRepresentative;
608
+ attestationAccepted: true;
609
+ }
610
+ export interface PhoneNumberKybSubmission {
611
+ id: string;
612
+ organizationId: string;
613
+ status: PhoneNumberKybSubmissionStatus;
614
+ businessProfile: PhoneNumberKybBusinessProfile | null;
615
+ authorizedRepresentative: PhoneNumberKybAuthorizedRepresentative | null;
616
+ attestationAccepted: boolean;
617
+ attestedAt: string | null;
618
+ submittedByUserId: string | null;
619
+ submittedByEmail: string | null;
620
+ submittedByApiKeyId: string | null;
621
+ submittedAt: string | null;
622
+ reviewerUserId: string | null;
623
+ reviewerEmail: string | null;
624
+ reviewedAt: string | null;
625
+ rejectionReason: string | null;
626
+ slackNotificationStatus: PhoneNumberKybSlackNotificationStatus;
627
+ slackNotificationJobId: string | null;
628
+ slackNotificationError: string | null;
629
+ createdAt: string;
630
+ updatedAt: string;
631
+ }
632
+ export interface PhoneNumberKybOverview {
633
+ status: PhoneNumberKybStatus;
634
+ submission: PhoneNumberKybSubmission | null;
635
+ prefill: {
636
+ businessProfile: PhoneNumberKybBusinessProfile;
637
+ authorizedRepresentative: PhoneNumberKybAuthorizedRepresentative;
638
+ } | null;
639
+ }
454
640
  /**
455
641
  * Routing intent for an agent's voice pipeline. Narrower than the
456
642
  * top-level {@link RoutingIntent} — the agents API specifically
@@ -478,6 +664,71 @@ export interface AgentSttOptions {
478
664
  /** Vocabulary keywords forwarded to whichever STT provider the router picks. */
479
665
  keywords?: string[];
480
666
  }
667
+ /**
668
+ * Built-in ambience clip ids supported by the hosted worker. Custom clip
669
+ * uploads are intentionally not yet supported — pinning to the built-ins
670
+ * keeps the v1 API simple and lets the worker map straight to the
671
+ * `BuiltinAudioClip` enum.
672
+ */
673
+ export type AgentAmbientClip = 'office-ambience' | 'keyboard-typing' | 'keyboard-typing2';
674
+ /**
675
+ * Per-agent background audio. Today only ambient (continuous loop) is
676
+ * supported. The ambience plays on a separate media track mixed
677
+ * server-side, so it reaches both browser (WebRTC) and phone (SIP) callers
678
+ * without any client-side change.
679
+ */
680
+ export interface AgentBackgroundAudio {
681
+ ambient?: {
682
+ clip: AgentAmbientClip;
683
+ /** Linear gain in [0, 1]. Defaults to 1.0 (clip's natural level). */
684
+ volume?: number;
685
+ };
686
+ }
687
+ export interface AgentSpeechNormalization {
688
+ pronunciationDictionary?: Record<string, string>;
689
+ textReplacements?: Record<string, string>;
690
+ }
691
+ export interface AgentLifecycleWebhookCreate {
692
+ url: string;
693
+ /** Deprecated. Lifecycle webhooks use the org-level signing secret from API keys. */
694
+ secret?: string;
695
+ headers?: Record<string, string>;
696
+ timeoutMs?: number;
697
+ responseMode?: 'sync' | 'async';
698
+ asyncAck?: string;
699
+ }
700
+ export interface AgentLifecycleWebhookUpdate {
701
+ url: string;
702
+ /** Deprecated. Lifecycle webhooks use the org-level signing secret from API keys. */
703
+ secret?: string;
704
+ headers?: Record<string, string>;
705
+ timeoutMs?: number;
706
+ responseMode?: 'sync' | 'async';
707
+ asyncAck?: string;
708
+ }
709
+ export interface AgentLifecycleWebhookSerialized {
710
+ url: string;
711
+ secretRef: string;
712
+ headers?: Record<string, string>;
713
+ timeoutMs?: number;
714
+ responseMode?: 'sync' | 'async';
715
+ asyncAck?: string;
716
+ }
717
+ export interface AgentWebhooksSerialized {
718
+ preCall?: AgentLifecycleWebhookSerialized;
719
+ postCall?: AgentLifecycleWebhookSerialized;
720
+ status?: AgentLifecycleWebhookSerialized;
721
+ }
722
+ export interface AgentWebhooksCreate {
723
+ preCall?: AgentLifecycleWebhookCreate;
724
+ postCall?: AgentLifecycleWebhookCreate;
725
+ status?: AgentLifecycleWebhookCreate;
726
+ }
727
+ export interface AgentWebhooksUpdate {
728
+ preCall?: AgentLifecycleWebhookUpdate | null;
729
+ postCall?: AgentLifecycleWebhookUpdate | null;
730
+ status?: AgentLifecycleWebhookUpdate | null;
731
+ }
481
732
  export interface AgentRow {
482
733
  id: string;
483
734
  organizationId: string;
@@ -488,6 +739,9 @@ export interface AgentRow {
488
739
  llmOptions: AgentLlmOptions | null;
489
740
  stackPreferences: AgentStackPreferences | null;
490
741
  sttOptions: AgentSttOptions | null;
742
+ backgroundAudio: AgentBackgroundAudio | null;
743
+ speechNormalization: AgentSpeechNormalization | null;
744
+ webhooks: AgentWebhooksSerialized | null;
491
745
  createdAt: string;
492
746
  updatedAt: string;
493
747
  }
@@ -499,8 +753,252 @@ export interface AgentCreateParams {
499
753
  llmOptions?: AgentLlmOptions;
500
754
  stackPreferences?: AgentStackPreferences;
501
755
  sttOptions?: AgentSttOptions;
756
+ backgroundAudio?: AgentBackgroundAudio;
757
+ speechNormalization?: AgentSpeechNormalization;
758
+ webhooks?: AgentWebhooksCreate;
759
+ }
760
+ export type AgentUpdateParams = Partial<Omit<AgentCreateParams, 'webhooks'>> & {
761
+ webhooks?: AgentWebhooksUpdate | null;
762
+ };
763
+ export interface CallTranscriptEntry {
764
+ id: string;
765
+ index: number;
766
+ source: 'user' | 'agent' | 'system';
767
+ text: string;
768
+ started_at: string;
769
+ ended_at: string | null;
770
+ provider: string | null;
771
+ model: string | null;
772
+ metadata: Record<string, unknown>;
773
+ }
774
+ export interface CallCostLine {
775
+ provider: string;
776
+ metric: string;
777
+ quantity: number;
778
+ keySource: KeySource;
779
+ costMicroUsd: string;
780
+ }
781
+ export interface CallReport {
782
+ session_id: string;
783
+ organization_id: string;
784
+ summary: string;
785
+ outcome: string;
786
+ structured_data: Record<string, unknown>;
787
+ transcript: {
788
+ entries: CallTranscriptEntry[];
789
+ };
790
+ cost_micro_usd: string;
791
+ cost_breakdown: CallCostLine[];
792
+ artifacts: Record<string, unknown>;
793
+ metadata: Record<string, unknown>;
794
+ scheduled_callback: ScheduledCallback | Record<string, unknown> | null;
795
+ analysis_status: 'heuristic' | 'completed' | 'failed';
796
+ analysis_provider: string | null;
797
+ analysis_model: string | null;
798
+ analysis_error: string | null;
799
+ analysis_completed_at: string | null;
800
+ post_call_webhook_status: 'not_configured' | 'pending' | 'delivered' | 'failed';
801
+ post_call_webhook_attempts: number;
802
+ post_call_webhook_next_retry_at: string | null;
803
+ post_call_webhook_delivered_at: string | null;
804
+ post_call_webhook_error: string | null;
805
+ created_at: string;
806
+ updated_at: string;
807
+ }
808
+ export type ScheduledCallbackStatus = 'scheduled' | 'dispatching' | 'dispatched' | 'cancelled' | 'failed';
809
+ export interface ScheduledCallback {
810
+ id: string;
811
+ organization_id: string;
812
+ source_session_id: string | null;
813
+ created_session_id: string | null;
814
+ agent_id: string | null;
815
+ phone_number_id: string | null;
816
+ to_number: string;
817
+ from_number: string | null;
818
+ scheduled_at: string;
819
+ status: ScheduledCallbackStatus;
820
+ reason: string | null;
821
+ instructions: string | null;
822
+ summary: string | null;
823
+ pipeline_config: Record<string, unknown>;
824
+ metadata: Record<string, unknown>;
825
+ failure_cause: string | null;
826
+ attempted_at: string | null;
827
+ dispatched_at: string | null;
828
+ cancelled_at: string | null;
829
+ created_at: string;
830
+ updated_at: string;
831
+ }
832
+ export interface ScheduledCallbacksListParams {
833
+ status?: ScheduledCallbackStatus;
834
+ sourceSessionId?: string;
835
+ limit?: number;
836
+ }
837
+ export interface CancelScheduledCallbackParams {
838
+ reason?: string;
839
+ }
840
+ export interface FinalizeCallReportParams {
841
+ forceAnalysis?: boolean;
842
+ retryWebhook?: boolean;
843
+ }
844
+ export interface FinalizeCallReportResult {
845
+ session_id: string;
846
+ summary: string;
847
+ outcome: string;
848
+ cost_micro_usd: string;
849
+ webhook: unknown;
850
+ }
851
+ export interface CallRecording {
852
+ url: string;
853
+ }
854
+ export interface CallEvent {
855
+ id: string;
856
+ session_id: string | null;
857
+ organization_id: string;
858
+ provider: 'livekit' | 'telnyx' | 'speko' | string;
859
+ event_type: string;
860
+ status: string | null;
861
+ failure_cause: string | null;
862
+ sip_status_code: number | null;
863
+ sip_status: string | null;
864
+ occurred_at: string;
865
+ payload: Record<string, unknown>;
866
+ created_at: string;
867
+ }
868
+ export interface CallTransfer {
869
+ id: string;
870
+ session_id: string;
871
+ organization_id: string;
872
+ kind: 'blind' | 'warm';
873
+ status: 'requested' | 'screening' | 'bridging' | 'completed' | 'failed' | 'cancelled';
874
+ transfer_to: string;
875
+ from_room_name: string | null;
876
+ consultation_room_name: string | null;
877
+ caller_participant_identity: string | null;
878
+ recipient_participant_identity: string | null;
879
+ outbound_trunk_id: string | null;
880
+ screening_prompt: string | null;
881
+ summary: string | null;
882
+ failure_cause: string | null;
883
+ metadata: Record<string, unknown>;
884
+ created_at: string;
885
+ updated_at: string;
886
+ completed_at: string | null;
887
+ }
888
+ export interface CallTransferResponse extends CallTransfer {
889
+ routing_attempts?: (CallTransfer | null)[];
890
+ next_transfer?: CallTransfer | null;
891
+ fallback?: WarmTransferFallbackResult | null;
892
+ }
893
+ export interface CallDetail {
894
+ id: string;
895
+ call_id: string;
896
+ resource_uri: string;
897
+ agent_id: string | null;
898
+ status: string;
899
+ kind: string;
900
+ room_name: string | null;
901
+ language: string;
902
+ pipeline_config: Record<string, unknown>;
903
+ metadata: Record<string, unknown>;
904
+ created_at: string;
905
+ updated_at: string;
906
+ ended_at: string | null;
907
+ duration_seconds: number | null;
908
+ recording_status: string | null;
909
+ recording_duration_ms: number | null;
910
+ recording_resource_uri: string;
911
+ report: CallReport | null;
912
+ transfers: CallTransfer[];
913
+ transcript: {
914
+ entries: CallTranscriptEntry[];
915
+ };
916
+ span_tree: Record<string, unknown>;
917
+ }
918
+ export interface BlindTransferParams {
919
+ to: string;
920
+ participantIdentity?: string;
921
+ playDialtone?: boolean;
922
+ ringingTimeout?: number;
923
+ headers?: Record<string, string>;
924
+ }
925
+ export interface WarmTransferDestination {
926
+ to: string;
927
+ label?: string;
928
+ outboundTrunkId?: string;
929
+ screeningPrompt?: string;
930
+ summary?: string;
931
+ metadata?: Record<string, unknown>;
932
+ }
933
+ export interface WarmTransferFallback {
934
+ strategy?: 'return_to_assistant' | 'take_message' | 'end_call';
935
+ message?: string;
936
+ takeMessagePrompt?: string;
937
+ holdAudioUrl?: string;
938
+ }
939
+ export interface WarmTransferVoicemailDetection {
940
+ mode?: 'agent' | 'amd' | 'disabled';
941
+ enabled?: boolean;
942
+ timeoutSeconds?: number;
943
+ }
944
+ export interface WarmTransferFallbackResult {
945
+ action: 'return_to_assistant' | 'take_message' | 'end_call';
946
+ message: string;
947
+ take_message_prompt: string | null;
948
+ hold_audio_url: string | null;
949
+ voicemail_detected: boolean;
950
+ }
951
+ export interface WarmTransferParams {
952
+ to?: string;
953
+ destinations?: WarmTransferDestination[];
954
+ from?: string;
955
+ participantIdentity?: string;
956
+ outboundTrunkId?: string;
957
+ screeningPrompt?: string;
958
+ summary?: string;
959
+ ringingTimeout?: number;
960
+ waitUntilAnswered?: boolean;
961
+ fallback?: WarmTransferFallback;
962
+ voicemailDetection?: WarmTransferVoicemailDetection;
963
+ metadata?: Record<string, unknown>;
964
+ }
965
+ export interface CompleteWarmTransferParams {
966
+ recipientParticipantIdentity?: string;
967
+ summary?: string;
968
+ }
969
+ export interface CancelWarmTransferParams {
970
+ reason?: string;
971
+ summary?: string;
972
+ tryNext?: boolean;
973
+ voicemailDetected?: boolean;
974
+ }
975
+ export interface AgentCallListParams {
976
+ /** Max rows. Default 50, server-capped at 100. */
977
+ limit?: number;
978
+ /** ISO timestamp returned as `next_cursor` from the previous page. */
979
+ cursor?: string;
980
+ /** ISO timestamp lower bound for calls to include. */
981
+ since?: string;
982
+ }
983
+ export interface AgentCallListEntry {
984
+ id: string;
985
+ call_id: string;
986
+ resource_uri: string;
987
+ agent_id: string;
988
+ status: string;
989
+ kind: string;
990
+ room_name: string | null;
991
+ language: string;
992
+ created_at: string;
993
+ ended_at: string | null;
994
+ duration_seconds: number | null;
995
+ recording_status: string | null;
996
+ }
997
+ export interface AgentCallListPage {
998
+ calls: AgentCallListEntry[];
999
+ entries: AgentCallListEntry[];
1000
+ next_cursor: string | null;
502
1001
  }
503
- export type AgentUpdateParams = Partial<AgentCreateParams>;
504
1002
  export interface AgentToolSourceInline {
505
1003
  kind: 'inline';
506
1004
  }
@@ -534,8 +1032,35 @@ export interface AgentToolSourceBuiltin {
534
1032
  name: string;
535
1033
  config?: unknown;
536
1034
  }
537
- export type AgentToolSourceCreate = AgentToolSourceInline | AgentToolSourceWebhookCreate | AgentToolSourceBuiltin;
538
- export type AgentToolSourceSerialized = AgentToolSourceInline | AgentToolSourceWebhookSerialized | AgentToolSourceBuiltin;
1035
+ /**
1036
+ * Integration source binds the tool to an org-installed Speko app action
1037
+ * (e.g. Google Calendar `create_event`). Speko resolves the installation and
1038
+ * runs the action server-side at completion time. The shape is identical on
1039
+ * create and in the serialized row (there is no secret to strip).
1040
+ */
1041
+ export interface AgentToolSourceIntegration {
1042
+ kind: 'integration';
1043
+ installationId: string;
1044
+ appKey: string;
1045
+ actionKey: string;
1046
+ config?: unknown;
1047
+ }
1048
+ /**
1049
+ * Webhook source as sent to {@link AgentTools.update}. Unlike the create
1050
+ * shape, `secret` is optional: omit it to keep the existing encrypted secret
1051
+ * untouched, or supply a new one to rotate it.
1052
+ */
1053
+ export interface AgentToolSourceWebhookUpdate {
1054
+ kind: 'webhook';
1055
+ url: string;
1056
+ /** Plaintext shared secret. Omit to keep the existing stored secret; supply to rotate. */
1057
+ secret?: string;
1058
+ headers?: Record<string, string>;
1059
+ timeoutMs?: number;
1060
+ }
1061
+ export type AgentToolSourceCreate = AgentToolSourceInline | AgentToolSourceWebhookCreate | AgentToolSourceBuiltin | AgentToolSourceIntegration;
1062
+ export type AgentToolSourceSerialized = AgentToolSourceInline | AgentToolSourceWebhookSerialized | AgentToolSourceBuiltin | AgentToolSourceIntegration;
1063
+ export type AgentToolSourceUpdate = AgentToolSourceInline | AgentToolSourceWebhookUpdate | AgentToolSourceBuiltin | AgentToolSourceIntegration;
539
1064
  export interface AgentToolRow {
540
1065
  id: string;
541
1066
  agentId: string;
@@ -555,7 +1080,7 @@ export interface AgentToolCreateParams {
555
1080
  export interface AgentToolUpdateParams {
556
1081
  description?: string;
557
1082
  parameters?: Record<string, unknown>;
558
- source?: AgentToolSourceCreate;
1083
+ source?: AgentToolSourceUpdate;
559
1084
  }
560
1085
  export interface KnowledgeBaseRow {
561
1086
  id: string;