fix: base_url
doc: created
This commit is contained in:
parent
6e02559f4e
commit
43165f86f2
17 changed files with 2151 additions and 293 deletions
437
doc/examples.md
Normal file
437
doc/examples.md
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
# Examples
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### Simple Chat
|
||||
|
||||
```javascript
|
||||
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
|
||||
|
||||
```javascript
|
||||
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
|
||||
|
||||
```javascript
|
||||
// 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
|
||||
|
||||
```javascript
|
||||
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
|
||||
|
||||
```javascript
|
||||
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
|
||||
|
||||
```javascript
|
||||
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:
|
||||
|
||||
```javascript
|
||||
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
|
||||
|
||||
```javascript
|
||||
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)
|
||||
|
||||
```javascript
|
||||
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)
|
||||
|
||||
```javascript
|
||||
// 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
|
||||
|
||||
```javascript
|
||||
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
|
||||
|
||||
```html
|
||||
<!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
|
||||
|
||||
```javascript
|
||||
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
|
||||
|
||||
```javascript
|
||||
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
|
||||
|
||||
```javascript
|
||||
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
|
||||
|
||||
```javascript
|
||||
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:
|
||||
|
||||
```typescript
|
||||
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();
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue