nexus-ai-pro 0.9.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/API_STABILITY.md +44 -3
  2. package/CHANGELOG.md +45 -2
  3. package/README.md +281 -6
  4. package/ROADMAP.md +52 -3
  5. package/SECURITY.md +31 -0
  6. package/dist/core/config-builder.d.ts +3 -0
  7. package/dist/core/config-builder.js +5 -0
  8. package/dist/core/nexus.d.ts +10 -0
  9. package/dist/core/nexus.js +17 -0
  10. package/dist/images/assets.d.ts +115 -0
  11. package/dist/images/assets.js +343 -0
  12. package/dist/images/errors.d.ts +35 -0
  13. package/dist/images/errors.js +79 -0
  14. package/dist/images/index.d.ts +4 -0
  15. package/dist/images/index.js +2 -0
  16. package/dist/images/manager.d.ts +23 -0
  17. package/dist/images/manager.js +574 -0
  18. package/dist/images/mock.d.ts +17 -0
  19. package/dist/images/mock.js +237 -0
  20. package/dist/images/openai.d.ts +46 -0
  21. package/dist/images/openai.js +355 -0
  22. package/dist/index.d.ts +5 -0
  23. package/dist/index.js +3 -0
  24. package/dist/realtime/conversation.d.ts +19 -0
  25. package/dist/realtime/conversation.js +406 -0
  26. package/dist/realtime/errors.d.ts +25 -0
  27. package/dist/realtime/errors.js +74 -0
  28. package/dist/realtime/events.d.ts +10 -0
  29. package/dist/realtime/events.js +39 -0
  30. package/dist/realtime/id.d.ts +2 -0
  31. package/dist/realtime/id.js +8 -0
  32. package/dist/realtime/index.d.ts +22 -0
  33. package/dist/realtime/index.js +12 -0
  34. package/dist/realtime/mock.transport.d.ts +55 -0
  35. package/dist/realtime/mock.transport.js +169 -0
  36. package/dist/realtime/openai-events.d.ts +5 -0
  37. package/dist/realtime/openai-events.js +404 -0
  38. package/dist/realtime/openai-server.d.ts +33 -0
  39. package/dist/realtime/openai-server.js +138 -0
  40. package/dist/realtime/openai-webrtc.transport.d.ts +153 -0
  41. package/dist/realtime/openai-webrtc.transport.js +871 -0
  42. package/dist/realtime/openai-websocket.transport.d.ts +65 -0
  43. package/dist/realtime/openai-websocket.transport.js +420 -0
  44. package/dist/realtime/provider.d.ts +37 -0
  45. package/dist/realtime/provider.js +59 -0
  46. package/dist/realtime/session.d.ts +110 -0
  47. package/dist/realtime/session.js +962 -0
  48. package/dist/realtime/tools.d.ts +47 -0
  49. package/dist/realtime/tools.js +358 -0
  50. package/dist/realtime/transport-utils.d.ts +55 -0
  51. package/dist/realtime/transport-utils.js +240 -0
  52. package/dist/realtime/types.d.ts +544 -0
  53. package/dist/realtime/types.js +1 -0
  54. package/dist/testing/image-provider-conformance.d.ts +33 -0
  55. package/dist/testing/image-provider-conformance.js +324 -0
  56. package/dist/types/config.d.ts +2 -0
  57. package/dist/types/images.d.ts +245 -0
  58. package/dist/types/images.js +1 -0
  59. package/package.json +54 -2
package/API_STABILITY.md CHANGED
@@ -1,10 +1,13 @@
1
1
  # API Stability Policy
2
2
 
3
- This policy describes compatibility guarantees for `nexus-ai-pro` beginning with version 0.9.0.
3
+ This policy describes compatibility guarantees for `nexus-ai-pro`. The 1.x compatibility guarantees
4
+ apply beginning with version 1.0.0.
4
5
 
5
6
  ## Release stages
6
7
 
7
- The package is pre-1.0. Minor releases may contain breaking changes when they are necessary, but those changes will be called out in the changelog with migration guidance. Patch releases are intended to remain backward compatible.
8
+ The package follows semantic versioning. Within the 1.x line, incompatible changes to stable public
9
+ APIs require a major release. Minor releases may add backward-compatible features, and patch releases
10
+ are intended to remain backward compatible.
8
11
 
9
12
  The following surfaces are public and covered by this policy:
10
13
 
@@ -25,8 +28,46 @@ Source files, `dist` file paths, examples, test helpers that are not exported, a
25
28
 
26
29
  The package is ESM-only and supports Node.js 22 or newer. CommonJS `require()` and deep imports into `dist` or `src` are not supported.
27
30
 
31
+ ## Realtime API stage
32
+
33
+ The opt-in `nexus-ai-pro/realtime` family is public in the current development line. This includes the
34
+ explicit `realtime/session`, `realtime/tools`, `realtime/conversation`, `realtime/openai-webrtc`,
35
+ `realtime/openai-websocket`, `realtime/openai-server`, and `realtime/mock` subpaths. Its exported symbols,
36
+ normalized event names, configuration fields, and conversation/export shapes follow the same patch
37
+ compatibility rules as the rest of the package.
38
+
39
+ The realtime surface follows the 1.x compatibility rules for its normalized public API. Provider-specific
40
+ wire events returned by `openai-events`, values
41
+ under `raw`, SDP/ICE behavior, and upstream model or voice availability are controlled by the provider
42
+ and are not normalized compatibility guarantees. New normalized event variants or optional metrics may
43
+ be added in a minor release. Incompatible normalized API changes require a major release unless an urgent
44
+ security fix makes preserving the old behavior unsafe.
45
+
46
+ Platform interfaces for WebRTC and WebSocket are structural so applications can inject browser, server,
47
+ mobile, or test adapters without a framework dependency. A documented structural member is public;
48
+ private transport internals and unexported protocol helpers are not.
49
+
50
+ `VoiceSession` and `RealtimeSession` are independent public APIs. `VoiceSession` remains a batch,
51
+ turn-oriented transcription/completion/speech workflow. `RealtimeSession` owns a persistent transport,
52
+ live events, interruption, and normalized realtime conversation state. Neither is a compatibility alias
53
+ for the other.
54
+
55
+ ## Image API stage
56
+
57
+ The `nexus-ai-pro/images` family is experimental in production-readiness, but published normalized
58
+ types, manager methods, operation events, and explicit subpath exports still follow the 1.x semantic
59
+ versioning rules. The experimental label does not permit an incompatible minor or patch release.
60
+
61
+ Provider payloads under `raw`, provider-specific error metadata, temporary delivery URLs, upstream model
62
+ availability, and generative output are not normalized compatibility guarantees. The current local
63
+ operation handle is process-bound and does not promise durable recovery, distributed cancellation, or
64
+ exactly-once provider execution. Those capabilities will use additive adapters and contracts when added.
65
+ `MemoryAssetStore` is likewise process-local and does not promise cross-process durability or shared
66
+ tenant state.
67
+
28
68
  ## Deprecation process
29
69
 
30
- Deprecated APIs are marked with `@deprecated` in declarations and described in the changelog. During the 0.x series, removal will not normally occur earlier than the next minor release. After 1.0, removals will be reserved for major releases, except when an urgent security issue requires otherwise.
70
+ Deprecated APIs are marked with `@deprecated` in declarations and described in the changelog. Removals
71
+ are reserved for major releases, except when an urgent security issue requires otherwise.
31
72
 
32
73
  Report accidental compatibility regressions through the project issue tracker. Security issues should follow [SECURITY.md](./SECURITY.md).
package/CHANGELOG.md CHANGED
@@ -1,9 +1,51 @@
1
1
  # Changelog
2
2
 
3
- Notable changes to this project are recorded here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and releases use semantic versioning while accounting for the pre-1.0 stability policy.
3
+ Notable changes to this project are recorded here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and releases use semantic versioning.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ### Added
8
+
9
+ - An experimental provider-neutral image operation family with portable asset locations,
10
+ `ImageManager`, generation/editing, strict capability negotiation, runtime provider registration,
11
+ visual-safety hooks, and cancellable local operation handles.
12
+ - Opt-in `images`, `images/assets`, `images/mock`, and `images/openai` subpaths with a deterministic
13
+ mock provider and an OpenAI Image API adapter for one-shot generation and reference-based editing.
14
+ - An image-provider conformance harness covering normalized assets, metadata, generation, editing, and
15
+ pre-aborted calls.
16
+ - A bounded tenant-isolated `MemoryAssetStore` with retention, defensive byte copies, computed SHA-256
17
+ checksums, capacity enforcement, and optional HTTP(S) signing.
18
+
19
+ ### Changed
20
+
21
+ - Reconciled the changelog and API stability policy with the tagged 1.0.0 release.
22
+
23
+ ## [1.0.0] - 2026-07-17
24
+
25
+ ### Added
26
+
27
+ - An opt-in realtime package family with `realtime`, `realtime/session`, `realtime/tools`,
28
+ `realtime/conversation`, provider transport, server-helper, and deterministic mock subpaths. Realtime
29
+ code is not added to the root or batch voice import graph.
30
+ - Framework-independent OpenAI WebRTC and WebSocket transports with injectable platform interfaces,
31
+ secure server-owned WebRTC negotiation, microphone and remote-audio handling, cancellation, and
32
+ reconnect support.
33
+ - A persistent `RealtimeSession` and higher-level `createRealtimeAgent()` API with normalized and raw
34
+ events, barge-in, response cancellation, unheard-audio truncation, typed tools, confirmations,
35
+ idempotency keys, bounded execution, and transcript/usage state.
36
+ - Immutable normalized conversations with JSON, OpenAI-event, text, and analytics exports, plus
37
+ connection, first-audio, turn, tool, interruption, reconnect, token, audio-duration, and cost metrics.
38
+ - Realtime security controls for tool allowlists, transcript retention, PII hooks, and maximum session
39
+ and audio duration, with structural OpenTelemetry-compatible tracing and metrics hooks.
40
+ - Opt-in safe-tool result caching, active-connection/audio-duration metrics, and an application-owned
41
+ realtime cost estimator hook without bundled pricing tables.
42
+ - A network-free realtime scheduling example using the deterministic mock transport.
43
+
44
+ ### Changed
45
+
46
+ - Realtime connections are documented as a separate opt-in operation family. Existing `VoiceSession`
47
+ behavior remains the batch transcription -> completion/tools -> speech workflow.
48
+
7
49
  ## [0.9.0] - 2026-07-15
8
50
 
9
51
  ### Added
@@ -31,5 +73,6 @@ Notable changes to this project are recorded here. The format follows [Keep a Ch
31
73
  - URL fetching rejects unsafe private-network targets and limits response reads.
32
74
  - CLI and audit findings no longer disclose detected secret values.
33
75
 
34
- [Unreleased]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v0.9.0...HEAD
76
+ [Unreleased]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v1.0.0...HEAD
77
+ [1.0.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/releases/tag/v1.0.0
35
78
  [0.9.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/releases/tag/v0.9.0
package/README.md CHANGED
@@ -7,7 +7,7 @@ Use the whole pipeline for production AI features, or turn pieces off when you o
7
7
  - NPM: https://www.npmjs.com/package/nexus-ai-pro
8
8
  - GitHub: https://github.com/mkhitar-abrahamyan/nexus-ai
9
9
  - Full technical notes and manual test cases: [NEXUS.md](./NEXUS.md)
10
- - Planned image generation and infrastructure work: [ROADMAP.md](./ROADMAP.md)
10
+ - Image generation status and remaining infrastructure work: [ROADMAP.md](./ROADMAP.md)
11
11
 
12
12
  ## Install
13
13
 
@@ -16,6 +16,8 @@ npm install nexus-ai-pro
16
16
  ```
17
17
 
18
18
  Requires Node.js 22 or newer. `nexus-ai-pro` is ESM-only: use `import` from an ES module rather than CommonJS `require()`.
19
+ The main Nexus pipeline is Node-oriented; the isolated realtime subpaths use portable structural
20
+ interfaces and can be bundled for modern browsers.
19
21
 
20
22
  Install only the provider SDKs your app uses. The OpenAI SDK also powers OpenAI-compatible adapters such as OpenRouter, Groq, Mistral, DeepSeek, Azure OpenAI, LM Studio, and llama.cpp.
21
23
 
@@ -24,6 +26,8 @@ npm install openai @anthropic-ai/sdk ollama
24
26
  ```
25
27
 
26
28
  The Google Gemini provider uses Node.js `fetch`, so it does not need an extra SDK.
29
+ Realtime transports use injected or platform WebRTC, WebSocket, and `fetch` interfaces and do not
30
+ require the OpenAI SDK.
27
31
 
28
32
  ## Quick Start
29
33
 
@@ -77,6 +81,7 @@ You can still pass a plain `NexusAIConfig` to `new NexusAI(...)` when you want f
77
81
  - estimate tokens and cost before provider calls
78
82
  - cache exact or semantically similar prompts
79
83
  - add tools, agents, RAG context, evals, batch jobs, and queues
84
+ - build persistent realtime voice agents with interruption, live tools, and normalized conversation state
80
85
  - keep TypeScript types around every request and response
81
86
 
82
87
  ## CLI
@@ -302,6 +307,63 @@ const response = await ai.completeVerified(
302
307
  );
303
308
  ```
304
309
 
310
+ ## Image Generation and Editing (Experimental)
311
+
312
+ Image operations use a separate provider-neutral manager because generated assets have different
313
+ capabilities, delivery modes, safety checks, and lifecycles from text completions.
314
+
315
+ ```ts
316
+ import { NexusAI } from 'nexus-ai-pro';
317
+ import { OpenAIImageProvider } from 'nexus-ai-pro/images/openai';
318
+
319
+ const openaiImages = new OpenAIImageProvider({
320
+ apiKey: process.env.OPENAI_API_KEY!,
321
+ });
322
+
323
+ const mediaAi = new NexusAI({
324
+ providers: {},
325
+ images: {
326
+ defaultProvider: 'openai',
327
+ providers: { openai: openaiImages },
328
+ },
329
+ });
330
+
331
+ const image = await mediaAi.images.generate({
332
+ model: 'auto',
333
+ prompt: 'A clean product photograph of a red mechanical keyboard',
334
+ dimensions: { width: 1536, height: 1024 },
335
+ quality: 'high',
336
+ delivery: { kind: 'bytes', format: 'png' },
337
+ });
338
+
339
+ console.log(image.assets[0]?.location);
340
+ ```
341
+
342
+ `ImageProvider` is independent from completion providers. Explicit options are negotiated against the
343
+ selected provider's declared capabilities, so unsupported formats, delivery kinds, masks, seeds, or
344
+ dimensions fail before a provider call. The OpenAI adapter supports one-shot generation and
345
+ reference-based editing through byte assets. Masked OpenAI edits remain disabled until a transformer can
346
+ verify dimensions and convert the neutral mask contract to OpenAI's alpha-channel semantics.
347
+
348
+ Use `submit()` for a cancellable local operation handle with replayable lifecycle events:
349
+
350
+ ```ts
351
+ const operation = mediaAi.images.submit('generate', {
352
+ prompt: 'A minimal blue geometric poster',
353
+ delivery: { kind: 'bytes', format: 'png' },
354
+ });
355
+
356
+ for await (const event of operation.events()) {
357
+ console.log(event.type);
358
+ }
359
+ ```
360
+
361
+ For deterministic tests, register `MockImageProvider` from `nexus-ai-pro/images/mock`. The current
362
+ `submit()` handle is in-process; durable leases, recovery, distributed deduplication, and webhooks remain
363
+ future infrastructure work. `nexus-ai-pro/images/assets` includes a bounded, tenant-isolated
364
+ `MemoryAssetStore` for local development and single-process workloads; it computes SHA-256 checksums,
365
+ copies bytes at its boundaries, enforces retention and capacity, and never silently evicts live assets.
366
+
305
367
  ## Voice Integrations
306
368
 
307
369
  Voice support is optional and split into small imports.
@@ -469,7 +531,210 @@ ai.registerVoiceProvider('private-voice', {
469
531
  });
470
532
  ```
471
533
 
472
- Low-level realtime transport adapters are still future work; the current voice layer covers transcription, speech generation, full request/response voice turns, and stateful voice sessions with tool calls.
534
+ `VoiceSession` remains the batch-oriented path: each turn is transcription -> completion/tools -> optional
535
+ speech. For a persistent connection with live microphone audio, streamed remote audio, barge-in, and
536
+ provider events, use the separate realtime entry points below. Neither API replaces the other.
537
+
538
+ ## Realtime Voice Agents
539
+
540
+ Realtime is opt-in and is not re-exported from the package root or from `nexus-ai-pro/voice`:
541
+
542
+ ```ts
543
+ import {
544
+ createRealtimeAgent,
545
+ defineTool,
546
+ OpenAIRealtimeProvider,
547
+ } from 'nexus-ai-pro/realtime';
548
+ ```
549
+
550
+ The framework-independent session normalizes connection, speech, transcript, response, tool,
551
+ interruption, error, conversation, and metrics events while retaining provider events when configured.
552
+ The browser and server transports use structural platform interfaces, so the realtime core does not
553
+ require React, a DOM shim, or an OpenAI SDK.
554
+
555
+ ### Browser WebRTC
556
+
557
+ Give the browser a same-origin `sessionEndpoint`; never put a permanent provider API key in browser
558
+ code. The endpoint receives the SDP offer and returns the SDP answer while your server owns the
559
+ provider key and authoritative session configuration.
560
+
561
+ ```ts
562
+ type BookingInput = { startTime: string; endTime: string; timezone: string };
563
+
564
+ const createBooking = defineTool({
565
+ name: 'create_calendar_booking',
566
+ description: 'Create a calendar booking after the user confirms it.',
567
+ parameters: {
568
+ type: 'object',
569
+ properties: {
570
+ startTime: { type: 'string', format: 'date-time' },
571
+ endTime: { type: 'string', format: 'date-time' },
572
+ timezone: { type: 'string' },
573
+ },
574
+ required: ['startTime', 'endTime', 'timezone'],
575
+ additionalProperties: false,
576
+ },
577
+ requiresConfirmation: true,
578
+ execute: async (input: BookingInput, context) =>
579
+ calendar.create(input, { idempotencyKey: context.idempotencyKey, signal: context.signal }),
580
+ });
581
+
582
+ const provider = new OpenAIRealtimeProvider({
583
+ sessionEndpoint: '/api/realtime/session',
584
+ });
585
+
586
+ const agent = createRealtimeAgent({
587
+ provider,
588
+ model: 'gpt-realtime',
589
+ modalities: ['audio', 'text'],
590
+ instructions: 'Check availability before booking. Never write without confirmation.',
591
+ tools: [createBooking],
592
+ voice: {
593
+ transport: 'webrtc',
594
+ voice: 'alloy',
595
+ turnDetection: { type: 'server_vad', silenceDurationMs: 450 },
596
+ interruption: {
597
+ enabled: true,
598
+ cancelResponse: true,
599
+ truncateUnheardAudio: true,
600
+ },
601
+ },
602
+ toolExecution: { mode: 'automatic', timeoutMs: 8_000, maxParallelCalls: 3 },
603
+ reconnect: { enabled: true, maxAttempts: 3, initialDelayMs: 500 },
604
+ conversation: { captureTranscripts: true, captureToolCalls: true, maxRawEvents: 2_000 },
605
+ security: {
606
+ maxSessionDurationMs: 30 * 60_000,
607
+ maxAudioDurationMs: 20 * 60_000,
608
+ toolAllowlist: ['create_calendar_booking'],
609
+ },
610
+ telemetry: {
611
+ includeTranscripts: false,
612
+ estimateCost: (usage) => pricing.estimateRealtime(usage),
613
+ },
614
+ });
615
+
616
+ agent.on('tool.confirmation.required', ({ call }) => {
617
+ const approved = window.confirm(`Create booking requested by ${call.name}?`);
618
+ agent.confirmTool(call.callId, approved);
619
+ });
620
+
621
+ agent.on('metrics', (metrics) => {
622
+ console.log('speech end -> first audio', metrics.speechEndToFirstAudioMs);
623
+ });
624
+
625
+ const audioElement = document.querySelector<HTMLAudioElement>('#assistant-audio')!;
626
+ await agent.connect({ microphone: true, audioElement });
627
+ ```
628
+
629
+ WebRTC attaches the selected microphone track directly to the peer connection and assigns the remote
630
+ media stream to `audioElement`. Browsers still require HTTPS (or localhost), user permission, and often
631
+ a user gesture before audio playback. `sendAudio()` is intended for transports that accept binary
632
+ chunks; normal WebRTC microphone use should stay on the media track.
633
+
634
+ WebRTC first-audio timing uses the provider's `output_audio_buffer.started` event. WebSocket playback
635
+ remains application-owned, so its player must call `markAudioPlayed()` as described below.
636
+
637
+ A minimal server endpoint can use the focused server helper:
638
+
639
+ ```ts
640
+ import { createOpenAIRealtimeCall } from 'nexus-ai-pro/realtime/openai-server';
641
+
642
+ export async function POST(request: Request) {
643
+ const answerSdp = await createOpenAIRealtimeCall(await request.text(), {
644
+ apiKey: process.env.OPENAI_API_KEY!,
645
+ model: 'gpt-realtime',
646
+ session: {
647
+ instructions: 'You are a concise scheduling assistant.',
648
+ max_output_tokens: 1_024,
649
+ },
650
+ }, request.signal);
651
+
652
+ return new Response(answerSdp, { headers: { 'content-type': 'application/sdp' } });
653
+ }
654
+ ```
655
+
656
+ Authenticate that endpoint, authorize the tenant and requested tools, apply origin/CSRF and rate-limit
657
+ controls, and keep its accepted session options allowlisted. The client must not choose arbitrary tools,
658
+ instructions, limits, or credentials.
659
+
660
+ ### Server WebSocket
661
+
662
+ Server-to-server agents can inject their WebSocket implementation and keep provider authorization in
663
+ request headers. The package deliberately does not force a WebSocket dependency:
664
+
665
+ ```ts
666
+ import {
667
+ OpenAIWebSocketTransport,
668
+ type OpenAIWebSocketFactory,
669
+ } from 'nexus-ai-pro/realtime/openai-websocket';
670
+ import { createRealtimeSession } from 'nexus-ai-pro/realtime/session';
671
+
672
+ const webSocketFactory: OpenAIWebSocketFactory = (url, { headers, protocols }) =>
673
+ serverWebSocketClient.connect(url, { headers, protocols });
674
+
675
+ const session = createRealtimeSession({
676
+ provider: 'openai',
677
+ model: 'gpt-realtime',
678
+ transport: new OpenAIWebSocketTransport({
679
+ apiKey: process.env.OPENAI_API_KEY!,
680
+ webSocketFactory,
681
+ }),
682
+ modalities: ['audio', 'text'],
683
+ reconnect: { enabled: true, maxAttempts: 3 },
684
+ connection: {
685
+ remoteAudioSink: (audio) => audioPlayer.enqueue(audio.data),
686
+ },
687
+ });
688
+
689
+ await session.connect();
690
+ ```
691
+
692
+ When an application plays WebSocket audio itself, call `session.markAudioPlayed()` when the first bytes
693
+ actually reach playback. That makes the primary latency metric—user speech ended to first assistant
694
+ audio played—represent user experience rather than network receipt.
695
+
696
+ The global browser WebSocket path accepts only an ephemeral token. Supplying a permanent API key to a
697
+ browser adapter is rejected; use an injected server factory or an ephemeral-token provider instead.
698
+
699
+ ### Interruption, tools, state, and exports
700
+
701
+ With interruption enabled, a `speech.started` event can stop local playback, cancel the active response,
702
+ and, for WebSocket playback with a known position, truncate unheard assistant audio. Applications can
703
+ also call `session.interrupt('manual')`.
704
+
705
+ Realtime tools support structural `parse`, `safeParse`, or `validate` schemas, execution timeouts,
706
+ bounded parallelism, safe-tool retries, duplicate call suppression, idempotency keys, allowlists, and
707
+ write confirmation. A tool marked `safe: true` can also opt into cross-call caching with `cache: true`
708
+ or `{ ttlMs, key }` when `toolExecution.cache` supplies a structural cache adapter; cache failures are
709
+ ignored unless `cacheFailureMode: 'fail'` is configured. `requiresConfirmation` does not replace server
710
+ authorization: re-check identity, permissions, business invariants, and idempotency in the tool
711
+ implementation.
712
+
713
+ Session state is available as immutable snapshots and four export formats:
714
+
715
+ ```ts
716
+ const json = session.export('json');
717
+ const providerEvents = session.export('openai-events');
718
+ const transcript = session.export('text');
719
+ const analytics = session.export('analytics');
720
+
721
+ session.on('conversation.updated', (snapshot) => conversationStore.save(snapshot));
722
+ session.on('error', (error) => telemetry.recordException(error));
723
+ ```
724
+
725
+ `json` contains normalized user/assistant speech, text messages, tool calls/results, interruptions,
726
+ errors, and latency/usage metrics. `openai-events` returns retained raw provider events; it is useful for
727
+ diagnostics and replay but follows the upstream provider schema. Disable transcript/raw-event retention
728
+ for sensitive workloads. `piiHook` redacts normalized conversation/event text, but deliberately does not
729
+ rewrite raw provider exports. Telemetry transcript fields are redacted by default; `includeTranscripts`
730
+ must be explicitly enabled. `estimateCost` accepts an application-owned pricing callback so model price
731
+ changes are not hard-coded into the package. The built-in limits and telemetry hooks are local controls,
732
+ not a durable session store, distributed rate limiter, or authorization system.
733
+
734
+ Focused public imports are available for `realtime`, `realtime/session`, `realtime/tools`,
735
+ `realtime/conversation`, `realtime/openai-webrtc`, `realtime/openai-websocket`,
736
+ `realtime/openai-server`, and `realtime/mock`. The deterministic mock is suitable for tests and demos;
737
+ see [`examples/realtime-scheduling.ts`](./examples/realtime-scheduling.ts).
473
738
 
474
739
  ## Phone Number Telephony
475
740
 
@@ -598,6 +863,7 @@ Available runtime helpers:
598
863
  - Redis and BullMQ queue adapters
599
864
  - eval runner with quality, operations, RAG, safety metrics, and optional LLM-as-judge scoring
600
865
  - voice sessions for multi-turn calls with conditional task prompts and app tools
866
+ - realtime sessions with WebRTC/WebSocket transports, interruption, tools, metrics, and conversation exports
601
867
  - workflow templates for RAG answers, extraction, classification, comparison, support, sales, legal review, and code review
602
868
 
603
869
  Use a plain assertion for small evals, or add an LLM judge when a rubric is more useful than exact matching:
@@ -683,6 +949,12 @@ import { ContextWindowManager } from 'nexus-ai-pro/context';
683
949
  import { guardrailPolicy } from 'nexus-ai-pro/security';
684
950
  import { RedisCacheAdapter } from 'nexus-ai-pro/cache';
685
951
  import { DeepSeekProvider } from 'nexus-ai-pro/providers/deepseek';
952
+ import { ImageManager } from 'nexus-ai-pro/images';
953
+ import { MemoryAssetStore } from 'nexus-ai-pro/images/assets';
954
+ import { MockImageProvider } from 'nexus-ai-pro/images/mock';
955
+ import { OpenAIImageProvider } from 'nexus-ai-pro/images/openai';
956
+ import { createRealtimeSession } from 'nexus-ai-pro/realtime/session';
957
+ import { OpenAIWebRTCTransport } from 'nexus-ai-pro/realtime/openai-webrtc';
686
958
  ```
687
959
 
688
960
  Provider SDKs are optional peer dependencies. The package is ESM-only, supports Node.js 22+, and is marked with `sideEffects: false`. Only the entry points listed in the package export map are public; deep imports into `dist` or `src` are unsupported.
@@ -699,6 +971,8 @@ npm run example:basic
699
971
  npm run example:security
700
972
  npm run example:optimizer
701
973
  npm run example:agent
974
+ npm run build && npx tsx examples/realtime-scheduling.ts
975
+ npx tsc -p tsconfig.examples.browser.json
702
976
  ```
703
977
 
704
978
  Repository example files cover:
@@ -710,6 +984,7 @@ Repository example files cover:
710
984
  - classifier calibration
711
985
  - domain workflows
712
986
  - custom providers
987
+ - deterministic realtime scheduling with tools, confirmation, metrics, and conversation exports
713
988
  - import examples under `examples/exports`
714
989
 
715
990
  ## Test Commands
@@ -732,10 +1007,10 @@ npm run test:conformance:real
732
1007
 
733
1008
  ## Roadmap
734
1009
 
735
- The next recommended feature family is first-class image generation and editing through a
736
- provider-neutral `ImageManager`, portable asset types, durable operation handles, visual safety,
737
- asset storage, and media-specific evaluations. The design and prioritized infrastructure backlog
738
- are in [ROADMAP.md](./ROADMAP.md).
1010
+ The experimental image foundation now includes portable asset types, `ImageManager`, provider
1011
+ capability negotiation, local operation handles, visual-safety hooks, deterministic conformance, and an
1012
+ opt-in OpenAI adapter. Durable operations, production asset storage, additional providers, and
1013
+ media-specific evaluations remain planned in [ROADMAP.md](./ROADMAP.md).
739
1014
 
740
1015
  ## Production Notes
741
1016
 
package/ROADMAP.md CHANGED
@@ -3,7 +3,56 @@
3
3
  This roadmap is a design proposal, not a compatibility promise. Stable and experimental
4
4
  surfaces are defined in [API_STABILITY.md](./API_STABILITY.md).
5
5
 
6
- ## Recommended next release: first-class image generation
6
+ ## Delivered in the current development line: realtime voice foundation
7
+
8
+ The first native realtime milestone is implemented as an opt-in package family rather than as another
9
+ `complete()` mode or an eager dependency of `NexusAI`:
10
+
11
+ - persistent provider-neutral `RealtimeSession` and higher-level `createRealtimeAgent()` APIs;
12
+ - OpenAI WebRTC for browser microphone/remote-media connections and WebSocket for server agents;
13
+ - structural, injectable browser/server interfaces plus a deterministic mock transport;
14
+ - normalized speech, transcript, text, response, tool, interruption, error, conversation, metrics, and
15
+ retained raw-provider events;
16
+ - barge-in, response cancellation, optional unheard-audio truncation, reconnect backoff, and cancellation;
17
+ - typed/validated tools with automatic or manual execution, confirmation, timeouts, bounded parallelism,
18
+ safe retries, opt-in read caching, duplicate suppression, allowlists, and idempotency keys;
19
+ - normalized JSON conversation state and OpenAI-event, text, and analytics exports;
20
+ - server-owned SDP/client-secret helpers, retention controls, PII hooks, session/audio limits, and
21
+ OpenTelemetry-compatible hooks.
22
+
23
+ Current limitations are intentional and should remain visible:
24
+
25
+ - OpenAI is the only native realtime provider; provider-neutral contracts have not yet been validated
26
+ against a second wire protocol.
27
+ - The package supplies framework-independent transports, not React hooks, UI/audio-player components,
28
+ mobile SDK wrappers, SIP, or a telephone gateway.
29
+ - WebRTC requires application-owned HTTPS session negotiation and browser permission/autoplay handling.
30
+ WebSocket consumers are responsible for audio capture/playback and for injecting a server socket
31
+ implementation when authenticated headers are required.
32
+ - Conversation snapshots and exports are in memory. Durable storage, distributed deduplication,
33
+ cross-process session recovery, and provider-state replay remain application responsibilities.
34
+ - Compatibility/load validation across Safari, iOS Safari, Firefox, Android Chrome, long conversations,
35
+ and large concurrent session counts is still required before making broad production-scale claims.
36
+ - Realtime video tracks, SIP transports, durable cost accounting beyond the configurable local estimate,
37
+ and a published latency benchmark methodology remain follow-on work.
38
+
39
+ ## Current next-release work: first-class image generation
40
+
41
+ The experimental foundation is now implemented in the current development line:
42
+
43
+ - portable byte, URL, and stored asset locations plus image request/result, usage, safety, provenance,
44
+ provider-call context, and operation-handle types;
45
+ - a provider-neutral `ImageManager` with generation, editing, provider registration, strict capability
46
+ negotiation, visual-safety hooks, and cancellable in-process submissions;
47
+ - a deterministic network-free mock and a parallel image-provider conformance harness;
48
+ - an opt-in OpenAI Image API adapter for one-shot generation and reference-based editing;
49
+ - a bounded tenant-aware in-memory asset store with retention, defensive byte copies, computed SHA-256
50
+ checksums, capacity rejection, and optional signed-URL integration.
51
+
52
+ This surface remains experimental. OpenAI masks are intentionally disabled until a transformer can
53
+ verify dimensions and convert neutral mask polarity into provider alpha semantics. Durable operations,
54
+ filesystem/S3-compatible asset stores, a second cloud provider, ComfyUI, and media evaluation are still
55
+ required before promotion.
7
56
 
8
57
  Image generation should be a separate operation family rather than another variation of
9
58
  `complete()`. Text completions and generated assets have different request shapes, response
@@ -164,7 +213,8 @@ code should only perform the provider call and normalize its result.
164
213
 
165
214
  1. True mixed text/asset outputs and tool results that pass asset references without base64 JSON.
166
215
  2. OCR, captioning, visual question answering, image embeddings, and visual moderation.
167
- 3. Realtime voice/video sessions with interruption handling, turn detection, and live tool calls.
216
+ 3. Realtime follow-ons: a second provider, SIP/video transports, durable recovery, browser compatibility
217
+ automation, and published latency/load benchmarks. The native voice foundation is delivered above.
168
218
  4. Video generation through the same asynchronous operation, job, and asset contracts.
169
219
  5. Media search and RAG using image embeddings.
170
220
  6. MCP client/server adapters with asset and tool interoperability.
@@ -185,4 +235,3 @@ code should only perform the provider call and normalize its result.
185
235
  6. Add true multimodal outputs and media evaluation.
186
236
  7. Promote the media API only after packed-package tests, provider conformance, and image evals
187
237
  cover the supported capability matrix.
188
-
package/SECURITY.md CHANGED
@@ -13,3 +13,34 @@ Include the affected version, impact, a minimal reproduction, and any suggested
13
13
  ## Scope and safe operation
14
14
 
15
15
  Nexus guardrails reduce common AI application risks, but they are not a complete authorization or security boundary. Applications remain responsible for access control, provider-side safety controls, tool authorization, network egress policy, secret storage, and review of high-impact model actions.
16
+
17
+ ## Realtime voice security
18
+
19
+ - Never ship a permanent provider API key to a browser or mobile client. For WebRTC, configure a
20
+ same-origin `sessionEndpoint` that performs provider negotiation or returns a short-lived client
21
+ secret. For WebSocket API-key authentication, run the transport on a trusted server and inject a
22
+ WebSocket factory that can set authorization headers.
23
+ - Authenticate and authorize the session endpoint before contacting the provider. Restrict origins,
24
+ apply CSRF and rate-limit controls, cap request size and duration, and derive the model, tools,
25
+ instructions, retention, and safety settings from trusted server policy rather than client input.
26
+ - Treat microphone permission, remote audio, provider data-channel events, transcripts, and raw events
27
+ as sensitive data. Request microphone access only after a user action, stop owned tracks on cleanup,
28
+ minimize retention, and avoid putting transcripts or audio in logs and telemetry by default.
29
+ - Use `security.maxSessionDurationMs`, `security.maxAudioDurationMs`, `security.toolAllowlist`,
30
+ `security.retainTranscripts`, `security.piiHook`, and bounded raw-event retention as defense-in-depth.
31
+ These process-local controls do not replace tenant quotas, durable retention enforcement, or a DLP
32
+ system.
33
+ - A realtime tool confirmation is a user-experience checkpoint, not authorization. Every read and write
34
+ tool must enforce tenant access and validate arguments server-side. Writes should require explicit
35
+ confirmation, use the supplied idempotency key, and remain safe under retries and duplicate provider
36
+ events.
37
+ - Redact API keys, ephemeral tokens, SDP diagnostics, tool arguments/results, and PII from errors and
38
+ telemetry. Realtime telemetry transcript fields are redacted by default; set
39
+ `telemetry.includeTranscripts: true` only when the destination and retention policy are explicitly
40
+ approved. `piiHook` applies to normalized events and conversation state, not retained raw events.
41
+ - Reconnects can repeat provider events or tool requests and do not guarantee restoration of remote
42
+ conversation state. Keep write tools idempotent, deduplicate by call ID/idempotency key, and surface
43
+ recovery failures to the user.
44
+ - Browser WebRTC still requires a backend security boundary. A direct media path reduces latency; it
45
+ does not remove the need for server-owned credentials, session policy, tool authorization, abuse
46
+ monitoring, and provider-side safety controls.
@@ -1,6 +1,7 @@
1
1
  import { NexusAI } from './nexus.js';
2
2
  import type { AnthropicProviderConfig, AuditLogConfig, AzureOpenAIProviderConfig, CacheConfig, CohereProviderConfig, CostBudgetConfig, CustomProviderConfig, DeepSeekProviderConfig, GoogleProviderConfig, GroqProviderConfig, LMStudioProviderConfig, LlamaCppProviderConfig, LoggerConfig, MistralProviderConfig, NexusAIConfig, OllamaProviderConfig, OpenAIProviderConfig, OpenRouterProviderConfig, ProvidersConfig, RateLimitConfig, ResponseFormatConfig, RetryConfig, RoutingConfig, RoutingStrategy } from '../types/config.js';
3
3
  import type { ContextWindowConfig } from '../types/context-window.js';
4
+ import type { ImageConfig } from '../types/images.js';
4
5
  import type { SecurityConfig, SecurityLevel } from '../types/security.js';
5
6
  import type { TokenOptimizerConfig } from '../types/optimizer.js';
6
7
  import type { PipelineConfig } from '../pipeline/types.js';
@@ -53,6 +54,8 @@ export declare class NexusConfigBuilder {
53
54
  security(config: SecurityLevel | SecurityConfig): this;
54
55
  /** Sets context-window compaction behavior. */
55
56
  contextWindow(config: ContextWindowConfig): this;
57
+ /** Sets image-provider defaults and registrations. */
58
+ images(config: ImageConfig): this;
56
59
  /** Sets token optimization behavior. */
57
60
  tokenOptimizer(config: TokenOptimizerConfig): this;
58
61
  /** Sets exact, semantic, or hybrid cache behavior. */
@@ -98,6 +98,11 @@ export class NexusConfigBuilder {
98
98
  this.config.contextWindow = config;
99
99
  return this;
100
100
  }
101
+ /** Sets image-provider defaults and registrations. */
102
+ images(config) {
103
+ this.config.images = config;
104
+ return this;
105
+ }
101
106
  /** Sets token optimization behavior. */
102
107
  tokenOptimizer(config) {
103
108
  this.config.tokenOptimizer = config;