mojentic 1.2.4 → 1.5.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.
Files changed (81) hide show
  1. package/dist/agents/async-dispatcher.d.ts +1 -0
  2. package/dist/agents/async-dispatcher.d.ts.map +1 -1
  3. package/dist/agents/async-dispatcher.js +6 -1
  4. package/dist/agents/async-dispatcher.js.map +1 -1
  5. package/dist/agents/simple-recursive-agent.d.ts +8 -0
  6. package/dist/agents/simple-recursive-agent.d.ts.map +1 -1
  7. package/dist/agents/simple-recursive-agent.js +35 -5
  8. package/dist/agents/simple-recursive-agent.js.map +1 -1
  9. package/dist/context/shared-working-memory.js +1 -1
  10. package/dist/context/shared-working-memory.js.map +1 -1
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +1 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/llm/broker.d.ts +10 -4
  16. package/dist/llm/broker.d.ts.map +1 -1
  17. package/dist/llm/broker.js +78 -68
  18. package/dist/llm/broker.js.map +1 -1
  19. package/dist/llm/gateways/openai-messages-adapter.js +3 -3
  20. package/dist/llm/gateways/openai-messages-adapter.js.map +1 -1
  21. package/dist/llm/gateways/openai-model-registry.d.ts.map +1 -1
  22. package/dist/llm/gateways/openai-model-registry.js +34 -1
  23. package/dist/llm/gateways/openai-model-registry.js.map +1 -1
  24. package/dist/llm/models.d.ts +2 -0
  25. package/dist/llm/models.d.ts.map +1 -1
  26. package/dist/llm/tools/index.d.ts +1 -0
  27. package/dist/llm/tools/index.d.ts.map +1 -1
  28. package/dist/llm/tools/index.js +1 -0
  29. package/dist/llm/tools/index.js.map +1 -1
  30. package/dist/llm/tools/runner.d.ts +89 -0
  31. package/dist/llm/tools/runner.d.ts.map +1 -0
  32. package/dist/llm/tools/runner.js +130 -0
  33. package/dist/llm/tools/runner.js.map +1 -0
  34. package/dist/llm/tools/tool.d.ts +18 -3
  35. package/dist/llm/tools/tool.d.ts.map +1 -1
  36. package/dist/llm/tools/tool.js.map +1 -1
  37. package/dist/realtime/broker.d.ts +40 -0
  38. package/dist/realtime/broker.d.ts.map +1 -0
  39. package/dist/realtime/broker.js +74 -0
  40. package/dist/realtime/broker.js.map +1 -0
  41. package/dist/realtime/config.d.ts +134 -0
  42. package/dist/realtime/config.d.ts.map +1 -0
  43. package/dist/realtime/config.js +23 -0
  44. package/dist/realtime/config.js.map +1 -0
  45. package/dist/realtime/events.d.ts +146 -0
  46. package/dist/realtime/events.d.ts.map +1 -0
  47. package/dist/realtime/events.js +10 -0
  48. package/dist/realtime/events.js.map +1 -0
  49. package/dist/realtime/gateway.d.ts +48 -0
  50. package/dist/realtime/gateway.d.ts.map +1 -0
  51. package/dist/realtime/gateway.js +9 -0
  52. package/dist/realtime/gateway.js.map +1 -0
  53. package/dist/realtime/index.d.ts +14 -0
  54. package/dist/realtime/index.d.ts.map +1 -0
  55. package/dist/realtime/index.js +30 -0
  56. package/dist/realtime/index.js.map +1 -0
  57. package/dist/realtime/openai-gateway.d.ts +39 -0
  58. package/dist/realtime/openai-gateway.d.ts.map +1 -0
  59. package/dist/realtime/openai-gateway.js +154 -0
  60. package/dist/realtime/openai-gateway.js.map +1 -0
  61. package/dist/realtime/schemas.d.ts +333 -0
  62. package/dist/realtime/schemas.d.ts.map +1 -0
  63. package/dist/realtime/schemas.js +243 -0
  64. package/dist/realtime/schemas.js.map +1 -0
  65. package/dist/realtime/session.d.ts +115 -0
  66. package/dist/realtime/session.d.ts.map +1 -0
  67. package/dist/realtime/session.js +715 -0
  68. package/dist/realtime/session.js.map +1 -0
  69. package/dist/realtime/transport.d.ts +87 -0
  70. package/dist/realtime/transport.d.ts.map +1 -0
  71. package/dist/realtime/transport.js +115 -0
  72. package/dist/realtime/transport.js.map +1 -0
  73. package/dist/tracer/tracerEvents.d.ts +23 -0
  74. package/dist/tracer/tracerEvents.d.ts.map +1 -1
  75. package/dist/tracer/tracerEvents.js +40 -1
  76. package/dist/tracer/tracerEvents.js.map +1 -1
  77. package/dist/tracer/tracerSystem.d.ts +16 -0
  78. package/dist/tracer/tracerSystem.d.ts.map +1 -1
  79. package/dist/tracer/tracerSystem.js +22 -0
  80. package/dist/tracer/tracerSystem.js.map +1 -1
  81. package/package.json +27 -14
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Configuration for the realtime voice subsystem.
3
+ *
4
+ * Mirrors the slice of OpenAI's Realtime session config that ports cleanly
5
+ * to other Mojentic implementations. Provider-specific knobs live in
6
+ * `providerExtras`.
7
+ */
8
+ import { LlmTool } from '../llm/tools';
9
+ /**
10
+ * Built-in voice options OpenAI's Realtime API exposes.
11
+ *
12
+ * Accepts arbitrary strings to allow new voices without a library update.
13
+ */
14
+ export type RealtimeVoice = 'alloy' | 'verse' | 'shimmer' | 'echo' | 'ballad' | 'sage' | string;
15
+ /**
16
+ * Audio modality selector.
17
+ */
18
+ export type RealtimeModality = 'audio' | 'text';
19
+ /**
20
+ * Audio frame format OpenAI accepts on the wire.
21
+ *
22
+ * `pcm16` is the default — 16-bit signed little-endian PCM, mono, 24 kHz.
23
+ */
24
+ export type RealtimeAudioFormat = 'pcm16' | 'g711_ulaw' | 'g711_alaw';
25
+ /**
26
+ * Tunable parameters for server-side voice-activity detection.
27
+ *
28
+ * Bump `threshold` up (e.g. 0.7–0.9) to make the VAD less sensitive to
29
+ * background noise. Set `interruptResponse: false` to disable barge-in
30
+ * entirely so the assistant's reply can't be cancelled mid-sentence by a
31
+ * cough or keyboard click.
32
+ */
33
+ export interface ServerVadConfig {
34
+ type?: 'server_vad';
35
+ /** Activation threshold (0.0–1.0). Lower fires on quieter speech. Default ≈ 0.5. */
36
+ threshold?: number;
37
+ /** Padding (ms) added to the start of a detected utterance. */
38
+ prefixPaddingMs?: number;
39
+ /** Silence (ms) before declaring the user is done speaking. */
40
+ silenceDurationMs?: number;
41
+ /** Whether VAD should auto-fire a `response.create` after the user stops. Default true. */
42
+ createResponse?: boolean;
43
+ /**
44
+ * Whether speech detected during an in-flight assistant response should
45
+ * cancel it (barge-in). Default true. Set false to mute false-positive
46
+ * interruptions from background noise.
47
+ */
48
+ interruptResponse?: boolean;
49
+ /** Max silence (ms) before the server idles the session. */
50
+ idleTimeoutMs?: number;
51
+ }
52
+ /**
53
+ * Semantic VAD mode — uses an LLM-side classifier to decide whether
54
+ * detected audio is intentional speech vs background noise. More robust
55
+ * than energy-threshold VAD in noisy environments.
56
+ */
57
+ export interface SemanticVadConfig {
58
+ type: 'semantic_vad';
59
+ /** Sensitivity of the classifier. `low` = least likely to fire. */
60
+ eagerness?: 'low' | 'medium' | 'high' | 'auto';
61
+ createResponse?: boolean;
62
+ interruptResponse?: boolean;
63
+ }
64
+ /**
65
+ * Turn-detection strategy.
66
+ *
67
+ * - `server_vad` — server decides when the user stopped talking and auto-fires
68
+ * a response. Natural phone-call mode. Energy-threshold-based.
69
+ * - `none` — client decides when to commit the buffer and request a response.
70
+ * Useful for push-to-talk and tests.
71
+ * - `semantic_vad` — LLM-classifier-driven VAD. Best for noisy environments.
72
+ * - A {@link ServerVadConfig} or {@link SemanticVadConfig} object — tune
73
+ * thresholds and behaviour.
74
+ */
75
+ export type TurnDetectionMode = 'server_vad' | 'semantic_vad' | 'none' | ServerVadConfig | SemanticVadConfig;
76
+ /**
77
+ * Policy for handling tool outputs from a cancelled response.
78
+ *
79
+ * - `drop` (default) — don't submit any outputs from the cancelled batch.
80
+ * Stale answers don't pollute context.
81
+ * - `submit-completed-only` — submit outputs for tools that finished before
82
+ * the abort signal landed; drop in-flight ones.
83
+ * - `submit` — submit all outputs that eventually arrive, even after the
84
+ * model started a new response.
85
+ */
86
+ export type InterruptOutputPolicy = 'drop' | 'submit' | 'submit-completed-only';
87
+ /**
88
+ * Choice strategy for tools in the session.
89
+ */
90
+ export type RealtimeToolChoice = 'auto' | 'none' | 'required' | {
91
+ name: string;
92
+ };
93
+ /**
94
+ * Vendor-neutral configuration for a realtime voice session.
95
+ *
96
+ * The library forwards a curated subset to the active gateway and translates
97
+ * vendor-specific shapes at the boundary.
98
+ */
99
+ export interface RealtimeVoiceConfig {
100
+ /** System-level instructions injected into every assistant turn. */
101
+ instructions?: string;
102
+ /** Voice id to render assistant audio with. */
103
+ voice?: RealtimeVoice;
104
+ /** Active modalities. Default `['audio', 'text']`. */
105
+ modalities?: RealtimeModality[];
106
+ /** Encoding of audio frames the client sends. Default `pcm16`. */
107
+ inputAudioFormat?: RealtimeAudioFormat;
108
+ /** Encoding of audio frames the server returns. Default `pcm16`. */
109
+ outputAudioFormat?: RealtimeAudioFormat;
110
+ /** Turn-detection strategy. Default `server_vad`. */
111
+ turnDetection?: TurnDetectionMode;
112
+ /** Whisper transcription config for user audio. Pass `false` to disable. */
113
+ inputAudioTranscription?: {
114
+ model: 'whisper-1';
115
+ } | false;
116
+ /** Tools available to the model in this session. */
117
+ tools?: LlmTool[];
118
+ /** Tool-selection strategy. Default `auto`. */
119
+ toolChoice?: RealtimeToolChoice;
120
+ /** Sampling temperature. */
121
+ temperature?: number;
122
+ /** Cap on output tokens per response. */
123
+ maxResponseOutputTokens?: number;
124
+ /** How to treat tool outputs from interrupted/cancelled responses. */
125
+ onInterrupt?: InterruptOutputPolicy;
126
+ /** Provider-specific escape hatch — passed through verbatim to the gateway. */
127
+ providerExtras?: Record<string, unknown>;
128
+ }
129
+ /**
130
+ * Default config used when a field is omitted. Surfaced so consumers can
131
+ * read effective values without re-implementing the merge themselves.
132
+ */
133
+ export declare const REALTIME_DEFAULTS: Required<Pick<RealtimeVoiceConfig, 'modalities' | 'inputAudioFormat' | 'outputAudioFormat' | 'turnDetection' | 'toolChoice' | 'onInterrupt'>>;
134
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/realtime/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAEhG;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEhD;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,CAAC;AAEtE;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2FAA2F;IAC3F,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,cAAc,CAAC;IACrB,mEAAmE;IACnE,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IAC/C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,cAAc,GACd,MAAM,GACN,eAAe,GACf,iBAAiB,CAAC;AAEtB;;;;;;;;;GASG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,QAAQ,GAAG,uBAAuB,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjF;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,sDAAsD;IACtD,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAChC,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,mBAAmB,CAAC;IACvC,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,mBAAmB,CAAC;IACxC,qDAAqD;IACrD,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,4EAA4E;IAC5E,uBAAuB,CAAC,EAAE;QAAE,KAAK,EAAE,WAAW,CAAA;KAAE,GAAG,KAAK,CAAC;IACzD,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,sEAAsE;IACtE,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CACtC,IAAI,CACF,mBAAmB,EACjB,YAAY,GACZ,kBAAkB,GAClB,mBAAmB,GACnB,eAAe,GACf,YAAY,GACZ,aAAa,CAChB,CAQF,CAAC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ /**
3
+ * Configuration for the realtime voice subsystem.
4
+ *
5
+ * Mirrors the slice of OpenAI's Realtime session config that ports cleanly
6
+ * to other Mojentic implementations. Provider-specific knobs live in
7
+ * `providerExtras`.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.REALTIME_DEFAULTS = void 0;
11
+ /**
12
+ * Default config used when a field is omitted. Surfaced so consumers can
13
+ * read effective values without re-implementing the merge themselves.
14
+ */
15
+ exports.REALTIME_DEFAULTS = {
16
+ modalities: ['audio', 'text'],
17
+ inputAudioFormat: 'pcm16',
18
+ outputAudioFormat: 'pcm16',
19
+ turnDetection: 'server_vad',
20
+ toolChoice: 'auto',
21
+ onInterrupt: 'drop',
22
+ };
23
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/realtime/config.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAsIH;;;GAGG;AACU,QAAA,iBAAiB,GAU1B;IACF,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;IAC7B,gBAAgB,EAAE,OAAO;IACzB,iBAAiB,EAAE,OAAO;IAC1B,aAAa,EAAE,YAAY;IAC3B,UAAU,EAAE,MAAM;IAClB,WAAW,EAAE,MAAM;CACpB,CAAC"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Vendor-neutral event union for the realtime subsystem.
3
+ *
4
+ * Consumers subscribe to this union rather than raw OpenAI events so the
5
+ * same observer code ports cleanly to other realtime providers and other
6
+ * Mojentic implementations (Python, Elixir, Rust).
7
+ */
8
+ import { ToolArgs, ToolResult } from '../llm/tools';
9
+ import { RealtimeVoiceConfig } from './config';
10
+ /**
11
+ * Token usage reported when a response turn completes.
12
+ */
13
+ export interface TokenUsage {
14
+ promptTokens?: number;
15
+ completionTokens?: number;
16
+ totalTokens?: number;
17
+ /** Provider-specific breakdown (e.g. audio vs text tokens). */
18
+ extras?: Record<string, unknown>;
19
+ }
20
+ /**
21
+ * Conversation item in a realtime session.
22
+ *
23
+ * Realtime sessions don't map cleanly to chat-completion `LlmMessage`s
24
+ * because they carry audio, multi-modal content, and tool-call lifecycle
25
+ * separate from any single message. We carry a small dedicated shape so
26
+ * `LlmMessage` doesn't get bent out of shape.
27
+ */
28
+ export interface RealtimeItem {
29
+ id: string;
30
+ /** Item kind — message, function-call, or function-call output. */
31
+ type: 'message' | 'function_call' | 'function_call_output';
32
+ /** Role for message items. */
33
+ role?: 'system' | 'user' | 'assistant';
34
+ /** Text content (assembled from streamed deltas). */
35
+ text?: string;
36
+ /** Transcript content (assembled from streamed audio deltas). */
37
+ transcript?: string;
38
+ /** Function name for function_call / function_call_output items. */
39
+ name?: string;
40
+ /** Parsed JSON arguments for function_call items. */
41
+ args?: ToolArgs;
42
+ /** Tool execution result for function_call_output items. */
43
+ output?: ToolResult;
44
+ /** Pair function_call → function_call_output. */
45
+ callId?: string;
46
+ }
47
+ /**
48
+ * Vendor-neutral event types emitted by {@link RealtimeSession}.
49
+ */
50
+ export type RealtimeEvent = {
51
+ kind: 'session_opened';
52
+ sessionId: string;
53
+ } | {
54
+ kind: 'session_updated';
55
+ config: Partial<RealtimeVoiceConfig>;
56
+ } | {
57
+ kind: 'session_closed';
58
+ reason: 'client' | 'server' | 'error';
59
+ } | {
60
+ kind: 'user_speech_started';
61
+ atMs: number;
62
+ } | {
63
+ kind: 'user_speech_stopped';
64
+ atMs: number;
65
+ } | {
66
+ kind: 'user_transcript_delta';
67
+ itemId: string;
68
+ delta: string;
69
+ } | {
70
+ kind: 'user_transcript';
71
+ itemId: string;
72
+ text: string;
73
+ } | {
74
+ kind: 'assistant_turn_started';
75
+ turnId: string;
76
+ } | {
77
+ kind: 'assistant_text_delta';
78
+ turnId: string;
79
+ delta: string;
80
+ } | {
81
+ kind: 'assistant_text';
82
+ turnId: string;
83
+ text: string;
84
+ } | {
85
+ kind: 'assistant_transcript_delta';
86
+ turnId: string;
87
+ delta: string;
88
+ } | {
89
+ kind: 'assistant_transcript';
90
+ turnId: string;
91
+ text: string;
92
+ } | {
93
+ kind: 'assistant_audio_delta';
94
+ turnId: string;
95
+ pcm: Int16Array;
96
+ } | {
97
+ kind: 'assistant_turn_completed';
98
+ turnId: string;
99
+ usage?: TokenUsage;
100
+ } | {
101
+ kind: 'tool_call_started';
102
+ turnId: string;
103
+ callId: string;
104
+ name: string;
105
+ } | {
106
+ kind: 'tool_call_args_delta';
107
+ callId: string;
108
+ delta: string;
109
+ } | {
110
+ kind: 'tool_call_dispatched';
111
+ callId: string;
112
+ name: string;
113
+ args: ToolArgs;
114
+ } | {
115
+ kind: 'tool_call_completed';
116
+ callId: string;
117
+ name: string;
118
+ result: ToolResult;
119
+ } | {
120
+ kind: 'tool_call_failed';
121
+ callId: string;
122
+ name: string;
123
+ error: Error;
124
+ } | {
125
+ kind: 'tool_batch_submitted';
126
+ turnId: string;
127
+ callIds: string[];
128
+ } | {
129
+ kind: 'interrupted';
130
+ turnId: string;
131
+ reason: 'barge_in' | 'manual' | 'error';
132
+ } | {
133
+ kind: 'rate_limited';
134
+ resetMs: number;
135
+ details: Record<string, unknown>;
136
+ } | {
137
+ kind: 'error';
138
+ error: Error;
139
+ recoverable: boolean;
140
+ };
141
+ /**
142
+ * Narrow helper for discriminating events by `kind` in switch statements
143
+ * without losing exhaustiveness checking.
144
+ */
145
+ export type RealtimeEventKind = RealtimeEvent['kind'];
146
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/realtime/events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /**
3
+ * Vendor-neutral event union for the realtime subsystem.
4
+ *
5
+ * Consumers subscribe to this union rather than raw OpenAI events so the
6
+ * same observer code ports cleanly to other realtime providers and other
7
+ * Mojentic implementations (Python, Elixir, Rust).
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/realtime/events.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Realtime voice gateway interface.
3
+ *
4
+ * Sibling to {@link LlmGateway}: where the chat-completions gateway exposes
5
+ * a request/response surface, this one exposes a duplex session.
6
+ */
7
+ import { Result } from '../error';
8
+ import { RealtimeVoiceConfig } from './config';
9
+ /**
10
+ * Client → Server event envelope. The gateway forwards verbatim; vendor-
11
+ * neutral translation happens in {@link RealtimeVoiceBroker}.
12
+ */
13
+ export interface ClientRealtimeEvent {
14
+ /** Vendor-specific event type (e.g. `session.update`, `response.create`). */
15
+ type: string;
16
+ [k: string]: unknown;
17
+ }
18
+ /**
19
+ * Server → Client event envelope. The gateway parses bytes to JSON and
20
+ * runs them through a Zod boundary check before yielding.
21
+ */
22
+ export interface ServerRealtimeEvent {
23
+ type: string;
24
+ [k: string]: unknown;
25
+ }
26
+ /**
27
+ * Live duplex session opened by a {@link RealtimeVoiceGateway}.
28
+ *
29
+ * `events()` yields server events in arrival order, terminating when the
30
+ * session closes. `sendEvent` queues a client event. `close` is idempotent.
31
+ */
32
+ export interface RealtimeGatewaySession {
33
+ readonly sessionId: string;
34
+ sendEvent(event: ClientRealtimeEvent): Promise<Result<void, Error>>;
35
+ events(): AsyncGenerator<ServerRealtimeEvent>;
36
+ close(): Promise<void>;
37
+ isClosed(): boolean;
38
+ }
39
+ /**
40
+ * Open duplex realtime sessions against a provider.
41
+ *
42
+ * Implementations are intentionally thin: own the transport, validate
43
+ * events at the boundary, do no orchestration.
44
+ */
45
+ export interface RealtimeVoiceGateway {
46
+ open(model: string, config: RealtimeVoiceConfig, correlationId?: string): Promise<Result<RealtimeGatewaySession, Error>>;
47
+ }
48
+ //# sourceMappingURL=gateway.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../src/realtime/gateway.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,cAAc,CAAC,mBAAmB,CAAC,CAAC;IAC9C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,QAAQ,IAAI,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,CACF,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,mBAAmB,EAC3B,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC,CAAC;CACnD"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ /**
3
+ * Realtime voice gateway interface.
4
+ *
5
+ * Sibling to {@link LlmGateway}: where the chat-completions gateway exposes
6
+ * a request/response surface, this one exposes a duplex session.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ //# sourceMappingURL=gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../../src/realtime/gateway.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Realtime voice subsystem.
3
+ *
4
+ * Sibling to the `llm` module — duplex audio + text sessions with
5
+ * parallel tool calling. Currently supports OpenAI's Realtime API.
6
+ */
7
+ export * from './config';
8
+ export * from './events';
9
+ export * from './gateway';
10
+ export * from './openai-gateway';
11
+ export * from './session';
12
+ export * from './broker';
13
+ export * from './transport';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/realtime/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ /**
3
+ * Realtime voice subsystem.
4
+ *
5
+ * Sibling to the `llm` module — duplex audio + text sessions with
6
+ * parallel tool calling. Currently supports OpenAI's Realtime API.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ __exportStar(require("./config"), exports);
24
+ __exportStar(require("./events"), exports);
25
+ __exportStar(require("./gateway"), exports);
26
+ __exportStar(require("./openai-gateway"), exports);
27
+ __exportStar(require("./session"), exports);
28
+ __exportStar(require("./broker"), exports);
29
+ __exportStar(require("./transport"), exports);
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/realtime/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;AAEH,2CAAyB;AACzB,2CAAyB;AACzB,4CAA0B;AAC1B,mDAAiC;AACjC,4CAA0B;AAC1B,2CAAyB;AACzB,8CAA4B"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * OpenAI Realtime API gateway.
3
+ *
4
+ * Owns the WebSocket, validates server events at the boundary using Zod
5
+ * schemas, and forwards client events verbatim. No tool orchestration,
6
+ * no audio decoding — those live in the broker.
7
+ */
8
+ import { Result } from '../error';
9
+ import { RealtimeVoiceConfig } from './config';
10
+ import { RealtimeGatewaySession, RealtimeVoiceGateway } from './gateway';
11
+ import { RealtimeTransport } from './transport';
12
+ /**
13
+ * Options for the OpenAI realtime gateway.
14
+ */
15
+ export interface OpenAIRealtimeGatewayOptions {
16
+ /** API key. Defaults to `process.env.OPENAI_API_KEY`. */
17
+ apiKey?: string;
18
+ /** Override the realtime endpoint (e.g. for proxies, regions, beta hosts). */
19
+ baseUrl?: string;
20
+ /**
21
+ * Build the transport for a given URL. Defaults to {@link WebSocketTransport}.
22
+ * Exposed for tests to inject a scripted in-memory transport.
23
+ */
24
+ transportFactory?: (url: string, headers: Record<string, string>, protocols: string[]) => RealtimeTransport;
25
+ }
26
+ /**
27
+ * Gateway against OpenAI's Realtime API.
28
+ *
29
+ * Each `open()` call provisions a new WebSocket and a fresh session id.
30
+ * The returned {@link RealtimeGatewaySession} is the only stateful surface.
31
+ */
32
+ export declare class OpenAIRealtimeGateway implements RealtimeVoiceGateway {
33
+ private readonly apiKey;
34
+ private readonly baseUrl;
35
+ private readonly transportFactory;
36
+ constructor(options?: OpenAIRealtimeGatewayOptions);
37
+ open(model: string, _config: RealtimeVoiceConfig, correlationId?: string): Promise<Result<RealtimeGatewaySession, Error>>;
38
+ }
39
+ //# sourceMappingURL=openai-gateway.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-gateway.d.ts","sourceRoot":"","sources":["../../src/realtime/openai-gateway.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAW,MAAM,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAEL,sBAAsB,EACtB,oBAAoB,EAErB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,iBAAiB,EAAsB,MAAM,aAAa,CAAC;AAIpE;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CACjB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,SAAS,EAAE,MAAM,EAAE,KAChB,iBAAiB,CAAC;CACxB;AA4ED;;;;;GAKG;AACH,qBAAa,qBAAsB,YAAW,oBAAoB;IAChE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAIV;gBAEX,OAAO,GAAE,4BAAiC;IAYhD,IAAI,CACR,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,mBAAmB,EAC5B,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;CAuDlD"}
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ /**
3
+ * OpenAI Realtime API gateway.
4
+ *
5
+ * Owns the WebSocket, validates server events at the boundary using Zod
6
+ * schemas, and forwards client events verbatim. No tool orchestration,
7
+ * no audio decoding — those live in the broker.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.OpenAIRealtimeGateway = void 0;
11
+ const crypto_1 = require("crypto");
12
+ const error_1 = require("../error");
13
+ const schemas_1 = require("./schemas");
14
+ const transport_1 = require("./transport");
15
+ const DEFAULT_OPENAI_REALTIME_URL = 'wss://api.openai.com/v1/realtime';
16
+ const EOS = Symbol('realtime-eos');
17
+ class OpenAIRealtimeSession {
18
+ transport;
19
+ sessionId;
20
+ closed = false;
21
+ queue = [];
22
+ waiters = [];
23
+ constructor(sessionId, transport) {
24
+ this.transport = transport;
25
+ this.sessionId = sessionId;
26
+ }
27
+ enqueue(event) {
28
+ const waiter = this.waiters.shift();
29
+ if (waiter) {
30
+ waiter.resolve(event);
31
+ }
32
+ else {
33
+ this.queue.push(event);
34
+ }
35
+ }
36
+ signalEnd() {
37
+ if (this.closed)
38
+ return;
39
+ this.closed = true;
40
+ while (this.waiters.length > 0) {
41
+ const waiter = this.waiters.shift();
42
+ waiter?.resolve(EOS);
43
+ }
44
+ }
45
+ async sendEvent(event) {
46
+ if (this.closed) {
47
+ return (0, error_1.Err)(new Error('Session is closed'));
48
+ }
49
+ return this.transport.send(event);
50
+ }
51
+ async *events() {
52
+ while (true) {
53
+ if (this.queue.length > 0) {
54
+ yield this.queue.shift();
55
+ continue;
56
+ }
57
+ if (this.closed) {
58
+ return;
59
+ }
60
+ const next = await new Promise((resolve) => {
61
+ this.waiters.push({ resolve });
62
+ });
63
+ if (next === EOS) {
64
+ return;
65
+ }
66
+ yield next;
67
+ }
68
+ }
69
+ async close() {
70
+ if (this.closed)
71
+ return;
72
+ await this.transport.close();
73
+ this.signalEnd();
74
+ }
75
+ isClosed() {
76
+ return this.closed;
77
+ }
78
+ }
79
+ /**
80
+ * Gateway against OpenAI's Realtime API.
81
+ *
82
+ * Each `open()` call provisions a new WebSocket and a fresh session id.
83
+ * The returned {@link RealtimeGatewaySession} is the only stateful surface.
84
+ */
85
+ class OpenAIRealtimeGateway {
86
+ apiKey;
87
+ baseUrl;
88
+ transportFactory;
89
+ constructor(options = {}) {
90
+ const apiKey = options.apiKey ?? process.env.OPENAI_API_KEY;
91
+ if (!apiKey) {
92
+ throw new Error('OpenAIRealtimeGateway requires an apiKey (or OPENAI_API_KEY env var).');
93
+ }
94
+ this.apiKey = apiKey;
95
+ this.baseUrl = options.baseUrl ?? DEFAULT_OPENAI_REALTIME_URL;
96
+ this.transportFactory =
97
+ options.transportFactory ??
98
+ ((url, headers, protocols) => new transport_1.WebSocketTransport(url, { headers, protocols }));
99
+ }
100
+ async open(model, _config, correlationId) {
101
+ const url = `${this.baseUrl}?model=${encodeURIComponent(model)}`;
102
+ const headers = {
103
+ Authorization: `Bearer ${this.apiKey}`,
104
+ };
105
+ if (correlationId) {
106
+ headers['X-Correlation-Id'] = correlationId;
107
+ }
108
+ // OpenAI also accepts auth via WebSocket subprotocols, which is the only
109
+ // option for environments where the WebSocket constructor doesn't allow
110
+ // custom headers (e.g. Node's built-in global `WebSocket`). Sending both
111
+ // is safe — the `ws` package picks up the headers, the global picks up
112
+ // the protocols.
113
+ const protocols = ['realtime', `openai-insecure-api-key.${this.apiKey}`];
114
+ const transport = this.transportFactory(url, headers, protocols);
115
+ const sessionId = (0, crypto_1.randomUUID)();
116
+ const session = new OpenAIRealtimeSession(sessionId, transport);
117
+ const connectResult = await transport.connect({
118
+ onOpen: () => {
119
+ /* no-op — session is usable as soon as connect resolves */
120
+ },
121
+ onMessage: (data) => {
122
+ try {
123
+ const raw = JSON.parse(data);
124
+ const parsed = (0, schemas_1.parseServerEvent)(raw);
125
+ session.enqueue(parsed);
126
+ }
127
+ catch (err) {
128
+ session.enqueue({
129
+ type: 'error',
130
+ error: {
131
+ type: 'parse_error',
132
+ message: err instanceof Error ? err.message : String(err),
133
+ },
134
+ });
135
+ }
136
+ },
137
+ onClose: () => {
138
+ session.signalEnd();
139
+ },
140
+ onError: (err) => {
141
+ session.enqueue({
142
+ type: 'error',
143
+ error: { type: 'transport_error', message: err.message },
144
+ });
145
+ },
146
+ });
147
+ if (!connectResult.ok) {
148
+ return (0, error_1.Err)(connectResult.error);
149
+ }
150
+ return (0, error_1.Ok)(session);
151
+ }
152
+ }
153
+ exports.OpenAIRealtimeGateway = OpenAIRealtimeGateway;
154
+ //# sourceMappingURL=openai-gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-gateway.js","sourceRoot":"","sources":["../../src/realtime/openai-gateway.ts"],"names":[],"mappings":"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"}