@inferencesh/sdk 0.4.8 → 0.4.13
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/dist/client.d.ts +38 -13
- package/dist/client.js +101 -20
- package/dist/index.d.ts +1 -1
- package/dist/proxy/express.d.ts +14 -21
- package/dist/proxy/express.js +52 -65
- package/dist/proxy/hono.d.ts +10 -42
- package/dist/proxy/hono.js +28 -57
- package/dist/proxy/index.d.ts +75 -35
- package/dist/proxy/index.js +127 -85
- package/dist/proxy/nextjs.d.ts +28 -26
- package/dist/proxy/nextjs.js +77 -49
- package/dist/proxy/remix.d.ts +9 -25
- package/dist/proxy/remix.js +20 -30
- package/dist/proxy/svelte.d.ts +8 -21
- package/dist/proxy/svelte.js +20 -27
- package/dist/stream.js +10 -9
- package/dist/stream.test.js +2 -1
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
- package/dist/proxy/index.test.d.ts +0 -1
- package/dist/proxy/index.test.js +0 -220
- package/dist/proxy/index.test.mjs +0 -1
package/dist/client.d.ts
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import { ApiAppRunRequest, TaskDTO as Task, File, ChatDTO, ChatMessageDTO, AgentConfig } from './types';
|
|
2
2
|
import { EventSource } from 'eventsource';
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
/** Core LLM app ref: namespace/name@shortid (required for ad-hoc agents) */
|
|
9
|
-
core_app_ref: string;
|
|
10
|
-
};
|
|
3
|
+
/** Options for creating an agent */
|
|
4
|
+
export interface AgentOptions {
|
|
5
|
+
/** Optional name for the adhoc agent (used for deduplication and display) */
|
|
6
|
+
name?: string;
|
|
7
|
+
}
|
|
11
8
|
export interface SendMessageOptions {
|
|
12
|
-
/** File attachments
|
|
13
|
-
files?: (Blob |
|
|
9
|
+
/** File attachments - Blob (will be uploaded) or FileDTO (already uploaded, has uri) */
|
|
10
|
+
files?: (Blob | File)[];
|
|
14
11
|
/** Callback for message updates */
|
|
15
12
|
onMessage?: (message: ChatMessageDTO) => void;
|
|
16
13
|
/** Callback for chat updates */
|
|
@@ -137,11 +134,17 @@ export declare class Inference {
|
|
|
137
134
|
* tools: [...]
|
|
138
135
|
* })
|
|
139
136
|
*
|
|
137
|
+
* // Ad-hoc agent with name for grouping
|
|
138
|
+
* const agent = client.agent(
|
|
139
|
+
* { core_app_ref: 'infsh/claude-sonnet-4@xyz789' },
|
|
140
|
+
* { name: 'My Assistant' }
|
|
141
|
+
* )
|
|
142
|
+
*
|
|
140
143
|
* // Send messages
|
|
141
144
|
* const response = await agent.sendMessage('Hello!')
|
|
142
145
|
* ```
|
|
143
146
|
*/
|
|
144
|
-
agent(config: string |
|
|
147
|
+
agent(config: string | AgentConfig, options?: AgentOptions): Agent;
|
|
145
148
|
}
|
|
146
149
|
/**
|
|
147
150
|
* Agent for chat interactions
|
|
@@ -151,15 +154,19 @@ export declare class Inference {
|
|
|
151
154
|
export declare class Agent {
|
|
152
155
|
private readonly client;
|
|
153
156
|
private readonly config;
|
|
157
|
+
private readonly agentName;
|
|
154
158
|
private chatId;
|
|
155
159
|
private stream;
|
|
156
160
|
private dispatchedToolCalls;
|
|
157
161
|
/** @internal */
|
|
158
|
-
constructor(client: Inference, config: string |
|
|
162
|
+
constructor(client: Inference, config: string | AgentConfig, options?: AgentOptions);
|
|
159
163
|
/** Get current chat ID */
|
|
160
164
|
get currentChatId(): string | null;
|
|
161
165
|
/** Send a message to the agent */
|
|
162
|
-
sendMessage(text: string, options?: SendMessageOptions): Promise<
|
|
166
|
+
sendMessage(text: string, options?: SendMessageOptions): Promise<{
|
|
167
|
+
userMessage: ChatMessageDTO;
|
|
168
|
+
assistantMessage: ChatMessageDTO;
|
|
169
|
+
}>;
|
|
163
170
|
/** Get chat by ID */
|
|
164
171
|
getChat(chatId?: string): Promise<ChatDTO | null>;
|
|
165
172
|
/** Stop the current chat generation */
|
|
@@ -180,6 +187,24 @@ export declare class Agent {
|
|
|
180
187
|
disconnect(): void;
|
|
181
188
|
/** Reset the agent (start fresh chat) */
|
|
182
189
|
reset(): void;
|
|
190
|
+
/**
|
|
191
|
+
* Start streaming for the current chat.
|
|
192
|
+
* Call this after sendMessage to receive real-time updates.
|
|
193
|
+
* This is useful when you want to manage streaming separately from sendMessage.
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* ```typescript
|
|
197
|
+
* // Send message without waiting for streaming
|
|
198
|
+
* const { userMessage, assistantMessage } = await agent.sendMessage('hello');
|
|
199
|
+
*
|
|
200
|
+
* // Start streaming separately
|
|
201
|
+
* agent.startStreaming({
|
|
202
|
+
* onMessage: (msg) => console.log(msg.content),
|
|
203
|
+
* onChat: (chat) => console.log(chat.status),
|
|
204
|
+
* });
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
startStreaming(options?: Omit<SendMessageOptions, 'files'>): void;
|
|
183
208
|
/** Stream events until chat becomes idle */
|
|
184
209
|
private streamUntilIdle;
|
|
185
210
|
}
|
package/dist/client.js
CHANGED
|
@@ -109,14 +109,24 @@ class Inference {
|
|
|
109
109
|
_createEventSource(endpoint) {
|
|
110
110
|
const targetUrl = new URL(`${this.baseUrl}${endpoint}`);
|
|
111
111
|
const isProxyMode = !!this.proxyUrl;
|
|
112
|
-
|
|
112
|
+
// For proxy mode: Browser EventSource can't send custom headers,
|
|
113
|
+
// so append target URL as query param instead
|
|
114
|
+
let fetchUrl;
|
|
115
|
+
if (isProxyMode) {
|
|
116
|
+
const proxyUrlWithQuery = new URL(this.proxyUrl, window?.location?.origin || 'http://localhost');
|
|
117
|
+
proxyUrlWithQuery.searchParams.set('__inf_target', targetUrl.toString());
|
|
118
|
+
fetchUrl = proxyUrlWithQuery.toString();
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
fetchUrl = targetUrl.toString();
|
|
122
|
+
}
|
|
113
123
|
return new eventsource_1.EventSource(fetchUrl, {
|
|
114
124
|
fetch: (input, init) => {
|
|
115
125
|
const headers = {
|
|
116
126
|
...init?.headers,
|
|
117
127
|
};
|
|
118
128
|
if (isProxyMode) {
|
|
119
|
-
// Proxy mode: send target URL as header
|
|
129
|
+
// Proxy mode: also send target URL as header (for non-browser clients)
|
|
120
130
|
headers["x-inf-target-url"] = targetUrl.toString();
|
|
121
131
|
}
|
|
122
132
|
else {
|
|
@@ -246,10 +256,21 @@ class Inference {
|
|
|
246
256
|
}
|
|
247
257
|
},
|
|
248
258
|
onPartialData: (data, fields) => {
|
|
249
|
-
//
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
259
|
+
// Strip and send partial update if callback provided
|
|
260
|
+
const stripped = this._stripTask(data);
|
|
261
|
+
onPartialUpdate?.(stripped, fields);
|
|
262
|
+
// Also check for status changes in partial updates
|
|
263
|
+
if (data.status === types_1.TaskStatusCompleted) {
|
|
264
|
+
streamManager.stop();
|
|
265
|
+
resolve(stripped);
|
|
266
|
+
}
|
|
267
|
+
else if (data.status === types_1.TaskStatusFailed) {
|
|
268
|
+
streamManager.stop();
|
|
269
|
+
reject(new Error(data.error || "task failed"));
|
|
270
|
+
}
|
|
271
|
+
else if (data.status === types_1.TaskStatusCancelled) {
|
|
272
|
+
streamManager.stop();
|
|
273
|
+
reject(new Error("task cancelled"));
|
|
253
274
|
}
|
|
254
275
|
},
|
|
255
276
|
onError: (error) => {
|
|
@@ -346,12 +367,18 @@ class Inference {
|
|
|
346
367
|
* tools: [...]
|
|
347
368
|
* })
|
|
348
369
|
*
|
|
370
|
+
* // Ad-hoc agent with name for grouping
|
|
371
|
+
* const agent = client.agent(
|
|
372
|
+
* { core_app_ref: 'infsh/claude-sonnet-4@xyz789' },
|
|
373
|
+
* { name: 'My Assistant' }
|
|
374
|
+
* )
|
|
375
|
+
*
|
|
349
376
|
* // Send messages
|
|
350
377
|
* const response = await agent.sendMessage('Hello!')
|
|
351
378
|
* ```
|
|
352
379
|
*/
|
|
353
|
-
agent(config) {
|
|
354
|
-
return new Agent(this, config);
|
|
380
|
+
agent(config, options) {
|
|
381
|
+
return new Agent(this, config, options);
|
|
355
382
|
}
|
|
356
383
|
}
|
|
357
384
|
exports.Inference = Inference;
|
|
@@ -365,12 +392,13 @@ exports.Inference = Inference;
|
|
|
365
392
|
*/
|
|
366
393
|
class Agent {
|
|
367
394
|
/** @internal */
|
|
368
|
-
constructor(client, config) {
|
|
395
|
+
constructor(client, config, options) {
|
|
369
396
|
this.chatId = null;
|
|
370
397
|
this.stream = null;
|
|
371
398
|
this.dispatchedToolCalls = new Set();
|
|
372
399
|
this.client = client;
|
|
373
400
|
this.config = config;
|
|
401
|
+
this.agentName = options?.name;
|
|
374
402
|
}
|
|
375
403
|
/** Get current chat ID */
|
|
376
404
|
get currentChatId() {
|
|
@@ -379,40 +407,69 @@ class Agent {
|
|
|
379
407
|
/** Send a message to the agent */
|
|
380
408
|
async sendMessage(text, options = {}) {
|
|
381
409
|
const isTemplate = typeof this.config === 'string';
|
|
382
|
-
|
|
410
|
+
const hasCallbacks = !!(options.onMessage || options.onChat || options.onToolCall);
|
|
411
|
+
// Process files - either already uploaded (FileDTO with uri) or needs upload (Blob)
|
|
383
412
|
let imageUri;
|
|
384
413
|
let fileUris;
|
|
385
414
|
if (options.files && options.files.length > 0) {
|
|
386
|
-
|
|
387
|
-
const
|
|
388
|
-
const
|
|
415
|
+
// Separate files that need uploading from those already uploaded
|
|
416
|
+
const toUpload = [];
|
|
417
|
+
const alreadyUploaded = [];
|
|
418
|
+
for (const file of options.files) {
|
|
419
|
+
// FileDTO has a uri property, Blob does not
|
|
420
|
+
if ('uri' in file && typeof file.uri === 'string') {
|
|
421
|
+
alreadyUploaded.push(file);
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
toUpload.push(file);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
// Upload any Blobs that need uploading
|
|
428
|
+
const uploadedFiles = toUpload.length > 0
|
|
429
|
+
? await Promise.all(toUpload.map((blob) => this.client.uploadFile(blob)))
|
|
430
|
+
: [];
|
|
431
|
+
// Combine all files (already uploaded + newly uploaded)
|
|
432
|
+
const allFiles = [...alreadyUploaded, ...uploadedFiles];
|
|
433
|
+
// Separate images from other files
|
|
434
|
+
const images = allFiles.filter((f) => f.content_type?.startsWith('image/'));
|
|
435
|
+
const others = allFiles.filter((f) => !f.content_type?.startsWith('image/'));
|
|
389
436
|
if (images.length > 0)
|
|
390
437
|
imageUri = images[0].uri;
|
|
391
438
|
if (others.length > 0)
|
|
392
|
-
fileUris = others.map(f => f.uri);
|
|
439
|
+
fileUris = others.map((f) => f.uri);
|
|
393
440
|
}
|
|
394
441
|
const body = isTemplate
|
|
395
442
|
? {
|
|
396
443
|
chat_id: this.chatId,
|
|
397
|
-
|
|
444
|
+
agent: this.config,
|
|
398
445
|
input: { text, image: imageUri, files: fileUris, role: 'user', context: [], system_prompt: '', context_size: 0 },
|
|
399
446
|
}
|
|
400
447
|
: {
|
|
401
448
|
chat_id: this.chatId,
|
|
402
449
|
agent_config: this.config,
|
|
450
|
+
agent_name: this.agentName,
|
|
403
451
|
input: { text, image: imageUri, files: fileUris, role: 'user', context: [], system_prompt: '', context_size: 0 },
|
|
404
452
|
};
|
|
453
|
+
// For existing chats with callbacks: Start streaming BEFORE POST so we don't miss updates
|
|
454
|
+
let streamPromise = null;
|
|
455
|
+
if (this.chatId && hasCallbacks) {
|
|
456
|
+
streamPromise = this.streamUntilIdle(options);
|
|
457
|
+
}
|
|
458
|
+
// Make the POST request
|
|
405
459
|
const response = await this.client._request('post', '/agents/run', { data: body });
|
|
406
|
-
//
|
|
460
|
+
// For new chats: Set chatId and start streaming immediately after POST
|
|
407
461
|
const isNewChat = !this.chatId && response.assistant_message.chat_id;
|
|
408
462
|
if (isNewChat) {
|
|
409
463
|
this.chatId = response.assistant_message.chat_id;
|
|
464
|
+
if (hasCallbacks) {
|
|
465
|
+
streamPromise = this.streamUntilIdle(options);
|
|
466
|
+
}
|
|
410
467
|
}
|
|
411
|
-
// Wait for streaming to complete
|
|
412
|
-
if (
|
|
413
|
-
await
|
|
468
|
+
// Wait for streaming to complete
|
|
469
|
+
if (streamPromise) {
|
|
470
|
+
await streamPromise;
|
|
414
471
|
}
|
|
415
|
-
return response.assistant_message;
|
|
472
|
+
return { userMessage: response.user_message, assistantMessage: response.assistant_message };
|
|
416
473
|
}
|
|
417
474
|
/** Get chat by ID */
|
|
418
475
|
async getChat(chatId) {
|
|
@@ -450,6 +507,28 @@ class Agent {
|
|
|
450
507
|
this.chatId = null;
|
|
451
508
|
this.dispatchedToolCalls.clear();
|
|
452
509
|
}
|
|
510
|
+
/**
|
|
511
|
+
* Start streaming for the current chat.
|
|
512
|
+
* Call this after sendMessage to receive real-time updates.
|
|
513
|
+
* This is useful when you want to manage streaming separately from sendMessage.
|
|
514
|
+
*
|
|
515
|
+
* @example
|
|
516
|
+
* ```typescript
|
|
517
|
+
* // Send message without waiting for streaming
|
|
518
|
+
* const { userMessage, assistantMessage } = await agent.sendMessage('hello');
|
|
519
|
+
*
|
|
520
|
+
* // Start streaming separately
|
|
521
|
+
* agent.startStreaming({
|
|
522
|
+
* onMessage: (msg) => console.log(msg.content),
|
|
523
|
+
* onChat: (chat) => console.log(chat.status),
|
|
524
|
+
* });
|
|
525
|
+
* ```
|
|
526
|
+
*/
|
|
527
|
+
startStreaming(options = {}) {
|
|
528
|
+
if (!this.chatId)
|
|
529
|
+
return;
|
|
530
|
+
this.streamUntilIdle(options);
|
|
531
|
+
}
|
|
453
532
|
/** Stream events until chat becomes idle */
|
|
454
533
|
streamUntilIdle(options) {
|
|
455
534
|
if (!this.chatId)
|
|
@@ -461,6 +540,7 @@ class Agent {
|
|
|
461
540
|
createEventSource: async () => this.client._createEventSource(`/chats/${this.chatId}/stream`),
|
|
462
541
|
autoReconnect: true,
|
|
463
542
|
});
|
|
543
|
+
// Listen for Chat object updates (status changes)
|
|
464
544
|
this.stream.addEventListener('chats', (chat) => {
|
|
465
545
|
options.onChat?.(chat);
|
|
466
546
|
// Resolve when chat becomes idle (generation complete)
|
|
@@ -468,6 +548,7 @@ class Agent {
|
|
|
468
548
|
resolve();
|
|
469
549
|
}
|
|
470
550
|
});
|
|
551
|
+
// Listen for ChatMessage updates
|
|
471
552
|
this.stream.addEventListener('chat_messages', (message) => {
|
|
472
553
|
options.onMessage?.(message);
|
|
473
554
|
if (message.tool_invocations && options.onToolCall) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Inference, inference, InferenceConfig, RunOptions, UploadFileOptions, Agent,
|
|
1
|
+
export { Inference, inference, InferenceConfig, RunOptions, UploadFileOptions, Agent, AgentOptions, SendMessageOptions, } from './client';
|
|
2
2
|
export { tool, appTool, agentTool, webhookTool, internalTools, string, number, integer, boolean, enumOf, object, array, optional } from './tool-builder';
|
|
3
3
|
export { StreamManager, PartialDataWrapper } from './stream';
|
|
4
4
|
export { InferenceError, RequirementsNotMetException } from './errors';
|
package/dist/proxy/express.d.ts
CHANGED
|
@@ -1,37 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Express.js
|
|
2
|
+
* @inferencesh/sdk/proxy/express - Express.js Proxy Handler
|
|
3
3
|
*
|
|
4
4
|
* @example
|
|
5
5
|
* ```typescript
|
|
6
6
|
* import express from "express";
|
|
7
|
-
* import
|
|
7
|
+
* import { createHandler, PROXY_ROUTE } from "@inferencesh/sdk/proxy/express";
|
|
8
8
|
*
|
|
9
9
|
* const app = express();
|
|
10
10
|
* app.use(express.json());
|
|
11
|
-
* app.all(
|
|
11
|
+
* app.all(PROXY_ROUTE, createHandler());
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
14
14
|
import type { RequestHandler } from "express";
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
*/
|
|
15
|
+
/** Default proxy route path */
|
|
16
|
+
export declare const PROXY_ROUTE = "/api/inference/proxy";
|
|
17
|
+
/** @deprecated Use PROXY_ROUTE */
|
|
18
18
|
export declare const route = "/api/inference/proxy";
|
|
19
|
+
export interface ExpressProxyOptions {
|
|
20
|
+
/** Custom API key (overrides INFERENCE_API_KEY env var) */
|
|
21
|
+
apiKey?: string;
|
|
22
|
+
}
|
|
19
23
|
/**
|
|
20
|
-
* Express middleware handler for the Inference.sh proxy.
|
|
24
|
+
* Creates an Express middleware handler for the Inference.sh proxy.
|
|
21
25
|
*
|
|
22
26
|
* Requires `express.json()` middleware to be applied before this handler.
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```typescript
|
|
26
|
-
* import express from "express";
|
|
27
|
-
* import cors from "cors";
|
|
28
|
-
* import * as inferenceProxy from "@inferencesh/sdk/proxy/express";
|
|
29
|
-
*
|
|
30
|
-
* const app = express();
|
|
31
|
-
* app.use(express.json());
|
|
32
|
-
*
|
|
33
|
-
* // If clients are external, enable CORS
|
|
34
|
-
* app.all(inferenceProxy.route, cors(), inferenceProxy.handler);
|
|
35
|
-
* ```
|
|
36
27
|
*/
|
|
37
|
-
export declare
|
|
28
|
+
export declare function createHandler(options?: ExpressProxyOptions): RequestHandler;
|
|
29
|
+
/** @deprecated Use createHandler() */
|
|
30
|
+
export declare const handler: RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
|
package/dist/proxy/express.js
CHANGED
|
@@ -1,84 +1,71 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Express.js
|
|
3
|
+
* @inferencesh/sdk/proxy/express - Express.js Proxy Handler
|
|
4
4
|
*
|
|
5
5
|
* @example
|
|
6
6
|
* ```typescript
|
|
7
7
|
* import express from "express";
|
|
8
|
-
* import
|
|
8
|
+
* import { createHandler, PROXY_ROUTE } from "@inferencesh/sdk/proxy/express";
|
|
9
9
|
*
|
|
10
10
|
* const app = express();
|
|
11
11
|
* app.use(express.json());
|
|
12
|
-
* app.all(
|
|
12
|
+
* app.all(PROXY_ROUTE, createHandler());
|
|
13
13
|
* ```
|
|
14
14
|
*/
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.handler = exports.route = void 0;
|
|
16
|
+
exports.handler = exports.route = exports.PROXY_ROUTE = void 0;
|
|
17
|
+
exports.createHandler = createHandler;
|
|
17
18
|
const index_1 = require("./index");
|
|
19
|
+
/** Default proxy route path */
|
|
20
|
+
exports.PROXY_ROUTE = index_1.PROXY_PATH;
|
|
21
|
+
/** @deprecated Use PROXY_ROUTE */
|
|
22
|
+
exports.route = exports.PROXY_ROUTE;
|
|
18
23
|
/**
|
|
19
|
-
*
|
|
20
|
-
*/
|
|
21
|
-
exports.route = index_1.DEFAULT_PROXY_ROUTE;
|
|
22
|
-
/**
|
|
23
|
-
* Express middleware handler for the Inference.sh proxy.
|
|
24
|
+
* Creates an Express middleware handler for the Inference.sh proxy.
|
|
24
25
|
*
|
|
25
26
|
* Requires `express.json()` middleware to be applied before this handler.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```typescript
|
|
29
|
-
* import express from "express";
|
|
30
|
-
* import cors from "cors";
|
|
31
|
-
* import * as inferenceProxy from "@inferencesh/sdk/proxy/express";
|
|
32
|
-
*
|
|
33
|
-
* const app = express();
|
|
34
|
-
* app.use(express.json());
|
|
35
|
-
*
|
|
36
|
-
* // If clients are external, enable CORS
|
|
37
|
-
* app.all(inferenceProxy.route, cors(), inferenceProxy.handler);
|
|
38
|
-
* ```
|
|
39
27
|
*/
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
break;
|
|
69
|
-
res.write(value);
|
|
28
|
+
function createHandler(options) {
|
|
29
|
+
return async (req, res, _next) => {
|
|
30
|
+
return (0, index_1.processProxyRequest)({
|
|
31
|
+
framework: "express",
|
|
32
|
+
method: req.method,
|
|
33
|
+
body: async () => JSON.stringify(req.body),
|
|
34
|
+
headers: () => req.headers,
|
|
35
|
+
header: (name) => req.headers[name],
|
|
36
|
+
query: (name) => {
|
|
37
|
+
const v = req.query[name];
|
|
38
|
+
return typeof v === "string" ? v : undefined;
|
|
39
|
+
},
|
|
40
|
+
setHeader: (name, value) => res.setHeader(name, value),
|
|
41
|
+
error: (status, data) => res.status(status).json(data),
|
|
42
|
+
respond: async (response) => {
|
|
43
|
+
res.status(response.status);
|
|
44
|
+
// Handle streaming responses
|
|
45
|
+
const contentType = response.headers.get("content-type");
|
|
46
|
+
if (contentType?.includes("text/event-stream") ||
|
|
47
|
+
contentType?.includes("application/octet-stream")) {
|
|
48
|
+
if (response.body) {
|
|
49
|
+
const reader = response.body.getReader();
|
|
50
|
+
while (true) {
|
|
51
|
+
const { done, value } = await reader.read();
|
|
52
|
+
if (done)
|
|
53
|
+
break;
|
|
54
|
+
res.write(value);
|
|
55
|
+
}
|
|
70
56
|
}
|
|
57
|
+
res.end();
|
|
58
|
+
return res;
|
|
59
|
+
}
|
|
60
|
+
// Handle JSON responses
|
|
61
|
+
if (contentType?.includes("application/json")) {
|
|
62
|
+
return res.json(await response.json());
|
|
71
63
|
}
|
|
72
|
-
|
|
73
|
-
return res;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return res.send(await response.text());
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
|
-
};
|
|
84
|
-
exports.handler = handler;
|
|
64
|
+
// Handle text responses
|
|
65
|
+
return res.send(await response.text());
|
|
66
|
+
},
|
|
67
|
+
}, options);
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/** @deprecated Use createHandler() */
|
|
71
|
+
exports.handler = createHandler();
|
package/dist/proxy/hono.d.ts
CHANGED
|
@@ -1,59 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* @inferencesh/sdk/proxy/hono - Hono Framework Proxy Handler
|
|
3
3
|
*
|
|
4
|
-
* Lightweight handler for Hono
|
|
4
|
+
* Lightweight handler for Hono, ideal for edge/serverless deployments.
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
7
|
* ```typescript
|
|
8
8
|
* import { Hono } from "hono";
|
|
9
|
-
* import {
|
|
9
|
+
* import { createHandler } from "@inferencesh/sdk/proxy/hono";
|
|
10
10
|
*
|
|
11
11
|
* const app = new Hono();
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* app.all("/api/inference/proxy", proxyHandler);
|
|
12
|
+
* app.all("/api/inference/proxy", createHandler());
|
|
15
13
|
* ```
|
|
16
14
|
*/
|
|
17
15
|
import type { Context } from "hono";
|
|
18
16
|
export interface HonoProxyOptions {
|
|
19
|
-
/**
|
|
20
|
-
* Custom function to resolve the API key.
|
|
21
|
-
* Defaults to reading from INFERENCE_API_KEY environment variable.
|
|
22
|
-
*/
|
|
17
|
+
/** Custom function to resolve the API key */
|
|
23
18
|
resolveApiKey?: () => Promise<string | undefined>;
|
|
24
19
|
}
|
|
25
|
-
type
|
|
20
|
+
type HonoHandler = (context: Context) => Promise<Response>;
|
|
26
21
|
/**
|
|
27
|
-
* Creates a Hono route handler
|
|
28
|
-
*
|
|
29
|
-
* This is a drop-in handler for Hono applications that keeps API keys safe
|
|
30
|
-
* by running on your server.
|
|
31
|
-
*
|
|
32
|
-
* @param options - Proxy options
|
|
33
|
-
* @returns A Hono route handler function
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```typescript
|
|
37
|
-
* import { Hono } from "hono";
|
|
38
|
-
* import { createRouteHandler } from "@inferencesh/sdk/proxy/hono";
|
|
39
|
-
*
|
|
40
|
-
* const app = new Hono();
|
|
41
|
-
* const proxyHandler = createRouteHandler();
|
|
42
|
-
*
|
|
43
|
-
* app.all("/api/inference/proxy", proxyHandler);
|
|
44
|
-
*
|
|
45
|
-
* export default app;
|
|
46
|
-
* ```
|
|
47
|
-
*
|
|
48
|
-
* @example Custom API key resolver
|
|
49
|
-
* ```typescript
|
|
50
|
-
* const proxyHandler = createRouteHandler({
|
|
51
|
-
* resolveApiKey: async () => {
|
|
52
|
-
* // Load from a secrets manager
|
|
53
|
-
* return await getSecretFromVault("INFERENCE_API_KEY");
|
|
54
|
-
* },
|
|
55
|
-
* });
|
|
56
|
-
* ```
|
|
22
|
+
* Creates a Hono route handler for the Inference.sh proxy.
|
|
57
23
|
*/
|
|
58
|
-
export declare function
|
|
24
|
+
export declare function createHandler({ resolveApiKey, }?: HonoProxyOptions): HonoHandler;
|
|
25
|
+
/** @deprecated Use createHandler */
|
|
26
|
+
export declare const createRouteHandler: typeof createHandler;
|
|
59
27
|
export {};
|