@spekoai/sdk 0.4.3 → 0.5.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.
- package/CHANGELOG.md +6 -0
- package/README.md +88 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/lib/client.d.ts +13 -1
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/client.js +22 -2
- package/dist/lib/http.d.ts +12 -4
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js +31 -14
- package/dist/lib/resources/agents.d.ts +12 -2
- package/dist/lib/resources/agents.d.ts.map +1 -1
- package/dist/lib/resources/agents.js +12 -4
- package/dist/lib/resources/calls.d.ts +19 -1
- package/dist/lib/resources/calls.d.ts.map +1 -1
- package/dist/lib/resources/calls.js +22 -0
- package/dist/lib/resources/knowledge-bases.d.ts +1 -1
- package/dist/lib/resources/knowledge-bases.js +1 -1
- package/dist/lib/resources/phone-numbers.d.ts +2 -1
- package/dist/lib/resources/phone-numbers.d.ts.map +1 -1
- package/dist/lib/resources/phone-numbers.js +2 -1
- package/dist/lib/resources/realtime.d.ts +3 -5
- package/dist/lib/resources/realtime.d.ts.map +1 -1
- package/dist/lib/resources/realtime.js +829 -91
- package/dist/lib/resources/sessions.d.ts +53 -0
- package/dist/lib/resources/sessions.d.ts.map +1 -0
- package/dist/lib/resources/sessions.js +166 -0
- package/dist/lib/resources/sms.d.ts +80 -0
- package/dist/lib/resources/sms.d.ts.map +1 -0
- package/dist/lib/resources/sms.js +152 -0
- package/dist/lib/resources/synthesize.d.ts.map +1 -1
- package/dist/lib/resources/synthesize.js +12 -6
- package/dist/lib/resources/transcribe.d.ts.map +1 -1
- package/dist/lib/resources/transcribe.js +9 -2
- package/dist/lib/resources/voice.d.ts +283 -1
- package/dist/lib/resources/voice.d.ts.map +1 -1
- package/dist/lib/resources/voice.js +345 -0
- package/dist/lib/resources/webhooks.d.ts +25 -0
- package/dist/lib/resources/webhooks.d.ts.map +1 -0
- package/dist/lib/resources/webhooks.js +46 -0
- package/dist/lib/types/index.d.ts +998 -9
- package/dist/lib/types/index.d.ts.map +1 -1
- package/dist/lib/voice-contract.d.ts +280 -0
- package/dist/lib/voice-contract.d.ts.map +1 -0
- package/dist/lib/voice-contract.js +115 -0
- package/package.json +2 -1
- package/src/index.ts +212 -0
- package/src/lib/client.ts +169 -0
- package/src/lib/errors.ts +28 -0
- package/src/lib/http.ts +442 -0
- package/src/lib/resources/agents.ts +211 -0
- package/src/lib/resources/callbacks.ts +40 -0
- package/src/lib/resources/calls.ts +113 -0
- package/src/lib/resources/complete.ts +63 -0
- package/src/lib/resources/credits.ts +41 -0
- package/src/lib/resources/knowledge-bases.ts +199 -0
- package/src/lib/resources/phone-numbers.ts +109 -0
- package/src/lib/resources/realtime-globals.d.ts +31 -0
- package/src/lib/resources/realtime.spec.ts +565 -0
- package/src/lib/resources/realtime.ts +1169 -0
- package/src/lib/resources/sessions.ts +191 -0
- package/src/lib/resources/sms.ts +214 -0
- package/src/lib/resources/synthesize.ts +101 -0
- package/src/lib/resources/transcribe.ts +91 -0
- package/src/lib/resources/usage.ts +24 -0
- package/src/lib/resources/voice.ts +426 -0
- package/src/lib/resources/voices.ts +32 -0
- package/src/lib/resources/webhooks.ts +67 -0
- package/src/lib/types/index.ts +2409 -0
- package/src/lib/voice-contract.ts +358 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { HttpClient } from '../http.js';
|
|
2
|
+
import type { EndCallResult, SessionStreamEvent, SessionStreamOptions, SessionTranscript } from '../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Session-scoped reads. A `sessionId` is the id returned by
|
|
5
|
+
* `voice.dial(...)` / session create — the same id `calls.*` accepts.
|
|
6
|
+
*/
|
|
7
|
+
export declare class Sessions {
|
|
8
|
+
private readonly http;
|
|
9
|
+
constructor(http: HttpClient);
|
|
10
|
+
/**
|
|
11
|
+
* End a live session now (kill switch): tears the room down, which drops
|
|
12
|
+
* every participant; the normal close + metering flow runs server-side.
|
|
13
|
+
* Works for any session kind — browser/WebRTC sessions included. Alias of
|
|
14
|
+
* `calls.end()`, which accepts the same session id. Resolves with
|
|
15
|
+
* `status: 'ending'` once teardown is requested, or
|
|
16
|
+
* `status: 'already_ended'` if the session was over. Use this from your
|
|
17
|
+
* backend to stop billing for a session your client can no longer reach
|
|
18
|
+
* (for example an abandoned browser tab).
|
|
19
|
+
*/
|
|
20
|
+
end(sessionId: string): Promise<EndCallResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Transcript of a session, oldest turn first — the point-in-time snapshot.
|
|
23
|
+
* For live consumption prefer `stream()`, which pushes each turn as it
|
|
24
|
+
* lands; this endpoint stays the final word on per-turn latency numbers
|
|
25
|
+
* (legs keep enriching after a turn is first written).
|
|
26
|
+
*/
|
|
27
|
+
transcript(sessionId: string): Promise<SessionTranscript>;
|
|
28
|
+
/**
|
|
29
|
+
* Observe a session live: transcript turns, call events, and status changes
|
|
30
|
+
* pushed as they happen (SSE under the hood). Iterate until `end` — the
|
|
31
|
+
* SDK reconnects through server stream rotations and transient drops with
|
|
32
|
+
* an internal cursor, so consumers never poll and never see duplicates.
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* for await (const ev of speko.sessions.stream(sessionId)) {
|
|
36
|
+
* if (ev.type === 'transcript') render(ev.turn);
|
|
37
|
+
* if (ev.type === 'event') timeline(ev.event.event_type);
|
|
38
|
+
* if (ev.type === 'end') break; // session over
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* A stream opened on an already-ended session replays the backlog and then
|
|
43
|
+
* ends, so late subscribers converge on the same picture.
|
|
44
|
+
*
|
|
45
|
+
* The no-duplicates guarantee holds per iterator: reconnects re-read a
|
|
46
|
+
* short server-side overlap window, and this iterator filters the replays
|
|
47
|
+
* by event id. A brand-new iterator resumed via `options.cursor` (process
|
|
48
|
+
* restart) starts with no memory and may replay up to ~2 s of events —
|
|
49
|
+
* dedupe by `event.id` if that matters to you.
|
|
50
|
+
*/
|
|
51
|
+
stream(sessionId: string, options?: SessionStreamOptions): AsyncIterableIterator<SessionStreamEvent>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/sessions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAEV,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EAElB,MAAM,mBAAmB,CAAC;AAW3B;;;GAGG;AACH,qBAAa,QAAQ;IACP,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;;;;;;OASG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAI9C;;;;;OAKG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAMzD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACI,MAAM,CACX,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,oBAAyB,GACjC,qBAAqB,CAAC,kBAAkB,CAAC;CA+G7C"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { SpekoApiError } from '../errors.js';
|
|
2
|
+
/** Consecutive failed connect attempts (no frame received) before giving up. */
|
|
3
|
+
const MAX_RECONNECT_ATTEMPTS = 10;
|
|
4
|
+
/**
|
|
5
|
+
* Per-connection cap, above the server's own stream rotation (10 min +
|
|
6
|
+
* `end {reason:'timeout'}`) so the server always rotates first and this
|
|
7
|
+
* client-side abort only nets a server that went quiet.
|
|
8
|
+
*/
|
|
9
|
+
const STREAM_REQUEST_TIMEOUT_MS = 15 * 60_000;
|
|
10
|
+
/**
|
|
11
|
+
* Session-scoped reads. A `sessionId` is the id returned by
|
|
12
|
+
* `voice.dial(...)` / session create — the same id `calls.*` accepts.
|
|
13
|
+
*/
|
|
14
|
+
export class Sessions {
|
|
15
|
+
http;
|
|
16
|
+
constructor(http) {
|
|
17
|
+
this.http = http;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* End a live session now (kill switch): tears the room down, which drops
|
|
21
|
+
* every participant; the normal close + metering flow runs server-side.
|
|
22
|
+
* Works for any session kind — browser/WebRTC sessions included. Alias of
|
|
23
|
+
* `calls.end()`, which accepts the same session id. Resolves with
|
|
24
|
+
* `status: 'ending'` once teardown is requested, or
|
|
25
|
+
* `status: 'already_ended'` if the session was over. Use this from your
|
|
26
|
+
* backend to stop billing for a session your client can no longer reach
|
|
27
|
+
* (for example an abandoned browser tab).
|
|
28
|
+
*/
|
|
29
|
+
end(sessionId) {
|
|
30
|
+
return this.http.post(`/v1/calls/${encodeURIComponent(sessionId)}/end`, {});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Transcript of a session, oldest turn first — the point-in-time snapshot.
|
|
34
|
+
* For live consumption prefer `stream()`, which pushes each turn as it
|
|
35
|
+
* lands; this endpoint stays the final word on per-turn latency numbers
|
|
36
|
+
* (legs keep enriching after a turn is first written).
|
|
37
|
+
*/
|
|
38
|
+
transcript(sessionId) {
|
|
39
|
+
return this.http.get(`/v1/sessions/${encodeURIComponent(sessionId)}/transcript`);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Observe a session live: transcript turns, call events, and status changes
|
|
43
|
+
* pushed as they happen (SSE under the hood). Iterate until `end` — the
|
|
44
|
+
* SDK reconnects through server stream rotations and transient drops with
|
|
45
|
+
* an internal cursor, so consumers never poll and never see duplicates.
|
|
46
|
+
*
|
|
47
|
+
* ```ts
|
|
48
|
+
* for await (const ev of speko.sessions.stream(sessionId)) {
|
|
49
|
+
* if (ev.type === 'transcript') render(ev.turn);
|
|
50
|
+
* if (ev.type === 'event') timeline(ev.event.event_type);
|
|
51
|
+
* if (ev.type === 'end') break; // session over
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* A stream opened on an already-ended session replays the backlog and then
|
|
56
|
+
* ends, so late subscribers converge on the same picture.
|
|
57
|
+
*
|
|
58
|
+
* The no-duplicates guarantee holds per iterator: reconnects re-read a
|
|
59
|
+
* short server-side overlap window, and this iterator filters the replays
|
|
60
|
+
* by event id. A brand-new iterator resumed via `options.cursor` (process
|
|
61
|
+
* restart) starts with no memory and may replay up to ~2 s of events —
|
|
62
|
+
* dedupe by `event.id` if that matters to you.
|
|
63
|
+
*/
|
|
64
|
+
async *stream(sessionId, options = {}) {
|
|
65
|
+
// Cursor is derived from payloads (max turn index / max event created_at),
|
|
66
|
+
// so resume needs no SSE `id:` plumbing in the shared HTTP client.
|
|
67
|
+
let turnIndex = -1;
|
|
68
|
+
let eventMs = 0;
|
|
69
|
+
if (options.cursor) {
|
|
70
|
+
const m = /^(-?\d+):(\d+)$/.exec(options.cursor.trim());
|
|
71
|
+
if (m?.[1] !== undefined && m[2] !== undefined) {
|
|
72
|
+
turnIndex = Number(m[1]);
|
|
73
|
+
eventMs = Number(m[2]);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Every reconnect re-reads the server's overlap window (its own dedupe
|
|
77
|
+
// state dies with the response), so the iterator remembers delivered
|
|
78
|
+
// event ids to keep replays away from the consumer. Retention is by the
|
|
79
|
+
// EVENT's timestamp falling behind the cursor window — the same invariant
|
|
80
|
+
// the server uses — never by count: a capacity ring can evict ids that a
|
|
81
|
+
// reconnect is still allowed to replay (a >capacity burst inside the
|
|
82
|
+
// overlap window), reintroducing duplicates. All timestamps are
|
|
83
|
+
// DB-stamped, so no client clock is involved; the horizon just needs to
|
|
84
|
+
// comfortably exceed the server's 2 s overlap re-read. Turns need no
|
|
85
|
+
// dedupe — their cursor (`index`) is exact and resumed with strict `>`.
|
|
86
|
+
const SEEN_EVENT_WINDOW_MS = 10_000;
|
|
87
|
+
const seenEvents = new Map();
|
|
88
|
+
const rememberEvent = (id, createdMs) => {
|
|
89
|
+
seenEvents.set(id, Number.isFinite(createdMs) ? createdMs : eventMs);
|
|
90
|
+
for (const [seenId, seenMs] of seenEvents) {
|
|
91
|
+
if (seenMs < eventMs - SEEN_EVENT_WINDOW_MS)
|
|
92
|
+
seenEvents.delete(seenId);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
let failedAttempts = 0;
|
|
96
|
+
while (true) {
|
|
97
|
+
if (options.signal?.aborted)
|
|
98
|
+
return;
|
|
99
|
+
let receivedFrame = false;
|
|
100
|
+
try {
|
|
101
|
+
const path = `/v1/sessions/${encodeURIComponent(sessionId)}/stream` +
|
|
102
|
+
`?cursor=${turnIndex}:${eventMs}`;
|
|
103
|
+
const frames = this.http.requestSse('GET', path, undefined, options.signal, { Accept: 'text/event-stream' }, STREAM_REQUEST_TIMEOUT_MS);
|
|
104
|
+
for await (const frame of frames) {
|
|
105
|
+
receivedFrame = true;
|
|
106
|
+
failedAttempts = 0;
|
|
107
|
+
switch (frame.event) {
|
|
108
|
+
case 'status': {
|
|
109
|
+
const data = frame.data;
|
|
110
|
+
yield { type: 'status', status: data.status, endedAt: data.endedAt ?? null };
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
case 'transcript': {
|
|
114
|
+
const turn = frame.data;
|
|
115
|
+
turnIndex = Math.max(turnIndex, turn.index);
|
|
116
|
+
yield { type: 'transcript', turn };
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
case 'event': {
|
|
120
|
+
const event = frame.data;
|
|
121
|
+
const createdMs = Date.parse(event.created_at);
|
|
122
|
+
if (Number.isFinite(createdMs))
|
|
123
|
+
eventMs = Math.max(eventMs, createdMs);
|
|
124
|
+
if (seenEvents.has(event.id))
|
|
125
|
+
break;
|
|
126
|
+
rememberEvent(event.id, createdMs);
|
|
127
|
+
yield { type: 'event', event };
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
case 'end': {
|
|
131
|
+
const data = frame.data;
|
|
132
|
+
if (data.reason === 'session_ended') {
|
|
133
|
+
yield { type: 'end', reason: 'session_ended' };
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
// 'timeout' is the server rotating a long response — reconnect.
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
default:
|
|
140
|
+
// 'error' or unknown frame: the server closes after these;
|
|
141
|
+
// fall through to the reconnect path below.
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
if (options.signal?.aborted)
|
|
148
|
+
return;
|
|
149
|
+
// Auth failures and unknown sessions are not transient — surface them.
|
|
150
|
+
if (err instanceof SpekoApiError && err.status >= 400 && err.status < 500) {
|
|
151
|
+
throw err;
|
|
152
|
+
}
|
|
153
|
+
// Anything else (network drop, mid-stream abort) → reconnect below.
|
|
154
|
+
}
|
|
155
|
+
if (options.signal?.aborted)
|
|
156
|
+
return;
|
|
157
|
+
if (!receivedFrame) {
|
|
158
|
+
failedAttempts += 1;
|
|
159
|
+
if (failedAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
|
160
|
+
throw new SpekoApiError(`session stream: ${MAX_RECONNECT_ATTEMPTS} consecutive reconnect attempts failed`, 0, 'STREAM_DISCONNECTED');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(500 * Math.max(failedAttempts, 1), 5000)));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { HttpClient } from '../http.js';
|
|
2
|
+
import type { SmsBatch, SmsBatchCreateParams, SmsConsent, SmsConsentInput, SmsConsentListParams, SmsConversation, SmsConversationListParams, SmsConversationNote, SmsConversationSendParams, SmsConversationUpdate, SmsMessage, SmsMessageListParams, SmsPage, SmsSendParams, SmsSettings, SmsSettingsUpdate, SmsStreamEvent, SmsSuppression } from '../types/index.js';
|
|
3
|
+
export declare class Sms {
|
|
4
|
+
private readonly http;
|
|
5
|
+
readonly messages: SmsMessages;
|
|
6
|
+
readonly batches: SmsBatches;
|
|
7
|
+
readonly conversations: SmsConversations;
|
|
8
|
+
readonly consents: SmsConsents;
|
|
9
|
+
readonly suppressions: SmsSuppressions;
|
|
10
|
+
readonly settings: SmsSettingsResource;
|
|
11
|
+
constructor(http: HttpClient);
|
|
12
|
+
stream(options?: {
|
|
13
|
+
lastEventId?: string;
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
}): AsyncIterableIterator<SmsStreamEvent>;
|
|
16
|
+
}
|
|
17
|
+
export declare class SmsMessages {
|
|
18
|
+
private readonly http;
|
|
19
|
+
constructor(http: HttpClient);
|
|
20
|
+
send(params: SmsSendParams): Promise<SmsMessage>;
|
|
21
|
+
list(params?: SmsMessageListParams): Promise<SmsPage<SmsMessage>>;
|
|
22
|
+
get(messageId: string): Promise<SmsMessage>;
|
|
23
|
+
cancel(messageId: string): Promise<SmsMessage>;
|
|
24
|
+
}
|
|
25
|
+
export declare class SmsBatches {
|
|
26
|
+
private readonly http;
|
|
27
|
+
constructor(http: HttpClient);
|
|
28
|
+
create(params: SmsBatchCreateParams): Promise<SmsBatch>;
|
|
29
|
+
get(batchId: string): Promise<SmsBatch>;
|
|
30
|
+
messages(batchId: string, params?: {
|
|
31
|
+
cursor?: string;
|
|
32
|
+
limit?: number;
|
|
33
|
+
}): Promise<SmsPage<SmsMessage>>;
|
|
34
|
+
cancel(batchId: string): Promise<SmsBatch>;
|
|
35
|
+
}
|
|
36
|
+
export declare class SmsConversations {
|
|
37
|
+
private readonly http;
|
|
38
|
+
constructor(http: HttpClient);
|
|
39
|
+
list(params?: SmsConversationListParams): Promise<SmsPage<SmsConversation>>;
|
|
40
|
+
get(conversationId: string): Promise<SmsConversation>;
|
|
41
|
+
messages(conversationId: string, params?: {
|
|
42
|
+
cursor?: string;
|
|
43
|
+
limit?: number;
|
|
44
|
+
}): Promise<SmsPage<SmsMessage>>;
|
|
45
|
+
send(conversationId: string, params: SmsConversationSendParams): Promise<SmsMessage>;
|
|
46
|
+
update(conversationId: string, params: SmsConversationUpdate): Promise<SmsConversation>;
|
|
47
|
+
markRead(conversationId: string): Promise<SmsConversation>;
|
|
48
|
+
addNote(conversationId: string, body: string): Promise<SmsConversationNote>;
|
|
49
|
+
notes(conversationId: string, params?: {
|
|
50
|
+
limit?: number;
|
|
51
|
+
}): Promise<SmsPage<SmsConversationNote>>;
|
|
52
|
+
redact(conversationId: string): Promise<void>;
|
|
53
|
+
}
|
|
54
|
+
export declare class SmsConsents {
|
|
55
|
+
private readonly http;
|
|
56
|
+
constructor(http: HttpClient);
|
|
57
|
+
list(params?: SmsConsentListParams): Promise<SmsPage<SmsConsent>>;
|
|
58
|
+
create(params: SmsConsentInput): Promise<SmsConsent>;
|
|
59
|
+
import(records: readonly SmsConsentInput[]): Promise<{
|
|
60
|
+
data: SmsConsent[];
|
|
61
|
+
imported: number;
|
|
62
|
+
}>;
|
|
63
|
+
revoke(consentId: string, reason?: string): Promise<SmsConsent>;
|
|
64
|
+
}
|
|
65
|
+
export declare class SmsSuppressions {
|
|
66
|
+
private readonly http;
|
|
67
|
+
constructor(http: HttpClient);
|
|
68
|
+
list(params?: {
|
|
69
|
+
recipient?: string;
|
|
70
|
+
active?: boolean;
|
|
71
|
+
limit?: number;
|
|
72
|
+
}): Promise<SmsPage<SmsSuppression>>;
|
|
73
|
+
}
|
|
74
|
+
export declare class SmsSettingsResource {
|
|
75
|
+
private readonly http;
|
|
76
|
+
constructor(http: HttpClient);
|
|
77
|
+
get(): Promise<SmsSettings | null>;
|
|
78
|
+
update(params: SmsSettingsUpdate): Promise<SmsSettings>;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=sms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sms.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/sms.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
export class Sms {
|
|
2
|
+
http;
|
|
3
|
+
messages;
|
|
4
|
+
batches;
|
|
5
|
+
conversations;
|
|
6
|
+
consents;
|
|
7
|
+
suppressions;
|
|
8
|
+
settings;
|
|
9
|
+
constructor(http) {
|
|
10
|
+
this.http = http;
|
|
11
|
+
this.messages = new SmsMessages(http);
|
|
12
|
+
this.batches = new SmsBatches(http);
|
|
13
|
+
this.conversations = new SmsConversations(http);
|
|
14
|
+
this.consents = new SmsConsents(http);
|
|
15
|
+
this.suppressions = new SmsSuppressions(http);
|
|
16
|
+
this.settings = new SmsSettingsResource(http);
|
|
17
|
+
}
|
|
18
|
+
async *stream(options = {}) {
|
|
19
|
+
const headers = options.lastEventId ? { 'Last-Event-ID': options.lastEventId } : undefined;
|
|
20
|
+
for await (const event of this.http.requestSse('GET', '/v1/sms/stream', undefined, options.signal, headers, 0)) {
|
|
21
|
+
if (event.event === 'heartbeat')
|
|
22
|
+
continue;
|
|
23
|
+
const data = event.data;
|
|
24
|
+
yield { event: event.event, ...(event.id ? { id: event.id } : {}), ...data };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export class SmsMessages {
|
|
29
|
+
http;
|
|
30
|
+
constructor(http) {
|
|
31
|
+
this.http = http;
|
|
32
|
+
}
|
|
33
|
+
send(params) {
|
|
34
|
+
const { idempotencyKey, ...body } = params;
|
|
35
|
+
return this.http.post('/v1/sms/messages', body, undefined, {
|
|
36
|
+
'Idempotency-Key': idempotencyKey,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
list(params = {}) {
|
|
40
|
+
return this.http.get(`/v1/sms/messages${query(params)}`);
|
|
41
|
+
}
|
|
42
|
+
get(messageId) {
|
|
43
|
+
return this.http.get(`/v1/sms/messages/${encodeURIComponent(messageId)}`);
|
|
44
|
+
}
|
|
45
|
+
cancel(messageId) {
|
|
46
|
+
return this.http.post(`/v1/sms/messages/${encodeURIComponent(messageId)}/cancel`, {});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export class SmsBatches {
|
|
50
|
+
http;
|
|
51
|
+
constructor(http) {
|
|
52
|
+
this.http = http;
|
|
53
|
+
}
|
|
54
|
+
create(params) {
|
|
55
|
+
const { idempotencyKey, ...body } = params;
|
|
56
|
+
return this.http.post('/v1/sms/batches', body, undefined, {
|
|
57
|
+
'Idempotency-Key': idempotencyKey,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
get(batchId) {
|
|
61
|
+
return this.http.get(`/v1/sms/batches/${encodeURIComponent(batchId)}`);
|
|
62
|
+
}
|
|
63
|
+
messages(batchId, params = {}) {
|
|
64
|
+
return this.http.get(`/v1/sms/batches/${encodeURIComponent(batchId)}/messages${query(params)}`);
|
|
65
|
+
}
|
|
66
|
+
cancel(batchId) {
|
|
67
|
+
return this.http.post(`/v1/sms/batches/${encodeURIComponent(batchId)}/cancel`, {});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export class SmsConversations {
|
|
71
|
+
http;
|
|
72
|
+
constructor(http) {
|
|
73
|
+
this.http = http;
|
|
74
|
+
}
|
|
75
|
+
list(params = {}) {
|
|
76
|
+
return this.http.get(`/v1/sms/conversations${query(params)}`);
|
|
77
|
+
}
|
|
78
|
+
get(conversationId) {
|
|
79
|
+
return this.http.get(`/v1/sms/conversations/${encodeURIComponent(conversationId)}`);
|
|
80
|
+
}
|
|
81
|
+
messages(conversationId, params = {}) {
|
|
82
|
+
return this.http.get(`/v1/sms/conversations/${encodeURIComponent(conversationId)}/messages${query(params)}`);
|
|
83
|
+
}
|
|
84
|
+
send(conversationId, params) {
|
|
85
|
+
const { idempotencyKey, ...body } = params;
|
|
86
|
+
return this.http.post(`/v1/sms/conversations/${encodeURIComponent(conversationId)}/messages`, body, undefined, { 'Idempotency-Key': idempotencyKey });
|
|
87
|
+
}
|
|
88
|
+
update(conversationId, params) {
|
|
89
|
+
return this.http.patch(`/v1/sms/conversations/${encodeURIComponent(conversationId)}`, params);
|
|
90
|
+
}
|
|
91
|
+
markRead(conversationId) {
|
|
92
|
+
return this.http.post(`/v1/sms/conversations/${encodeURIComponent(conversationId)}/read`, {});
|
|
93
|
+
}
|
|
94
|
+
addNote(conversationId, body) {
|
|
95
|
+
return this.http.post(`/v1/sms/conversations/${encodeURIComponent(conversationId)}/notes`, {
|
|
96
|
+
body,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
notes(conversationId, params = {}) {
|
|
100
|
+
return this.http.get(`/v1/sms/conversations/${encodeURIComponent(conversationId)}/notes${query(params)}`);
|
|
101
|
+
}
|
|
102
|
+
async redact(conversationId) {
|
|
103
|
+
await this.http.delete(`/v1/sms/conversations/${encodeURIComponent(conversationId)}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
export class SmsConsents {
|
|
107
|
+
http;
|
|
108
|
+
constructor(http) {
|
|
109
|
+
this.http = http;
|
|
110
|
+
}
|
|
111
|
+
list(params = {}) {
|
|
112
|
+
return this.http.get(`/v1/sms/consents${query(params)}`);
|
|
113
|
+
}
|
|
114
|
+
create(params) {
|
|
115
|
+
return this.http.post('/v1/sms/consents', params);
|
|
116
|
+
}
|
|
117
|
+
import(records) {
|
|
118
|
+
return this.http.post('/v1/sms/consents/import', { records });
|
|
119
|
+
}
|
|
120
|
+
revoke(consentId, reason = 'manual_revocation') {
|
|
121
|
+
return this.http.post(`/v1/sms/consents/${encodeURIComponent(consentId)}/revoke`, { reason });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
export class SmsSuppressions {
|
|
125
|
+
http;
|
|
126
|
+
constructor(http) {
|
|
127
|
+
this.http = http;
|
|
128
|
+
}
|
|
129
|
+
list(params = {}) {
|
|
130
|
+
return this.http.get(`/v1/sms/suppressions${query(params)}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export class SmsSettingsResource {
|
|
134
|
+
http;
|
|
135
|
+
constructor(http) {
|
|
136
|
+
this.http = http;
|
|
137
|
+
}
|
|
138
|
+
get() {
|
|
139
|
+
return this.http.get('/v1/sms/settings');
|
|
140
|
+
}
|
|
141
|
+
update(params) {
|
|
142
|
+
return this.http.patch('/v1/sms/settings', params);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function query(params) {
|
|
146
|
+
const search = new URLSearchParams();
|
|
147
|
+
for (const [key, value] of Object.entries(params)) {
|
|
148
|
+
if (value !== undefined && value !== null)
|
|
149
|
+
search.set(key, String(value));
|
|
150
|
+
}
|
|
151
|
+
return search.size ? `?${search.toString()}` : '';
|
|
152
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synthesize.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/synthesize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;;;;;;;;;;;;OAeG;IACG,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,gBAAgB,CAAC;IAiBtB,MAAM,CACV,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"synthesize.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/synthesize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;;;;;;;;;;;;OAeG;IACG,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,gBAAgB,CAAC;IAiBtB,MAAM,CACV,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,sBAAsB,CAAC;CAsCnC"}
|
|
@@ -35,6 +35,8 @@ export class Synthesize {
|
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
async stream(text, options, abortSignal) {
|
|
38
|
+
const trimmedSessionId = options.sessionId?.trim();
|
|
39
|
+
const requestHeaders = trimmedSessionId ? { 'x-session-id': trimmedSessionId } : undefined;
|
|
38
40
|
const intent = {
|
|
39
41
|
language: options.language,
|
|
40
42
|
...(options.region !== undefined && { region: options.region }),
|
|
@@ -47,15 +49,19 @@ export class Synthesize {
|
|
|
47
49
|
body['model'] = options.model;
|
|
48
50
|
if (options.speed !== undefined)
|
|
49
51
|
body['speed'] = options.speed;
|
|
52
|
+
if (options.instructions !== undefined)
|
|
53
|
+
body['instructions'] = options.instructions;
|
|
54
|
+
if (options.spokenForm !== undefined)
|
|
55
|
+
body['spokenForm'] = options.spokenForm;
|
|
50
56
|
if (options.constraints !== undefined)
|
|
51
57
|
body['constraints'] = options.constraints;
|
|
52
|
-
const { chunks, headers } = await this.http.requestBinaryStream('POST', '/v1/synthesize', body, abortSignal);
|
|
58
|
+
const { chunks, headers: responseHeaders } = await this.http.requestBinaryStream('POST', '/v1/synthesize', body, abortSignal, requestHeaders);
|
|
53
59
|
const result = {
|
|
54
|
-
contentType:
|
|
55
|
-
provider:
|
|
56
|
-
model:
|
|
57
|
-
failoverCount: parseInt(
|
|
58
|
-
scoresRunId:
|
|
60
|
+
contentType: responseHeaders['content-type'] ?? 'application/octet-stream',
|
|
61
|
+
provider: responseHeaders['x-speko-provider'] ?? 'unknown',
|
|
62
|
+
model: responseHeaders['x-speko-model'] ?? 'unknown',
|
|
63
|
+
failoverCount: parseInt(responseHeaders['x-speko-failover-count'] ?? '0', 10),
|
|
64
|
+
scoresRunId: responseHeaders['x-speko-scores-run-id'] || null,
|
|
59
65
|
[Symbol.asyncIterator]() {
|
|
60
66
|
return chunks;
|
|
61
67
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcribe.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/transcribe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAEpG,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;;;;;;;;OAWG;IACG,IAAI,CACR,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,gBAAgB,CAAC;IAsBrB,MAAM,CACX,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,qBAAqB,CAAC,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"transcribe.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/transcribe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAEpG,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;;;;;;;;OAWG;IACG,IAAI,CACR,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,gBAAgB,CAAC;IAsBrB,MAAM,CACX,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,qBAAqB,CAAC,qBAAqB,CAAC;CAyChD"}
|
|
@@ -48,12 +48,19 @@ export class Transcribe {
|
|
|
48
48
|
'Content-Type': options.contentType ?? 'audio/wav',
|
|
49
49
|
'X-Speko-Intent': JSON.stringify(intent),
|
|
50
50
|
};
|
|
51
|
+
const trimmedSessionId = options.sessionId?.trim();
|
|
52
|
+
if (trimmedSessionId) {
|
|
53
|
+
headers['x-session-id'] = trimmedSessionId;
|
|
54
|
+
}
|
|
51
55
|
if (options.constraints) {
|
|
52
56
|
headers['X-Speko-Constraints'] = JSON.stringify(options.constraints);
|
|
53
57
|
}
|
|
54
|
-
|
|
58
|
+
const keywords = options.keywords && options.keywords.length > 0 ? options.keywords : undefined;
|
|
59
|
+
const sttLanguage = options.sttOptions?.language;
|
|
60
|
+
if (keywords !== undefined || sttLanguage !== undefined) {
|
|
55
61
|
headers['X-Speko-Stt-Options'] = JSON.stringify({
|
|
56
|
-
keywords: [...
|
|
62
|
+
...(keywords !== undefined && { keywords: [...keywords] }),
|
|
63
|
+
...(sttLanguage !== undefined && { language: sttLanguage }),
|
|
57
64
|
});
|
|
58
65
|
}
|
|
59
66
|
const stream = await this.http.requestRawSse('POST', '/v1/transcribe', audio, headers, abortSignal);
|