niyoos
v0.1.0
Published
Beta — the API may change before 1.0. Run labelling for the Niyoos proxy: wraps your own OpenAI client so every call carries its run id, step and parent run.
Maintainers
Readme
niyoos — TypeScript / JavaScript SDK
Niyoos is the model gateway for your AI agents: every LLM call they make goes through the Niyoos proxy, where it is recorded, priced and governed. This SDK labels each call with the run it belongs to, so you can see what an agent did, step by step.
Beta — the API may change before 1.0.
Labels every LLM call your agent makes through the Niyoos proxy with the run it belongs to, its
step, and the run that spawned it. Your agent keeps its own openai client. One package for
TypeScript and JavaScript: ES modules, CommonJS, and type definitions. Node 18 or later.
Install
npm install niyoos openaiQuickstart — TypeScript (or JavaScript with import)
Create an agent in the Niyoos dashboard, copy its agent key, and wrap your own OpenAI client with it:
import * as niyoos from 'niyoos';
import OpenAI from 'openai';
const client = niyoos.wrap(new OpenAI({ apiKey: process.env.NIYOOS_AGENT_KEY })); // -> https://api.niyoos.com/proxy/v1
await niyoos.run(async () => { // a new run: a UUIDv7 id, steps counted 1, 2, 3 …
await client.chat.completions.create({ model: 'gpt-4o', messages });
await niyoos.run(async () => { // a sub-agent: its own run, parent linked automatically
await client.chat.completions.create({ model: 'gpt-4o', messages });
});
emitter.on('job', niyoos.bind(handleJob)); // callbacks fired from outside the run need bind()
});Quickstart — plain JavaScript (require)
const niyoos = require('niyoos');
const { OpenAI } = require('openai');
const client = niyoos.wrap(new OpenAI({ apiKey: process.env.NIYOOS_AGENT_KEY }));
niyoos.run(async () => {
await client.chat.completions.create({ model: 'gpt-4o', messages });
await niyoos.run(async () => { /* sub-agent */ });
}).then(() => console.log('run finished'));niyoos.run(fn, { runId, parentRunId }) continues a run, or links a sub-agent that runs in another
process or worker thread: pass it niyoos.currentRunId() from the parent. run() returns whatever
fn returns.
What goes on the wire
| Header | Value |
|---|---|
| x-niyoos-run-id | the run id, 8–64 of A-Z a-z 0-9 _ - |
| x-niyoos-step | 1, 2, 3 … within the run; a retry repeats its step |
| x-niyoos-parent-run-id | the parent run, for a nested run |
| x-niyoos-client | sdk-typescript, on every request |
| User-Agent | the openai library's own, with niyoos-typescript/0.1.0 appended |
Outside a run, none of the three run headers is sent. Run headers also work without this SDK: any HTTP client can send them; the SDK only mints the ids, counts steps and links parents for you.
Behaviour you should know
- Labels are advisory. Every policy (kill switch, rate and cost limits) is enforced by the
server whether or not a call is labelled. If the SDK ever fails to build a label, the call goes
out unlabelled, with one
NiyoosWarningprocess warning, and is not otherwise affected. wrap()changes the client you pass and returns it (openai 4.x–7.x). It sets the Niyoos base URL only when the client still points at the OpenAI default; abaseURLyou set yourself is left alone. Copies made later withclient.withOptions()stay labelled.- The run follows
await,Promise.all, timers and callbacks started inside it. AnEventEmitterlistener runs in the context of whoever callsemit(): if that happens outside the run, wrap the listener withniyoos.bind(fn). - worker_threads share nothing: post
niyoos.currentRunId()to the worker and callniyoos.run(fn, { parentRunId })inside it — the worker's calls become a child run. - A generator that makes calls belongs to whichever run is open when it is resumed.
- Retries are recognised from the openai library's
x-stainless-retry-countheader and repeat the step of the attempt they retry, even insidePromise.all. - The request body is never modified.
- Node only. The SDK needs
node:async_hooks. Do not use it in a browser: an agent key must never be shipped to one. Server-side runtimes are the supported target. - For other libraries, pass
niyoos.wrapFetch()(or the ready-madeniyoos.fetch) as theirfetchoption, e.g.new Anthropic({ fetch: niyoos.wrapFetch(), baseURL: 'https://api.niyoos.com/proxy' }). There are no dedicated Anthropic or LangChain adapters in v0.1.
openai is an optional peer dependency: >=4 <8. Note that openai 7.x itself requires Node 22.
Licence
Apache-2.0. Questions: [email protected] · https://niyoos.com
