nexus-ai-pro 0.6.0 → 0.8.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/EXPLANATION.md +52 -7
- package/NEXUS.md +44 -3
- package/README.md +222 -29
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +418 -0
- package/dist/core/config-builder.d.ts +94 -0
- package/dist/core/config-builder.js +192 -0
- package/dist/core/create-nexus.d.ts +33 -0
- package/dist/core/create-nexus.js +180 -0
- package/dist/core/nexus.d.ts +107 -1
- package/dist/core/nexus.js +160 -1
- package/dist/evals/index.d.ts +3 -0
- package/dist/evals/index.js +3 -0
- package/dist/evals/judge.d.ts +50 -0
- package/dist/evals/judge.js +154 -0
- package/dist/evals/runner.d.ts +13 -1
- package/dist/evals/runner.js +18 -1
- package/dist/index.d.ts +13 -4
- package/dist/index.js +9 -1
- package/dist/providers/anthropic.d.ts +2 -0
- package/dist/providers/anthropic.js +33 -12
- package/dist/providers/azure-openai.d.ts +8 -0
- package/dist/providers/azure-openai.js +26 -0
- package/dist/providers/deepseek.d.ts +8 -0
- package/dist/providers/deepseek.js +14 -0
- package/dist/providers/llamacpp.d.ts +8 -0
- package/dist/providers/llamacpp.js +15 -0
- package/dist/providers/lmstudio.d.ts +8 -0
- package/dist/providers/lmstudio.js +15 -0
- package/dist/providers/openai.d.ts +2 -0
- package/dist/providers/openai.js +37 -14
- package/dist/router/auto-router.js +24 -6
- package/dist/security/schema-validator.d.ts +4 -4
- package/dist/telephony/errors.d.ts +8 -0
- package/dist/telephony/errors.js +16 -0
- package/dist/telephony/index.d.ts +4 -0
- package/dist/telephony/index.js +3 -0
- package/dist/telephony/manager.d.ts +18 -0
- package/dist/telephony/manager.js +78 -0
- package/dist/telephony/providers/twilio.d.ts +24 -0
- package/dist/telephony/providers/twilio.js +274 -0
- package/dist/telephony/twiml.d.ts +2 -0
- package/dist/telephony/twiml.js +87 -0
- package/dist/types/config.d.ts +65 -0
- package/dist/types/providers.js +17 -1
- package/dist/types/telephony.d.ts +171 -0
- package/dist/types/telephony.js +1 -0
- package/dist/types/voice.d.ts +71 -1
- package/dist/utils/logger.d.ts +5 -1
- package/dist/utils/logger.js +54 -4
- package/dist/voice/index.d.ts +2 -1
- package/dist/voice/index.js +1 -0
- package/dist/voice/manager.d.ts +3 -1
- package/dist/voice/manager.js +4 -0
- package/dist/voice/session.d.ts +33 -0
- package/dist/voice/session.js +234 -0
- package/examples/cli-eval.json +16 -0
- package/examples/config-builder.ts +18 -0
- package/examples/create-nexus.ts +15 -0
- package/examples/custom-provider.ts +16 -0
- package/examples/exports/README.md +10 -0
- package/examples/exports/config.ts +18 -0
- package/examples/exports/providers.ts +33 -0
- package/examples/exports/root.ts +54 -0
- package/examples/exports/runtime-modules.ts +40 -0
- package/package.json +30 -4
package/EXPLANATION.md
CHANGED
|
@@ -17,15 +17,15 @@ Most AI apps begin with one provider call. Then the app grows:
|
|
|
17
17
|
- documents need RAG
|
|
18
18
|
- production needs metrics, retries, health checks, and test fixtures
|
|
19
19
|
|
|
20
|
-
`nexus-ai-pro` puts those pieces behind one main class: `NexusAI
|
|
20
|
+
`nexus-ai-pro` puts those pieces behind one main class: `NexusAI`, plus a small `createNexus()` helper for beginner setups.
|
|
21
21
|
|
|
22
22
|
You can use it lightly:
|
|
23
23
|
|
|
24
24
|
```ts
|
|
25
|
-
const ai =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
const ai = createNexus({
|
|
26
|
+
provider: 'openai',
|
|
27
|
+
apiKey: process.env.OPENAI_API_KEY!,
|
|
28
|
+
model: 'openai/fast',
|
|
29
29
|
security: 'off',
|
|
30
30
|
tokenOptimizer: { enabled: false },
|
|
31
31
|
});
|
|
@@ -91,9 +91,38 @@ Supported adapters:
|
|
|
91
91
|
- Groq
|
|
92
92
|
- Mistral
|
|
93
93
|
- Cohere
|
|
94
|
+
- DeepSeek
|
|
95
|
+
- Azure OpenAI
|
|
96
|
+
- LM Studio
|
|
97
|
+
- llama.cpp
|
|
98
|
+
- custom OpenAI- or Anthropic-compatible endpoints
|
|
94
99
|
|
|
95
100
|
Provider SDKs are optional peer dependencies. Install only the SDKs your app uses.
|
|
96
101
|
|
|
102
|
+
For typed setup without a large config object, use the builder:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
const ai = createNexusConfig()
|
|
106
|
+
.openai(process.env.OPENAI_API_KEY!)
|
|
107
|
+
.deepseek(process.env.DEEPSEEK_API_KEY!)
|
|
108
|
+
.auto('quality')
|
|
109
|
+
.security('standard')
|
|
110
|
+
.create();
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## CLI
|
|
114
|
+
|
|
115
|
+
The package also installs `nexus`:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
nexus scan src --json
|
|
119
|
+
nexus models --provider openai
|
|
120
|
+
nexus optimize prompt.txt --max-input-tokens 4000
|
|
121
|
+
nexus eval examples/cli-eval.json
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The CLI is intentionally small. It calls the same scanner, model registry, eval runner, and token optimizer that library users can import directly.
|
|
125
|
+
|
|
97
126
|
### Routing
|
|
98
127
|
|
|
99
128
|
Routing chooses a model and provider.
|
|
@@ -269,6 +298,7 @@ Evals:
|
|
|
269
298
|
- operational metrics
|
|
270
299
|
- RAG metrics
|
|
271
300
|
- safety heuristics
|
|
301
|
+
- optional LLM-as-judge scoring with rubrics and thresholds
|
|
272
302
|
|
|
273
303
|
## Voice Integrations
|
|
274
304
|
|
|
@@ -285,6 +315,7 @@ The basic operations are:
|
|
|
285
315
|
- `ai.transcribe(...)` for speech-to-text
|
|
286
316
|
- `ai.speak(...)` for text-to-speech
|
|
287
317
|
- `ai.voice(...)` for the full voice pipeline
|
|
318
|
+
- `ai.createVoiceSession(...)` for multi-turn call sessions with tools
|
|
288
319
|
- `registerVoiceProvider(...)` for private, local, or hosted services
|
|
289
320
|
|
|
290
321
|
The full voice turn is:
|
|
@@ -299,7 +330,17 @@ audio/transcript
|
|
|
299
330
|
|
|
300
331
|
Because the completion step calls `ai.complete(...)`, it reuses routing, security, context-window compaction, token optimization, cache, retries, metrics, and tracing.
|
|
301
332
|
|
|
302
|
-
|
|
333
|
+
`VoiceSession` adds state across caller turns. It accepts transcript or audio, builds prompts from any combination of `prompt`, `instructions`, and conditional `taskPrompts`, executes registered tools when the model requests app data, and can synthesize the final answer.
|
|
334
|
+
|
|
335
|
+
Low-level realtime transport is still future work. That should be added as a bridge from telephony/WebSocket/SIP media events into `VoiceSession` instead of forcing socket state into normal completion streams.
|
|
336
|
+
|
|
337
|
+
Phone-number telephony is a separate optional layer:
|
|
338
|
+
|
|
339
|
+
- `nexus-ai-pro/telephony` provides provider-neutral call, webhook, and media-stream types.
|
|
340
|
+
- `nexus-ai-pro/telephony/twilio` provides a Twilio adapter without adding the Twilio SDK as a required dependency.
|
|
341
|
+
- `NexusAI` exposes helper methods for outbound calls, TwiML webhook responses, webhook validation, and media event normalization.
|
|
342
|
+
|
|
343
|
+
This keeps a small transcription/TTS app small, while larger phone-agent apps can add Twilio or another carrier as needed.
|
|
303
344
|
|
|
304
345
|
## Choosing a Setup
|
|
305
346
|
|
|
@@ -351,12 +392,16 @@ const ai = new NexusAI({
|
|
|
351
392
|
retry: { enabled: true, maxRetries: 2 },
|
|
352
393
|
health: { enabled: true },
|
|
353
394
|
metrics: { enabled: true },
|
|
395
|
+
logger: { console: false, sink: (event) => console.log(JSON.stringify(event)) },
|
|
354
396
|
});
|
|
355
397
|
```
|
|
356
398
|
|
|
357
399
|
## Important Files
|
|
358
400
|
|
|
359
401
|
- `src/core/nexus.ts` - main runtime
|
|
402
|
+
- `src/core/create-nexus.ts` - beginner factory
|
|
403
|
+
- `src/core/config-builder.ts` - fluent typed config builder
|
|
404
|
+
- `src/cli.ts` - `nexus` command implementation
|
|
360
405
|
- `src/providers/*` - provider adapters
|
|
361
406
|
- `src/router/*` - routing and failover
|
|
362
407
|
- `src/security/*` - guardrails
|
|
@@ -373,7 +418,7 @@ const ai = new NexusAI({
|
|
|
373
418
|
|
|
374
419
|
## Known Limitations
|
|
375
420
|
|
|
376
|
-
- Voice
|
|
421
|
+
- Voice, telephony, local models, and custom providers are optional layers; apps should enable only the pieces they use.
|
|
377
422
|
- Audio/video preprocessing is limited.
|
|
378
423
|
- Provider modality support differs and may require preprocessing.
|
|
379
424
|
- Built-in model metadata is a routing convenience, not a pricing contract.
|
package/NEXUS.md
CHANGED
|
@@ -49,6 +49,8 @@ Core runtime:
|
|
|
49
49
|
- `ai.plan(...)`
|
|
50
50
|
- `ai.batchComplete(...)`
|
|
51
51
|
- `ai.createQueue(...)`
|
|
52
|
+
- `createNexus(...)`
|
|
53
|
+
- `createNexusConfig(...)`
|
|
52
54
|
|
|
53
55
|
Provider adapters:
|
|
54
56
|
|
|
@@ -60,7 +62,18 @@ Provider adapters:
|
|
|
60
62
|
- Groq
|
|
61
63
|
- Mistral
|
|
62
64
|
- Cohere
|
|
63
|
-
-
|
|
65
|
+
- DeepSeek
|
|
66
|
+
- Azure OpenAI
|
|
67
|
+
- LM Studio
|
|
68
|
+
- llama.cpp
|
|
69
|
+
- custom providers through `providers.custom` or `registerProvider(...)`
|
|
70
|
+
|
|
71
|
+
CLI:
|
|
72
|
+
|
|
73
|
+
- `nexus scan`
|
|
74
|
+
- `nexus models`
|
|
75
|
+
- `nexus eval`
|
|
76
|
+
- `nexus optimize`
|
|
64
77
|
|
|
65
78
|
Pipeline layers:
|
|
66
79
|
|
|
@@ -74,6 +87,7 @@ Pipeline layers:
|
|
|
74
87
|
- metrics and provider health
|
|
75
88
|
- audit logs and rate limits
|
|
76
89
|
- pipeline hooks and custom steps
|
|
90
|
+
- structured logger hooks
|
|
77
91
|
|
|
78
92
|
Supporting modules:
|
|
79
93
|
|
|
@@ -83,6 +97,7 @@ Supporting modules:
|
|
|
83
97
|
- Chain of Verification
|
|
84
98
|
- self-consistency sampling
|
|
85
99
|
- eval runner and metrics
|
|
100
|
+
- optional LLM-as-judge eval scoring
|
|
86
101
|
- workflow templates
|
|
87
102
|
- web/search connector tools
|
|
88
103
|
- provider conformance fixtures
|
|
@@ -95,6 +110,8 @@ Voice is implemented as an optional layer. Import size is controlled through sub
|
|
|
95
110
|
|
|
96
111
|
- `nexus-ai-pro/voice` for provider-neutral types, errors, and `VoiceManager`
|
|
97
112
|
- `nexus-ai-pro/voice/openai` for the OpenAI voice adapter
|
|
113
|
+
- `nexus-ai-pro/telephony` for provider-neutral phone-call types and `TelephonyManager`
|
|
114
|
+
- `nexus-ai-pro/telephony/twilio` for the Twilio phone-number adapter
|
|
98
115
|
|
|
99
116
|
Current support:
|
|
100
117
|
|
|
@@ -102,21 +119,30 @@ Current support:
|
|
|
102
119
|
- `ai.speak(...)`
|
|
103
120
|
- `ai.voice(...)`
|
|
104
121
|
- `ai.voiceTurn(...)`
|
|
122
|
+
- `ai.createVoiceSession(...)`
|
|
105
123
|
- `registerVoiceProvider(...)`
|
|
106
124
|
- configurable `voice.providers`
|
|
107
125
|
- custom voice providers
|
|
108
126
|
- OpenAI voice provider adapter
|
|
109
127
|
- full completion pipeline reuse after transcription
|
|
128
|
+
- stateful `VoiceSession` turns with prompts, task prompts, tool calls, history, and optional speech
|
|
129
|
+
- optional telephony providers for calls, webhook responses, webhook validation, and media-stream event parsing
|
|
110
130
|
|
|
111
131
|
Useful test cases:
|
|
112
132
|
|
|
113
133
|
- registered voice provider can transcribe
|
|
114
134
|
- registered voice provider can synthesize speech
|
|
115
135
|
- `ai.voice(...)` transcribes, appends transcript, calls `ai.complete(...)`, and optionally speaks
|
|
136
|
+
- `VoiceSession` can accept transcript or audio, select matching task prompts, execute tools, and speak
|
|
116
137
|
- `nexus-ai-pro/voice` imports without provider adapters
|
|
117
138
|
- `nexus-ai-pro/voice/openai` imports separately
|
|
139
|
+
- `nexus-ai-pro/voice/session` imports separately
|
|
118
140
|
- type consumer can configure `VoiceConfig`
|
|
119
141
|
- missing voice provider errors clearly
|
|
142
|
+
- registered telephony provider can create calls
|
|
143
|
+
- Twilio adapter can create inline-TwiML/media-stream calls
|
|
144
|
+
- Twilio webhook signatures can be validated
|
|
145
|
+
- Twilio media-stream messages can be normalized
|
|
120
146
|
|
|
121
147
|
Example:
|
|
122
148
|
|
|
@@ -144,9 +170,16 @@ const result = await ai.voice({
|
|
|
144
170
|
|
|
145
171
|
Still future work:
|
|
146
172
|
|
|
147
|
-
- realtime `VoiceSession`
|
|
148
173
|
- audio chunks in `NexusStream`
|
|
149
|
-
- WebRTC/
|
|
174
|
+
- WebRTC/SIP session helpers
|
|
175
|
+
- fully managed Twilio/OpenAI realtime bridge
|
|
176
|
+
|
|
177
|
+
Telephony is intentionally separate from voice:
|
|
178
|
+
|
|
179
|
+
- `voice` handles file/buffer/stream audio turns.
|
|
180
|
+
- `VoiceSession` handles multi-turn call state and app/tool requests during a conversation.
|
|
181
|
+
- `telephony` handles phone numbers, TwiML, provider webhooks, and media-stream protocol messages.
|
|
182
|
+
- apps can use one, both, or neither.
|
|
150
183
|
|
|
151
184
|
## Context Window Testing
|
|
152
185
|
|
|
@@ -200,6 +233,14 @@ npm install
|
|
|
200
233
|
npm run build
|
|
201
234
|
```
|
|
202
235
|
|
|
236
|
+
Quick CLI checks after build:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
node dist/cli.js models --provider deepseek
|
|
240
|
+
node dist/cli.js scan src --no-fail
|
|
241
|
+
node dist/cli.js optimize README.md --model gpt-5.4-mini
|
|
242
|
+
```
|
|
243
|
+
|
|
203
244
|
Main test suite:
|
|
204
245
|
|
|
205
246
|
```bash
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ Use the whole pipeline for production AI features, or turn pieces off when you o
|
|
|
14
14
|
npm install nexus-ai-pro
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Install only the provider SDKs your app uses
|
|
17
|
+
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.
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
npm install openai @anthropic-ai/sdk ollama
|
|
@@ -25,33 +25,13 @@ The Google Gemini provider uses Node.js `fetch`, so it does not need an extra SD
|
|
|
25
25
|
## Quick Start
|
|
26
26
|
|
|
27
27
|
```ts
|
|
28
|
-
import {
|
|
28
|
+
import { createNexus } from 'nexus-ai-pro';
|
|
29
29
|
|
|
30
|
-
const ai =
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
google: { apiKey: process.env.GOOGLE_API_KEY! },
|
|
35
|
-
ollama: { baseUrl: 'http://localhost:11434' },
|
|
36
|
-
},
|
|
37
|
-
routing: {
|
|
38
|
-
mode: 'auto',
|
|
39
|
-
strategy: 'quality',
|
|
40
|
-
},
|
|
30
|
+
const ai = createNexus({
|
|
31
|
+
provider: 'openai',
|
|
32
|
+
apiKey: process.env.OPENAI_API_KEY!,
|
|
33
|
+
model: 'gpt-5.4-mini',
|
|
41
34
|
security: 'standard',
|
|
42
|
-
contextWindow: {
|
|
43
|
-
strategy: 'last-messages-with-summary',
|
|
44
|
-
lastMessages: 10,
|
|
45
|
-
summary: { model: 'openai/fast', maxTokens: 600 },
|
|
46
|
-
},
|
|
47
|
-
tokenOptimizer: {
|
|
48
|
-
densification: { enabled: true },
|
|
49
|
-
budget: {
|
|
50
|
-
enabled: true,
|
|
51
|
-
maxInputTokens: 8000,
|
|
52
|
-
onExceeded: 'densify',
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
35
|
});
|
|
56
36
|
|
|
57
37
|
const response = await ai.complete({
|
|
@@ -64,6 +44,24 @@ console.log(response.meta.providerUsed);
|
|
|
64
44
|
console.log(response.meta.modelUsed);
|
|
65
45
|
```
|
|
66
46
|
|
|
47
|
+
For a fuller typed config, use the builder:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { createNexusConfig } from 'nexus-ai-pro';
|
|
51
|
+
|
|
52
|
+
const ai = createNexusConfig()
|
|
53
|
+
.openai(process.env.OPENAI_API_KEY!)
|
|
54
|
+
.anthropic(process.env.ANTHROPIC_API_KEY!)
|
|
55
|
+
.deepseek(process.env.DEEPSEEK_API_KEY!)
|
|
56
|
+
.lmstudio({ baseUrl: 'http://localhost:1234/v1' })
|
|
57
|
+
.auto('quality')
|
|
58
|
+
.security('standard')
|
|
59
|
+
.retry({ enabled: true, maxRetries: 2 })
|
|
60
|
+
.create();
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
You can still pass a plain `NexusAIConfig` to `new NexusAI(...)` when you want full object-literal control.
|
|
64
|
+
|
|
67
65
|
## Why Use It
|
|
68
66
|
|
|
69
67
|
`nexus-ai-pro` is useful when an app needs more than a direct SDK call:
|
|
@@ -78,6 +76,24 @@ console.log(response.meta.modelUsed);
|
|
|
78
76
|
- add tools, agents, RAG context, evals, batch jobs, and queues
|
|
79
77
|
- keep TypeScript types around every request and response
|
|
80
78
|
|
|
79
|
+
## CLI
|
|
80
|
+
|
|
81
|
+
The package installs a `nexus` command:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
nexus scan src --json
|
|
85
|
+
nexus models --provider deepseek
|
|
86
|
+
nexus optimize prompt.txt --model gpt-5.4-mini --max-input-tokens 4000
|
|
87
|
+
nexus eval examples/cli-eval.json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
CLI commands are intentionally thin wrappers around library modules:
|
|
91
|
+
|
|
92
|
+
- `nexus scan` checks files for secrets, PII, and prompt-injection patterns.
|
|
93
|
+
- `nexus models` lists the bundled model registry.
|
|
94
|
+
- `nexus eval` runs JSON or JS eval cases.
|
|
95
|
+
- `nexus optimize` previews token optimization for a request or prompt file.
|
|
96
|
+
|
|
81
97
|
## Core Concepts
|
|
82
98
|
|
|
83
99
|
### Providers and Routing
|
|
@@ -88,7 +104,10 @@ const ai = new NexusAI({
|
|
|
88
104
|
openai: { apiKey: process.env.OPENAI_API_KEY! },
|
|
89
105
|
anthropic: { apiKey: process.env.ANTHROPIC_API_KEY! },
|
|
90
106
|
groq: { apiKey: process.env.GROQ_API_KEY! },
|
|
107
|
+
deepseek: { apiKey: process.env.DEEPSEEK_API_KEY! },
|
|
108
|
+
openrouter: { apiKey: process.env.OPENROUTER_API_KEY! },
|
|
91
109
|
ollama: { baseUrl: 'http://localhost:11434' },
|
|
110
|
+
lmstudio: { baseUrl: 'http://localhost:1234/v1' },
|
|
92
111
|
},
|
|
93
112
|
routing: {
|
|
94
113
|
mode: 'auto',
|
|
@@ -101,6 +120,22 @@ const ai = new NexusAI({
|
|
|
101
120
|
});
|
|
102
121
|
```
|
|
103
122
|
|
|
123
|
+
First-class provider adapters:
|
|
124
|
+
|
|
125
|
+
- OpenAI
|
|
126
|
+
- Anthropic
|
|
127
|
+
- Google Gemini
|
|
128
|
+
- Ollama
|
|
129
|
+
- OpenRouter
|
|
130
|
+
- Groq
|
|
131
|
+
- Mistral
|
|
132
|
+
- Cohere
|
|
133
|
+
- DeepSeek
|
|
134
|
+
- Azure OpenAI
|
|
135
|
+
- LM Studio
|
|
136
|
+
- llama.cpp
|
|
137
|
+
- custom OpenAI- or Anthropic-compatible endpoints through `providers.custom` or `registerProvider(...)`
|
|
138
|
+
|
|
104
139
|
Routing modes:
|
|
105
140
|
|
|
106
141
|
- `direct` - always use the requested model or `defaultModel`
|
|
@@ -343,6 +378,62 @@ console.log(result.response.content);
|
|
|
343
378
|
console.log(result.speech?.audio.data);
|
|
344
379
|
```
|
|
345
380
|
|
|
381
|
+
### Voice Session With App Requests
|
|
382
|
+
|
|
383
|
+
Use `VoiceSession` when a call has multiple turns, should keep history, and may need to call your app while talking.
|
|
384
|
+
|
|
385
|
+
The prompt setup is flexible:
|
|
386
|
+
|
|
387
|
+
- `prompt` describes the assistant or business role.
|
|
388
|
+
- `instructions` describe behavior.
|
|
389
|
+
- `taskPrompts` add conditional instructions when the caller asks about something specific.
|
|
390
|
+
- `tools` let the model call your app, such as booking, CRM, billing, or inventory APIs.
|
|
391
|
+
|
|
392
|
+
```ts
|
|
393
|
+
import { tool } from 'nexus-ai-pro';
|
|
394
|
+
|
|
395
|
+
const session = ai.createVoiceSession({
|
|
396
|
+
model: 'auto',
|
|
397
|
+
prompt: 'You are a phone booking assistant for a small clinic.',
|
|
398
|
+
instructions: [
|
|
399
|
+
'Keep answers short and natural for a phone call.',
|
|
400
|
+
'Ask one follow-up question at a time.',
|
|
401
|
+
],
|
|
402
|
+
taskPrompts: [
|
|
403
|
+
{
|
|
404
|
+
name: 'booking',
|
|
405
|
+
when: ['book', 'appointment', 'free slot'],
|
|
406
|
+
instructions: 'When the caller asks about availability, call check_free_slots before offering times.',
|
|
407
|
+
tools: ['check_free_slots'],
|
|
408
|
+
},
|
|
409
|
+
],
|
|
410
|
+
tools: [
|
|
411
|
+
tool({
|
|
412
|
+
name: 'check_free_slots',
|
|
413
|
+
description: 'Check available booking slots for a date.',
|
|
414
|
+
parameters: {
|
|
415
|
+
type: 'object',
|
|
416
|
+
properties: { date: { type: 'string' } },
|
|
417
|
+
required: ['date'],
|
|
418
|
+
},
|
|
419
|
+
execute: async ({ date }) => bookingApi.freeSlots(String(date)),
|
|
420
|
+
}),
|
|
421
|
+
],
|
|
422
|
+
toolSelection: 'task',
|
|
423
|
+
speech: { provider: 'openai', voice: 'alloy', format: 'mp3' },
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
const turn = await session.handleTurn({
|
|
427
|
+
transcript: 'Do you have any free slots tomorrow?',
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
console.log(turn.response.content);
|
|
431
|
+
console.log(turn.toolSteps);
|
|
432
|
+
console.log(turn.speech?.audio.data);
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
You can use only `prompt`, only `instructions`, only `taskPrompts`, or all of them together. For phone calls through Twilio media streams, parse incoming audio/media events in `telephony`, feed complete caller turns into `session.handleTurn(...)`, then send the returned speech audio back through your call transport.
|
|
436
|
+
|
|
346
437
|
### Custom Voice Provider
|
|
347
438
|
|
|
348
439
|
Bring any private, local, or hosted voice service:
|
|
@@ -369,7 +460,62 @@ ai.registerVoiceProvider('private-voice', {
|
|
|
369
460
|
});
|
|
370
461
|
```
|
|
371
462
|
|
|
372
|
-
|
|
463
|
+
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.
|
|
464
|
+
|
|
465
|
+
## Phone Number Telephony
|
|
466
|
+
|
|
467
|
+
Phone-number support is optional and separate from the voice layer. Use `voice` for audio transcription/TTS, and use `telephony` when calls, webhooks, TwiML, or media-stream events are involved.
|
|
468
|
+
|
|
469
|
+
```ts
|
|
470
|
+
import { TelephonyManager } from 'nexus-ai-pro/telephony';
|
|
471
|
+
import { TwilioTelephonyProvider } from 'nexus-ai-pro/telephony/twilio';
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
Configure only the provider you need:
|
|
475
|
+
|
|
476
|
+
```ts
|
|
477
|
+
const ai = new NexusAI({
|
|
478
|
+
providers: { openai: { apiKey: process.env.OPENAI_API_KEY! } },
|
|
479
|
+
telephony: {
|
|
480
|
+
defaultProvider: 'twilio',
|
|
481
|
+
providers: {
|
|
482
|
+
twilio: new TwilioTelephonyProvider({
|
|
483
|
+
accountSid: process.env.TWILIO_ACCOUNT_SID!,
|
|
484
|
+
authToken: process.env.TWILIO_AUTH_TOKEN!,
|
|
485
|
+
}),
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
});
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
Generate a Twilio webhook response for an inbound phone number:
|
|
492
|
+
|
|
493
|
+
```ts
|
|
494
|
+
const response = await ai.createTelephonyResponse({
|
|
495
|
+
say: 'Thanks for calling. Connecting you now.',
|
|
496
|
+
stream: {
|
|
497
|
+
url: 'wss://voice.example.com/twilio',
|
|
498
|
+
mode: 'bidirectional',
|
|
499
|
+
parameters: { tenant: 'acme' },
|
|
500
|
+
},
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
return new Response(response.body, {
|
|
504
|
+
headers: { 'content-type': response.contentType },
|
|
505
|
+
});
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
Start an outbound call with either a webhook, inline TwiML, an application SID, or a media-stream URL:
|
|
509
|
+
|
|
510
|
+
```ts
|
|
511
|
+
const call = await ai.createCall({
|
|
512
|
+
to: '+15551230000',
|
|
513
|
+
from: '+15557650000',
|
|
514
|
+
mediaStreamUrl: 'wss://voice.example.com/twilio',
|
|
515
|
+
});
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
For smaller apps, skip Twilio entirely and register your own `TelephonyProvider`.
|
|
373
519
|
|
|
374
520
|
## Security
|
|
375
521
|
|
|
@@ -435,9 +581,35 @@ Available runtime helpers:
|
|
|
435
581
|
- batch completion with concurrency control
|
|
436
582
|
- in-memory job queue
|
|
437
583
|
- Redis and BullMQ queue adapters
|
|
438
|
-
- eval runner with quality, operations, RAG, and
|
|
584
|
+
- eval runner with quality, operations, RAG, safety metrics, and optional LLM-as-judge scoring
|
|
585
|
+
- voice sessions for multi-turn calls with conditional task prompts and app tools
|
|
439
586
|
- workflow templates for RAG answers, extraction, classification, comparison, support, sales, legal review, and code review
|
|
440
587
|
|
|
588
|
+
Use a plain assertion for small evals, or add an LLM judge when a rubric is more useful than exact matching:
|
|
589
|
+
|
|
590
|
+
```ts
|
|
591
|
+
import { LLMJudge } from 'nexus-ai-pro/evals';
|
|
592
|
+
|
|
593
|
+
const judge = new LLMJudge({
|
|
594
|
+
client: ai,
|
|
595
|
+
model: 'openai/gpt-4.1-mini',
|
|
596
|
+
rubric: 'Score whether the answer is correct, concise, and grounded in the supplied context.',
|
|
597
|
+
passThreshold: 0.7,
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
const run = await ai.runEvals([
|
|
601
|
+
{
|
|
602
|
+
name: 'support answer quality',
|
|
603
|
+
request: {
|
|
604
|
+
model: 'auto',
|
|
605
|
+
messages: [{ role: 'user', content: 'Explain our refund policy.' }],
|
|
606
|
+
},
|
|
607
|
+
expected: 'Refunds are available within 30 days.',
|
|
608
|
+
judge: judge.asEvalJudge(),
|
|
609
|
+
},
|
|
610
|
+
]);
|
|
611
|
+
```
|
|
612
|
+
|
|
441
613
|
## Observability and Reliability
|
|
442
614
|
|
|
443
615
|
```ts
|
|
@@ -452,6 +624,19 @@ console.log(ai.getPrometheusMetrics());
|
|
|
452
624
|
console.log(await ai.checkProviders());
|
|
453
625
|
```
|
|
454
626
|
|
|
627
|
+
Structured logging can be injected without replacing audit logs or metrics:
|
|
628
|
+
|
|
629
|
+
```ts
|
|
630
|
+
const ai = createNexusConfig()
|
|
631
|
+
.openai(process.env.OPENAI_API_KEY!)
|
|
632
|
+
.direct('gpt-5.4-mini')
|
|
633
|
+
.logger({
|
|
634
|
+
console: false,
|
|
635
|
+
sink: (event) => myLogger.info(event),
|
|
636
|
+
})
|
|
637
|
+
.create();
|
|
638
|
+
```
|
|
639
|
+
|
|
455
640
|
Production controls include:
|
|
456
641
|
|
|
457
642
|
- request timeouts
|
|
@@ -462,6 +647,7 @@ Production controls include:
|
|
|
462
647
|
- Prometheus metrics
|
|
463
648
|
- OpenTelemetry metrics and trace export helpers
|
|
464
649
|
- audit log sink
|
|
650
|
+
- structured logger sink
|
|
465
651
|
- rate limiting
|
|
466
652
|
|
|
467
653
|
## Import Surface
|
|
@@ -469,17 +655,19 @@ Production controls include:
|
|
|
469
655
|
The root import is convenient:
|
|
470
656
|
|
|
471
657
|
```ts
|
|
472
|
-
import { NexusAI } from 'nexus-ai-pro';
|
|
658
|
+
import { NexusAI, createNexus, createNexusConfig } from 'nexus-ai-pro';
|
|
473
659
|
```
|
|
474
660
|
|
|
475
661
|
Focused subpaths are available for smaller imports:
|
|
476
662
|
|
|
477
663
|
```ts
|
|
478
664
|
import { NexusAI } from 'nexus-ai-pro/core';
|
|
665
|
+
import { createNexusConfig } from 'nexus-ai-pro/config';
|
|
479
666
|
import { TokenOptimizer } from 'nexus-ai-pro/optimizer';
|
|
480
667
|
import { ContextWindowManager } from 'nexus-ai-pro/context';
|
|
481
668
|
import { guardrailPolicy } from 'nexus-ai-pro/security';
|
|
482
669
|
import { RedisCacheAdapter } from 'nexus-ai-pro/cache';
|
|
670
|
+
import { DeepSeekProvider } from 'nexus-ai-pro/providers/deepseek';
|
|
483
671
|
```
|
|
484
672
|
|
|
485
673
|
Provider SDKs are optional peer dependencies. The package is ESM-first and marked with `sideEffects: false`.
|
|
@@ -488,6 +676,9 @@ Provider SDKs are optional peer dependencies. The package is ESM-first and marke
|
|
|
488
676
|
|
|
489
677
|
```bash
|
|
490
678
|
npm run example:minimal
|
|
679
|
+
npm run example:create-nexus
|
|
680
|
+
npm run example:config-builder
|
|
681
|
+
npm run example:custom-provider
|
|
491
682
|
npm run example:feature-flags
|
|
492
683
|
npm run example:basic
|
|
493
684
|
npm run example:security
|
|
@@ -503,6 +694,8 @@ Included example files cover:
|
|
|
503
694
|
- persisted vector stores
|
|
504
695
|
- classifier calibration
|
|
505
696
|
- domain workflows
|
|
697
|
+
- custom providers
|
|
698
|
+
- import examples under `examples/exports`
|
|
506
699
|
|
|
507
700
|
## Test Commands
|
|
508
701
|
|
package/dist/cli.d.ts
ADDED