11 KiB
11 KiB
Examples
Basic Usage
Simple Chat
import { SecureChatCompletion } from 'nomyo-js';
const client = new SecureChatCompletion({ apiKey: process.env.NOMYO_API_KEY });
const response = await client.create({
model: 'Qwen/Qwen3-0.6B',
messages: [{ role: 'user', content: 'Hello, how are you?' }],
temperature: 0.7,
});
console.log(response.choices[0].message.content);
client.dispose();
Chat with System Message
const response = await client.create({
model: 'Qwen/Qwen3-0.6B',
messages: [
{ role: 'system', content: 'You are a concise technical assistant.' },
{ role: 'user', content: 'What is the capital of France?' },
],
temperature: 0.7,
});
console.log(response.choices[0].message.content);
Security Tiers
// Standard — general use (GPU)
const r1 = await client.create({
model: 'Qwen/Qwen3-0.6B',
messages: [{ role: 'user', content: 'General query' }],
security_tier: 'standard',
});
// High — sensitive business data
const r2 = await client.create({
model: 'Qwen/Qwen3-0.6B',
messages: [{ role: 'user', content: 'Review this contract clause...' }],
security_tier: 'high',
});
// Maximum — HIPAA PHI / classified data (CPU-only)
const r3 = await client.create({
model: 'Qwen/Qwen3-0.6B',
messages: [{ role: 'user', content: 'Patient record summary...' }],
security_tier: 'maximum',
});
Tool / Function Calling
const response = await client.create({
model: 'Qwen/Qwen3-0.6B',
messages: [{ role: 'user', content: "What's the weather in Paris?" }],
tools: [
{
type: 'function',
function: {
name: 'get_weather',
description: 'Get weather information for a location',
parameters: {
type: 'object',
properties: {
location: { type: 'string', description: 'City name' },
},
required: ['location'],
},
},
},
],
tool_choice: 'auto',
});
const message = response.choices[0].message;
if (message.tool_calls?.length) {
const call = message.tool_calls[0];
const args = JSON.parse(call.function.arguments);
console.log(`Call ${call.function.name}(location="${args.location}")`);
// → Call get_weather(location="Paris")
}
Error Handling
import {
SecureChatCompletion,
AuthenticationError,
RateLimitError,
ForbiddenError,
InvalidRequestError,
ServerError,
ServiceUnavailableError,
APIConnectionError,
SecurityError,
} from 'nomyo-js';
const client = new SecureChatCompletion({ apiKey: process.env.NOMYO_API_KEY });
try {
const response = await client.create({
model: 'Qwen/Qwen3-0.6B',
messages: [{ role: 'user', content: 'Hello' }],
});
console.log(response.choices[0].message.content);
} catch (err) {
if (err instanceof AuthenticationError) {
console.error('Check your API key:', err.message);
} else if (err instanceof RateLimitError) {
console.error('Rate limit hit after all retries:', err.message);
} else if (err instanceof ForbiddenError) {
console.error('Model not allowed for this security tier:', err.message);
} else if (err instanceof InvalidRequestError) {
console.error('Bad request:', err.message, err.errorDetails);
} else if (err instanceof ServerError || err instanceof ServiceUnavailableError) {
console.error('Server error after retries:', err.message);
} else if (err instanceof APIConnectionError) {
console.error('Network error after retries:', err.message);
} else if (err instanceof SecurityError) {
console.error('Security/crypto failure:', err.message);
} else {
throw err;
}
}
Real-World Scenarios
Chat Application with History
import { SecureChatCompletion } from 'nomyo-js';
class SecureChatApp {
constructor(apiKey) {
this.client = new SecureChatCompletion({ apiKey });
this.history = [];
}
async chat(userMessage) {
this.history.push({ role: 'user', content: userMessage });
const response = await this.client.create({
model: 'Qwen/Qwen3-0.6B',
messages: this.history,
temperature: 0.7,
});
const assistantMessage = response.choices[0].message;
this.history.push({ role: assistantMessage.role, content: assistantMessage.content });
return assistantMessage.content;
}
dispose() {
this.client.dispose();
}
}
const app = new SecureChatApp(process.env.NOMYO_API_KEY);
const r1 = await app.chat("What's your name?");
console.log('Assistant:', r1);
const r2 = await app.chat('What did I just ask you?');
console.log('Assistant:', r2);
app.dispose();
Per-Request Base URL Override
For multi-tenant setups or testing against different router instances from a single client:
const client = new SecureChatCompletion({
baseUrl: 'https://primary.nomyo.ai:12435',
apiKey: process.env.NOMYO_API_KEY,
});
// This single request goes to a different router; a temporary client is
// created, used, and disposed automatically — the main client is unchanged
const response = await client.create({
model: 'Qwen/Qwen3-0.6B',
messages: [{ role: 'user', content: 'Hello from secondary router' }],
base_url: 'https://secondary.nomyo.ai:12435',
});
Environment-Based Configuration
import 'dotenv/config';
import { SecureChatCompletion } from 'nomyo-js';
const client = new SecureChatCompletion({
baseUrl: process.env.NOMYO_SERVER_URL ?? 'https://api.nomyo.ai',
apiKey: process.env.NOMYO_API_KEY,
keyDir: process.env.NOMYO_KEY_DIR ?? 'client_keys',
maxRetries: Number(process.env.NOMYO_MAX_RETRIES ?? '2'),
debug: process.env.NODE_ENV === 'development',
});
Batch Processing
Sequential (Rate-Limit-Safe)
const queries = [
'Summarise document A',
'Summarise document B',
'Summarise document C',
];
const summaries = [];
for (const query of queries) {
const response = await client.create({
model: 'Qwen/Qwen3-0.6B',
messages: [{ role: 'user', content: query }],
});
summaries.push(response.choices[0].message.content);
// Optional: add a small delay to stay within rate limits
await new Promise(r => setTimeout(r, 600));
}
Concurrent (With Throttling)
// Process in batches of 2 (the default rate limit)
async function batchN(items, batchSize, fn) {
const results = [];
for (let i = 0; i < items.length; i += batchSize) {
const batch = items.slice(i, i + batchSize);
const batchResults = await Promise.all(batch.map(fn));
results.push(...batchResults);
if (i + batchSize < items.length) {
await new Promise(r => setTimeout(r, 1100)); // wait >1 s between batches
}
}
return results;
}
const summaries = await batchN(documents, 2, async (doc) => {
const response = await client.create({
model: 'Qwen/Qwen3-0.6B',
messages: [{ role: 'user', content: `Summarise: ${doc}` }],
});
return response.choices[0].message.content;
});
Thinking Models
const response = await client.create({
model: 'LiquidAI/LFM2.5-1.2B-Thinking',
messages: [{ role: 'user', content: 'Is 9.9 larger than 9.11?' }],
});
const { content, reasoning_content } = response.choices[0].message;
console.log('Reasoning:', reasoning_content); // internal chain-of-thought
console.log('Answer:', content); // final answer to the user
Browser Usage
<!DOCTYPE html>
<html>
<head>
<title>NOMYO Secure Chat</title>
</head>
<body>
<textarea id="input" placeholder="Ask something..."></textarea>
<button id="send">Send</button>
<div id="output"></div>
<script type="module">
import { SecureChatCompletion } from 'https://unpkg.com/nomyo-js/dist/browser/index.js';
// In production, proxy through your backend instead of exposing the API key
const client = new SecureChatCompletion({
baseUrl: 'https://api.nomyo.ai',
apiKey: 'your-api-key', // see note above
});
document.getElementById('send').addEventListener('click', async () => {
const text = document.getElementById('input').value.trim();
if (!text) return;
document.getElementById('output').textContent = 'Thinking...';
try {
const response = await client.create({
model: 'Qwen/Qwen3-0.6B',
messages: [{ role: 'user', content: text }],
});
document.getElementById('output').textContent =
response.choices[0].message.content;
} catch (err) {
document.getElementById('output').textContent = `Error: ${err.message}`;
}
});
</script>
</body>
</html>
Advanced Key Management
Custom Key Directory
const client = new SecureChatCompletion({
apiKey: process.env.NOMYO_API_KEY,
keyDir: '/var/lib/myapp/nomyo-keys', // outside project directory
keyRotationDir: '/var/lib/myapp/nomyo-keys',
keyRotationPassword: process.env.NOMYO_KEY_PASSWORD,
});
Generating Keys Manually
import { SecureCompletionClient } from 'nomyo-js';
const client = new SecureCompletionClient({
routerUrl: 'https://api.nomyo.ai',
});
// Generate a new 4096-bit key pair and save it with password protection
await client.generateKeys({
saveToFile: true,
keyDir: 'client_keys',
password: process.env.NOMYO_KEY_PASSWORD,
});
console.log('Keys generated and saved to client_keys/');
client.dispose();
Loading Keys Explicitly
import { SecureCompletionClient } from 'nomyo-js';
const client = new SecureCompletionClient({ routerUrl: 'https://api.nomyo.ai' });
await client.loadKeys(
'client_keys/private_key.pem',
'client_keys/public_key.pem',
process.env.NOMYO_KEY_PASSWORD
);
// Now send requests using the loaded keys
const result = await client.sendSecureRequest(
{ model: 'Qwen/Qwen3-0.6B', messages: [{ role: 'user', content: 'Hello' }] },
crypto.randomUUID()
);
client.dispose();
Inspecting Memory Protection
import { getMemoryProtectionInfo } from 'nomyo-js';
const info = getMemoryProtectionInfo();
console.log(`Memory method: ${info.method}`); // 'zero-only' or 'mlock'
console.log(`Can lock: ${info.canLock}`); // true if native addon present
console.log(`Details: ${info.details}`);
TypeScript
Full type safety out of the box:
import {
SecureChatCompletion,
ChatCompletionRequest,
ChatCompletionResponse,
Message,
} from 'nomyo-js';
const client = new SecureChatCompletion({ apiKey: process.env.NOMYO_API_KEY! });
const messages: Message[] = [
{ role: 'user', content: 'Hello!' },
];
const request: ChatCompletionRequest = {
model: 'Qwen/Qwen3-0.6B',
messages,
temperature: 0.7,
};
const response: ChatCompletionResponse = await client.create(request);
const content = response.choices[0].message.content;
client.dispose();