@ariaflowagents/livekit-plugin-transport-smartpbx 0.9.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 +36 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/transport_adapter.d.ts +53 -0
- package/dist/transport_adapter.d.ts.map +1 -0
- package/dist/transport_adapter.js +189 -0
- package/dist/transport_adapter.js.map +1 -0
- package/dist/types.d.ts +20 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# @ariaflow/livekit-plugin-transport-smartpbx
|
|
2
|
+
|
|
3
|
+
SmartPBX transport adapter for AriaFlow voice agents.
|
|
4
|
+
|
|
5
|
+
This package provides a reusable `TransportAdapter` implementation for SmartPBX-like
|
|
6
|
+
WebSocket media streams so production code can live in a package, while playground
|
|
7
|
+
examples stay thin.
|
|
8
|
+
|
|
9
|
+
Protocol stance:
|
|
10
|
+
|
|
11
|
+
- Follow the SmartPBX AI Provider contract documented in `SmartPBX AI Provider Docs`
|
|
12
|
+
version `2025.10.29`.
|
|
13
|
+
- Treat `start`, `media`, and WebSocket close as the normative protocol surface.
|
|
14
|
+
- Do not invent SmartPBX protocol events for agent text or client turn markers.
|
|
15
|
+
|
|
16
|
+
## Exports
|
|
17
|
+
|
|
18
|
+
- `SmartPBXTransportAdapter`
|
|
19
|
+
- `SmartPBXAudioInput`
|
|
20
|
+
- `SmartPBXAudioOutput`
|
|
21
|
+
- `SmartPBXTextOutput`
|
|
22
|
+
- `DEFAULT_SMARTPBX_SAMPLE_RATE`
|
|
23
|
+
- `DEFAULT_WEBSOCKET_OPEN_STATE`
|
|
24
|
+
|
|
25
|
+
## Notes
|
|
26
|
+
|
|
27
|
+
- This package focuses on transport I/O contract and stream lifecycle.
|
|
28
|
+
- Codec conversion (G.711, Opus, resample strategy) can be composed in the host app
|
|
29
|
+
through the `onAudioFrame` callback.
|
|
30
|
+
- `audioInput.endCurrentTurn()` finalizes the local inbound stream only. It does not
|
|
31
|
+
emit SmartPBX protocol messages back to the peer.
|
|
32
|
+
- Outbound playback lifecycle is only reported after a frame is actually handed to
|
|
33
|
+
`onAudioFrame`, so interruption logic is not driven by undeliverable audio.
|
|
34
|
+
- Agent text is surfaced through an optional `onText(text, session)` host callback
|
|
35
|
+
rather than through SmartPBX WebSocket messages, because the official protocol
|
|
36
|
+
does not define a text event.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { SmartPBXAudioInput, SmartPBXAudioOutput, SmartPBXTextOutput, SmartPBXTransportAdapter, } from './transport_adapter.js';
|
|
2
|
+
export { DEFAULT_SMARTPBX_SAMPLE_RATE, DEFAULT_WEBSOCKET_OPEN_STATE, } from './types.js';
|
|
3
|
+
export type { SmartPBXSessionState, SmartPBXSocketLike, SmartPBXTransportAdapterOptions, } from './types.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,+BAA+B,GAChC,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { AudioInput, AudioOutput, TextOutput, TransportAdapter, type AudioFrame, type TimedString } from '@ariaflow/livekit-plugin';
|
|
2
|
+
import type { SmartPBXSessionState, SmartPBXSocketLike, SmartPBXTransportAdapterOptions } from './types.js';
|
|
3
|
+
export declare class SmartPBXAudioInput extends AudioInput {
|
|
4
|
+
private session;
|
|
5
|
+
private sampleRate;
|
|
6
|
+
private byteStream;
|
|
7
|
+
private currentStreamId;
|
|
8
|
+
private streamWriter;
|
|
9
|
+
constructor(session: SmartPBXSessionState, sampleRate: number);
|
|
10
|
+
pushSmartPBXFrame(frame: Float32Array): void;
|
|
11
|
+
endCurrentTurn(): void;
|
|
12
|
+
close(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export declare class SmartPBXAudioOutput extends AudioOutput {
|
|
15
|
+
private socket;
|
|
16
|
+
private session;
|
|
17
|
+
private websocketOpenState;
|
|
18
|
+
private onAudioFrame?;
|
|
19
|
+
private playing;
|
|
20
|
+
private segmentSamplesSent;
|
|
21
|
+
constructor(socket: SmartPBXSocketLike, session: SmartPBXSessionState, websocketOpenState: number, onAudioFrame?: ((frame: Float32Array, session: SmartPBXSessionState) => void) | undefined, sampleRate?: number);
|
|
22
|
+
captureFrame(frame: AudioFrame): Promise<void>;
|
|
23
|
+
clearBuffer(): void;
|
|
24
|
+
flush(): void;
|
|
25
|
+
close(): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export declare class SmartPBXTextOutput extends TextOutput {
|
|
28
|
+
private session;
|
|
29
|
+
private onText?;
|
|
30
|
+
constructor(session: SmartPBXSessionState, onText?: ((text: string, session: SmartPBXSessionState) => void) | undefined);
|
|
31
|
+
captureText(text: string | TimedString): Promise<void>;
|
|
32
|
+
flush(): void;
|
|
33
|
+
close(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
export declare class SmartPBXTransportAdapter extends TransportAdapter {
|
|
36
|
+
readonly id: string;
|
|
37
|
+
readonly audioInput: SmartPBXAudioInput;
|
|
38
|
+
readonly audioOutput: SmartPBXAudioOutput;
|
|
39
|
+
readonly textOutput: SmartPBXTextOutput;
|
|
40
|
+
readonly config: {
|
|
41
|
+
sampleRate: number;
|
|
42
|
+
numChannels: 1;
|
|
43
|
+
encoding: 'pcm_s16le';
|
|
44
|
+
samplesPerChannel: null;
|
|
45
|
+
};
|
|
46
|
+
private socket;
|
|
47
|
+
private session;
|
|
48
|
+
private websocketOpenState;
|
|
49
|
+
constructor(options: SmartPBXTransportAdapterOptions);
|
|
50
|
+
get isOpen(): boolean;
|
|
51
|
+
close(): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=transport_adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport_adapter.d.ts","sourceRoot":"","sources":["../src/transport_adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,WAAW,EAEX,UAAU,EACV,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,+BAA+B,EAChC,MAAM,YAAY,CAAC;AAUpB,qBAAa,kBAAmB,SAAQ,UAAU;IAM9C,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IANpB,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,YAAY,CAAwD;gBAGlE,OAAO,EAAE,oBAAoB,EAC7B,UAAU,EAAE,MAAM;IAM5B,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAyB5C,cAAc,IAAI,IAAI;IAgBP,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAWtC;AAED,qBAAa,mBAAoB,SAAQ,WAAW;IAKhD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,YAAY,CAAC;IAPvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,kBAAkB,CAAK;gBAGrB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,oBAAoB,EAC7B,kBAAkB,EAAE,MAAM,EAC1B,YAAY,CAAC,GAAE,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,oBAAoB,KAAK,IAAI,aAAA,EACnF,UAAU,GAAE,MAAqC;IAKpC,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BpD,WAAW,IAAI,IAAI;IAWnB,KAAK,IAAI,IAAI;IAYhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAU7B;AAED,qBAAa,kBAAmB,SAAQ,UAAU;IAE9C,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM,CAAC;gBADP,OAAO,EAAE,oBAAoB,EAC7B,MAAM,CAAC,GAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,KAAK,IAAI,aAAA;IAKzD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5D,KAAK,IAAI,IAAI;IAIhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AAED,qBAAa,wBAAyB,SAAQ,gBAAgB;IAC5D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC;IAC1C,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,CAAC,CAAC;QACf,QAAQ,EAAE,WAAW,CAAC;QACtB,iBAAiB,EAAE,IAAI,CAAC;KACzB,CAAC;IAEF,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,kBAAkB,CAAS;gBAEvB,OAAO,EAAE,+BAA+B;IA4BpD,IAAI,MAAM,IAAI,OAAO,CAEpB;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { AudioByteStream, AudioInput, AudioOutput, isTimedString, TextOutput, TransportAdapter, } from '@ariaflow/livekit-plugin';
|
|
2
|
+
import { TransformStream } from 'node:stream/web';
|
|
3
|
+
import { DEFAULT_SMARTPBX_SAMPLE_RATE, DEFAULT_WEBSOCKET_OPEN_STATE, } from './types.js';
|
|
4
|
+
function isSocketOpen(socket, websocketOpenState) {
|
|
5
|
+
return socket.readyState === websocketOpenState;
|
|
6
|
+
}
|
|
7
|
+
export class SmartPBXAudioInput extends AudioInput {
|
|
8
|
+
session;
|
|
9
|
+
sampleRate;
|
|
10
|
+
byteStream;
|
|
11
|
+
currentStreamId = null;
|
|
12
|
+
streamWriter = null;
|
|
13
|
+
constructor(session, sampleRate) {
|
|
14
|
+
super();
|
|
15
|
+
this.session = session;
|
|
16
|
+
this.sampleRate = sampleRate;
|
|
17
|
+
this.byteStream = new AudioByteStream(sampleRate, 1);
|
|
18
|
+
}
|
|
19
|
+
pushSmartPBXFrame(frame) {
|
|
20
|
+
if (!this.session.isActive) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (!this.currentStreamId) {
|
|
24
|
+
const { readable, writable } = new TransformStream();
|
|
25
|
+
this.streamWriter = writable.getWriter();
|
|
26
|
+
this.currentStreamId = this.multiStream.addInputStream(readable);
|
|
27
|
+
}
|
|
28
|
+
const pcm16 = new Int16Array(frame.length);
|
|
29
|
+
for (let i = 0; i < frame.length; i++) {
|
|
30
|
+
const sample = Math.max(-1, Math.min(1, frame[i] ?? 0));
|
|
31
|
+
pcm16[i] = sample * 0x7fff;
|
|
32
|
+
}
|
|
33
|
+
const frames = this.byteStream.write(pcm16.buffer.slice(0));
|
|
34
|
+
for (const nextFrame of frames) {
|
|
35
|
+
this.streamWriter?.write(nextFrame).catch((error) => {
|
|
36
|
+
console.error('[SmartPBXAudioInput] Failed to write frame:', error);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
endCurrentTurn() {
|
|
41
|
+
const pending = this.byteStream.flush();
|
|
42
|
+
for (const nextFrame of pending) {
|
|
43
|
+
this.streamWriter?.write(nextFrame).catch((error) => {
|
|
44
|
+
console.error('[SmartPBXAudioInput] Failed to write flush frame:', error);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
this.streamWriter?.close().catch((error) => {
|
|
48
|
+
console.error('[SmartPBXAudioInput] Failed to close writer:', error);
|
|
49
|
+
});
|
|
50
|
+
this.streamWriter = null;
|
|
51
|
+
this.currentStreamId = null;
|
|
52
|
+
}
|
|
53
|
+
async close() {
|
|
54
|
+
if (this.streamWriter) {
|
|
55
|
+
await this.streamWriter.close().catch((error) => {
|
|
56
|
+
console.error('[SmartPBXAudioInput] Failed to close writer during cleanup:', error);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
this.streamWriter = null;
|
|
60
|
+
this.currentStreamId = null;
|
|
61
|
+
await super.close();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export class SmartPBXAudioOutput extends AudioOutput {
|
|
65
|
+
socket;
|
|
66
|
+
session;
|
|
67
|
+
websocketOpenState;
|
|
68
|
+
onAudioFrame;
|
|
69
|
+
playing = false;
|
|
70
|
+
segmentSamplesSent = 0;
|
|
71
|
+
constructor(socket, session, websocketOpenState, onAudioFrame, sampleRate = DEFAULT_SMARTPBX_SAMPLE_RATE) {
|
|
72
|
+
super(sampleRate);
|
|
73
|
+
this.socket = socket;
|
|
74
|
+
this.session = session;
|
|
75
|
+
this.websocketOpenState = websocketOpenState;
|
|
76
|
+
this.onAudioFrame = onAudioFrame;
|
|
77
|
+
}
|
|
78
|
+
async captureFrame(frame) {
|
|
79
|
+
await super.captureFrame(frame);
|
|
80
|
+
if (!this.onAudioFrame) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (!this.session.isActive || !isSocketOpen(this.socket, this.websocketOpenState)) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const float32 = new Float32Array(frame.data.length);
|
|
87
|
+
for (let i = 0; i < frame.data.length; i++) {
|
|
88
|
+
float32[i] = frame.data[i] / 32768.0;
|
|
89
|
+
}
|
|
90
|
+
this.onAudioFrame(float32, this.session);
|
|
91
|
+
if (!this.playing) {
|
|
92
|
+
this.playing = true;
|
|
93
|
+
this.segmentSamplesSent = 0;
|
|
94
|
+
this.onPlaybackStarted(Date.now());
|
|
95
|
+
}
|
|
96
|
+
this.segmentSamplesSent += frame.samplesPerChannel;
|
|
97
|
+
}
|
|
98
|
+
clearBuffer() {
|
|
99
|
+
if (this.playing) {
|
|
100
|
+
this.playing = false;
|
|
101
|
+
this.onPlaybackFinished({
|
|
102
|
+
playbackPosition: this.sampleRate ? this.segmentSamplesSent / this.sampleRate : 0,
|
|
103
|
+
interrupted: true,
|
|
104
|
+
});
|
|
105
|
+
this.segmentSamplesSent = 0;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
flush() {
|
|
109
|
+
super.flush();
|
|
110
|
+
if (this.playing) {
|
|
111
|
+
this.playing = false;
|
|
112
|
+
this.onPlaybackFinished({
|
|
113
|
+
playbackPosition: this.sampleRate ? this.segmentSamplesSent / this.sampleRate : 0,
|
|
114
|
+
interrupted: false,
|
|
115
|
+
});
|
|
116
|
+
this.segmentSamplesSent = 0;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async close() {
|
|
120
|
+
if (this.playing) {
|
|
121
|
+
this.playing = false;
|
|
122
|
+
this.onPlaybackFinished({
|
|
123
|
+
playbackPosition: this.sampleRate ? this.segmentSamplesSent / this.sampleRate : 0,
|
|
124
|
+
interrupted: false,
|
|
125
|
+
});
|
|
126
|
+
this.segmentSamplesSent = 0;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export class SmartPBXTextOutput extends TextOutput {
|
|
131
|
+
session;
|
|
132
|
+
onText;
|
|
133
|
+
constructor(session, onText) {
|
|
134
|
+
super();
|
|
135
|
+
this.session = session;
|
|
136
|
+
this.onText = onText;
|
|
137
|
+
}
|
|
138
|
+
async captureText(text) {
|
|
139
|
+
const content = isTimedString(text) ? text.text : text;
|
|
140
|
+
if (!content || !this.session.isActive || !this.onText) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
this.onText(content, this.session);
|
|
144
|
+
}
|
|
145
|
+
flush() {
|
|
146
|
+
// No-op for SmartPBX text metadata.
|
|
147
|
+
}
|
|
148
|
+
async close() {
|
|
149
|
+
// No additional cleanup required for SmartPBX text output.
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
export class SmartPBXTransportAdapter extends TransportAdapter {
|
|
153
|
+
id;
|
|
154
|
+
audioInput;
|
|
155
|
+
audioOutput;
|
|
156
|
+
textOutput;
|
|
157
|
+
config;
|
|
158
|
+
socket;
|
|
159
|
+
session;
|
|
160
|
+
websocketOpenState;
|
|
161
|
+
constructor(options) {
|
|
162
|
+
super();
|
|
163
|
+
this.socket = options.socket;
|
|
164
|
+
this.session = options.session;
|
|
165
|
+
this.websocketOpenState = options.websocketOpenState ?? DEFAULT_WEBSOCKET_OPEN_STATE;
|
|
166
|
+
const sampleRate = options.sampleRate ?? DEFAULT_SMARTPBX_SAMPLE_RATE;
|
|
167
|
+
this.id = this.session.callId || crypto.randomUUID();
|
|
168
|
+
this.audioInput = new SmartPBXAudioInput(this.session, sampleRate);
|
|
169
|
+
this.audioOutput = new SmartPBXAudioOutput(this.socket, this.session, this.websocketOpenState, options.onAudioFrame, sampleRate);
|
|
170
|
+
this.textOutput = new SmartPBXTextOutput(this.session, options.onText);
|
|
171
|
+
this.config = {
|
|
172
|
+
sampleRate,
|
|
173
|
+
numChannels: 1,
|
|
174
|
+
encoding: 'pcm_s16le',
|
|
175
|
+
samplesPerChannel: null,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
get isOpen() {
|
|
179
|
+
return this.session.isActive && isSocketOpen(this.socket, this.websocketOpenState);
|
|
180
|
+
}
|
|
181
|
+
async close() {
|
|
182
|
+
await Promise.allSettled([
|
|
183
|
+
this.audioInput.close(),
|
|
184
|
+
this.audioOutput.close(),
|
|
185
|
+
this.textOutput.close(),
|
|
186
|
+
]);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=transport_adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport_adapter.js","sourceRoot":"","sources":["../src/transport_adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const DEFAULT_SMARTPBX_SAMPLE_RATE = 24000;
|
|
2
|
+
export declare const DEFAULT_WEBSOCKET_OPEN_STATE = 1;
|
|
3
|
+
export interface SmartPBXSocketLike {
|
|
4
|
+
readyState: number;
|
|
5
|
+
send: (data: string) => void;
|
|
6
|
+
}
|
|
7
|
+
export interface SmartPBXSessionState {
|
|
8
|
+
callId: string;
|
|
9
|
+
accountId: string;
|
|
10
|
+
isActive: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface SmartPBXTransportAdapterOptions {
|
|
13
|
+
socket: SmartPBXSocketLike;
|
|
14
|
+
session: SmartPBXSessionState;
|
|
15
|
+
sampleRate?: number;
|
|
16
|
+
websocketOpenState?: number;
|
|
17
|
+
onAudioFrame?: (frame: Float32Array, session: SmartPBXSessionState) => void;
|
|
18
|
+
onText?: (text: string, session: SmartPBXSessionState) => void;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,QAAQ,CAAC;AAClD,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,kBAAkB,CAAC;IAC3B,OAAO,EAAE,oBAAoB,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC5E,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAChE"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG,KAAK,CAAC;AAClD,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ariaflowagents/livekit-plugin-transport-smartpbx",
|
|
3
|
+
"version": "0.9.0",
|
|
4
|
+
"description": "SmartPBX transport adapter for AriaFlow voice agents.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": ["dist"],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"clean": "rm -rf dist",
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"test": "bun test ./test",
|
|
20
|
+
"test:typecheck": "tsc -p ./test/tsconfig.json"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"@ariaflowagents/livekit-plugin": "workspace:*",
|
|
25
|
+
"@livekit/agents": ">=1.0.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"typescript": "^5.5.0"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"ariaflow",
|
|
32
|
+
"livekit",
|
|
33
|
+
"smartpbx",
|
|
34
|
+
"voice",
|
|
35
|
+
"transport"
|
|
36
|
+
],
|
|
37
|
+
"license": "Apache-2.0"
|
|
38
|
+
}
|