nomyo-js/doc/examples.md
2026-04-16 16:44:26 +02:00

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();