@novaqore/ai 0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Novaqore
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,306 @@
1
+ <h1 align="center">NovaQore AI</h1>
2
+
3
+ <p align="center">
4
+ <img src="assets/logo.png" alt="NovaQore AI" width="120" />
5
+ <br><br>
6
+ <strong>@novaqore/ai</strong>
7
+ <br>
8
+ The world's first private, quantum-encrypted LLM client.
9
+ <br><br>
10
+ <a href="https://www.npmjs.com/package/@novaqore/ai"><img src="https://img.shields.io/npm/v/@novaqore/ai?color=blue&label=npm" alt="npm version" /></a>
11
+ <a href="https://github.com/novaqore/ai/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="license" /></a>
12
+ <a href="https://img.shields.io/node/v/@novaqore/ai"><img src="https://img.shields.io/node/v/@novaqore/ai?color=brightgreen" alt="node version" /></a>
13
+ <a href="https://discord.gg/novaqore"><img src="https://img.shields.io/discord/1234567890?color=5865F2&label=discord&logo=discord&logoColor=white" alt="Discord" /></a>
14
+ <br><br>
15
+ <a href="https://novaqore.ai/developer"><strong>πŸ”‘ Get Your Quantum Keys</strong></a> &nbsp;|&nbsp;
16
+ <a href="https://novaqore.ai"><strong>🌐 Website</strong></a> &nbsp;|&nbsp;
17
+ <a href="https://novaqore.ai/roadmap"><strong>πŸ—ΊοΈ Roadmap</strong></a> &nbsp;|&nbsp;
18
+ <a href="https://novaqore.ai/white-papers"><strong>πŸ“„ White Papers</strong></a>
19
+ </p>
20
+
21
+ ---
22
+
23
+ ## The first private, quantum-encrypted LLMs
24
+
25
+ ### The problem
26
+
27
+ AI is eating the world, and the world is feeding it everything. Customer names, home addresses, credit card numbers, medical records, legal documents, internal business strategy, private conversations. All of it is being sent to large language models every day by millions of developers and businesses.
28
+
29
+ Most people assume HTTPS keeps that data safe. It does not. HTTPS encrypts the connection between your machine and the server, but that protection has limits. Corporate firewalls and network proxies routinely perform TLS inspection, decrypting and re-encrypting traffic so they can read everything passing through. Load balancers and CDNs terminate TLS at the edge, meaning your data sits in plaintext inside the provider's infrastructure. A compromised certificate or a stolen private key breaks the entire chain. The AI provider itself sees all of your data in the clear on their servers, and in most cases they log it, store it, and reserve the right to use it.
30
+
31
+ And then there is the future. Quantum computers are advancing fast. Attackers and nation-states are already recording encrypted internet traffic today with the intention of decrypting it later once quantum hardware catches up. This is called "harvest now, decrypt later," and it is not theoretical. It is happening. Every sensitive prompt you send over standard HTTPS today is a liability tomorrow.
32
+
33
+ ### The solution
34
+
35
+ NovaQore AI is a private LLM client created by [NovaQore](https://novaqore.ai). We built it because HTTPS alone is not enough to protect what people are feeding into AI.
36
+
37
+ **We run our own large language models on πŸ‡ΊπŸ‡Έ US-based infrastructure.** No third-party AI providers. No data leaving the country. No shared multi-tenant GPU clusters where your prompts sit next to someone else's. Our servers, our models, our network.
38
+
39
+ **Every request is encrypted end-to-end with post-quantum cryptography.** Before your data ever leaves your machine, it is locked using **CRYSTALS-Kyber** (Kyber1024 key encapsulation) and **AES-256-GCM**. This is not HTTPS. This is an additional layer of encryption on top of it. Even if someone breaks the TLS connection, intercepts traffic at a proxy, or sits inside the network infrastructure, they see nothing but random bytes. The server decrypts your prompt only in memory, runs the model, encrypts the response with the same shared secret, and sends it back. Fresh cryptographic keys are generated for every single request. Nothing is reused. Nothing is cached. Nothing is logged.
40
+
41
+ **The encryption is quantum-safe.** CRYSTALS-Kyber is a NIST-standardized post-quantum algorithm. Even if a future quantum computer could break today's TLS, it cannot break Kyber. Your data is protected now and it stays protected decades from now.
42
+
43
+ This is not a proxy. This is not a wrapper. This is a fully private AI pipeline from your code to our GPUs, with post-quantum encryption at every step.
44
+
45
+ ### What a traditional LLM request looks like
46
+
47
+ ```
48
+ POST /v1/chat/completions
49
+ x-api-key: sk-NqR7xT9vKmLpWz3bYhUd <- your key, fully exposed
50
+ x-uid: usr_8f3a1b2c
51
+
52
+ { "messages": [{ "role": "user", "content": "What is the meaning of life?" }] }
53
+ ```
54
+
55
+ Everything is readable. Your key, your identity, your prompt.
56
+
57
+ ### What the same request looks like through NovaQore AI
58
+
59
+ ```
60
+ POST /v1/chat/completions
61
+
62
+ {
63
+ "uid": "usr_8f3a1b2c",
64
+ "keyId": "OnHODAr8kb6r5iUaZk6",
65
+ "ciphertext": "K3mVpQ8xTz1Rf5wNyB7uHcLgA0jXoE4sDi9vMaG2kY...==",
66
+ "encrypted": "mNx8Kv2QpLrT5wYzBf1HcOjXgA4sEi7uDa9RtM3kWb...=="
67
+ }
68
+ ```
69
+
70
+ Random bytes. No API key. No readable content. The response comes back encrypted the same way.
71
+
72
+ ---
73
+
74
+ ## Who is NovaQore AI for
75
+
76
+ ### βœ… Built for
77
+
78
+ - βœ… **Healthcare and medical companies** handling patient data, HIPAA-regulated workflows, and clinical AI
79
+ - βœ… **Financial institutions** processing sensitive transactions, risk models, and customer data
80
+ - βœ… **Legal firms** working with privileged communications, contracts, and case strategy
81
+ - βœ… **Government agencies** that require data sovereignty and classified-level privacy
82
+ - βœ… **Defense contractors** building AI into systems where exposure is not an option
83
+ - βœ… **Enterprise teams** with internal data that cannot leave a controlled pipeline
84
+ - βœ… **Startups with proprietary IP** who need AI without leaking trade secrets to third-party providers
85
+ - βœ… **Developers building for regulated industries** where compliance requires encryption at rest and in transit
86
+ - βœ… **Anyone who believes their AI conversations are nobody else's business**
87
+
88
+ ### ❌ Not built for
89
+
90
+ - ❌ Illegal activity of any kind
91
+ - ❌ Spying, stalking, or surveillance
92
+ - ❌ Generating content that exploits or harms others
93
+ - ❌ Mass data collection or scraping
94
+ - ❌ Anything that violates local, state, or federal law
95
+
96
+ ---
97
+
98
+ ## What makes NovaQore AI different
99
+
100
+ | | Traditional LLM API | NovaQore AI |
101
+ |---|---|---|
102
+ | Your prompts | Plaintext, readable by anyone in the middle | Quantum-encrypted, unreadable in transit |
103
+ | Your API key | Exposed in headers on every request | Never sent. Replaced by quantum handshake |
104
+ | Key exchange | None | Kyber1024 (post-quantum safe) |
105
+ | Per-request keys | No, same key forever | Yes, fresh keys every single call |
106
+ | Infrastructure | Shared, third-party, often overseas | Dedicated πŸ‡ΊπŸ‡Έ US-based servers |
107
+ | Quantum-safe | No | Yes |
108
+
109
+ ---
110
+
111
+ ## Install
112
+
113
+ ```bash
114
+ npm install @novaqore/ai
115
+ ```
116
+
117
+ ```javascript
118
+ // CommonJS
119
+ const NovaQoreAI = require("@novaqore/ai");
120
+
121
+ // ES Module
122
+ import NovaQoreAI from "@novaqore/ai";
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Quick Start
128
+
129
+ Get your quantum keys from the [developer dashboard](https://novaqore.ai/developer).
130
+
131
+ ### 1. Drop in your service file and go
132
+
133
+ Download your `novaqore-ai-service-*.json` and drop it in your project root:
134
+
135
+ ```javascript
136
+ import NovaQoreAI from "@novaqore/ai";
137
+
138
+ const nq = new NovaQoreAI();
139
+
140
+ const res = await nq.chat([
141
+ { role: "user", content: "Hello" }
142
+ ]);
143
+
144
+ console.log(res.choices[0].message.content);
145
+ ```
146
+
147
+ NovaQore AI auto-detects the service file. If no service file is found, it falls back to environment variables automatically.
148
+
149
+ ### 2. Or pass the path explicitly
150
+
151
+ ```javascript
152
+ const nq = new NovaQoreAI("./novaqore-ai-service-MkT3xYpLqN8vRwS1.json");
153
+ ```
154
+
155
+ ### 3. Or use environment variables
156
+
157
+ ```env
158
+ NOVAQORE_UID=your-user-id
159
+ NOVAQORE_QUANTUM_KEY=your-base64-quantum-key
160
+ NOVAQORE_KEY_ID=your-key-id
161
+ ```
162
+
163
+ ```javascript
164
+ const nq = new NovaQoreAI({
165
+ uid: process.env.NOVAQORE_UID,
166
+ quantumKey: process.env.NOVAQORE_QUANTUM_KEY,
167
+ keyId: process.env.NOVAQORE_KEY_ID,
168
+ });
169
+ ```
170
+
171
+ If you call `new NovaQoreAI()` with no arguments and no service file is present, it will automatically read from these environment variables.
172
+
173
+ ---
174
+
175
+ ## Examples
176
+
177
+ ### System prompt
178
+
179
+ ```javascript
180
+ const res = await nq.chat([
181
+ { role: "system", content: "You are a helpful assistant that responds in haikus." },
182
+ { role: "user", content: "Tell me about the ocean" }
183
+ ]);
184
+ ```
185
+
186
+ ### Tool use
187
+
188
+ ```javascript
189
+ const res = await nq.chat(
190
+ [{ role: "user", content: "What's the weather in NYC?" }],
191
+ {
192
+ tools: [
193
+ {
194
+ type: "function",
195
+ function: {
196
+ name: "get_weather",
197
+ description: "Get weather for a location",
198
+ parameters: {
199
+ type: "object",
200
+ properties: {
201
+ location: { type: "string", description: "City name" }
202
+ },
203
+ required: ["location"]
204
+ }
205
+ }
206
+ }
207
+ ]
208
+ }
209
+ );
210
+
211
+ const toolCall = res.choices[0].message.tool_calls[0];
212
+ console.log(toolCall.function.name); // "get_weather"
213
+ console.log(toolCall.function.arguments); // '{"location":"New York City"}'
214
+ ```
215
+
216
+ ### Streaming
217
+
218
+ ```javascript
219
+ const stream = await nq.chat(
220
+ [{ role: "user", content: "Tell me about the ocean" }],
221
+ { stream: true }
222
+ );
223
+
224
+ for await (const chunk of stream) {
225
+ const content = chunk.choices[0]?.delta?.content || "";
226
+ process.stdout.write(content);
227
+ }
228
+ console.log();
229
+ ```
230
+
231
+ ### Options
232
+
233
+ | Option | Type | Default | Description |
234
+ |--------|------|---------|-------------|
235
+ | `temperature` | float | - | Sampling temperature (0-2) |
236
+ | `stream` | bool | `false` | Stream response |
237
+ | `tools` | array | - | Tool definitions |
238
+ | `tool_choice` | string | - | Tool selection mode |
239
+
240
+ ### Health check
241
+
242
+ ```javascript
243
+ const status = await nq.health();
244
+ ```
245
+
246
+ ---
247
+
248
+ ## Zero Dependencies
249
+
250
+ NovaQore AI vendors all of its cryptographic libraries. Kyber1024 and SHA-3 are bundled directly in `lib/`. There are no external npm dependencies. No supply chain risk. The only requirement is Node 18 or higher.
251
+
252
+ ---
253
+
254
+ ## Roadmap
255
+
256
+ We are actively building the next generation of private AI infrastructure. Multi-model support, streaming encryption, and more.
257
+
258
+ **[View the Roadmap](https://novaqore.ai/roadmap)**
259
+
260
+ ---
261
+
262
+ ## White Papers
263
+
264
+ Technical deep dives into the cryptography, architecture, and threat models behind NovaQore AI. How we protect your data, why we chose Kyber1024, and what post-quantum safety actually means in practice.
265
+
266
+ **[Read the White Papers](https://novaqore.ai/white-papers)**
267
+
268
+ ---
269
+
270
+ ## Community
271
+
272
+ We are building this in the open. Join us.
273
+
274
+ <p>
275
+ <a href="https://discord.gg/novaqore"><strong>Discord</strong></a> &nbsp;|&nbsp;
276
+ <a href="https://x.com/novaqore"><strong>X (Twitter)</strong></a> &nbsp;|&nbsp;
277
+ <a href="https://tiktok.com/@novaqore"><strong>TikTok</strong></a> &nbsp;|&nbsp;
278
+ <a href="https://youtube.com/@novaqore"><strong>YouTube</strong></a>
279
+ </p>
280
+
281
+ ---
282
+
283
+ ## Credits
284
+
285
+ - [CRYSTALS-Kyber](https://github.com/antontutoveanu/crystals-kyber-javascript) - Post-quantum key encapsulation (Kyber1024)
286
+ - [sha3](https://github.com/phusion/node-sha3) - Keccak/SHA-3 hashing
287
+
288
+ ## Disclaimer
289
+
290
+ NovaQore AI is provided as-is. We do not store your conversations. We do not log your prompts or responses. We do not use your data to train models. Your messages are encrypted on your machine, decrypted only long enough to run the model, and the response is encrypted before it leaves our server. We do not have access to the content of your requests and we do not keep copies.
291
+
292
+ We built NovaQore AI to give people and businesses a genuinely private way to use AI. That said, NovaQore AI is not a tool for illegal activity. We do not tolerate unlawful use of our service. While we cannot see your data, we will cooperate with law enforcement when presented with a valid legal order as required by law.
293
+
294
+ By using NovaQore AI, you agree to use it responsibly and in compliance with all applicable laws.
295
+
296
+ ## License
297
+
298
+ MIT
299
+
300
+ ---
301
+
302
+ <p align="center">
303
+ <a href="https://chat.novaqore.ai"><strong>πŸ’¬ Start Chat β€” Quantum-Private AI</strong></a>
304
+ <br><br>
305
+ Powered by <a href="https://novaqore.ai">NovaQore Tech</a>
306
+ </p>
package/index.js ADDED
@@ -0,0 +1,186 @@
1
+ const { Encrypt1024 } = require("./lib/kyber1024");
2
+ const crypto = require("crypto");
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ const BASE_URL = "https://api.novaqore.ai";
7
+ const { version } = require("./package.json");
8
+
9
+ class NovaQoreAI {
10
+ #uid;
11
+ #quantumKey;
12
+ #keyId;
13
+
14
+ constructor(config) {
15
+ if (config === undefined) {
16
+ const files = fs.readdirSync(process.cwd()).filter(f => f.startsWith("novaqore-ai-service-") && f.endsWith(".json"));
17
+ if (files.length > 0) {
18
+ config = JSON.parse(fs.readFileSync(path.resolve(files[0]), "utf-8"));
19
+ } else {
20
+ config = {
21
+ uid: process.env.NOVAQORE_UID,
22
+ quantumKey: process.env.NOVAQORE_QUANTUM_KEY,
23
+ keyId: process.env.NOVAQORE_KEY_ID,
24
+ };
25
+ }
26
+ } else if (typeof config === "string") {
27
+ const filePath = path.resolve(config);
28
+ if (!fs.existsSync(filePath)) {
29
+ throw new Error(`Service file not found: ${filePath}`);
30
+ }
31
+ config = JSON.parse(fs.readFileSync(filePath, "utf-8"));
32
+ }
33
+ if (!config || typeof config !== "object") {
34
+ throw new Error("NovaQoreAI requires { uid, quantumKey, keyId }");
35
+ }
36
+ if (!config.uid) {
37
+ throw new Error("uid is required");
38
+ }
39
+ if (!config.quantumKey) {
40
+ throw new Error("quantumKey is required");
41
+ }
42
+ if (!config.keyId) {
43
+ throw new Error("keyId is required");
44
+ }
45
+ this.#uid = config.uid;
46
+ this.#quantumKey = config.quantumKey;
47
+ this.#keyId = config.keyId;
48
+ this.version = version;
49
+ this.description = "NovaQore AI - Quantum-encrypted LLM client by NovaQore";
50
+ this.methods = ["chat", "health"];
51
+ }
52
+
53
+ async #encryptPayload(payload) {
54
+ const quantumKey = new Uint8Array(Buffer.from(this.#quantumKey, "base64"));
55
+
56
+ const [ciphertext, sharedSecret] = await Encrypt1024(quantumKey);
57
+
58
+ const iv = crypto.randomBytes(12);
59
+ const cipher = crypto.createCipheriv("aes-256-gcm", Buffer.from(sharedSecret), iv);
60
+ const plaintext = Buffer.from(JSON.stringify(payload), "utf-8");
61
+ const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);
62
+ const tag = cipher.getAuthTag();
63
+
64
+ const packed = Buffer.concat([iv, encrypted, tag]);
65
+
66
+ return {
67
+ ciphertext: Buffer.from(ciphertext).toString("base64"),
68
+ encrypted: packed.toString("base64"),
69
+ sharedSecret: Buffer.from(sharedSecret),
70
+ };
71
+ }
72
+
73
+ #decryptResponse(encryptedB64, sharedSecret) {
74
+ const buf = Buffer.from(encryptedB64, "base64");
75
+ const iv = buf.subarray(0, 12);
76
+ const tag = buf.subarray(buf.length - 16);
77
+ const ciphertext = buf.subarray(12, buf.length - 16);
78
+ const decipher = crypto.createDecipheriv("aes-256-gcm", sharedSecret, iv);
79
+ decipher.setAuthTag(tag);
80
+ const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
81
+ return JSON.parse(decrypted.toString("utf-8"));
82
+ }
83
+
84
+ async chat(messages, options = {}) {
85
+ if (!messages || !Array.isArray(messages) || messages.length === 0) {
86
+ throw new Error("Messages must be a non-empty array");
87
+ }
88
+
89
+ try {
90
+ const payload = {
91
+ messages,
92
+ temperature: options.temperature,
93
+ stream: options.stream || false,
94
+ ...(options.tools && { tools: options.tools }),
95
+ ...(options.tool_choice && { tool_choice: options.tool_choice }),
96
+ };
97
+
98
+ const { ciphertext, encrypted, sharedSecret } = await this.#encryptPayload(payload);
99
+
100
+ const res = await fetch(`${BASE_URL}/v1/chat/completions`, {
101
+ method: "POST",
102
+ headers: { "Content-Type": "application/json" },
103
+ body: JSON.stringify({
104
+ uid: this.#uid,
105
+ keyId: this.#keyId,
106
+ ciphertext,
107
+ encrypted,
108
+ }),
109
+ });
110
+
111
+ if (!res.ok) {
112
+ const body = await res.text();
113
+ try {
114
+ const parsed = JSON.parse(body);
115
+ throw new Error(parsed.error || `Request failed with status ${res.status}`);
116
+ } catch (e) {
117
+ if (e.message && !e.message.includes("JSON")) throw e;
118
+ throw new Error(`Request failed with status ${res.status}`);
119
+ }
120
+ }
121
+
122
+ if (options.stream) {
123
+ return this.#readStream(res, sharedSecret);
124
+ }
125
+
126
+ const { encrypted: encryptedResponse } = await res.json();
127
+ return this.#decryptResponse(encryptedResponse, sharedSecret);
128
+ } catch (err) {
129
+ if (err.message) throw err;
130
+ throw new Error("Failed to connect to NovaQore AI");
131
+ }
132
+ }
133
+
134
+ async *#readStream(res, sharedSecret) {
135
+ const decoder = new TextDecoder();
136
+ const reader = res.body.getReader();
137
+ let buffer = "";
138
+ let expectedSeq = 0;
139
+
140
+ while (true) {
141
+ const { done, value } = await reader.read();
142
+ if (done) break;
143
+ buffer += decoder.decode(value, { stream: true });
144
+
145
+ const lines = buffer.split("\n");
146
+ buffer = lines.pop();
147
+
148
+ for (const line of lines) {
149
+ const trimmed = line.trim();
150
+ if (!trimmed || !trimmed.startsWith("data: ")) continue;
151
+ const data = trimmed.slice(6);
152
+
153
+ if (data === "[DONE]") return;
154
+
155
+ const { encrypted } = JSON.parse(data);
156
+ const chunk = this.#decryptResponse(encrypted, sharedSecret);
157
+
158
+ if (chunk.seq !== expectedSeq) {
159
+ throw new Error(`Chunk out of order: expected ${expectedSeq}, got ${chunk.seq}`);
160
+ }
161
+ expectedSeq++;
162
+
163
+ yield chunk;
164
+ }
165
+ }
166
+ }
167
+
168
+ async health() {
169
+ try {
170
+ const res = await fetch(`${BASE_URL}/health`, {
171
+ headers: {
172
+ "x-uid": this.#uid,
173
+ },
174
+ });
175
+ if (!res.ok) {
176
+ throw new Error(`Health check failed with status ${res.status}`);
177
+ }
178
+ return res.json();
179
+ } catch (err) {
180
+ if (err.message) throw err;
181
+ throw new Error("Failed to connect to NovaQore AI");
182
+ }
183
+ }
184
+ }
185
+
186
+ module.exports = NovaQoreAI;