@rouvanpm/rouva 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -3
- package/package.json +2 -2
- package/dist/index.d.mts +0 -67
- package/dist/index.d.ts +0 -67
- package/dist/index.js +0 -67
- package/dist/index.mjs +0 -40
package/README.md
CHANGED
|
@@ -5,13 +5,13 @@ Official Node.js SDK for [Rouva](https://rouva.io) — managed AI gateway with i
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install rouva
|
|
8
|
+
npm install @rouvanpm/rouva
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
|
-
import { Rouva } from 'rouva'
|
|
14
|
+
import { Rouva } from '@rouvanpm/rouva'
|
|
15
15
|
|
|
16
16
|
const rouva = new Rouva({ apiKey: 'rva_...' })
|
|
17
17
|
|
|
@@ -22,6 +22,29 @@ const response = await rouva.chat.completions.create({
|
|
|
22
22
|
console.log(response.choices[0].message.content)
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
## Provider agnostic
|
|
26
|
+
|
|
27
|
+
Rouva works with all connected providers — Anthropic and OpenAI today, more coming. You can request a specific model or omit it entirely and let Rouva route to the cheapest capable model automatically.
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// Request a specific model
|
|
31
|
+
const res = await rouva.chat.completions.create({
|
|
32
|
+
model: 'gpt-4o',
|
|
33
|
+
messages,
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
// Request a specific Anthropic model
|
|
37
|
+
const res = await rouva.chat.completions.create({
|
|
38
|
+
model: 'claude-sonnet-4-6',
|
|
39
|
+
messages,
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// Let Rouva decide — routes to cheapest model for the task
|
|
43
|
+
const res = await rouva.chat.completions.create({
|
|
44
|
+
messages,
|
|
45
|
+
})
|
|
46
|
+
```
|
|
47
|
+
|
|
25
48
|
## Drop-in replacement for OpenAI
|
|
26
49
|
|
|
27
50
|
```typescript
|
|
@@ -31,7 +54,7 @@ const openai = new OpenAI({ apiKey: '...' })
|
|
|
31
54
|
const res = await openai.chat.completions.create({ messages, model: 'gpt-4o' })
|
|
32
55
|
|
|
33
56
|
// After — Rouva routes to the cheapest capable model automatically
|
|
34
|
-
import { Rouva } from 'rouva'
|
|
57
|
+
import { Rouva } from '@rouvanpm/rouva'
|
|
35
58
|
const rouva = new Rouva({ apiKey: 'rva_...' })
|
|
36
59
|
const res = await rouva.chat.completions.create({ messages })
|
|
37
60
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rouvanpm/rouva",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Official Node.js SDK for Rouva — managed AI gateway with intelligent routing and spend tracking",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -38,4 +38,4 @@
|
|
|
38
38
|
"typescript": "^5.0.0",
|
|
39
39
|
"vitest": "^1.0.0"
|
|
40
40
|
}
|
|
41
|
-
}
|
|
41
|
+
}
|
package/dist/index.d.mts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
interface RouvaOptions {
|
|
2
|
-
/** Your Rouva gateway API key (rva_...) */
|
|
3
|
-
apiKey: string;
|
|
4
|
-
/** Override the default gateway URL — useful for self-hosted or testing */
|
|
5
|
-
baseURL?: string;
|
|
6
|
-
}
|
|
7
|
-
interface Message {
|
|
8
|
-
role: 'system' | 'user' | 'assistant';
|
|
9
|
-
content: string;
|
|
10
|
-
}
|
|
11
|
-
interface ChatCompletionParams {
|
|
12
|
-
messages: Message[];
|
|
13
|
-
/** Target model — omit to let Rouva route intelligently */
|
|
14
|
-
model?: string;
|
|
15
|
-
/** Maximum tokens to generate */
|
|
16
|
-
max_tokens?: number;
|
|
17
|
-
/** Sampling temperature 0–1 */
|
|
18
|
-
temperature?: number;
|
|
19
|
-
/** Stream the response */
|
|
20
|
-
stream?: boolean;
|
|
21
|
-
}
|
|
22
|
-
interface ChatCompletionChoice {
|
|
23
|
-
index: number;
|
|
24
|
-
message: Message;
|
|
25
|
-
finish_reason: string | null;
|
|
26
|
-
}
|
|
27
|
-
interface ChatCompletionUsage {
|
|
28
|
-
prompt_tokens: number;
|
|
29
|
-
completion_tokens: number;
|
|
30
|
-
total_tokens: number;
|
|
31
|
-
}
|
|
32
|
-
interface ChatCompletion {
|
|
33
|
-
id: string;
|
|
34
|
-
object: 'chat.completion';
|
|
35
|
-
created: number;
|
|
36
|
-
model: string;
|
|
37
|
-
choices: ChatCompletionChoice[];
|
|
38
|
-
usage: ChatCompletionUsage;
|
|
39
|
-
/** Rouva metadata — cost, savings, routing decision */
|
|
40
|
-
_rouva?: RouvaResponseMeta;
|
|
41
|
-
}
|
|
42
|
-
interface RouvaResponseMeta {
|
|
43
|
-
/** Actual model used (may differ from requested when intelligently routed) */
|
|
44
|
-
model_used: string;
|
|
45
|
-
/** USD cost for this request */
|
|
46
|
-
cost: number;
|
|
47
|
-
/** USD saved vs your baseline model */
|
|
48
|
-
savings: number;
|
|
49
|
-
/** Whether intelligent routing selected the model */
|
|
50
|
-
intelligently_routed: boolean;
|
|
51
|
-
/** Task type classified by Rouva */
|
|
52
|
-
task_type: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
declare class Rouva {
|
|
56
|
-
private apiKey;
|
|
57
|
-
private baseURL;
|
|
58
|
-
readonly chat: {
|
|
59
|
-
completions: {
|
|
60
|
-
create(params: ChatCompletionParams): Promise<ChatCompletion | ReadableStream>;
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
|
-
constructor(options: RouvaOptions);
|
|
64
|
-
private _createChatCompletion;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export { type ChatCompletion, type ChatCompletionChoice, type ChatCompletionParams, type ChatCompletionUsage, type Message, Rouva, type RouvaOptions, type RouvaResponseMeta };
|
package/dist/index.d.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
interface RouvaOptions {
|
|
2
|
-
/** Your Rouva gateway API key (rva_...) */
|
|
3
|
-
apiKey: string;
|
|
4
|
-
/** Override the default gateway URL — useful for self-hosted or testing */
|
|
5
|
-
baseURL?: string;
|
|
6
|
-
}
|
|
7
|
-
interface Message {
|
|
8
|
-
role: 'system' | 'user' | 'assistant';
|
|
9
|
-
content: string;
|
|
10
|
-
}
|
|
11
|
-
interface ChatCompletionParams {
|
|
12
|
-
messages: Message[];
|
|
13
|
-
/** Target model — omit to let Rouva route intelligently */
|
|
14
|
-
model?: string;
|
|
15
|
-
/** Maximum tokens to generate */
|
|
16
|
-
max_tokens?: number;
|
|
17
|
-
/** Sampling temperature 0–1 */
|
|
18
|
-
temperature?: number;
|
|
19
|
-
/** Stream the response */
|
|
20
|
-
stream?: boolean;
|
|
21
|
-
}
|
|
22
|
-
interface ChatCompletionChoice {
|
|
23
|
-
index: number;
|
|
24
|
-
message: Message;
|
|
25
|
-
finish_reason: string | null;
|
|
26
|
-
}
|
|
27
|
-
interface ChatCompletionUsage {
|
|
28
|
-
prompt_tokens: number;
|
|
29
|
-
completion_tokens: number;
|
|
30
|
-
total_tokens: number;
|
|
31
|
-
}
|
|
32
|
-
interface ChatCompletion {
|
|
33
|
-
id: string;
|
|
34
|
-
object: 'chat.completion';
|
|
35
|
-
created: number;
|
|
36
|
-
model: string;
|
|
37
|
-
choices: ChatCompletionChoice[];
|
|
38
|
-
usage: ChatCompletionUsage;
|
|
39
|
-
/** Rouva metadata — cost, savings, routing decision */
|
|
40
|
-
_rouva?: RouvaResponseMeta;
|
|
41
|
-
}
|
|
42
|
-
interface RouvaResponseMeta {
|
|
43
|
-
/** Actual model used (may differ from requested when intelligently routed) */
|
|
44
|
-
model_used: string;
|
|
45
|
-
/** USD cost for this request */
|
|
46
|
-
cost: number;
|
|
47
|
-
/** USD saved vs your baseline model */
|
|
48
|
-
savings: number;
|
|
49
|
-
/** Whether intelligent routing selected the model */
|
|
50
|
-
intelligently_routed: boolean;
|
|
51
|
-
/** Task type classified by Rouva */
|
|
52
|
-
task_type: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
declare class Rouva {
|
|
56
|
-
private apiKey;
|
|
57
|
-
private baseURL;
|
|
58
|
-
readonly chat: {
|
|
59
|
-
completions: {
|
|
60
|
-
create(params: ChatCompletionParams): Promise<ChatCompletion | ReadableStream>;
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
|
-
constructor(options: RouvaOptions);
|
|
64
|
-
private _createChatCompletion;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export { type ChatCompletion, type ChatCompletionChoice, type ChatCompletionParams, type ChatCompletionUsage, type Message, Rouva, type RouvaOptions, type RouvaResponseMeta };
|
package/dist/index.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
Rouva: () => Rouva
|
|
24
|
-
});
|
|
25
|
-
module.exports = __toCommonJS(index_exports);
|
|
26
|
-
|
|
27
|
-
// src/client.ts
|
|
28
|
-
var DEFAULT_BASE_URL = "https://app.rouva.io";
|
|
29
|
-
var Rouva = class {
|
|
30
|
-
constructor(options) {
|
|
31
|
-
if (!options.apiKey) throw new Error("[Rouva] apiKey is required");
|
|
32
|
-
if (!options.apiKey.startsWith("rva_")) {
|
|
33
|
-
throw new Error("[Rouva] apiKey must start with rva_");
|
|
34
|
-
}
|
|
35
|
-
this.apiKey = options.apiKey;
|
|
36
|
-
this.baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
37
|
-
this.chat = {
|
|
38
|
-
completions: {
|
|
39
|
-
create: (params) => this._createChatCompletion(params)
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
async _createChatCompletion(params) {
|
|
44
|
-
const url = `${this.baseURL}/api/gateway/messages`;
|
|
45
|
-
const res = await fetch(url, {
|
|
46
|
-
method: "POST",
|
|
47
|
-
headers: {
|
|
48
|
-
"Content-Type": "application/json",
|
|
49
|
-
"x-api-key": this.apiKey
|
|
50
|
-
},
|
|
51
|
-
body: JSON.stringify(params)
|
|
52
|
-
});
|
|
53
|
-
if (!res.ok) {
|
|
54
|
-
const body = await res.text().catch(() => res.statusText);
|
|
55
|
-
throw new Error(`[Rouva] Gateway error ${res.status}: ${body}`);
|
|
56
|
-
}
|
|
57
|
-
if (params.stream) {
|
|
58
|
-
if (!res.body) throw new Error("[Rouva] No response body for streaming request");
|
|
59
|
-
return res.body;
|
|
60
|
-
}
|
|
61
|
-
return res.json();
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
65
|
-
0 && (module.exports = {
|
|
66
|
-
Rouva
|
|
67
|
-
});
|
package/dist/index.mjs
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
// src/client.ts
|
|
2
|
-
var DEFAULT_BASE_URL = "https://app.rouva.io";
|
|
3
|
-
var Rouva = class {
|
|
4
|
-
constructor(options) {
|
|
5
|
-
if (!options.apiKey) throw new Error("[Rouva] apiKey is required");
|
|
6
|
-
if (!options.apiKey.startsWith("rva_")) {
|
|
7
|
-
throw new Error("[Rouva] apiKey must start with rva_");
|
|
8
|
-
}
|
|
9
|
-
this.apiKey = options.apiKey;
|
|
10
|
-
this.baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
11
|
-
this.chat = {
|
|
12
|
-
completions: {
|
|
13
|
-
create: (params) => this._createChatCompletion(params)
|
|
14
|
-
}
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
async _createChatCompletion(params) {
|
|
18
|
-
const url = `${this.baseURL}/api/gateway/messages`;
|
|
19
|
-
const res = await fetch(url, {
|
|
20
|
-
method: "POST",
|
|
21
|
-
headers: {
|
|
22
|
-
"Content-Type": "application/json",
|
|
23
|
-
"x-api-key": this.apiKey
|
|
24
|
-
},
|
|
25
|
-
body: JSON.stringify(params)
|
|
26
|
-
});
|
|
27
|
-
if (!res.ok) {
|
|
28
|
-
const body = await res.text().catch(() => res.statusText);
|
|
29
|
-
throw new Error(`[Rouva] Gateway error ${res.status}: ${body}`);
|
|
30
|
-
}
|
|
31
|
-
if (params.stream) {
|
|
32
|
-
if (!res.body) throw new Error("[Rouva] No response body for streaming request");
|
|
33
|
-
return res.body;
|
|
34
|
-
}
|
|
35
|
-
return res.json();
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
export {
|
|
39
|
-
Rouva
|
|
40
|
-
};
|