@hyperion-ai/sdk 0.1.0
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 +79 -0
- package/dist/admin.d.ts +121 -0
- package/dist/admin.d.ts.map +1 -0
- package/dist/admin.js +206 -0
- package/dist/admin.js.map +1 -0
- package/dist/client.d.ts +60 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +132 -0
- package/dist/client.js.map +1 -0
- package/dist/demo.d.ts +1 -0
- package/dist/demo.js +29 -0
- package/dist/demo_tenant_auth.d.ts +1 -0
- package/dist/demo_tenant_auth.js +51 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/admin.d.ts +8 -0
- package/dist/resources/admin.js +17 -0
- package/dist/resources/cache.d.ts +11 -0
- package/dist/resources/cache.js +28 -0
- package/dist/resources/chat.d.ts +9 -0
- package/dist/resources/chat.js +15 -0
- package/dist/resources/embeddings.d.ts +7 -0
- package/dist/resources/embeddings.js +13 -0
- package/dist/types.d.ts +118 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Hyperion TypeScript SDK
|
|
2
|
+
|
|
3
|
+
The official TypeScript/Node.js SDK for the Hyperion AI Gateway. This SDK is a thin, type-safe wrapper around the official `openai` SDK, providing native support for Hyperion's caching, routing, and administrative features.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @hyperion-ai/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { HyperionClient } from '@hyperion-ai/sdk';
|
|
15
|
+
|
|
16
|
+
const client = new HyperionClient({
|
|
17
|
+
apiKey: "your-hyperion-key",
|
|
18
|
+
baseURL: "http://your-gateway:8080/v1"
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const res = await client.chat.completions.create({
|
|
22
|
+
model: "openai/gpt-5.2",
|
|
23
|
+
messages: [{ role: "user", content: "Explain Hyperion." }],
|
|
24
|
+
// Hyperion-specific config
|
|
25
|
+
hyperion: {
|
|
26
|
+
bypassCache: false,
|
|
27
|
+
tags: ["production"],
|
|
28
|
+
routeIntent: "balanced"
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
console.log(`Cache Status: ${res.hyperion.cacheStatus}`);
|
|
33
|
+
console.log(`Similarity Score: ${res.hyperion.similarityScore}`);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
- **Standard OpenAI API**: Drop-in replacement for `OpenAI`. All your existing code works exactly the same.
|
|
39
|
+
- **Type Safety**: Fully typed `hyperion` config block and response metadata.
|
|
40
|
+
- **Enriched Metadata**: Every completion response includes a `.hyperion` property with cache status and semantic similarity details.
|
|
41
|
+
- **Admin Client**: Programmatic management of keys, organizations, and budgets.
|
|
42
|
+
- **Isomorphic**: Works in Node.js, Vercel Edge, Cloudflare Workers, and the browser.
|
|
43
|
+
|
|
44
|
+
## Admin Client
|
|
45
|
+
|
|
46
|
+
The `HyperionAdmin` client provides full control over the gateway management plane.
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { HyperionAdmin } from '@hyperion-ai/sdk';
|
|
50
|
+
|
|
51
|
+
const admin = new HyperionAdmin({ adminKey: "admin_secret" });
|
|
52
|
+
|
|
53
|
+
// Create a new API key with a spend limit
|
|
54
|
+
const key = await admin.keys.create({
|
|
55
|
+
name: "Internal Bot",
|
|
56
|
+
budgetLimitUsd: 50,
|
|
57
|
+
allowedModels: ["gpt-5.2-mini"]
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// List all keys
|
|
61
|
+
const keys = await admin.keys.list();
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Using with standard OpenAI SDK
|
|
65
|
+
|
|
66
|
+
If you don't want to use the `HyperionClient` wrapper, you can manually pass Hyperion headers to the standard OpenAI client:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import OpenAI from 'openai';
|
|
70
|
+
|
|
71
|
+
const client = new OpenAI({ baseURL: "http://your-gateway:8080/v1" });
|
|
72
|
+
|
|
73
|
+
const response = await client.chat.completions.create({
|
|
74
|
+
model: "gpt-5.2",
|
|
75
|
+
messages: [...],
|
|
76
|
+
}, {
|
|
77
|
+
headers: { 'X-Cache-Bypass': 'true' }
|
|
78
|
+
});
|
|
79
|
+
```
|
package/dist/admin.d.ts
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { ApiKey, CreateKeyParams, Tenant, SetBudgetParams, InviteMemberParams, PricingUpsertParams } from './types';
|
|
2
|
+
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
3
|
+
export interface HyperionAdminOptions {
|
|
4
|
+
/** Gateway base URL. Defaults to HYPERION_BASE_URL env var or http://localhost:8080 */
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
/** Admin API key. Defaults to HYPERION_ADMIN_KEY env var. */
|
|
7
|
+
adminKey?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* HyperionAdmin — programmatic management client for the Hyperion Gateway.
|
|
11
|
+
*
|
|
12
|
+
* Separate from HyperionClient (inference). Use this to manage keys,
|
|
13
|
+
* organizations, budgets, members, analytics, and pricing.
|
|
14
|
+
*
|
|
15
|
+
* Works isomorphically in Node.js, Edge (Cloudflare Workers, Vercel Edge),
|
|
16
|
+
* and browser environments since it uses the native `fetch` API.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { HyperionAdmin } from '@hyperion-ai/sdk';
|
|
21
|
+
*
|
|
22
|
+
* const admin = new HyperionAdmin({ adminKey: "admin_secret" });
|
|
23
|
+
*
|
|
24
|
+
* const key = await admin.keys.create({
|
|
25
|
+
* name: "Production",
|
|
26
|
+
* budgetLimitUsd: 100,
|
|
27
|
+
* allowedModels: ["gpt-5.2-mini"],
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* const spend = await admin.analytics.timeseries({ period: "7d" });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class HyperionAdmin {
|
|
34
|
+
private readonly _baseUrl;
|
|
35
|
+
private readonly _adminKey;
|
|
36
|
+
readonly keys: KeysResource;
|
|
37
|
+
readonly tenants: TenantsResource;
|
|
38
|
+
readonly analytics: AnalyticsResource;
|
|
39
|
+
readonly members: MembersResource;
|
|
40
|
+
readonly pricing: PricingResource;
|
|
41
|
+
constructor(opts?: HyperionAdminOptions);
|
|
42
|
+
/** Get gateway health status. */
|
|
43
|
+
health(): Promise<{
|
|
44
|
+
status: string;
|
|
45
|
+
[k: string]: unknown;
|
|
46
|
+
}>;
|
|
47
|
+
}
|
|
48
|
+
type Requester = <T>(m: HttpMethod, path: string, body?: unknown, query?: Record<string, string>) => Promise<T>;
|
|
49
|
+
declare class KeysResource {
|
|
50
|
+
private req;
|
|
51
|
+
constructor(req: Requester);
|
|
52
|
+
/** List all API keys for the current organization. */
|
|
53
|
+
list(): Promise<ApiKey[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Create a new scoped API key.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* const key = await admin.keys.create({
|
|
60
|
+
* name: "Production Bot",
|
|
61
|
+
* budgetLimitUsd: 50,
|
|
62
|
+
* allowedModels: ["gpt-5.2-mini", "claude-3-haiku-20240307"],
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
create(params: CreateKeyParams): Promise<ApiKey>;
|
|
67
|
+
/** Update an existing API key's configuration. */
|
|
68
|
+
update(keyId: string, fields: Partial<CreateKeyParams>): Promise<ApiKey>;
|
|
69
|
+
/** Permanently delete an API key. */
|
|
70
|
+
delete(keyId: string): Promise<{
|
|
71
|
+
deleted: boolean;
|
|
72
|
+
}>;
|
|
73
|
+
/** Rotate the secret value of an API key, immediately invalidating the old one. */
|
|
74
|
+
rotate(keyId: string): Promise<ApiKey>;
|
|
75
|
+
}
|
|
76
|
+
declare class TenantsResource {
|
|
77
|
+
private req;
|
|
78
|
+
constructor(req: Requester);
|
|
79
|
+
/** List all tenants visible to this admin key. */
|
|
80
|
+
list(): Promise<Tenant[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Set or update a hard spend budget for a tenant.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* await admin.tenants.setBudget({ orgId: "org_123", limitUsd: 200, period: "monthly" });
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
setBudget(params: SetBudgetParams): Promise<unknown>;
|
|
90
|
+
}
|
|
91
|
+
declare class AnalyticsResource {
|
|
92
|
+
private req;
|
|
93
|
+
constructor(req: Requester);
|
|
94
|
+
/** Fetch request volume and cost timeseries. */
|
|
95
|
+
timeseries(params?: {
|
|
96
|
+
period?: string;
|
|
97
|
+
orgId?: string;
|
|
98
|
+
}): Promise<unknown>;
|
|
99
|
+
/** Fetch token usage and cost broken down by model. */
|
|
100
|
+
usageByModel(params?: {
|
|
101
|
+
orgId?: string;
|
|
102
|
+
}): Promise<unknown>;
|
|
103
|
+
}
|
|
104
|
+
declare class MembersResource {
|
|
105
|
+
private req;
|
|
106
|
+
constructor(req: Requester);
|
|
107
|
+
/** List all organization members. */
|
|
108
|
+
list(): Promise<unknown[]>;
|
|
109
|
+
/** Invite a new member to the organization by email. */
|
|
110
|
+
invite(params: InviteMemberParams): Promise<unknown>;
|
|
111
|
+
}
|
|
112
|
+
declare class PricingResource {
|
|
113
|
+
private req;
|
|
114
|
+
constructor(req: Requester);
|
|
115
|
+
/** List all model pricing records. */
|
|
116
|
+
list(): Promise<unknown[]>;
|
|
117
|
+
/** Insert or update pricing for a model (cost per 1k tokens, USD). */
|
|
118
|
+
upsert(params: PricingUpsertParams): Promise<unknown>;
|
|
119
|
+
}
|
|
120
|
+
export {};
|
|
121
|
+
//# sourceMappingURL=admin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../src/admin.ts"],"names":[],"mappings":"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"}
|
package/dist/admin.js
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HyperionAdmin = void 0;
|
|
4
|
+
async function request(baseUrl, adminKey, method, path, body, query) {
|
|
5
|
+
let url = `${baseUrl}${path}`;
|
|
6
|
+
if (query && Object.keys(query).length > 0) {
|
|
7
|
+
url += '?' + new URLSearchParams(query).toString();
|
|
8
|
+
}
|
|
9
|
+
const res = await fetch(url, {
|
|
10
|
+
method,
|
|
11
|
+
headers: {
|
|
12
|
+
'Content-Type': 'application/json',
|
|
13
|
+
'X-Admin-Key': adminKey,
|
|
14
|
+
},
|
|
15
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
16
|
+
});
|
|
17
|
+
if (!res.ok) {
|
|
18
|
+
const text = await res.text().catch(() => res.statusText);
|
|
19
|
+
throw new Error(`Hyperion Admin API error ${res.status}: ${text}`);
|
|
20
|
+
}
|
|
21
|
+
return res.json();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* HyperionAdmin — programmatic management client for the Hyperion Gateway.
|
|
25
|
+
*
|
|
26
|
+
* Separate from HyperionClient (inference). Use this to manage keys,
|
|
27
|
+
* organizations, budgets, members, analytics, and pricing.
|
|
28
|
+
*
|
|
29
|
+
* Works isomorphically in Node.js, Edge (Cloudflare Workers, Vercel Edge),
|
|
30
|
+
* and browser environments since it uses the native `fetch` API.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { HyperionAdmin } from '@hyperion-ai/sdk';
|
|
35
|
+
*
|
|
36
|
+
* const admin = new HyperionAdmin({ adminKey: "admin_secret" });
|
|
37
|
+
*
|
|
38
|
+
* const key = await admin.keys.create({
|
|
39
|
+
* name: "Production",
|
|
40
|
+
* budgetLimitUsd: 100,
|
|
41
|
+
* allowedModels: ["gpt-5.2-mini"],
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* const spend = await admin.analytics.timeseries({ period: "7d" });
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
class HyperionAdmin {
|
|
48
|
+
constructor(opts = {}) {
|
|
49
|
+
this._baseUrl = (opts.baseUrl ??
|
|
50
|
+
(typeof process !== 'undefined' ? process.env['HYPERION_BASE_URL'] : undefined) ??
|
|
51
|
+
'http://localhost:8080').replace(/\/+$/, '') + '/v1';
|
|
52
|
+
this._adminKey =
|
|
53
|
+
opts.adminKey ??
|
|
54
|
+
(typeof process !== 'undefined' ? process.env['HYPERION_ADMIN_KEY'] : undefined) ??
|
|
55
|
+
'';
|
|
56
|
+
const req = (method, path, body, query) => request(this._baseUrl, this._adminKey, method, path, body, query);
|
|
57
|
+
this.keys = new KeysResource(req);
|
|
58
|
+
this.tenants = new TenantsResource(req);
|
|
59
|
+
this.analytics = new AnalyticsResource(req);
|
|
60
|
+
this.members = new MembersResource(req);
|
|
61
|
+
this.pricing = new PricingResource(req);
|
|
62
|
+
}
|
|
63
|
+
/** Get gateway health status. */
|
|
64
|
+
async health() {
|
|
65
|
+
return request(this._baseUrl, this._adminKey, 'GET', '/admin/health');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.HyperionAdmin = HyperionAdmin;
|
|
69
|
+
class KeysResource {
|
|
70
|
+
constructor(req) {
|
|
71
|
+
this.req = req;
|
|
72
|
+
}
|
|
73
|
+
/** List all API keys for the current organization. */
|
|
74
|
+
list() {
|
|
75
|
+
return this.req('GET', '/admin/keys');
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Create a new scoped API key.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* const key = await admin.keys.create({
|
|
83
|
+
* name: "Production Bot",
|
|
84
|
+
* budgetLimitUsd: 50,
|
|
85
|
+
* allowedModels: ["gpt-5.2-mini", "claude-3-haiku-20240307"],
|
|
86
|
+
* });
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
create(params) {
|
|
90
|
+
const body = { name: params.name };
|
|
91
|
+
if (params.budgetLimitUsd !== undefined)
|
|
92
|
+
body['budget_limit_usd'] = params.budgetLimitUsd;
|
|
93
|
+
if (params.allowedModels)
|
|
94
|
+
body['allowed_models'] = params.allowedModels;
|
|
95
|
+
if (params.rateLimitRpm !== undefined)
|
|
96
|
+
body['rate_limit_rpm'] = params.rateLimitRpm;
|
|
97
|
+
if (params.tags)
|
|
98
|
+
body['tags'] = params.tags;
|
|
99
|
+
if (params.orgId)
|
|
100
|
+
body['org_id'] = params.orgId;
|
|
101
|
+
return this.req('POST', '/admin/tenants/key', body);
|
|
102
|
+
}
|
|
103
|
+
/** Update an existing API key's configuration. */
|
|
104
|
+
update(keyId, fields) {
|
|
105
|
+
return this.req('PUT', `/admin/keys/${keyId}`, fields);
|
|
106
|
+
}
|
|
107
|
+
/** Permanently delete an API key. */
|
|
108
|
+
delete(keyId) {
|
|
109
|
+
return this.req('DELETE', `/admin/keys/${keyId}`);
|
|
110
|
+
}
|
|
111
|
+
/** Rotate the secret value of an API key, immediately invalidating the old one. */
|
|
112
|
+
rotate(keyId) {
|
|
113
|
+
return this.req('POST', `/admin/keys/${keyId}/rotate`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
// Resource: Tenants
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
class TenantsResource {
|
|
120
|
+
constructor(req) {
|
|
121
|
+
this.req = req;
|
|
122
|
+
}
|
|
123
|
+
/** List all tenants visible to this admin key. */
|
|
124
|
+
list() {
|
|
125
|
+
return this.req('GET', '/admin/tenants');
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Set or update a hard spend budget for a tenant.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* await admin.tenants.setBudget({ orgId: "org_123", limitUsd: 200, period: "monthly" });
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
setBudget(params) {
|
|
136
|
+
return this.req('POST', '/admin/tenants/budget', {
|
|
137
|
+
org_id: params.orgId,
|
|
138
|
+
limit_usd: params.limitUsd,
|
|
139
|
+
period: params.period ?? 'monthly',
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
// Resource: Analytics
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
class AnalyticsResource {
|
|
147
|
+
constructor(req) {
|
|
148
|
+
this.req = req;
|
|
149
|
+
}
|
|
150
|
+
/** Fetch request volume and cost timeseries. */
|
|
151
|
+
timeseries(params) {
|
|
152
|
+
const query = {};
|
|
153
|
+
if (params?.period)
|
|
154
|
+
query['period'] = params.period;
|
|
155
|
+
if (params?.orgId)
|
|
156
|
+
query['org_id'] = params.orgId;
|
|
157
|
+
return this.req('GET', '/admin/timeseries', undefined, query);
|
|
158
|
+
}
|
|
159
|
+
/** Fetch token usage and cost broken down by model. */
|
|
160
|
+
usageByModel(params) {
|
|
161
|
+
const query = {};
|
|
162
|
+
if (params?.orgId)
|
|
163
|
+
query['org_id'] = params.orgId;
|
|
164
|
+
return this.req('GET', '/admin/usage-by-model', undefined, query);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
// Resource: Members
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
class MembersResource {
|
|
171
|
+
constructor(req) {
|
|
172
|
+
this.req = req;
|
|
173
|
+
}
|
|
174
|
+
/** List all organization members. */
|
|
175
|
+
list() {
|
|
176
|
+
return this.req('GET', '/admin/members');
|
|
177
|
+
}
|
|
178
|
+
/** Invite a new member to the organization by email. */
|
|
179
|
+
invite(params) {
|
|
180
|
+
return this.req('POST', '/admin/invites', {
|
|
181
|
+
email: params.email,
|
|
182
|
+
role: params.role ?? 'developer',
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
// Resource: Pricing
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
class PricingResource {
|
|
190
|
+
constructor(req) {
|
|
191
|
+
this.req = req;
|
|
192
|
+
}
|
|
193
|
+
/** List all model pricing records. */
|
|
194
|
+
list() {
|
|
195
|
+
return this.req('GET', '/admin/pricing/models');
|
|
196
|
+
}
|
|
197
|
+
/** Insert or update pricing for a model (cost per 1k tokens, USD). */
|
|
198
|
+
upsert(params) {
|
|
199
|
+
return this.req('POST', '/admin/pricing/models', {
|
|
200
|
+
model_id: params.modelId,
|
|
201
|
+
input_cost: params.inputCost,
|
|
202
|
+
output_cost: params.outputCost,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=admin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../src/admin.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import type { ClientOptions } from 'openai';
|
|
3
|
+
import type { HyperionConfig, HyperionMeta, HyperionChatCompletion, HyperionCreateParams } from './types';
|
|
4
|
+
export declare function configToHeaders(config: HyperionConfig): Record<string, string>;
|
|
5
|
+
export declare function parseHyperionMeta(headers: Record<string, string>): HyperionMeta;
|
|
6
|
+
export interface HyperionClientOptions extends Omit<ClientOptions, 'apiKey' | 'baseURL'> {
|
|
7
|
+
/** Hyperion API key. Defaults to `HYPERION_API_KEY` env var. */
|
|
8
|
+
apiKey?: string;
|
|
9
|
+
/** Gateway base URL. Defaults to `HYPERION_BASE_URL` env var or `http://localhost:8080/v1`. */
|
|
10
|
+
baseURL?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* HyperionClient — drop-in replacement for `openai.OpenAI`.
|
|
14
|
+
*
|
|
15
|
+
* Extends the official OpenAI SDK and adds:
|
|
16
|
+
* - `hyperion` config block on `chat.completions.create()` → translated to X-* headers
|
|
17
|
+
* - `.hyperion` (HyperionMeta) on every response with cache status and similarity score
|
|
18
|
+
*
|
|
19
|
+
* All other OpenAI features (streaming, embeddings, images, tool calls, etc.)
|
|
20
|
+
* are inherited unchanged.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { HyperionClient } from '@hyperion-ai/sdk';
|
|
25
|
+
*
|
|
26
|
+
* const client = new HyperionClient();
|
|
27
|
+
*
|
|
28
|
+
* const res = await client.chat.completions.create({
|
|
29
|
+
* model: "openai/gpt-5.2",
|
|
30
|
+
* messages: [{ role: "user", content: "Hello" }],
|
|
31
|
+
* hyperion: { tags: ["prod"], bypassCache: false },
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* console.log(res.hyperion.cacheStatus); // "HIT" | "MISS"
|
|
35
|
+
* console.log(res.hyperion.isHit); // boolean
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare class HyperionClient extends OpenAI {
|
|
39
|
+
chat: {
|
|
40
|
+
completions: {
|
|
41
|
+
create(params: HyperionCreateParams, options?: {
|
|
42
|
+
headers?: Record<string, string>;
|
|
43
|
+
[key: string]: unknown;
|
|
44
|
+
}): Promise<HyperionChatCompletion>;
|
|
45
|
+
};
|
|
46
|
+
} & OpenAI['chat'];
|
|
47
|
+
constructor(opts?: HyperionClientOptions);
|
|
48
|
+
/**
|
|
49
|
+
* Patches `this.chat.completions.create` at runtime to:
|
|
50
|
+
* 1. Extract the `hyperion` config block from params
|
|
51
|
+
* 2. Map it to X-* request headers
|
|
52
|
+
* 3. Call the original create method with those headers
|
|
53
|
+
* 4. Parse response headers and attach `.hyperion` to the result
|
|
54
|
+
*
|
|
55
|
+
* We patch at runtime (using `as any`) rather than overriding the full
|
|
56
|
+
* Completions class, so all other `completions.*` methods remain intact.
|
|
57
|
+
*/
|
|
58
|
+
private _patchCompletions;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,SAAS,CAAC;AAMjB,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAe9E;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY,CAwB/E;AAMD,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,SAAS,CAAC;IACtF,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+FAA+F;IAC/F,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,cAAe,SAAQ,MAAM;IAChC,IAAI,EAAE;QACZ,WAAW,EAAE;YACX,MAAM,CACJ,MAAM,EAAE,oBAAoB,EAC5B,OAAO,CAAC,EAAE;gBAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;aAAE,GACrE,OAAO,CAAC,sBAAsB,CAAC,CAAC;SACpC,CAAC;KACH,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;gBAEP,IAAI,GAAE,qBAA0B;IAc5C;;;;;;;;;OASG;IACH,OAAO,CAAC,iBAAiB;CA8B1B"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.HyperionClient = void 0;
|
|
7
|
+
exports.configToHeaders = configToHeaders;
|
|
8
|
+
exports.parseHyperionMeta = parseHyperionMeta;
|
|
9
|
+
const openai_1 = __importDefault(require("openai"));
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Utilities
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
function configToHeaders(config) {
|
|
14
|
+
const headers = {};
|
|
15
|
+
if (config.bypassCache)
|
|
16
|
+
headers['X-Cache-Bypass'] = 'true';
|
|
17
|
+
if (config.cacheTtl !== undefined)
|
|
18
|
+
headers['X-Cache-TTL'] = String(config.cacheTtl);
|
|
19
|
+
if (config.similarityThreshold !== undefined)
|
|
20
|
+
headers['X-Similarity-Threshold'] = config.similarityThreshold.toFixed(4);
|
|
21
|
+
if (config.cacheToolCalls === false)
|
|
22
|
+
headers['X-Cache-Tool-Calls'] = 'false';
|
|
23
|
+
if (config.routeIntent)
|
|
24
|
+
headers['X-Route-Intent'] = config.routeIntent;
|
|
25
|
+
if (config.forceProvider)
|
|
26
|
+
headers['X-Force-Provider'] = config.forceProvider;
|
|
27
|
+
if (config.fallbacks?.length)
|
|
28
|
+
headers['X-Fallbacks'] = config.fallbacks.join(',');
|
|
29
|
+
if (config.tags?.length)
|
|
30
|
+
headers['X-Tags'] = config.tags.join(',');
|
|
31
|
+
if (config.teamId)
|
|
32
|
+
headers['X-Team-ID'] = config.teamId;
|
|
33
|
+
return headers;
|
|
34
|
+
}
|
|
35
|
+
function parseHyperionMeta(headers) {
|
|
36
|
+
const cacheStatus = headers['x-cache-status'] ?? 'MISS';
|
|
37
|
+
const rawCacheType = headers['x-cache-type'];
|
|
38
|
+
// Gateway sends 'L1_EXACT' or 'L2_SEMANTIC'
|
|
39
|
+
let cacheType;
|
|
40
|
+
if (rawCacheType === 'L1_EXACT')
|
|
41
|
+
cacheType = 'L1_EXACT';
|
|
42
|
+
else if (rawCacheType === 'L2_SEMANTIC')
|
|
43
|
+
cacheType = 'L2_SEMANTIC';
|
|
44
|
+
else
|
|
45
|
+
cacheType = undefined;
|
|
46
|
+
const scoreRaw = headers['x-similarity-score'];
|
|
47
|
+
const similarityScore = scoreRaw ? parseFloat(scoreRaw) : undefined;
|
|
48
|
+
return {
|
|
49
|
+
cacheStatus,
|
|
50
|
+
cacheType,
|
|
51
|
+
similarityScore,
|
|
52
|
+
get isHit() {
|
|
53
|
+
return cacheStatus === 'HIT';
|
|
54
|
+
},
|
|
55
|
+
get formattedSimilarityScore() {
|
|
56
|
+
return similarityScore !== undefined ? similarityScore.toFixed(4) : 'N/A';
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* HyperionClient — drop-in replacement for `openai.OpenAI`.
|
|
62
|
+
*
|
|
63
|
+
* Extends the official OpenAI SDK and adds:
|
|
64
|
+
* - `hyperion` config block on `chat.completions.create()` → translated to X-* headers
|
|
65
|
+
* - `.hyperion` (HyperionMeta) on every response with cache status and similarity score
|
|
66
|
+
*
|
|
67
|
+
* All other OpenAI features (streaming, embeddings, images, tool calls, etc.)
|
|
68
|
+
* are inherited unchanged.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* import { HyperionClient } from '@hyperion-ai/sdk';
|
|
73
|
+
*
|
|
74
|
+
* const client = new HyperionClient();
|
|
75
|
+
*
|
|
76
|
+
* const res = await client.chat.completions.create({
|
|
77
|
+
* model: "openai/gpt-5.2",
|
|
78
|
+
* messages: [{ role: "user", content: "Hello" }],
|
|
79
|
+
* hyperion: { tags: ["prod"], bypassCache: false },
|
|
80
|
+
* });
|
|
81
|
+
*
|
|
82
|
+
* console.log(res.hyperion.cacheStatus); // "HIT" | "MISS"
|
|
83
|
+
* console.log(res.hyperion.isHit); // boolean
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
class HyperionClient extends openai_1.default {
|
|
87
|
+
constructor(opts = {}) {
|
|
88
|
+
const { apiKey, baseURL, ...rest } = opts;
|
|
89
|
+
super({
|
|
90
|
+
...rest,
|
|
91
|
+
apiKey: apiKey ?? process.env['HYPERION_API_KEY'] ?? 'sk-hyperion',
|
|
92
|
+
baseURL: baseURL ??
|
|
93
|
+
process.env['HYPERION_BASE_URL'] ??
|
|
94
|
+
'http://localhost:8080/v1',
|
|
95
|
+
});
|
|
96
|
+
this._patchCompletions();
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Patches `this.chat.completions.create` at runtime to:
|
|
100
|
+
* 1. Extract the `hyperion` config block from params
|
|
101
|
+
* 2. Map it to X-* request headers
|
|
102
|
+
* 3. Call the original create method with those headers
|
|
103
|
+
* 4. Parse response headers and attach `.hyperion` to the result
|
|
104
|
+
*
|
|
105
|
+
* We patch at runtime (using `as any`) rather than overriding the full
|
|
106
|
+
* Completions class, so all other `completions.*` methods remain intact.
|
|
107
|
+
*/
|
|
108
|
+
_patchCompletions() {
|
|
109
|
+
// Cast to parent type to retain .withResponse() before we overwrite .create
|
|
110
|
+
const completions = this.chat.completions;
|
|
111
|
+
const originalCreate = completions.create.bind(completions);
|
|
112
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
113
|
+
completions.create = async (params, options) => {
|
|
114
|
+
const { hyperion, ...rest } = params;
|
|
115
|
+
const hyperionHeaders = hyperion ? configToHeaders(hyperion) : {};
|
|
116
|
+
const mergedOptions = {
|
|
117
|
+
...options,
|
|
118
|
+
headers: { ...(options?.headers ?? {}), ...hyperionHeaders },
|
|
119
|
+
};
|
|
120
|
+
const { data, response } = await originalCreate(rest, mergedOptions).withResponse();
|
|
121
|
+
const rawHeaders = {};
|
|
122
|
+
response.headers.forEach((value, key) => {
|
|
123
|
+
rawHeaders[key] = value;
|
|
124
|
+
});
|
|
125
|
+
const enriched = data;
|
|
126
|
+
enriched.hyperion = parseHyperionMeta(rawHeaders);
|
|
127
|
+
return enriched;
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
exports.HyperionClient = HyperionClient;
|
|
132
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/demo.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/demo.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const client_1 = require("./client");
|
|
4
|
+
async function main() {
|
|
5
|
+
// Pass Admin API Key (matches docker-compose)
|
|
6
|
+
const client = new client_1.HyperionClient('http://127.0.0.1:8080', undefined, 'hyperion-admin-secret-123');
|
|
7
|
+
try {
|
|
8
|
+
// 1. Chat Completion
|
|
9
|
+
console.log("Testing Chat Completion (Explicit Routing)...");
|
|
10
|
+
const completion = await client.chat.completions.create({
|
|
11
|
+
model: 'openai/gpt-4.1-nano', // Explicit provider/model
|
|
12
|
+
messages: [{ role: 'user', content: 'What is the capital of France?' }],
|
|
13
|
+
max_tokens: 50
|
|
14
|
+
});
|
|
15
|
+
console.log("Chat Response:", JSON.stringify(completion, null, 2));
|
|
16
|
+
// 2. Admin Stats
|
|
17
|
+
console.log("\nTesting Admin Stats...");
|
|
18
|
+
const stats = await client.admin.getStats();
|
|
19
|
+
console.log("Stats:", JSON.stringify(stats, null, 2));
|
|
20
|
+
// 3. Cache Keys
|
|
21
|
+
console.log("\nTesting Cache List...");
|
|
22
|
+
const keys = await client.cache.listKeys();
|
|
23
|
+
console.log("Cache Keys:", JSON.stringify(keys, null, 2));
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
console.error("Error:", error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
main();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const client_1 = require("./client");
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
async function main() {
|
|
9
|
+
const adminClient = new client_1.HyperionClient('http://127.0.0.1:8080', undefined, 'hyperion-admin-secret-123');
|
|
10
|
+
console.log("1. Generating API Key for 'tenant-A'...");
|
|
11
|
+
try {
|
|
12
|
+
// Direct call to admin endpoint since SDK isn't updated for this specific method yet
|
|
13
|
+
const resp = await axios_1.default.post('http://127.0.0.1:8080/v1/admin/tenants/key', {
|
|
14
|
+
tenant_id: 'tenant-A'
|
|
15
|
+
}, {
|
|
16
|
+
headers: { 'X-Admin-Key': 'hyperion-admin-secret-123' }
|
|
17
|
+
});
|
|
18
|
+
const apiKey = resp.data.api_key;
|
|
19
|
+
console.log("Generated Key:", apiKey);
|
|
20
|
+
console.log("1.5 Setting Budget for 'tenant-A'...");
|
|
21
|
+
await axios_1.default.post('http://127.0.0.1:8080/v1/admin/tenants/budget', {
|
|
22
|
+
tenant_id: 'tenant-A',
|
|
23
|
+
limit: 10.0
|
|
24
|
+
}, {
|
|
25
|
+
headers: { 'X-Admin-Key': 'hyperion-admin-secret-123' }
|
|
26
|
+
});
|
|
27
|
+
console.log("\n2. Testing Chat with New Key...");
|
|
28
|
+
const client = new client_1.HyperionClient('http://127.0.0.1:8080', apiKey);
|
|
29
|
+
const completion = await client.chat.completions.create({
|
|
30
|
+
model: 'openai/gpt-4.1-mini',
|
|
31
|
+
messages: [{ role: 'user', content: 'Hello Tenant A!' }],
|
|
32
|
+
max_tokens: 10
|
|
33
|
+
});
|
|
34
|
+
console.log("Success! Response:", completion.choices[0].message.content);
|
|
35
|
+
console.log("\n3. Testing Unauthorized Access...");
|
|
36
|
+
const badClient = new client_1.HyperionClient('http://127.0.0.1:8080', 'invalid-key');
|
|
37
|
+
try {
|
|
38
|
+
await badClient.chat.completions.create({
|
|
39
|
+
model: 'openai/gpt-4.1-mini',
|
|
40
|
+
messages: [{ role: 'user', content: 'Intruder!' }]
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
console.log("Caught Expected Error:", e.response?.status, e.response?.statusText);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error("Test Failed:", error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
main();
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { HyperionClient } from './client';
|
|
2
|
+
export type { HyperionClientOptions } from './client';
|
|
3
|
+
export { HyperionAdmin } from './admin';
|
|
4
|
+
export type { HyperionAdminOptions } from './admin';
|
|
5
|
+
export type { HyperionConfig, HyperionMeta, HyperionChatCompletion, HyperionCreateParams, CacheStatus, CacheType, ApiKey, CreateKeyParams, Tenant, SetBudgetParams, InviteMemberParams, PricingUpsertParams, } from './types';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,YAAY,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,YAAY,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AACpD,YAAY,EACV,cAAc,EACd,YAAY,EACZ,sBAAsB,EACtB,oBAAoB,EACpB,WAAW,EACX,SAAS,EACT,MAAM,EACN,eAAe,EACf,MAAM,EACN,eAAe,EACf,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HyperionAdmin = exports.HyperionClient = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "HyperionClient", { enumerable: true, get: function () { return client_1.HyperionClient; } });
|
|
6
|
+
var admin_1 = require("./admin");
|
|
7
|
+
Object.defineProperty(exports, "HyperionAdmin", { enumerable: true, get: function () { return admin_1.HyperionAdmin; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAA0C;AAAjC,wGAAA,cAAc,OAAA;AAEvB,iCAAwC;AAA/B,sGAAA,aAAa,OAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
2
|
+
import { SystemStats, HealthResponse } from '../types';
|
|
3
|
+
export declare class AdminResource {
|
|
4
|
+
private client;
|
|
5
|
+
constructor(client: AxiosInstance);
|
|
6
|
+
getStats(): Promise<SystemStats>;
|
|
7
|
+
getHealth(): Promise<HealthResponse>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AdminResource = void 0;
|
|
4
|
+
class AdminResource {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
async getStats() {
|
|
9
|
+
const response = await this.client.get('/admin/stats');
|
|
10
|
+
return response.data;
|
|
11
|
+
}
|
|
12
|
+
async getHealth() {
|
|
13
|
+
const response = await this.client.get('/admin/health');
|
|
14
|
+
return response.data;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.AdminResource = AdminResource;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
2
|
+
import { CacheKeyList, CacheEntry, WarmingRequest } from '../types';
|
|
3
|
+
export declare class CacheResource {
|
|
4
|
+
private client;
|
|
5
|
+
constructor(client: AxiosInstance);
|
|
6
|
+
listKeys(pattern?: string, limit?: number): Promise<CacheKeyList>;
|
|
7
|
+
inspect(key: string): Promise<CacheEntry>;
|
|
8
|
+
flush(): Promise<void>;
|
|
9
|
+
warm(req: WarmingRequest): Promise<void>;
|
|
10
|
+
delete(key: string): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CacheResource = void 0;
|
|
4
|
+
class CacheResource {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
async listKeys(pattern = '*', limit = 50) {
|
|
9
|
+
const response = await this.client.get('/cache/keys', {
|
|
10
|
+
params: { pattern, limit }
|
|
11
|
+
});
|
|
12
|
+
return response.data;
|
|
13
|
+
}
|
|
14
|
+
async inspect(key) {
|
|
15
|
+
const response = await this.client.get(`/cache/inspect/${encodeURIComponent(key)}`);
|
|
16
|
+
return response.data;
|
|
17
|
+
}
|
|
18
|
+
async flush() {
|
|
19
|
+
await this.client.post('/cache/flush');
|
|
20
|
+
}
|
|
21
|
+
async warm(req) {
|
|
22
|
+
await this.client.post('/cache/warm', req);
|
|
23
|
+
}
|
|
24
|
+
async delete(key) {
|
|
25
|
+
await this.client.delete(`/cache/keys/${encodeURIComponent(key)}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.CacheResource = CacheResource;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
2
|
+
import { ChatCompletionRequest, ChatCompletionResponse } from '../types';
|
|
3
|
+
export declare class ChatResource {
|
|
4
|
+
private client;
|
|
5
|
+
constructor(client: AxiosInstance);
|
|
6
|
+
completions: {
|
|
7
|
+
create: (req: ChatCompletionRequest) => Promise<ChatCompletionResponse>;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ChatResource = void 0;
|
|
4
|
+
class ChatResource {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
this.completions = {
|
|
8
|
+
create: async (req) => {
|
|
9
|
+
const response = await this.client.post('/chat/completions', req);
|
|
10
|
+
return response.data;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.ChatResource = ChatResource;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
2
|
+
import { EmbeddingRequest, EmbeddingResponse } from '../types';
|
|
3
|
+
export declare class EmbeddingsResource {
|
|
4
|
+
private client;
|
|
5
|
+
constructor(client: AxiosInstance);
|
|
6
|
+
create: (req: EmbeddingRequest) => Promise<EmbeddingResponse>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EmbeddingsResource = void 0;
|
|
4
|
+
class EmbeddingsResource {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
this.create = async (req) => {
|
|
8
|
+
const response = await this.client.post('/embeddings', req);
|
|
9
|
+
return response.data;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.EmbeddingsResource = EmbeddingsResource;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { ChatCompletion, ChatCompletionCreateParams } from 'openai/resources/chat/completions';
|
|
2
|
+
/**
|
|
3
|
+
* Hyperion-specific configuration for a single inference request.
|
|
4
|
+
* Pass as the `hyperion` property on any `client.chat.completions.create()` call.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* const res = await client.chat.completions.create({
|
|
9
|
+
* model: "openai/gpt-5.2",
|
|
10
|
+
* messages: [{ role: "user", content: "Hello" }],
|
|
11
|
+
* hyperion: {
|
|
12
|
+
* bypassCache: true,
|
|
13
|
+
* tags: ["prod", "onboarding"],
|
|
14
|
+
* }
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export interface HyperionConfig {
|
|
19
|
+
/** Skip the cache entirely for this request. Forces a live LLM call. */
|
|
20
|
+
bypassCache?: boolean;
|
|
21
|
+
/** Override the cache TTL in seconds for the stored response. */
|
|
22
|
+
cacheTtl?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Override the semantic similarity threshold (0.0–1.0).
|
|
25
|
+
* Higher = stricter match required before serving from cache.
|
|
26
|
+
*/
|
|
27
|
+
similarityThreshold?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Whether to cache the model's tool_call decision response.
|
|
30
|
+
* Set to `false` to prevent caching tool call decisions.
|
|
31
|
+
* Defaults to `true` (gateway-configured default).
|
|
32
|
+
*/
|
|
33
|
+
cacheToolCalls?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Hint to the routing engine.
|
|
36
|
+
* Examples: "cheap_fast", "balanced", "high_reasoning", "code_generation".
|
|
37
|
+
*/
|
|
38
|
+
routeIntent?: string;
|
|
39
|
+
/** Force a specific provider for this request (e.g., "anthropic", "openai", "google"). */
|
|
40
|
+
forceProvider?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Ordered list of fallback models to try if the primary model fails.
|
|
43
|
+
* @example ["claude-3-5-sonnet", "gpt-5.2-mini"]
|
|
44
|
+
*/
|
|
45
|
+
fallbacks?: string[];
|
|
46
|
+
/** Arbitrary string tags attached to this request for dashboard filtering. */
|
|
47
|
+
tags?: string[];
|
|
48
|
+
/** Team or downstream tenant ID for usage attribution in analytics. */
|
|
49
|
+
teamId?: string;
|
|
50
|
+
}
|
|
51
|
+
export type CacheStatus = 'HIT' | 'MISS' | 'BYPASS' | 'BYPASS-TOOL-RESULT' | 'BYPASS-TOOL-NOCACHE';
|
|
52
|
+
export type CacheType = 'L1_EXACT' | 'L2_SEMANTIC';
|
|
53
|
+
/**
|
|
54
|
+
* Metadata extracted from Hyperion gateway response headers.
|
|
55
|
+
* Attached as `.hyperion` on every response returned by `HyperionClient`.
|
|
56
|
+
*/
|
|
57
|
+
export interface HyperionMeta {
|
|
58
|
+
/** Cache result for this request. */
|
|
59
|
+
cacheStatus: CacheStatus | string;
|
|
60
|
+
/** Cache layer that served the hit. Undefined on MISS or BYPASS. */
|
|
61
|
+
cacheType?: CacheType;
|
|
62
|
+
/** Cosine similarity score of a semantic cache match. Undefined on exact hit or miss. */
|
|
63
|
+
similarityScore?: number;
|
|
64
|
+
/** Convenience flag: true if this response was served from cache. */
|
|
65
|
+
readonly isHit: boolean;
|
|
66
|
+
/** Similarity score formatted to 4 decimal places, or 'N/A' if not applicable. */
|
|
67
|
+
readonly formattedSimilarityScore: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* `ChatCompletion` enriched with a `.hyperion` metadata object.
|
|
71
|
+
*/
|
|
72
|
+
export interface HyperionChatCompletion extends ChatCompletion {
|
|
73
|
+
hyperion: HyperionMeta;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Extended `create` params that accept a `hyperion` config block.
|
|
77
|
+
*/
|
|
78
|
+
export type HyperionCreateParams = ChatCompletionCreateParams & {
|
|
79
|
+
hyperion?: HyperionConfig;
|
|
80
|
+
};
|
|
81
|
+
export interface ApiKey {
|
|
82
|
+
id: string;
|
|
83
|
+
name: string;
|
|
84
|
+
key_preview: string;
|
|
85
|
+
budget_limit_usd?: number;
|
|
86
|
+
allowed_models?: string[];
|
|
87
|
+
rate_limit_rpm?: number;
|
|
88
|
+
created_at: string;
|
|
89
|
+
}
|
|
90
|
+
export interface CreateKeyParams {
|
|
91
|
+
name: string;
|
|
92
|
+
budgetLimitUsd?: number;
|
|
93
|
+
allowedModels?: string[];
|
|
94
|
+
rateLimitRpm?: number;
|
|
95
|
+
tags?: string[];
|
|
96
|
+
orgId?: string;
|
|
97
|
+
}
|
|
98
|
+
export interface Tenant {
|
|
99
|
+
id: string;
|
|
100
|
+
name: string;
|
|
101
|
+
slug: string;
|
|
102
|
+
created_at: string;
|
|
103
|
+
}
|
|
104
|
+
export interface SetBudgetParams {
|
|
105
|
+
orgId: string;
|
|
106
|
+
limitUsd: number;
|
|
107
|
+
period?: 'daily' | 'monthly';
|
|
108
|
+
}
|
|
109
|
+
export interface InviteMemberParams {
|
|
110
|
+
email: string;
|
|
111
|
+
role?: 'owner' | 'admin' | 'developer' | 'viewer';
|
|
112
|
+
}
|
|
113
|
+
export interface PricingUpsertParams {
|
|
114
|
+
modelId: string;
|
|
115
|
+
inputCost: number;
|
|
116
|
+
outputCost: number;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAuB,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAOzH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,cAAc;IAG7B,wEAAwE;IACxE,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAIzB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,0FAA0F;IAC1F,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAIrB,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAMD,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,oBAAoB,GAAG,qBAAqB,CAAC;AACnG,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC;AAEnD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,qCAAqC;IACrC,WAAW,EAAE,WAAW,GAAG,MAAM,CAAC;IAElC,oEAAoE;IACpE,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB,yFAAyF;IACzF,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,qEAAqE;IACrE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAExB,kFAAkF;IAClF,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;CAC3C;AAMD;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,0BAA0B,GAAG;IAC9D,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B,CAAC;AAMF,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAC;CACnD;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hyperion-ai/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The official TypeScript/Node.js SDK for the Hyperion AI Gateway",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"require": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"test:watch": "vitest",
|
|
22
|
+
"typecheck": "tsc --noEmit"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"openai": "^6.22.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "^20.0.0",
|
|
29
|
+
"typescript": "^5.0.0",
|
|
30
|
+
"vitest": "^1.0.0"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"hyperion",
|
|
34
|
+
"ai",
|
|
35
|
+
"gateway",
|
|
36
|
+
"openai",
|
|
37
|
+
"llm",
|
|
38
|
+
"caching",
|
|
39
|
+
"low-latency",
|
|
40
|
+
"high-performance"
|
|
41
|
+
],
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "https://github.com/hyperion-hq/hyperion.git",
|
|
46
|
+
"directory": "sdk/typescript"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://github.com/hyperion-hq/hyperion/tree/main/sdk/typescript",
|
|
49
|
+
"bugs": {
|
|
50
|
+
"url": "https://github.com/hyperion-hq/hyperion/issues"
|
|
51
|
+
}
|
|
52
|
+
}
|