nexus-ai-pro 0.2.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 (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1249 -0
  3. package/assets/nexus-ai-pro-presentation.jpg +0 -0
  4. package/dist/agent/loop.d.ts +12 -0
  5. package/dist/agent/loop.js +89 -0
  6. package/dist/agent/tool.d.ts +16 -0
  7. package/dist/agent/tool.js +43 -0
  8. package/dist/cache/adapters.d.ts +42 -0
  9. package/dist/cache/adapters.js +76 -0
  10. package/dist/cache/memory-cache.d.ts +20 -0
  11. package/dist/cache/memory-cache.js +63 -0
  12. package/dist/cache/semantic-cache.d.ts +19 -0
  13. package/dist/cache/semantic-cache.js +71 -0
  14. package/dist/connectors/web.d.ts +8 -0
  15. package/dist/connectors/web.js +60 -0
  16. package/dist/core/nexus.d.ts +71 -0
  17. package/dist/core/nexus.js +477 -0
  18. package/dist/core/response-format.d.ts +8 -0
  19. package/dist/core/response-format.js +121 -0
  20. package/dist/core/secure-stream.d.ts +3 -0
  21. package/dist/core/secure-stream.js +41 -0
  22. package/dist/core/streaming.d.ts +4 -0
  23. package/dist/core/streaming.js +30 -0
  24. package/dist/embeddings/providers.d.ts +20 -0
  25. package/dist/embeddings/providers.js +60 -0
  26. package/dist/evals/metrics.d.ts +75 -0
  27. package/dist/evals/metrics.js +157 -0
  28. package/dist/evals/runner.d.ts +35 -0
  29. package/dist/evals/runner.js +47 -0
  30. package/dist/hallucination/consistency.d.ts +14 -0
  31. package/dist/hallucination/consistency.js +58 -0
  32. package/dist/hallucination/factual.d.ts +14 -0
  33. package/dist/hallucination/factual.js +35 -0
  34. package/dist/hallucination/knowledge-graph.d.ts +27 -0
  35. package/dist/hallucination/knowledge-graph.js +70 -0
  36. package/dist/hallucination/rag.d.ts +21 -0
  37. package/dist/hallucination/rag.js +46 -0
  38. package/dist/hallucination/retrieval.d.ts +24 -0
  39. package/dist/hallucination/retrieval.js +71 -0
  40. package/dist/hallucination/verification.d.ts +36 -0
  41. package/dist/hallucination/verification.js +110 -0
  42. package/dist/index.d.ts +62 -0
  43. package/dist/index.js +53 -0
  44. package/dist/jobs/batch.d.ts +11 -0
  45. package/dist/jobs/batch.js +32 -0
  46. package/dist/jobs/durable-adapters.d.ts +48 -0
  47. package/dist/jobs/durable-adapters.js +50 -0
  48. package/dist/jobs/queue.d.ts +24 -0
  49. package/dist/jobs/queue.js +57 -0
  50. package/dist/models/registry.d.ts +15 -0
  51. package/dist/models/registry.js +43 -0
  52. package/dist/next/route-handler.d.ts +6 -0
  53. package/dist/next/route-handler.js +35 -0
  54. package/dist/ops/audit-logger.d.ts +6 -0
  55. package/dist/ops/audit-logger.js +19 -0
  56. package/dist/ops/health.d.ts +29 -0
  57. package/dist/ops/health.js +69 -0
  58. package/dist/ops/metrics.d.ts +53 -0
  59. package/dist/ops/metrics.js +122 -0
  60. package/dist/ops/otel-tracing.d.ts +20 -0
  61. package/dist/ops/otel-tracing.js +50 -0
  62. package/dist/ops/rate-limiter.d.ts +11 -0
  63. package/dist/ops/rate-limiter.js +33 -0
  64. package/dist/optimizer/budget.d.ts +19 -0
  65. package/dist/optimizer/budget.js +88 -0
  66. package/dist/optimizer/cost.d.ts +13 -0
  67. package/dist/optimizer/cost.js +31 -0
  68. package/dist/optimizer/densifier.d.ts +10 -0
  69. package/dist/optimizer/densifier.js +77 -0
  70. package/dist/optimizer/index.d.ts +12 -0
  71. package/dist/optimizer/index.js +59 -0
  72. package/dist/pipeline/pipeline.d.ts +14 -0
  73. package/dist/pipeline/pipeline.js +106 -0
  74. package/dist/pipeline/types.d.ts +46 -0
  75. package/dist/pipeline/types.js +1 -0
  76. package/dist/providers/anthropic.d.ts +15 -0
  77. package/dist/providers/anthropic.js +183 -0
  78. package/dist/providers/base.d.ts +19 -0
  79. package/dist/providers/base.js +75 -0
  80. package/dist/providers/cohere.d.ts +16 -0
  81. package/dist/providers/cohere.js +104 -0
  82. package/dist/providers/google.d.ts +22 -0
  83. package/dist/providers/google.js +226 -0
  84. package/dist/providers/groq.d.ts +15 -0
  85. package/dist/providers/groq.js +50 -0
  86. package/dist/providers/mistral.d.ts +15 -0
  87. package/dist/providers/mistral.js +50 -0
  88. package/dist/providers/ollama.d.ts +15 -0
  89. package/dist/providers/ollama.js +108 -0
  90. package/dist/providers/openai.d.ts +21 -0
  91. package/dist/providers/openai.js +304 -0
  92. package/dist/providers/openrouter.d.ts +14 -0
  93. package/dist/providers/openrouter.js +19 -0
  94. package/dist/rag/file-ingestion.d.ts +20 -0
  95. package/dist/rag/file-ingestion.js +55 -0
  96. package/dist/rag/ingestion.d.ts +21 -0
  97. package/dist/rag/ingestion.js +47 -0
  98. package/dist/router/auto-router.d.ts +17 -0
  99. package/dist/router/auto-router.js +228 -0
  100. package/dist/router/failover.d.ts +21 -0
  101. package/dist/router/failover.js +126 -0
  102. package/dist/router/index.d.ts +12 -0
  103. package/dist/router/index.js +31 -0
  104. package/dist/router/rules-router.d.ts +7 -0
  105. package/dist/router/rules-router.js +68 -0
  106. package/dist/router/types.d.ts +19 -0
  107. package/dist/router/types.js +1 -0
  108. package/dist/security/index.d.ts +31 -0
  109. package/dist/security/index.js +173 -0
  110. package/dist/security/injection-calibration.d.ts +17 -0
  111. package/dist/security/injection-calibration.js +48 -0
  112. package/dist/security/injection-detector.d.ts +8 -0
  113. package/dist/security/injection-detector.js +66 -0
  114. package/dist/security/input-guard.d.ts +7 -0
  115. package/dist/security/input-guard.js +109 -0
  116. package/dist/security/output-guard.d.ts +6 -0
  117. package/dist/security/output-guard.js +144 -0
  118. package/dist/security/pii-detector.d.ts +8 -0
  119. package/dist/security/pii-detector.js +66 -0
  120. package/dist/security/policies.d.ts +4 -0
  121. package/dist/security/policies.js +61 -0
  122. package/dist/security/prompt-hardening.d.ts +6 -0
  123. package/dist/security/prompt-hardening.js +18 -0
  124. package/dist/security/schema-validator.d.ts +234 -0
  125. package/dist/security/schema-validator.js +68 -0
  126. package/dist/security/semantic-injection-classifier.d.ts +19 -0
  127. package/dist/security/semantic-injection-classifier.js +75 -0
  128. package/dist/security/upload-scanner.d.ts +29 -0
  129. package/dist/security/upload-scanner.js +72 -0
  130. package/dist/testing/provider-conformance.d.ts +24 -0
  131. package/dist/testing/provider-conformance.js +97 -0
  132. package/dist/types/agent.d.ts +34 -0
  133. package/dist/types/agent.js +1 -0
  134. package/dist/types/config.d.ts +171 -0
  135. package/dist/types/config.js +1 -0
  136. package/dist/types/messages.d.ts +96 -0
  137. package/dist/types/messages.js +1 -0
  138. package/dist/types/optimizer.d.ts +30 -0
  139. package/dist/types/optimizer.js +1 -0
  140. package/dist/types/planning.d.ts +27 -0
  141. package/dist/types/planning.js +1 -0
  142. package/dist/types/providers.d.ts +39 -0
  143. package/dist/types/providers.js +479 -0
  144. package/dist/types/response.d.ts +55 -0
  145. package/dist/types/response.js +1 -0
  146. package/dist/types/security.d.ts +87 -0
  147. package/dist/types/security.js +1 -0
  148. package/dist/utils/ids.d.ts +1 -0
  149. package/dist/utils/ids.js +4 -0
  150. package/dist/utils/logger.d.ts +7 -0
  151. package/dist/utils/logger.js +17 -0
  152. package/dist/utils/tokenizer.d.ts +6 -0
  153. package/dist/utils/tokenizer.js +38 -0
  154. package/dist/workflow/chains.d.ts +53 -0
  155. package/dist/workflow/chains.js +117 -0
  156. package/dist/workflow/domain.d.ts +22 -0
  157. package/dist/workflow/domain.js +96 -0
  158. package/examples/agent.ts +69 -0
  159. package/examples/basic.ts +37 -0
  160. package/examples/bullmq-worker.ts +36 -0
  161. package/examples/classifier-calibration.ts +7 -0
  162. package/examples/domain-workflows.ts +38 -0
  163. package/examples/feature-flags.ts +65 -0
  164. package/examples/minimal.ts +45 -0
  165. package/examples/ocr-pdf-ingestion.ts +42 -0
  166. package/examples/optimizer.ts +43 -0
  167. package/examples/otel-express.ts +47 -0
  168. package/examples/otel-node-http.ts +46 -0
  169. package/examples/persisted-vector-store.ts +42 -0
  170. package/examples/security.ts +69 -0
  171. package/package.json +165 -0
@@ -0,0 +1,38 @@
1
+ export class Tokenizer {
2
+ estimateTextTokens(text) {
3
+ if (!text)
4
+ return 0;
5
+ const normalized = text.trim();
6
+ if (!normalized)
7
+ return 0;
8
+ const wordLike = normalized.match(/[\p{L}\p{N}_]+|[^\s\p{L}\p{N}_]/gu) || [];
9
+ const charEstimate = Math.ceil(normalized.length / 4);
10
+ return Math.max(1, Math.ceil((wordLike.length + charEstimate) / 2));
11
+ }
12
+ estimateMessageTokens(message) {
13
+ const roleOverhead = 4;
14
+ if (typeof message.content === 'string') {
15
+ return roleOverhead + this.estimateTextTokens(message.content);
16
+ }
17
+ return roleOverhead + message.content.reduce((total, part) => {
18
+ if (part.type === 'text')
19
+ return total + this.estimateTextTokens(part.text);
20
+ if (part.type === 'image')
21
+ return total + 85;
22
+ if (part.type === 'audio')
23
+ return total + 120;
24
+ if (part.type === 'video')
25
+ return total + 250;
26
+ return total;
27
+ }, 0);
28
+ }
29
+ estimateRequestTokens(request) {
30
+ const modelOverhead = 8;
31
+ const toolOverhead = request.tools?.reduce((total, tool) => {
32
+ return total + this.estimateTextTokens(tool.name) + this.estimateTextTokens(tool.description) + 20;
33
+ }, 0) || 0;
34
+ return modelOverhead + toolOverhead + request.messages.reduce((total, message) => {
35
+ return total + this.estimateMessageTokens(message);
36
+ }, 0);
37
+ }
38
+ }
@@ -0,0 +1,53 @@
1
+ import type { CompletionRequest } from '../types/messages.js';
2
+ import type { NexusResponse } from '../types/response.js';
3
+ import type { ResponseFormatConfig } from '../types/config.js';
4
+ import { type RagChunk } from '../hallucination/rag.js';
5
+ export interface WorkflowClient {
6
+ complete(request: CompletionRequest): Promise<NexusResponse>;
7
+ }
8
+ export interface WorkflowStepResult {
9
+ step: string;
10
+ response: NexusResponse;
11
+ }
12
+ export interface WorkflowResult {
13
+ content: string;
14
+ response: NexusResponse;
15
+ steps: WorkflowStepResult[];
16
+ }
17
+ export interface SummarizeVerifyFormatOptions {
18
+ model: string;
19
+ input: string;
20
+ verifyContext?: string[];
21
+ responseFormat?: ResponseFormatConfig;
22
+ summaryInstruction?: string;
23
+ finalInstruction?: string;
24
+ }
25
+ export interface RagAnswerOptions {
26
+ model: string;
27
+ question: string;
28
+ chunks: RagChunk[];
29
+ verify?: boolean;
30
+ }
31
+ export interface ExtractStructuredOptions {
32
+ model: string;
33
+ input: string;
34
+ schema: Record<string, unknown>;
35
+ instruction?: string;
36
+ }
37
+ export interface ClassifyRouteOptions {
38
+ model: string;
39
+ input: string;
40
+ labels: string[];
41
+ instruction?: string;
42
+ }
43
+ export interface CompareOptions {
44
+ model: string;
45
+ input: string;
46
+ options: string[];
47
+ criteria?: string[];
48
+ }
49
+ export declare function summarizeVerifyFormat(client: WorkflowClient, options: SummarizeVerifyFormatOptions): Promise<WorkflowResult>;
50
+ export declare function ragAnswer(client: WorkflowClient, options: RagAnswerOptions): Promise<WorkflowResult>;
51
+ export declare function extractStructured(client: WorkflowClient, options: ExtractStructuredOptions): Promise<WorkflowResult>;
52
+ export declare function classifyRoute(client: WorkflowClient, options: ClassifyRouteOptions): Promise<WorkflowResult>;
53
+ export declare function compareAndDecide(client: WorkflowClient, options: CompareOptions): Promise<WorkflowResult>;
@@ -0,0 +1,117 @@
1
+ import { withFactualDefaults } from '../hallucination/factual.js';
2
+ import { withRagContext } from '../hallucination/rag.js';
3
+ import { completeVerified } from '../hallucination/verification.js';
4
+ export async function summarizeVerifyFormat(client, options) {
5
+ const steps = [];
6
+ const summary = await client.complete(withFactualDefaults({
7
+ model: options.model,
8
+ messages: [
9
+ { role: 'user', content: `${options.summaryInstruction || 'Summarize the following content clearly.'}\n\n${options.input}` },
10
+ ],
11
+ }, { chainOfThought: 'private' }));
12
+ steps.push({ step: 'summarize', response: summary });
13
+ const verified = options.verifyContext?.length
14
+ ? await completeVerified(client, {
15
+ model: options.model,
16
+ messages: [{ role: 'user', content: summary.content }],
17
+ responseFormat: toRequestResponseFormat(options.responseFormat),
18
+ }, {
19
+ context: options.verifyContext,
20
+ repair: true,
21
+ })
22
+ : summary;
23
+ steps.push({ step: 'verify', response: verified });
24
+ const formatted = await client.complete({
25
+ model: options.model,
26
+ messages: [
27
+ {
28
+ role: 'user',
29
+ content: `${options.finalInstruction || 'Format this into the final answer.'}\n\n${verified.content}`,
30
+ },
31
+ ],
32
+ responseFormat: toRequestResponseFormat(options.responseFormat),
33
+ });
34
+ steps.push({ step: 'format', response: formatted });
35
+ return {
36
+ content: formatted.content,
37
+ response: formatted,
38
+ steps,
39
+ };
40
+ }
41
+ export async function ragAnswer(client, options) {
42
+ const request = withRagContext({
43
+ model: options.model,
44
+ messages: [{ role: 'user', content: options.question }],
45
+ }, {
46
+ chunks: options.chunks,
47
+ requireCitations: true,
48
+ });
49
+ const response = options.verify
50
+ ? await completeVerified(client, request, { context: options.chunks.map((chunk) => chunk.content), repair: true })
51
+ : await client.complete(request);
52
+ return {
53
+ content: response.content,
54
+ response,
55
+ steps: [{ step: 'rag-answer', response }],
56
+ };
57
+ }
58
+ export async function extractStructured(client, options) {
59
+ const response = await client.complete({
60
+ model: options.model,
61
+ messages: [{
62
+ role: 'user',
63
+ content: `${options.instruction || 'Extract the requested structured data from the input.'}\n\n${options.input}`,
64
+ }],
65
+ responseFormat: {
66
+ type: 'json_schema',
67
+ schema: options.schema,
68
+ },
69
+ });
70
+ return { content: response.content, response, steps: [{ step: 'extract-structured', response }] };
71
+ }
72
+ export async function classifyRoute(client, options) {
73
+ const response = await client.complete({
74
+ model: options.model,
75
+ messages: [{
76
+ role: 'user',
77
+ content: [
78
+ options.instruction || 'Classify the input into exactly one label.',
79
+ `Labels: ${options.labels.join(', ')}`,
80
+ `Input: ${options.input}`,
81
+ ].join('\n'),
82
+ }],
83
+ temperature: 0,
84
+ responseFormat: {
85
+ type: 'json_schema',
86
+ schema: {
87
+ type: 'object',
88
+ required: ['label'],
89
+ properties: {
90
+ label: { type: 'string' },
91
+ confidence: { type: 'number' },
92
+ },
93
+ },
94
+ },
95
+ });
96
+ return { content: response.content, response, steps: [{ step: 'classify-route', response }] };
97
+ }
98
+ export async function compareAndDecide(client, options) {
99
+ const response = await client.complete(withFactualDefaults({
100
+ model: options.model,
101
+ messages: [{
102
+ role: 'user',
103
+ content: [
104
+ 'Compare the options and choose the best one.',
105
+ `Input: ${options.input}`,
106
+ `Options:\n${options.options.map((item, index) => `${index + 1}. ${item}`).join('\n')}`,
107
+ options.criteria?.length ? `Criteria: ${options.criteria.join(', ')}` : '',
108
+ ].filter(Boolean).join('\n\n'),
109
+ }],
110
+ }, { chainOfThought: 'private' }));
111
+ return { content: response.content, response, steps: [{ step: 'compare-and-decide', response }] };
112
+ }
113
+ function toRequestResponseFormat(format) {
114
+ if (!format || format.type === 'text')
115
+ return undefined;
116
+ return { type: format.type, schema: format.schema };
117
+ }
@@ -0,0 +1,22 @@
1
+ import type { WorkflowClient, WorkflowResult } from './chains.js';
2
+ export interface DomainWorkflowOptions {
3
+ model: string;
4
+ input: string;
5
+ context?: string[];
6
+ }
7
+ export interface SupportWorkflowOptions extends DomainWorkflowOptions {
8
+ customerTier?: string;
9
+ }
10
+ export interface SalesWorkflowOptions extends DomainWorkflowOptions {
11
+ product?: string;
12
+ }
13
+ export interface LegalReviewWorkflowOptions extends DomainWorkflowOptions {
14
+ jurisdiction?: string;
15
+ }
16
+ export interface CodeReviewWorkflowOptions extends DomainWorkflowOptions {
17
+ language?: string;
18
+ }
19
+ export declare function supportTriageWorkflow(client: WorkflowClient, options: SupportWorkflowOptions): Promise<WorkflowResult>;
20
+ export declare function salesQualificationWorkflow(client: WorkflowClient, options: SalesWorkflowOptions): Promise<WorkflowResult>;
21
+ export declare function legalReviewWorkflow(client: WorkflowClient, options: LegalReviewWorkflowOptions): Promise<WorkflowResult>;
22
+ export declare function codeReviewWorkflow(client: WorkflowClient, options: CodeReviewWorkflowOptions): Promise<WorkflowResult>;
@@ -0,0 +1,96 @@
1
+ import { withFactualDefaults } from '../hallucination/factual.js';
2
+ export async function supportTriageWorkflow(client, options) {
3
+ return singleStepWorkflow(client, 'support-triage', {
4
+ model: options.model,
5
+ messages: [{
6
+ role: 'user',
7
+ content: [
8
+ 'Triage this support request.',
9
+ 'Return severity, category, likely cause, next best action, and a customer-safe reply.',
10
+ options.customerTier ? `Customer tier: ${options.customerTier}` : '',
11
+ contextBlock(options.context),
12
+ `Request:\n${options.input}`,
13
+ ].filter(Boolean).join('\n\n'),
14
+ }],
15
+ responseFormat: {
16
+ type: 'json_schema',
17
+ schema: objectSchema(['severity', 'category', 'nextAction', 'reply']),
18
+ },
19
+ });
20
+ }
21
+ export async function salesQualificationWorkflow(client, options) {
22
+ return singleStepWorkflow(client, 'sales-qualification', {
23
+ model: options.model,
24
+ messages: [{
25
+ role: 'user',
26
+ content: [
27
+ 'Qualify this sales lead.',
28
+ 'Return fitScore, painPoints, objections, recommendedOffer, and followUpEmail.',
29
+ options.product ? `Product: ${options.product}` : '',
30
+ contextBlock(options.context),
31
+ `Lead notes:\n${options.input}`,
32
+ ].filter(Boolean).join('\n\n'),
33
+ }],
34
+ responseFormat: {
35
+ type: 'json_schema',
36
+ schema: objectSchema(['fitScore', 'painPoints', 'recommendedOffer', 'followUpEmail']),
37
+ },
38
+ });
39
+ }
40
+ export async function legalReviewWorkflow(client, options) {
41
+ return singleStepWorkflow(client, 'legal-review', withFactualDefaults({
42
+ model: options.model,
43
+ messages: [{
44
+ role: 'user',
45
+ content: [
46
+ 'Review this text for legal risk. Do not provide legal advice.',
47
+ 'Return risks, missingClauses, suggestedQuestions, and safeSummary.',
48
+ options.jurisdiction ? `Jurisdiction: ${options.jurisdiction}` : '',
49
+ contextBlock(options.context),
50
+ `Text:\n${options.input}`,
51
+ ].filter(Boolean).join('\n\n'),
52
+ }],
53
+ responseFormat: {
54
+ type: 'json_schema',
55
+ schema: objectSchema(['risks', 'suggestedQuestions', 'safeSummary']),
56
+ },
57
+ }, { requireUnknownFallback: true, chainOfThought: 'private' }));
58
+ }
59
+ export async function codeReviewWorkflow(client, options) {
60
+ return singleStepWorkflow(client, 'code-review', {
61
+ model: options.model,
62
+ messages: [{
63
+ role: 'user',
64
+ content: [
65
+ 'Review this code for bugs, security risks, performance issues, and missing tests.',
66
+ 'Return findings ordered by severity with file/line references when available.',
67
+ options.language ? `Language: ${options.language}` : '',
68
+ contextBlock(options.context),
69
+ `Code:\n${options.input}`,
70
+ ].filter(Boolean).join('\n\n'),
71
+ }],
72
+ responseFormat: {
73
+ type: 'json_schema',
74
+ schema: objectSchema(['findings', 'riskLevel', 'testSuggestions']),
75
+ },
76
+ });
77
+ }
78
+ async function singleStepWorkflow(client, step, request) {
79
+ const response = await client.complete(request);
80
+ const steps = [{ step, response }];
81
+ return {
82
+ content: response.content,
83
+ response,
84
+ steps,
85
+ };
86
+ }
87
+ function contextBlock(context) {
88
+ return context?.length ? `Context:\n${context.map((item, index) => `[${index + 1}] ${item}`).join('\n')}` : '';
89
+ }
90
+ function objectSchema(required) {
91
+ return {
92
+ type: 'object',
93
+ required,
94
+ properties: Object.fromEntries(required.map((key) => [key, {}])),
95
+ };
96
+ }
@@ -0,0 +1,69 @@
1
+ import { NexusAI, tool } from 'nexus-ai-pro';
2
+
3
+ const getCurrentTime = tool({
4
+ name: 'get_current_time',
5
+ description: 'Get the current ISO timestamp.',
6
+ parameters: {
7
+ type: 'object',
8
+ properties: {},
9
+ },
10
+ execute: async () => ({ now: new Date().toISOString() }),
11
+ });
12
+
13
+ const calculate = tool<{ expression: string }>({
14
+ name: 'calculate',
15
+ description: 'Evaluate a simple arithmetic expression. Only supports numbers and arithmetic operators.',
16
+ parameters: {
17
+ type: 'object',
18
+ properties: {
19
+ expression: { type: 'string', description: 'Arithmetic expression like 2 + 2 * 10' },
20
+ },
21
+ required: ['expression'],
22
+ },
23
+ execute: async ({ expression }) => {
24
+ if (!/^[0-9+\-*/().\s]+$/.test(expression)) {
25
+ throw new Error('Unsafe expression');
26
+ }
27
+
28
+ return { result: Function(`"use strict"; return (${expression})`)() };
29
+ },
30
+ });
31
+
32
+ async function main() {
33
+ const ai = new NexusAI({
34
+ providers: {
35
+ openai: process.env.OPENAI_API_KEY ? { apiKey: process.env.OPENAI_API_KEY } : undefined,
36
+ anthropic: process.env.ANTHROPIC_API_KEY ? { apiKey: process.env.ANTHROPIC_API_KEY } : undefined,
37
+ ollama: { baseUrl: 'http://localhost:11434' },
38
+ },
39
+ routing: {
40
+ mode: 'auto',
41
+ strategy: process.env.OPENAI_API_KEY || process.env.ANTHROPIC_API_KEY ? 'quality' : 'privacy',
42
+ },
43
+ security: 'standard',
44
+ tokenOptimizer: {
45
+ densification: { enabled: true },
46
+ budget: { enabled: true, maxInputTokens: 4000, onExceeded: 'densify' },
47
+ },
48
+ debug: true,
49
+ });
50
+
51
+ const result = await ai.agent({
52
+ model: 'auto',
53
+ goal: 'What time is it now, and what is 12 * 7 + 5? Use tools when needed.',
54
+ tools: [getCurrentTime, calculate],
55
+ maxIterations: 5,
56
+ onStep: (step) => {
57
+ console.log(`[${step.iteration}] ${step.type}: ${step.message}`);
58
+ if (step.toolName) console.log(` tool=${step.toolName}`, step.toolArgs, step.toolResult);
59
+ },
60
+ });
61
+
62
+ console.log('\nFinal answer:\n');
63
+ console.log(result.content);
64
+ }
65
+
66
+ main().catch((err) => {
67
+ console.error(err);
68
+ process.exit(1);
69
+ });
@@ -0,0 +1,37 @@
1
+ import { NexusAI } from 'nexus-ai-pro';
2
+
3
+ async function main() {
4
+ const ai = new NexusAI({
5
+ providers: {
6
+ ollama: { baseUrl: 'http://localhost:11434' },
7
+ openai: process.env.OPENAI_API_KEY
8
+ ? { apiKey: process.env.OPENAI_API_KEY }
9
+ : undefined,
10
+ anthropic: process.env.ANTHROPIC_API_KEY
11
+ ? { apiKey: process.env.ANTHROPIC_API_KEY }
12
+ : undefined,
13
+ },
14
+ routing: {
15
+ mode: 'auto',
16
+ strategy: process.env.OPENAI_API_KEY || process.env.ANTHROPIC_API_KEY ? 'quality' : 'privacy',
17
+ },
18
+ debug: true,
19
+ });
20
+
21
+ const response = await ai.complete({
22
+ model: 'auto',
23
+ messages: [
24
+ { role: 'user', content: 'Explain what nexus-ai-pro is in 2 short bullets.' },
25
+ ],
26
+ });
27
+
28
+ console.log('\nResponse:\n');
29
+ console.log(response.content);
30
+ console.log('\nMeta:\n');
31
+ console.log(response.meta);
32
+ }
33
+
34
+ main().catch((err) => {
35
+ console.error(err);
36
+ process.exit(1);
37
+ });
@@ -0,0 +1,36 @@
1
+ import { Queue, Worker } from 'bullmq';
2
+ import { NexusAI } from '../src/index.js';
3
+
4
+ // Optional example dependency install:
5
+ // npm install bullmq ioredis
6
+ // Start Redis before running this example.
7
+
8
+ const connection = {
9
+ host: process.env.REDIS_HOST || '127.0.0.1',
10
+ port: Number(process.env.REDIS_PORT || 6379),
11
+ };
12
+
13
+ const queueName = 'nexus-ai-pro-jobs';
14
+ const queue = new Queue(queueName, { connection });
15
+
16
+ const ai = new NexusAI({
17
+ providers: {
18
+ ollama: { baseUrl: process.env.OLLAMA_BASE_URL || 'http://localhost:11434' },
19
+ },
20
+ routing: { mode: 'auto', strategy: 'privacy' },
21
+ });
22
+
23
+ new Worker(queueName, async (job) => {
24
+ const response = await ai.complete(job.data);
25
+ return {
26
+ content: response.content,
27
+ meta: response.meta,
28
+ };
29
+ }, { connection });
30
+
31
+ const job = await queue.add('completion', {
32
+ model: 'auto',
33
+ messages: [{ role: 'user', content: 'Summarize durable queues in one sentence.' }],
34
+ });
35
+
36
+ console.log(`Queued job ${job.id}`);
@@ -0,0 +1,7 @@
1
+ import {
2
+ SEMANTIC_INJECTION_CALIBRATION_SET,
3
+ calibrateSemanticInjectionClassifier,
4
+ } from '../src/index.js';
5
+
6
+ const results = calibrateSemanticInjectionClassifier(SEMANTIC_INJECTION_CALIBRATION_SET);
7
+ console.table(results);
@@ -0,0 +1,38 @@
1
+ import {
2
+ NexusAI,
3
+ supportTriageWorkflow,
4
+ salesQualificationWorkflow,
5
+ legalReviewWorkflow,
6
+ codeReviewWorkflow,
7
+ } from '../src/index.js';
8
+
9
+ const ai = new NexusAI({
10
+ providers: {
11
+ ollama: { baseUrl: process.env.OLLAMA_BASE_URL || 'http://localhost:11434' },
12
+ },
13
+ routing: { mode: 'auto', strategy: 'privacy' },
14
+ });
15
+
16
+ console.log(await supportTriageWorkflow(ai, {
17
+ model: 'auto',
18
+ input: 'Customer cannot log in after enabling SSO.',
19
+ customerTier: 'enterprise',
20
+ }));
21
+
22
+ console.log(await salesQualificationWorkflow(ai, {
23
+ model: 'auto',
24
+ input: 'Lead needs secure AI routing for a healthcare app.',
25
+ product: 'nexus-ai-pro',
26
+ }));
27
+
28
+ console.log(await legalReviewWorkflow(ai, {
29
+ model: 'auto',
30
+ input: 'Draft contract clause text...',
31
+ jurisdiction: 'US',
32
+ }));
33
+
34
+ console.log(await codeReviewWorkflow(ai, {
35
+ model: 'auto',
36
+ input: 'function add(a,b){ return a-b }',
37
+ language: 'JavaScript',
38
+ }));
@@ -0,0 +1,65 @@
1
+ import { NexusAI, guardrailPolicy } from 'nexus-ai-pro';
2
+
3
+ function envFlag(name: string): boolean {
4
+ return process.env[name] === '1' || process.env[name] === 'true';
5
+ }
6
+
7
+ async function main() {
8
+ const enableGuardrails = envFlag('NEXUS_GUARDRAILS');
9
+ const enableCache = envFlag('NEXUS_CACHE');
10
+ const enableTrace = envFlag('NEXUS_TRACE');
11
+
12
+ const ai = new NexusAI({
13
+ providers: {
14
+ openai: process.env.OPENAI_API_KEY
15
+ ? { apiKey: process.env.OPENAI_API_KEY }
16
+ : undefined,
17
+ ollama: { baseUrl: process.env.OLLAMA_BASE_URL || 'http://localhost:11434' },
18
+ },
19
+ routing: {
20
+ mode: process.env.NEXUS_MODEL ? 'direct' : 'auto',
21
+ strategy: process.env.OPENAI_API_KEY ? 'quality' : 'privacy',
22
+ },
23
+ defaultModel: process.env.NEXUS_MODEL,
24
+ security: enableGuardrails ? guardrailPolicy('enterprise-strict') : 'off',
25
+ tokenOptimizer: {
26
+ enabled: envFlag('NEXUS_OPTIMIZER'),
27
+ densification: { enabled: envFlag('NEXUS_DENSIFY') },
28
+ budget: {
29
+ enabled: envFlag('NEXUS_TOKEN_BUDGET'),
30
+ maxInputTokens: 4000,
31
+ onExceeded: 'densify',
32
+ },
33
+ },
34
+ cache: {
35
+ enabled: enableCache,
36
+ strategy: 'exact',
37
+ ttlSeconds: 300,
38
+ },
39
+ pipeline: {
40
+ enabled: enableTrace,
41
+ trace: enableTrace,
42
+ includeTraceInResponse: enableTrace,
43
+ },
44
+ metrics: {
45
+ enabled: envFlag('NEXUS_METRICS'),
46
+ },
47
+ });
48
+
49
+ const response = await ai.complete({
50
+ model: 'auto',
51
+ messages: [
52
+ { role: 'user', content: 'Give me a short production checklist for an AI endpoint.' },
53
+ ],
54
+ });
55
+
56
+ console.log(response.content);
57
+ if (response.meta.pipeline) {
58
+ console.log('\nPipeline steps:', response.meta.pipeline.steps.map((step) => step.name));
59
+ }
60
+ }
61
+
62
+ main().catch((err) => {
63
+ console.error(err);
64
+ process.exit(1);
65
+ });
@@ -0,0 +1,45 @@
1
+ import { NexusAI } from 'nexus-ai-pro';
2
+
3
+ async function main() {
4
+ const ai = new NexusAI({
5
+ providers: {
6
+ openai: process.env.OPENAI_API_KEY
7
+ ? { apiKey: process.env.OPENAI_API_KEY }
8
+ : undefined,
9
+ ollama: { baseUrl: process.env.OLLAMA_BASE_URL || 'http://localhost:11434' },
10
+ },
11
+ routing: {
12
+ mode: 'direct',
13
+ },
14
+ defaultModel: process.env.NEXUS_MODEL || (process.env.OPENAI_API_KEY ? 'gpt-5.4-mini' : 'ollama/llama3.2'),
15
+ security: 'off',
16
+ tokenOptimizer: {
17
+ enabled: false,
18
+ },
19
+ cache: {
20
+ enabled: false,
21
+ },
22
+ pipeline: {
23
+ enabled: false,
24
+ trace: false,
25
+ includeTraceInResponse: false,
26
+ },
27
+ metrics: {
28
+ enabled: false,
29
+ },
30
+ });
31
+
32
+ const response = await ai.complete({
33
+ model: 'auto',
34
+ messages: [
35
+ { role: 'user', content: 'Explain nexus-ai-pro in one sentence.' },
36
+ ],
37
+ });
38
+
39
+ console.log(response.content);
40
+ }
41
+
42
+ main().catch((err) => {
43
+ console.error(err);
44
+ process.exit(1);
45
+ });
@@ -0,0 +1,42 @@
1
+ import {
2
+ createOcrExtractor,
3
+ createPdfExtractor,
4
+ ingestFilesAfterScan,
5
+ } from '../src/index.js';
6
+
7
+ // Wire your preferred OCR/PDF libraries here, for example:
8
+ // - pdf-parse, pdfjs-dist, or a hosted document AI parser for PDFs
9
+ // - tesseract.js, cloud vision, or another OCR service for images
10
+
11
+ const pdfExtractor = createPdfExtractor(async (file) => {
12
+ return `[pdf text extracted from ${file.name}]`;
13
+ });
14
+
15
+ const ocrExtractor = createOcrExtractor(async (file) => {
16
+ return `[ocr text extracted from ${file.name}]`;
17
+ });
18
+
19
+ const result = await ingestFilesAfterScan([
20
+ {
21
+ name: 'policy.pdf',
22
+ mimeType: 'application/pdf',
23
+ sizeBytes: 1200,
24
+ content: Buffer.from('fake pdf bytes'),
25
+ },
26
+ {
27
+ name: 'diagram.png',
28
+ mimeType: 'image/png',
29
+ sizeBytes: 800,
30
+ content: Buffer.from('fake image bytes'),
31
+ },
32
+ ], {
33
+ scan: {
34
+ maxBytes: 5_000_000,
35
+ allowedMimeTypes: ['application/pdf', 'image/png', 'image/jpeg'],
36
+ },
37
+ extractors: [pdfExtractor, ocrExtractor],
38
+ chunkSize: 800,
39
+ overlap: 80,
40
+ });
41
+
42
+ console.log(result.chunks);