@ancatag/n-r 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 ADDED
@@ -0,0 +1,285 @@
1
+ # Nova-route AI SDK (n-r)
2
+
3
+ Official Node.js/TypeScript SDK for Nova-route AI API. OpenAI-compatible interface for chat completions and model management.
4
+
5
+ ## Installation
6
+
7
+ ### From npm (when published)
8
+ ```bash
9
+ npm install @ancatag/n-r
10
+ # or
11
+ pnpm add @ancatag/n-r
12
+ # or
13
+ yarn add @ancatag/n-r
14
+ ```
15
+
16
+ ### Local Development (for OpenChat)
17
+
18
+ For local development and testing within the Nova monorepo or OpenChat app:
19
+
20
+ ```bash
21
+ # In Nova repo
22
+ cd packages/sdk
23
+ pnpm build
24
+
25
+ # Link the package
26
+ pnpm link --global
27
+
28
+ # In OpenChat repo (or any project)
29
+ pnpm link --global @ancatag/n-r
30
+ ```
31
+
32
+ Or use pnpm workspace (if both repos are in a workspace):
33
+ ```bash
34
+ # In OpenChat package.json, add:
35
+ {
36
+ "dependencies": {
37
+ "@ancatag/n-r": "workspace:*"
38
+ }
39
+ }
40
+ ```
41
+
42
+ ### Using from OpenChat (local)
43
+
44
+ - Point the SDK to your local Nova API: `baseUrl: 'http://localhost:3000'` (REST) or `grpcUrl: '0.0.0.0:50051'` with `transport: 'grpc'`.
45
+ - Use a Nova-route API key (`nova_sk_...`) scoped to the project/model configs you need.
46
+ - Prefer workspace linking (above) or `pnpm link --global @ancatag/n-r` while developing both repos.
47
+
48
+
49
+ ## Quick Start
50
+
51
+ ```typescript
52
+ import { NovaClient } from '@ancatag/n-r';
53
+
54
+ // Initialize client with API key from Nova-route UI
55
+ const client = new NovaClient({
56
+ apiKey: process.env.NOVA_API_KEY || 'nova_sk_...', // from env
57
+ transport: process.env.NOVA_TRANSPORT || 'rest',
58
+ timeoutMs: 60000, // Optional, defaults to 60s
59
+ });
60
+
61
+ // Non-streaming chat completion
62
+ const response = await client.chat.create({
63
+ model: 'llama2',
64
+ messages: [
65
+ { role: 'system', content: 'You are a helpful assistant.' },
66
+ { role: 'user', content: 'Hello!' }
67
+ ],
68
+ temperature: 0.7,
69
+ max_tokens: 1000,
70
+ });
71
+
72
+ console.log(response.choices[0].message.content);
73
+ console.log('Tokens used:', response.usage.total_tokens);
74
+ console.log('Cache hit:', response.nova?.cacheHit);
75
+ ```
76
+
77
+ ## Streaming
78
+
79
+ ```typescript
80
+ // Streaming chat completion
81
+ const stream = client.chat.createStream({
82
+ model: 'llama2',
83
+ messages: [{ role: 'user', content: 'Tell me a story' }],
84
+ temperature: 0.7,
85
+ });
86
+
87
+ let fullContent = '';
88
+ for await (const chunk of stream) {
89
+ const content = chunk.choices[0]?.delta?.content || '';
90
+ if (content) {
91
+ process.stdout.write(content); // Print as it arrives
92
+ fullContent += content;
93
+ }
94
+
95
+ // Check if stream is complete
96
+ if (chunk.choices[0]?.finish_reason) {
97
+ console.log('\n\nStream complete!');
98
+ break;
99
+ }
100
+ }
101
+ ```
102
+
103
+ ## Cancellation
104
+
105
+ ```typescript
106
+ const controller = new AbortController();
107
+
108
+ // Cancel after 5 seconds
109
+ setTimeout(() => controller.abort(), 5000);
110
+
111
+ try {
112
+ for await (const chunk of client.chat.createStream(
113
+ {
114
+ model: 'llama2',
115
+ messages: [{ role: 'user', content: 'Hello' }],
116
+ },
117
+ controller.signal
118
+ )) {
119
+ console.log(chunk.choices[0]?.delta?.content || '');
120
+ }
121
+ } catch (error) {
122
+ if (error.name === 'AbortError') {
123
+ console.log('Stream cancelled');
124
+ }
125
+ }
126
+ ```
127
+
128
+ ## Models API
129
+
130
+ ```typescript
131
+ // List all available models
132
+ const models = await client.models.list();
133
+ console.log('Available models:', models.map(m => m.id));
134
+
135
+ // Get specific model details
136
+ const model = await client.models.get('llama2');
137
+ console.log('Model:', model);
138
+ ```
139
+
140
+ ## Error Handling
141
+
142
+ ```typescript
143
+ import { NovaClient, NovaError } from '@nova-route/sdk';
144
+
145
+ const client = new NovaClient({
146
+ apiKey: 'nova_sk_...',
147
+ });
148
+
149
+ try {
150
+ const response = await client.chat.create({
151
+ model: 'invalid-model',
152
+ messages: [{ role: 'user', content: 'Hello' }],
153
+ });
154
+ } catch (error) {
155
+ if (error instanceof NovaError) {
156
+ console.error('Nova API Error:', error.message);
157
+ console.error('Status:', error.status);
158
+ console.error('Code:', error.code);
159
+ console.error('Type:', error.type);
160
+ } else {
161
+ console.error('Unexpected error:', error);
162
+ }
163
+ }
164
+ ```
165
+
166
+ ## Nova-Specific Features
167
+
168
+ Nova extends the OpenAI API with additional features:
169
+
170
+ ```typescript
171
+ const response = await client.chat.create({
172
+ model: 'llama2',
173
+ messages: [{ role: 'user', content: 'Hello' }],
174
+
175
+ // Nova-route-specific options
176
+ nova: {
177
+ skipCache: false, // Skip cache for this request
178
+ modelConfigId: 'uuid', // Use specific model config
179
+ ragEnabled: true, // Enable RAG (if configured)
180
+ metadata: { userId: '123' }, // Custom metadata
181
+ systemPromptOverride: 'Custom system prompt', // Override system prompt
182
+ },
183
+ });
184
+
185
+ // Response includes Nova extensions
186
+ console.log('Cache hit:', response.nova?.cacheHit);
187
+ console.log('Cache layer:', response.nova?.cacheLayer); // 'hot' | 'semantic' | null
188
+ console.log('Tokens saved:', response.nova?.tokensSaved);
189
+ console.log('Response time:', response.nova?.responseTimeMs, 'ms');
190
+ console.log('Request ID:', response.nova?.requestId);
191
+ ```
192
+
193
+ ## Configuration
194
+
195
+ ```typescript
196
+ const client = new NovaClient({
197
+ apiKey: 'nova_sk_...', // Required: Get from Nova-route dashboard
198
+
199
+ baseUrl: 'https://api.nova.ai', // Optional: Defaults to http://localhost:3000
200
+ timeoutMs: 120000, // Optional: Request timeout in ms (default: 60000)
201
+ maxRetries: 3, // Optional: Max retries for failed requests (default: 2)
202
+ });
203
+ ```
204
+
205
+ ## API Key Setup
206
+
207
+ 1. Log in to Nova-route dashboard (http://localhost:3001)
208
+ 2. Navigate to API Keys section
209
+ 3. Create a new API key
210
+ 4. Copy the key (format: `nova_sk_...`)
211
+ 5. Use it in your SDK initialization
212
+
213
+ ## TypeScript Support
214
+
215
+ Full TypeScript support with exported types:
216
+
217
+ ```typescript
218
+ import type {
219
+ ChatMessage,
220
+ ChatCompletionRequest,
221
+ ChatCompletionResponse,
222
+ ChatCompletionChunk,
223
+ Model,
224
+ NovaClientConfig,
225
+ } from '@nova-route/sdk';
226
+ ```
227
+
228
+ ## Requirements
229
+
230
+ - Node.js 18+ (uses native `fetch`)
231
+ - TypeScript 5.0+ (for type definitions)
232
+
233
+ ## License
234
+
235
+ ISC
236
+
237
+
238
+
239
+
240
+
241
+ ## gRPC Transport
242
+
243
+ Use the gRPC path for lower overhead (ts-proto stubs).
244
+ ```typescript
245
+ import { NovaClient } from '@nova-route/sdk';
246
+
247
+ const client = new NovaClient({
248
+ apiKey: process.env.NOVA_API_KEY || 'nova_sk_...',
249
+ transport: 'grpc',
250
+ });
251
+
252
+ const res = await client.chat.create({
253
+ model: 'llama2',
254
+ messages: [{ role: 'user', content: 'Hello' }],
255
+ });
256
+ console.log(res.choices[0].message.content);
257
+ ```
258
+
259
+ Streaming works the same via `createStream`.
260
+
261
+ ```typescript
262
+ for await (const chunk of client.chat.createStream({
263
+ model: 'llama2',
264
+ messages: [{ role: 'user', content: 'Hey' }],
265
+ })) {
266
+ process.stdout.write(chunk.choices[0]?.delta?.content || '');
267
+ }
268
+ ```
269
+
270
+ Transport options:
271
+ - `transport: 'rest'` (default) uses HTTP fetch.
272
+ - `transport: 'grpc'` uses gRPC over grpc-js with ts-proto stubs.
273
+ - `grpcUrl` defaults to `0.0.0.0:50051`.
274
+
275
+ ## Publishing to npm
276
+
277
+ - Set env (recommended):
278
+ - `NOVA_API_KEY` (if needed for examples/tests)
279
+ - `NOVA_BASE_URL` (REST), `NOVA_GRPC_URL` (gRPC)
280
+ - Build & publish:
281
+ ```bash
282
+ pnpm install
283
+ pnpm publish:npm # runs prepublishOnly -> build, then npm publish --access public
284
+ ```
285
+ - Ensure `npmrc` has an auth token with publish rights.
package/dist/chat.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Chat Completions API
3
+ * Handles chat completion requests (streaming and non-streaming)
4
+ */
5
+ import { HttpClient } from './http-client.js';
6
+ import { GrpcClient } from './grpc-client.js';
7
+ import type { ChatCompletionRequest, ChatCompletionResponse, ChatCompletionChunk } from './types.js';
8
+ export declare class ChatCompletions {
9
+ private readonly httpClient;
10
+ private readonly grpcClient?;
11
+ constructor(httpClient: HttpClient, grpcClient?: GrpcClient | undefined);
12
+ private isGrpc;
13
+ /**
14
+ * Create a chat completion (non-streaming)
15
+ */
16
+ create(request: ChatCompletionRequest): Promise<ChatCompletionResponse>;
17
+ /**
18
+ * Create a streaming chat completion
19
+ * Returns an async iterator over chunks
20
+ */
21
+ createStream(request: ChatCompletionRequest, signal?: AbortSignal): AsyncGenerator<ChatCompletionChunk, void, unknown>;
22
+ }
23
+ //# sourceMappingURL=chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EACX,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,MAAM,YAAY,CAAC;AAEpB,qBAAa,eAAe;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;gBADX,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,UAAU,YAAA;IAGzC,OAAO,CAAC,MAAM;IAId;;OAEG;IACG,MAAM,CACX,OAAO,EAAE,qBAAqB,GAC5B,OAAO,CAAC,sBAAsB,CAAC;IAgBlC;;;OAGG;IACI,YAAY,CAClB,OAAO,EAAE,qBAAqB,EAC9B,MAAM,CAAC,EAAE,WAAW,GAClB,cAAc,CAAC,mBAAmB,EAAE,IAAI,EAAE,OAAO,CAAC;CAuDrD"}
package/dist/chat.js ADDED
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Chat Completions API
3
+ * Handles chat completion requests (streaming and non-streaming)
4
+ */
5
+ export class ChatCompletions {
6
+ httpClient;
7
+ grpcClient;
8
+ constructor(httpClient, grpcClient) {
9
+ this.httpClient = httpClient;
10
+ this.grpcClient = grpcClient;
11
+ }
12
+ isGrpc() {
13
+ return Boolean(this.grpcClient);
14
+ }
15
+ /**
16
+ * Create a chat completion (non-streaming)
17
+ */
18
+ async create(request) {
19
+ if (this.isGrpc() && this.grpcClient) {
20
+ return this.grpcClient.createChatCompletion(request);
21
+ }
22
+ const payload = {
23
+ ...request,
24
+ stream: false,
25
+ };
26
+ return this.httpClient.post('v1/chat/completions', payload);
27
+ }
28
+ /**
29
+ * Create a streaming chat completion
30
+ * Returns an async iterator over chunks
31
+ */
32
+ async *createStream(request, signal) {
33
+ if (this.isGrpc() && this.grpcClient) {
34
+ for await (const chunk of this.grpcClient.createChatCompletionStream(request)) {
35
+ yield chunk;
36
+ }
37
+ return;
38
+ }
39
+ const payload = {
40
+ ...request,
41
+ stream: true,
42
+ };
43
+ const stream = await this.httpClient.postStream('v1/chat/completions', payload, signal);
44
+ const reader = stream.getReader();
45
+ const decoder = new TextDecoder();
46
+ let buffer = '';
47
+ try {
48
+ while (true) {
49
+ const { done, value } = await reader.read();
50
+ if (done)
51
+ break;
52
+ buffer += decoder.decode(value, { stream: true });
53
+ const lines = buffer.split('\n');
54
+ buffer = lines.pop() || '';
55
+ for (const line of lines) {
56
+ const trimmed = line.trim();
57
+ if (!trimmed || trimmed === 'data: [DONE]') {
58
+ continue;
59
+ }
60
+ if (!trimmed.startsWith('data: ')) {
61
+ continue;
62
+ }
63
+ try {
64
+ const jsonStr = trimmed.slice(6); // Remove 'data: ' prefix
65
+ const chunk = JSON.parse(jsonStr);
66
+ yield chunk;
67
+ }
68
+ catch (parseError) {
69
+ // Skip malformed JSON chunks
70
+ continue;
71
+ }
72
+ }
73
+ }
74
+ }
75
+ finally {
76
+ reader.releaseLock();
77
+ }
78
+ }
79
+ }
80
+ //# sourceMappingURL=chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../src/chat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,MAAM,OAAO,eAAe;IAET;IACA;IAFlB,YACkB,UAAsB,EACtB,UAAuB;QADvB,eAAU,GAAV,UAAU,CAAY;QACtB,eAAU,GAAV,UAAU,CAAa;IACtC,CAAC;IAEI,MAAM;QACb,OAAO,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CACX,OAA8B;QAE9B,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC,UAAU,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACtD,CAAC;QAED,MAAM,OAAO,GAA0B;YACtC,GAAG,OAAO;YACV,MAAM,EAAE,KAAK;SACb,CAAC;QAEF,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAC1B,qBAAqB,EACrB,OAAO,CACP,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,CAAC,YAAY,CAClB,OAA8B,EAC9B,MAAoB;QAEpB,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACtC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,0BAA0B,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/E,MAAM,KAAK,CAAC;YACb,CAAC;YACD,OAAO;QACR,CAAC;QAED,MAAM,OAAO,GAA0B;YACtC,GAAG,OAAO;YACV,MAAM,EAAE,IAAI;SACZ,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAC9C,qBAAqB,EACrB,OAAO,EACP,MAAM,CACN,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,IAAI,CAAC;YACJ,OAAO,IAAI,EAAE,CAAC;gBACb,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC5C,IAAI,IAAI;oBAAE,MAAM;gBAEhB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBAClD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;gBAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;oBAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC;wBAC5C,SAAS;oBACV,CAAC;oBACD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACnC,SAAS;oBACV,CAAC;oBAED,IAAI,CAAC;wBACJ,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,yBAAyB;wBAC3D,MAAM,KAAK,GAAwB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;wBACvD,MAAM,KAAK,CAAC;oBACb,CAAC;oBAAC,OAAO,UAAU,EAAE,CAAC;wBACrB,6BAA6B;wBAC7B,SAAS;oBACV,CAAC;gBACF,CAAC;YACF,CAAC;QACF,CAAC;gBAAS,CAAC;YACV,MAAM,CAAC,WAAW,EAAE,CAAC;QACtB,CAAC;IACF,CAAC;CACD"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Nova Client
3
+ * Main client class for interacting with Nova AI API
4
+ */
5
+ import { ChatCompletions } from './chat.js';
6
+ import { Models } from './models.js';
7
+ import type { NovaClientConfig } from './types.js';
8
+ export declare class NovaClient {
9
+ readonly chat: ChatCompletions;
10
+ readonly models: Models;
11
+ private readonly httpClient;
12
+ private readonly grpcClient?;
13
+ constructor(config: NovaClientConfig);
14
+ private shouldUseGrpc;
15
+ /**
16
+ * Get the API key (masked for security)
17
+ */
18
+ getApiKey(): string;
19
+ }
20
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,KAAK,EAAE,gBAAgB,EAAiB,MAAM,YAAY,CAAC;AAElE,qBAAa,UAAU;IACtB,SAAgB,IAAI,EAAE,eAAe,CAAC;IACtC,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAa;gBAE7B,MAAM,EAAE,gBAAgB;IASpC,OAAO,CAAC,aAAa;IAIrB;;OAEG;IACH,SAAS,IAAI,MAAM;CAMnB"}
package/dist/client.js ADDED
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Nova Client
3
+ * Main client class for interacting with Nova AI API
4
+ */
5
+ import { HttpClient } from './http-client.js';
6
+ import { ChatCompletions } from './chat.js';
7
+ import { Models } from './models.js';
8
+ import { GrpcClient } from './grpc-client.js';
9
+ export class NovaClient {
10
+ chat;
11
+ models;
12
+ httpClient;
13
+ grpcClient;
14
+ constructor(config) {
15
+ this.httpClient = new HttpClient(config);
16
+ if (this.shouldUseGrpc(config.transport)) {
17
+ this.grpcClient = new GrpcClient(config);
18
+ }
19
+ this.chat = new ChatCompletions(this.httpClient, this.grpcClient);
20
+ this.models = new Models(this.httpClient, this.grpcClient);
21
+ }
22
+ shouldUseGrpc(transport) {
23
+ return transport === 'grpc';
24
+ }
25
+ /**
26
+ * Get the API key (masked for security)
27
+ */
28
+ getApiKey() {
29
+ // Access private field via type assertion for display purposes only
30
+ const key = this.httpClient.apiKey;
31
+ if (key.length <= 12)
32
+ return key;
33
+ return `${key.slice(0, 8)}...${key.slice(-4)}`;
34
+ }
35
+ }
36
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,OAAO,UAAU;IACN,IAAI,CAAkB;IACtB,MAAM,CAAS;IACd,UAAU,CAAa;IACvB,UAAU,CAAc;IAEzC,YAAY,MAAwB;QACnC,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5D,CAAC;IAEO,aAAa,CAAC,SAAyB;QAC9C,OAAO,SAAS,KAAK,MAAM,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,SAAS;QACR,oEAAoE;QACpE,MAAM,GAAG,GAAI,IAAI,CAAC,UAAkB,CAAC,MAAgB,CAAC;QACtD,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE;YAAE,OAAO,GAAG,CAAC;QACjC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChD,CAAC;CACD"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * gRPC Client (stub implementation)
3
+ *
4
+ * This is a placeholder for gRPC functionality.
5
+ * OpenChat uses REST transport only, so this is not implemented.
6
+ *
7
+ * To implement gRPC support, this would use @grpc/grpc-js and @nova-ai/proto
8
+ */
9
+ import type { ChatCompletionRequest, ChatCompletionResponse, ChatCompletionChunk, Model, NovaClientConfig } from './types.js';
10
+ export declare class GrpcClient {
11
+ constructor(config: NovaClientConfig);
12
+ createChatCompletion(request: ChatCompletionRequest): Promise<ChatCompletionResponse>;
13
+ createChatCompletionStream(request: ChatCompletionRequest): AsyncGenerator<ChatCompletionChunk, void, unknown>;
14
+ listModels(): Promise<Model[]>;
15
+ }
16
+ //# sourceMappingURL=grpc-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grpc-client.d.ts","sourceRoot":"","sources":["../src/grpc-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACX,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,KAAK,EACL,gBAAgB,EAChB,MAAM,YAAY,CAAC;AAEpB,qBAAa,UAAU;gBACV,MAAM,EAAE,gBAAgB;IAO9B,oBAAoB,CACzB,OAAO,EAAE,qBAAqB,GAC5B,OAAO,CAAC,sBAAsB,CAAC;IAI3B,0BAA0B,CAChC,OAAO,EAAE,qBAAqB,GAC5B,cAAc,CAAC,mBAAmB,EAAE,IAAI,EAAE,OAAO,CAAC;IAI/C,UAAU,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;CAGpC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * gRPC Client (stub implementation)
3
+ *
4
+ * This is a placeholder for gRPC functionality.
5
+ * OpenChat uses REST transport only, so this is not implemented.
6
+ *
7
+ * To implement gRPC support, this would use @grpc/grpc-js and @nova-ai/proto
8
+ */
9
+ export class GrpcClient {
10
+ constructor(config) {
11
+ // Stub implementation - gRPC not used by OpenChat
12
+ throw new Error('gRPC transport is not implemented. Use transport: "rest" instead.');
13
+ }
14
+ async createChatCompletion(request) {
15
+ throw new Error('gRPC not implemented');
16
+ }
17
+ async *createChatCompletionStream(request) {
18
+ throw new Error('gRPC not implemented');
19
+ }
20
+ async listModels() {
21
+ throw new Error('gRPC not implemented');
22
+ }
23
+ }
24
+ //# sourceMappingURL=grpc-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grpc-client.js","sourceRoot":"","sources":["../src/grpc-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,MAAM,OAAO,UAAU;IACtB,YAAY,MAAwB;QACnC,kDAAkD;QAClD,MAAM,IAAI,KAAK,CACd,mEAAmE,CACnE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,oBAAoB,CACzB,OAA8B;QAE9B,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,CAAC,0BAA0B,CAChC,OAA8B;QAE9B,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,UAAU;QACf,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACzC,CAAC;CACD"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * HTTP Client for Nova API
3
+ * Handles authentication, retries, timeouts, and error handling
4
+ */
5
+ import type { NovaClientConfig } from './types.js';
6
+ export declare class HttpClient {
7
+ private readonly apiKey;
8
+ private readonly baseUrl;
9
+ private readonly timeoutMs;
10
+ private readonly maxRetries;
11
+ constructor(config: NovaClientConfig);
12
+ /**
13
+ * Make a GET request
14
+ */
15
+ get<T>(path: string): Promise<T>;
16
+ /**
17
+ * Make a POST request
18
+ */
19
+ post<T>(path: string, body?: unknown): Promise<T>;
20
+ /**
21
+ * Make a streaming POST request (returns ReadableStream)
22
+ */
23
+ postStream(path: string, body?: unknown, signal?: AbortSignal): Promise<ReadableStream<Uint8Array>>;
24
+ /**
25
+ * Make an HTTP request with retries
26
+ */
27
+ private request;
28
+ /**
29
+ * Parse error response from API
30
+ */
31
+ private parseError;
32
+ }
33
+ //# sourceMappingURL=http-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../src/http-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,qBAAa,UAAU;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,MAAM,EAAE,gBAAgB;IAiBpC;;OAEG;IACG,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAItC;;OAEG;IACG,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIvD;;OAEG;IACG,UAAU,CACf,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAkDtC;;OAEG;YACW,OAAO;IAqErB;;OAEG;YACW,UAAU;CA6BxB"}
@@ -0,0 +1,153 @@
1
+ /**
2
+ * HTTP Client for Nova API
3
+ * Handles authentication, retries, timeouts, and error handling
4
+ */
5
+ import { NovaError } from './types.js';
6
+ export class HttpClient {
7
+ apiKey;
8
+ baseUrl;
9
+ timeoutMs;
10
+ maxRetries;
11
+ constructor(config) {
12
+ if (!config.apiKey) {
13
+ throw new NovaError('API key is required');
14
+ }
15
+ if (!config.apiKey.startsWith('nova_sk_')) {
16
+ throw new NovaError('Invalid API key format. Expected format: nova_sk_...');
17
+ }
18
+ this.apiKey = config.apiKey;
19
+ const envBase = (typeof process !== 'undefined') ? process.env.NOVA_BASE_URL : undefined;
20
+ const configBase = config.baseUrl;
21
+ const fallback = 'http://localhost:3000';
22
+ this.baseUrl = (configBase || envBase || fallback).replace(/\/$/, '');
23
+ this.timeoutMs = config.timeoutMs || 60000;
24
+ this.maxRetries = config.maxRetries ?? 2;
25
+ }
26
+ /**
27
+ * Make a GET request
28
+ */
29
+ async get(path) {
30
+ return this.request('GET', path);
31
+ }
32
+ /**
33
+ * Make a POST request
34
+ */
35
+ async post(path, body) {
36
+ return this.request('POST', path, body);
37
+ }
38
+ /**
39
+ * Make a streaming POST request (returns ReadableStream)
40
+ */
41
+ async postStream(path, body, signal) {
42
+ const url = `${this.baseUrl}/${path}`;
43
+ const controller = new AbortController();
44
+ const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
45
+ // Combine abort signals
46
+ if (signal) {
47
+ signal.addEventListener('abort', () => controller.abort());
48
+ }
49
+ try {
50
+ const response = await fetch(url, {
51
+ method: 'POST',
52
+ headers: {
53
+ 'Content-Type': 'application/json',
54
+ Authorization: `Bearer ${this.apiKey}`,
55
+ 'User-Agent': '@ancatag/n-r',
56
+ },
57
+ body: body ? JSON.stringify(body) : undefined,
58
+ signal: controller.signal,
59
+ });
60
+ clearTimeout(timeoutId);
61
+ if (!response.ok) {
62
+ const error = await this.parseError(response);
63
+ throw error;
64
+ }
65
+ if (!response.body) {
66
+ throw new NovaError('No response body');
67
+ }
68
+ return response.body;
69
+ }
70
+ catch (error) {
71
+ clearTimeout(timeoutId);
72
+ if (error instanceof NovaError) {
73
+ throw error;
74
+ }
75
+ if (error.name === 'AbortError') {
76
+ throw new NovaError('Request timeout', 408, 'timeout');
77
+ }
78
+ throw new NovaError(error.message || 'Network error', 0, 'network_error');
79
+ }
80
+ }
81
+ /**
82
+ * Make an HTTP request with retries
83
+ */
84
+ async request(method, path, body, retryCount = 0) {
85
+ const url = `${this.baseUrl}/${path}`;
86
+ const controller = new AbortController();
87
+ const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
88
+ try {
89
+ const response = await fetch(url, {
90
+ method,
91
+ headers: {
92
+ 'Content-Type': 'application/json',
93
+ Authorization: `Bearer ${this.apiKey}`,
94
+ 'User-Agent': '@ancatag/n-r',
95
+ },
96
+ body: body ? JSON.stringify(body) : undefined,
97
+ signal: controller.signal,
98
+ });
99
+ clearTimeout(timeoutId);
100
+ if (!response.ok) {
101
+ const error = await this.parseError(response);
102
+ // Retry on server errors (5xx) or rate limits (429)
103
+ if ((error.status && error.status >= 500) ||
104
+ error.status === 429) {
105
+ if (retryCount < this.maxRetries) {
106
+ // Exponential backoff: 1s, 2s, 4s
107
+ const delay = Math.pow(2, retryCount) * 1000;
108
+ await new Promise((resolve) => setTimeout(resolve, delay));
109
+ return this.request(method, path, body, retryCount + 1);
110
+ }
111
+ }
112
+ throw error;
113
+ }
114
+ const data = await response.json();
115
+ return data;
116
+ }
117
+ catch (error) {
118
+ clearTimeout(timeoutId);
119
+ if (error instanceof NovaError) {
120
+ throw error;
121
+ }
122
+ if (error.name === 'AbortError') {
123
+ throw new NovaError('Request timeout', 408, 'timeout');
124
+ }
125
+ // Retry on network errors
126
+ if (retryCount < this.maxRetries && method === 'GET') {
127
+ const delay = Math.pow(2, retryCount) * 1000;
128
+ await new Promise((resolve) => setTimeout(resolve, delay));
129
+ return this.request(method, path, body, retryCount + 1);
130
+ }
131
+ throw new NovaError(error.message || 'Network error', 0, 'network_error');
132
+ }
133
+ }
134
+ /**
135
+ * Parse error response from API
136
+ */
137
+ async parseError(response) {
138
+ let errorData;
139
+ try {
140
+ errorData = await response.json();
141
+ }
142
+ catch {
143
+ // If response is not JSON, use status text
144
+ return new NovaError(response.statusText || `HTTP ${response.status}`, response.status, 'http_error');
145
+ }
146
+ // Handle OpenAI-compatible error format
147
+ if (errorData.error) {
148
+ return new NovaError(errorData.error.message || 'API error', response.status, errorData.error.code, errorData.error.type);
149
+ }
150
+ return new NovaError(errorData.message || `HTTP ${response.status}`, response.status, 'http_error');
151
+ }
152
+ }
153
+ //# sourceMappingURL=http-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-client.js","sourceRoot":"","sources":["../src/http-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Nova AI SDK
3
+ * Official Node.js/TypeScript SDK for Nova AI API
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * import { NovaClient } from '@ancatag/n-r';
8
+ *
9
+ * const client = new NovaClient({
10
+ * apiKey: 'nova_sk_...',
11
+ * baseUrl: 'http://localhost:3000', // optional
12
+ * });
13
+ *
14
+ * // Non-streaming
15
+ * const response = await client.chat.create({
16
+ * model: 'llama2',
17
+ * messages: [{ role: 'user', content: 'Hello!' }],
18
+ * });
19
+ *
20
+ * // Streaming
21
+ * for await (const chunk of client.chat.createStream({
22
+ * model: 'llama2',
23
+ * messages: [{ role: 'user', content: 'Hello!' }],
24
+ * })) {
25
+ * console.log(chunk.choices[0]?.delta?.content || '');
26
+ * }
27
+ * ```
28
+ */
29
+ export { NovaClient } from './client.js';
30
+ export { ChatCompletions } from './chat.js';
31
+ export { Models } from './models.js';
32
+ export { HttpClient } from './http-client.js';
33
+ export { GrpcClient } from './grpc-client.js';
34
+ export { NovaError } from './types.js';
35
+ export type { ChatMessage, ChatCompletionRequest, ChatCompletionResponse, ChatCompletionChunk, ChatCompletionChoice, ChatCompletionUsage, ChatCompletionChunkChoice, ChatCompletionError, Model, NovaClientConfig, NovaTransport, } from './types.js';
36
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,YAAY,EACX,WAAW,EACX,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,KAAK,EACL,gBAAgB,EAChB,aAAa,GACb,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Nova AI SDK
3
+ * Official Node.js/TypeScript SDK for Nova AI API
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * import { NovaClient } from '@ancatag/n-r';
8
+ *
9
+ * const client = new NovaClient({
10
+ * apiKey: 'nova_sk_...',
11
+ * baseUrl: 'http://localhost:3000', // optional
12
+ * });
13
+ *
14
+ * // Non-streaming
15
+ * const response = await client.chat.create({
16
+ * model: 'llama2',
17
+ * messages: [{ role: 'user', content: 'Hello!' }],
18
+ * });
19
+ *
20
+ * // Streaming
21
+ * for await (const chunk of client.chat.createStream({
22
+ * model: 'llama2',
23
+ * messages: [{ role: 'user', content: 'Hello!' }],
24
+ * })) {
25
+ * console.log(chunk.choices[0]?.delta?.content || '');
26
+ * }
27
+ * ```
28
+ */
29
+ export { NovaClient } from './client.js';
30
+ export { ChatCompletions } from './chat.js';
31
+ export { Models } from './models.js';
32
+ export { HttpClient } from './http-client.js';
33
+ export { GrpcClient } from './grpc-client.js';
34
+ export { NovaError } from './types.js';
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Models API
3
+ * Handles model listing and retrieval
4
+ */
5
+ import { HttpClient } from './http-client.js';
6
+ import { GrpcClient } from './grpc-client.js';
7
+ import type { Model } from './types.js';
8
+ export declare class Models {
9
+ private readonly httpClient;
10
+ private readonly grpcClient?;
11
+ constructor(httpClient: HttpClient, grpcClient?: GrpcClient | undefined);
12
+ private isGrpc;
13
+ /**
14
+ * List all available models for the API key
15
+ */
16
+ list(): Promise<Model[]>;
17
+ /**
18
+ * Get a specific model by ID
19
+ */
20
+ get(modelId: string): Promise<Model>;
21
+ }
22
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,qBAAa,MAAM;IAEjB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;gBADX,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,UAAU,YAAA;IAGzC,OAAO,CAAC,MAAM;IAId;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAW9B;;OAEG;IACG,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;CAM1C"}
package/dist/models.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Models API
3
+ * Handles model listing and retrieval
4
+ */
5
+ export class Models {
6
+ httpClient;
7
+ grpcClient;
8
+ constructor(httpClient, grpcClient) {
9
+ this.httpClient = httpClient;
10
+ this.grpcClient = grpcClient;
11
+ }
12
+ isGrpc() {
13
+ return Boolean(this.grpcClient);
14
+ }
15
+ /**
16
+ * List all available models for the API key
17
+ */
18
+ async list() {
19
+ if (this.isGrpc() && this.grpcClient) {
20
+ return this.grpcClient.listModels();
21
+ }
22
+ const response = await this.httpClient.get('v1/models');
23
+ return response.data || [];
24
+ }
25
+ /**
26
+ * Get a specific model by ID
27
+ */
28
+ async get(modelId) {
29
+ const response = await this.httpClient.get(`v1/models/${modelId}`);
30
+ return response;
31
+ }
32
+ }
33
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,OAAO,MAAM;IAEA;IACA;IAFlB,YACkB,UAAsB,EACtB,UAAuB;QADvB,eAAU,GAAV,UAAU,CAAY;QACtB,eAAU,GAAV,UAAU,CAAa;IACtC,CAAC;IAEI,MAAM;QACb,OAAO,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACT,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;QACrC,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CACzC,WAAW,CACX,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CAAC,OAAe;QACxB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CACzC,aAAa,OAAO,EAAE,CACtB,CAAC;QACF,OAAO,QAAQ,CAAC;IACjB,CAAC;CACD"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Nova SDK Types
3
+ * OpenAI-compatible types for Nova AI API
4
+ */
5
+ export type NovaTransport = 'rest' | 'grpc';
6
+ /**
7
+ * Chat message format (OpenAI-compatible)
8
+ */
9
+ export interface ChatMessage {
10
+ role: 'system' | 'user' | 'assistant' | 'function';
11
+ content: string;
12
+ name?: string;
13
+ function_call?: {
14
+ name: string;
15
+ arguments: string;
16
+ };
17
+ }
18
+ /**
19
+ * Chat completion request (OpenAI-compatible)
20
+ */
21
+ export interface ChatCompletionRequest {
22
+ model: string;
23
+ messages: ChatMessage[];
24
+ temperature?: number;
25
+ top_p?: number;
26
+ n?: number;
27
+ stream?: boolean;
28
+ stop?: string | string[];
29
+ max_tokens?: number;
30
+ presence_penalty?: number;
31
+ frequency_penalty?: number;
32
+ logit_bias?: Record<string, number>;
33
+ user?: string;
34
+ nova?: {
35
+ skipCache?: boolean;
36
+ modelConfigId?: string;
37
+ ragEnabled?: boolean;
38
+ metadata?: Record<string, any>;
39
+ systemPromptOverride?: string;
40
+ };
41
+ }
42
+ /**
43
+ * Chat completion response (OpenAI-compatible)
44
+ */
45
+ export interface ChatCompletionResponse {
46
+ id: string;
47
+ object: 'chat.completion';
48
+ created: number;
49
+ model: string;
50
+ choices: ChatCompletionChoice[];
51
+ usage: ChatCompletionUsage;
52
+ nova?: {
53
+ cacheHit: boolean;
54
+ cacheLayer?: 'hot' | 'semantic' | null;
55
+ tokensSaved: number;
56
+ responseTimeMs: number;
57
+ requestId: string;
58
+ };
59
+ }
60
+ export interface ChatCompletionChoice {
61
+ index: number;
62
+ message: {
63
+ role: 'assistant';
64
+ content: string;
65
+ function_call?: {
66
+ name: string;
67
+ arguments: string;
68
+ };
69
+ };
70
+ finish_reason: 'stop' | 'length' | 'function_call' | 'content_filter' | null;
71
+ }
72
+ export interface ChatCompletionUsage {
73
+ prompt_tokens: number;
74
+ completion_tokens: number;
75
+ total_tokens: number;
76
+ }
77
+ /**
78
+ * Streaming response chunk (OpenAI-compatible)
79
+ */
80
+ export interface ChatCompletionChunk {
81
+ id: string;
82
+ object: 'chat.completion.chunk';
83
+ created: number;
84
+ model: string;
85
+ choices: ChatCompletionChunkChoice[];
86
+ }
87
+ export interface ChatCompletionChunkChoice {
88
+ index: number;
89
+ delta: {
90
+ role?: 'assistant';
91
+ content?: string;
92
+ function_call?: {
93
+ name?: string;
94
+ arguments?: string;
95
+ };
96
+ };
97
+ finish_reason: 'stop' | 'length' | 'function_call' | 'content_filter' | null;
98
+ }
99
+ /**
100
+ * Error response (OpenAI-compatible)
101
+ */
102
+ export interface ChatCompletionError {
103
+ error: {
104
+ message: string;
105
+ type: string;
106
+ param: string | null;
107
+ code: string;
108
+ };
109
+ }
110
+ /**
111
+ * Model information
112
+ */
113
+ export interface Model {
114
+ id: string;
115
+ object: 'model';
116
+ created: number;
117
+ owned_by: string;
118
+ }
119
+ /**
120
+ * Client configuration
121
+ */
122
+ export interface NovaClientConfig {
123
+ /** Nova API key (required, format: nova_sk_...) */
124
+ apiKey: string;
125
+ /** Base URL for REST API (default: http://localhost:3000) */
126
+ baseUrl?: string;
127
+ /** gRPC URL (default: 0.0.0.0:50051) */
128
+ grpcUrl?: string;
129
+ /** Preferred transport */
130
+ transport?: NovaTransport;
131
+ /** Request timeout in milliseconds (default: 60000) */
132
+ timeoutMs?: number;
133
+ /** Maximum number of retries for failed requests (default: 2) */
134
+ maxRetries?: number;
135
+ }
136
+ /**
137
+ * SDK error class
138
+ */
139
+ export declare class NovaError extends Error {
140
+ readonly status?: number | undefined;
141
+ readonly code?: string | undefined;
142
+ readonly type?: string | undefined;
143
+ constructor(message: string, status?: number | undefined, code?: string | undefined, type?: string | undefined);
144
+ }
145
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Nova SDK Types
3
+ * OpenAI-compatible types for Nova AI API
4
+ */
5
+ /**
6
+ * SDK error class
7
+ */
8
+ export class NovaError extends Error {
9
+ status;
10
+ code;
11
+ type;
12
+ constructor(message, status, code, type) {
13
+ super(message);
14
+ this.status = status;
15
+ this.code = code;
16
+ this.type = type;
17
+ this.name = 'NovaError';
18
+ }
19
+ }
20
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuJH;;GAEG;AACH,MAAM,OAAO,SAAU,SAAQ,KAAK;IAGlB;IACA;IACA;IAJjB,YACC,OAAe,EACC,MAAe,EACf,IAAa,EACb,IAAa;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,WAAM,GAAN,MAAM,CAAS;QACf,SAAI,GAAJ,IAAI,CAAS;QACb,SAAI,GAAJ,IAAI,CAAS;QAG7B,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IACzB,CAAC;CACD"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@ancatag/n-r",
3
+ "version": "0.1.0",
4
+ "description": "Official Node.js/TypeScript SDK for Nova AI API",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js",
10
+ "require": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "dev": "tsc --watch",
21
+ "clean": "rm -rf dist",
22
+ "type-check": "tsc --noEmit",
23
+ "prepublishOnly": "pnpm clean && pnpm build",
24
+ "publish:npm": "npm publish --access public"
25
+ },
26
+ "keywords": [
27
+ "nova",
28
+ "ai",
29
+ "sdk",
30
+ "chat",
31
+ "completions",
32
+ "openai-compatible"
33
+ ],
34
+ "author": "",
35
+ "license": "ISC",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "git+https://github.com/sayanmohsin/nova-route.git",
39
+ "directory": "packages/sdk"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "engines": {
45
+ "node": ">=18.0.0"
46
+ },
47
+ "devDependencies": {
48
+ "typescript": "^5.9.3",
49
+ "@types/node": "^20.11.30"
50
+ },
51
+ "type": "module",
52
+ "dependencies": {
53
+ "@grpc/grpc-js": "^1.14.3",
54
+ "@grpc/proto-loader": "^0.8.0"
55
+ }
56
+ }