artemii.js is a zero-dependency ES module for the Artemii Platform API. It works in browsers, Node 18+, Deno, Bun and Workers.
Copy the file into your project and import it. It is not published to a package registry.
Create a client
JavaScript
import { createClient } from './artemii.js';
const ai = createClient({ baseUrl: 'https://mayfair-ai.crelloo.workers.dev', apiKey: process.env.ARTEMII_KEY });
const reply = await ai.chat({ model: 'arlo', messages: [{ role: 'user', content: 'Hello' }] });
console.log(reply.choices[0].message.content);| Option | Notes |
|---|---|
baseUrl | Required. The gateway address, without /v1. |
getToken | async (forceRefresh) => accessToken. A Mayfair ID access token. On a 401 the SDK calls it once more with true so you can force a refresh. |
apiKey | A service key. Server side only. |
timeoutMs | Abort a request after this many milliseconds. Default: no timeout. |
fetch | Your own fetch implementation, for tests or proxies. |
dangerouslyAllowBrowser | Lets a service key run in a browser. Do not use it. |
You must pass either getToken or apiKey. The SDK refuses to run a service key in a browser.
Methods
| Method | Returns |
|---|---|
chat(params) | The OpenAI response object, or with stream: true an async iterator of chunks. Other fields (max_tokens, temperature, tools, user, ...) pass through. Add signal to cancel. |
chatText(params, onText) | The whole streamed answer as a string, calling onText for each piece. |
models() | The models this credential may use. |
me() | Who the credential is, and what is left. |
JavaScript
import { createClient } from './artemii.js';
const ai = createClient({ baseUrl: 'https://mayfair-ai.crelloo.workers.dev', apiKey: process.env.ARTEMII_KEY });
for await (const part of ai.chat({ model: 'arlo', stream: true, messages: [{ role: 'user', content: 'Tell me a story' }] })) {
process.stdout.write(part.choices[0]?.delta?.content ?? '');
}
// or collect the whole text and render each piece as it arrives
const text = await ai.chatText({ model: 'arlo', messages: [{ role: 'user', content: 'Hello' }] }, (piece) => process.stdout.write(piece));
console.log('\n' + text.length + ' characters');JavaScript
import { createClient } from './artemii.js';
const ai = createClient({ baseUrl: 'https://mayfair-ai.crelloo.workers.dev', apiKey: process.env.ARTEMII_KEY });
console.log(await ai.models()); // [{ id: 'arlo', label: 'Arlo', version: '3.2', ... }]
console.log(await ai.me()); // who the key is, and what is leftErrors
Failures throw ArtemiiError with status, code, type, retryAfter (seconds) and requestId. Network failures have code: "network" and cancelled requests code: "aborted".
JavaScript
import { createClient, ArtemiiError } from './artemii.js';
const ai = createClient({ baseUrl: 'https://mayfair-ai.crelloo.workers.dev', apiKey: process.env.ARTEMII_KEY });
async function ask(messages) {
for (let attempt = 0; attempt < 3; attempt++) {
try {
return await ai.chat({ model: 'arlo', messages });
} catch (err) {
if (!(err instanceof ArtemiiError)) throw err;
const retryable = err.status === 429 || err.status === 503; // see Errors and limits
if (!retryable || attempt === 2) {
console.error(err.status, err.code, err.message, 'request id:', err.requestId);
throw err;
}
await new Promise((resolve) => setTimeout(resolve, (err.retryAfter ?? 2) * 1000));
}
}
}
const reply = await ask([{ role: 'user', content: 'Hello' }]);
console.log(reply.choices[0].message.content);In a browser
JavaScript
import { createClient } from './artemii.js';
// In a browser use the signed-in person's Mayfair ID access token, never a service key.
const ai = createClient({
baseUrl: 'https://mayfair-ai.crelloo.workers.dev',
getToken: (forceRefresh) => mayfairId.getToken(forceRefresh), // a 401 triggers one retry with forceRefresh = true
});
const reply = await ai.chat({ model: 'arlo', messages: [{ role: 'user', content: 'Summarise this page' }] });Get the token from Mayfair ID with the helper described on the embed page.