@inferencesh/sdk 0.4.21 → 0.4.23
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 +49 -23
- package/dist/api/agents.d.ts +144 -0
- package/dist/api/agents.js +261 -0
- package/dist/api/apps.d.ts +72 -0
- package/dist/api/apps.js +94 -0
- package/dist/api/chats.d.ts +30 -0
- package/dist/api/chats.js +46 -0
- package/dist/api/engines.d.ts +37 -0
- package/dist/api/engines.js +52 -0
- package/dist/api/files.d.ts +37 -0
- package/dist/api/files.js +130 -0
- package/dist/api/flow-runs.d.ts +46 -0
- package/dist/api/flow-runs.js +70 -0
- package/dist/api/flows.d.ts +46 -0
- package/dist/api/flows.js +70 -0
- package/dist/api/index.d.ts +3 -0
- package/dist/api/index.js +13 -0
- package/dist/api/tasks.d.ts +68 -0
- package/dist/api/tasks.js +147 -0
- package/dist/client.test.js +143 -18
- package/dist/http/client.d.ts +56 -0
- package/dist/http/client.js +186 -0
- package/dist/{errors.d.ts → http/errors.d.ts} +1 -1
- package/dist/http/index.d.ts +3 -0
- package/dist/http/index.js +11 -0
- package/dist/index.cjs +165 -0
- package/dist/index.d.ts +94 -4
- package/dist/index.js +132 -13
- package/dist/index.mjs +141 -1
- package/dist/integration.test.js +3 -3
- package/dist/proxy/express.cjs +71 -0
- package/dist/proxy/express.d.ts +1 -1
- package/dist/proxy/express.mjs +2 -1
- package/dist/proxy/hono.cjs +55 -0
- package/dist/proxy/hono.mjs +2 -1
- package/dist/proxy/index.cjs +178 -0
- package/dist/proxy/index.mjs +2 -1
- package/dist/proxy/nextjs.cjs +123 -0
- package/dist/proxy/nextjs.mjs +2 -1
- package/dist/proxy/remix.cjs +51 -0
- package/dist/proxy/remix.mjs +2 -1
- package/dist/proxy/svelte.cjs +55 -0
- package/dist/proxy/svelte.mjs +2 -1
- package/dist/stream.test.js +1 -1
- package/dist/tool-builder.d.ts +3 -1
- package/dist/tool-builder.js +10 -5
- package/dist/types.d.ts +349 -0
- package/dist/types.js +53 -4
- package/package.json +2 -2
- package/dist/client.d.ts +0 -248
- package/dist/client.js +0 -618
- /package/dist/{errors.js → http/errors.js} +0 -0
- /package/dist/{stream.d.ts → http/stream.d.ts} +0 -0
- /package/dist/{stream.js → http/stream.js} +0 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { HttpClient } from '../http/client';
|
|
2
|
+
import { TaskDTO as Task, ApiAppRunRequest, CreateTaskRequest, CursorListRequest, CursorListResponse } from '../types';
|
|
3
|
+
export interface RunOptions {
|
|
4
|
+
/** Callback for real-time status updates */
|
|
5
|
+
onUpdate?: (update: Task) => void;
|
|
6
|
+
/** Callback for partial updates with list of changed fields */
|
|
7
|
+
onPartialUpdate?: (update: Task, fields: string[]) => void;
|
|
8
|
+
/** Wait for task completion (default: true) */
|
|
9
|
+
wait?: boolean;
|
|
10
|
+
/** Auto-reconnect on connection loss (default: true) */
|
|
11
|
+
autoReconnect?: boolean;
|
|
12
|
+
/** Maximum reconnection attempts (default: 5) */
|
|
13
|
+
maxReconnects?: number;
|
|
14
|
+
/** Delay between reconnection attempts in ms (default: 1000) */
|
|
15
|
+
reconnectDelayMs?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Tasks API
|
|
19
|
+
*/
|
|
20
|
+
export declare class TasksAPI {
|
|
21
|
+
private readonly http;
|
|
22
|
+
constructor(http: HttpClient);
|
|
23
|
+
/**
|
|
24
|
+
* List tasks with cursor-based pagination
|
|
25
|
+
*/
|
|
26
|
+
list(params?: Partial<CursorListRequest>): Promise<CursorListResponse<Task>>;
|
|
27
|
+
/**
|
|
28
|
+
* List featured tasks with cursor-based pagination
|
|
29
|
+
*/
|
|
30
|
+
listFeatured(params?: Partial<CursorListRequest>): Promise<CursorListResponse<Task>>;
|
|
31
|
+
/**
|
|
32
|
+
* Get a task by ID
|
|
33
|
+
*/
|
|
34
|
+
get(taskId: string): Promise<Task>;
|
|
35
|
+
/**
|
|
36
|
+
* Create a task directly
|
|
37
|
+
* Accepts either simple format { app: string; input: unknown } or full CreateTaskRequest
|
|
38
|
+
*/
|
|
39
|
+
create(data: CreateTaskRequest | {
|
|
40
|
+
app: string;
|
|
41
|
+
input: unknown;
|
|
42
|
+
}): Promise<Task>;
|
|
43
|
+
/**
|
|
44
|
+
* Delete a task
|
|
45
|
+
*/
|
|
46
|
+
delete(taskId: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Cancel a running task
|
|
49
|
+
*/
|
|
50
|
+
cancel(taskId: string): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Create an EventSource for streaming task updates
|
|
53
|
+
*/
|
|
54
|
+
stream(taskId: string): Promise<import("eventsource").EventSource | null>;
|
|
55
|
+
/**
|
|
56
|
+
* Run a task and optionally wait for completion
|
|
57
|
+
*/
|
|
58
|
+
run(params: ApiAppRunRequest, processedInput: unknown, options?: RunOptions): Promise<Task>;
|
|
59
|
+
/**
|
|
60
|
+
* Update task visibility
|
|
61
|
+
*/
|
|
62
|
+
updateVisibility(taskId: string, visibility: string): Promise<Task>;
|
|
63
|
+
/**
|
|
64
|
+
* Feature/unfeature a task
|
|
65
|
+
*/
|
|
66
|
+
feature(taskId: string, featured: boolean): Promise<Task>;
|
|
67
|
+
}
|
|
68
|
+
export declare function createTasksAPI(http: HttpClient): TasksAPI;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TasksAPI = void 0;
|
|
4
|
+
exports.createTasksAPI = createTasksAPI;
|
|
5
|
+
const stream_1 = require("../http/stream");
|
|
6
|
+
const types_1 = require("../types");
|
|
7
|
+
function stripTask(task) {
|
|
8
|
+
return {
|
|
9
|
+
...task,
|
|
10
|
+
id: task.id,
|
|
11
|
+
created_at: task.created_at,
|
|
12
|
+
updated_at: task.updated_at,
|
|
13
|
+
input: task.input,
|
|
14
|
+
output: task.output,
|
|
15
|
+
logs: task.logs,
|
|
16
|
+
status: task.status,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Tasks API
|
|
21
|
+
*/
|
|
22
|
+
class TasksAPI {
|
|
23
|
+
constructor(http) {
|
|
24
|
+
this.http = http;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* List tasks with cursor-based pagination
|
|
28
|
+
*/
|
|
29
|
+
async list(params) {
|
|
30
|
+
return this.http.request('post', '/tasks/list', { data: params });
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* List featured tasks with cursor-based pagination
|
|
34
|
+
*/
|
|
35
|
+
async listFeatured(params) {
|
|
36
|
+
return this.http.request('post', '/tasks/featured/list', { data: params });
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get a task by ID
|
|
40
|
+
*/
|
|
41
|
+
async get(taskId) {
|
|
42
|
+
return this.http.request('get', `/tasks/${taskId}`);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a task directly
|
|
46
|
+
* Accepts either simple format { app: string; input: unknown } or full CreateTaskRequest
|
|
47
|
+
*/
|
|
48
|
+
async create(data) {
|
|
49
|
+
return this.http.request('post', '/tasks', { data });
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Delete a task
|
|
53
|
+
*/
|
|
54
|
+
async delete(taskId) {
|
|
55
|
+
return this.http.request('delete', `/tasks/${taskId}`);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Cancel a running task
|
|
59
|
+
*/
|
|
60
|
+
async cancel(taskId) {
|
|
61
|
+
return this.http.request('post', `/tasks/${taskId}/cancel`);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Create an EventSource for streaming task updates
|
|
65
|
+
*/
|
|
66
|
+
stream(taskId) {
|
|
67
|
+
return this.http.createEventSource(`/tasks/${taskId}/stream`);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Run a task and optionally wait for completion
|
|
71
|
+
*/
|
|
72
|
+
async run(params, processedInput, options = {}) {
|
|
73
|
+
const { onUpdate, onPartialUpdate, wait = true, autoReconnect = true, maxReconnects = 5, reconnectDelayMs = 1000, } = options;
|
|
74
|
+
const task = await this.http.request('post', '/apps/run', {
|
|
75
|
+
data: {
|
|
76
|
+
...params,
|
|
77
|
+
input: processedInput,
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
// Return immediately if not waiting
|
|
81
|
+
if (!wait) {
|
|
82
|
+
return stripTask(task);
|
|
83
|
+
}
|
|
84
|
+
// Wait for completion with optional updates
|
|
85
|
+
return new Promise((resolve, reject) => {
|
|
86
|
+
const streamManager = new stream_1.StreamManager({
|
|
87
|
+
createEventSource: async () => this.http.createEventSource(`/tasks/${task.id}/stream`),
|
|
88
|
+
autoReconnect,
|
|
89
|
+
maxReconnects,
|
|
90
|
+
reconnectDelayMs,
|
|
91
|
+
onData: (data) => {
|
|
92
|
+
const stripped = stripTask(data);
|
|
93
|
+
onUpdate?.(stripped);
|
|
94
|
+
if (data.status === types_1.TaskStatusCompleted) {
|
|
95
|
+
streamManager.stop();
|
|
96
|
+
resolve(stripped);
|
|
97
|
+
}
|
|
98
|
+
else if (data.status === types_1.TaskStatusFailed) {
|
|
99
|
+
streamManager.stop();
|
|
100
|
+
reject(new Error(data.error || 'task failed'));
|
|
101
|
+
}
|
|
102
|
+
else if (data.status === types_1.TaskStatusCancelled) {
|
|
103
|
+
streamManager.stop();
|
|
104
|
+
reject(new Error('task cancelled'));
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
onPartialData: (data, fields) => {
|
|
108
|
+
const stripped = stripTask(data);
|
|
109
|
+
onPartialUpdate?.(stripped, fields);
|
|
110
|
+
if (data.status === types_1.TaskStatusCompleted) {
|
|
111
|
+
streamManager.stop();
|
|
112
|
+
resolve(stripped);
|
|
113
|
+
}
|
|
114
|
+
else if (data.status === types_1.TaskStatusFailed) {
|
|
115
|
+
streamManager.stop();
|
|
116
|
+
reject(new Error(data.error || 'task failed'));
|
|
117
|
+
}
|
|
118
|
+
else if (data.status === types_1.TaskStatusCancelled) {
|
|
119
|
+
streamManager.stop();
|
|
120
|
+
reject(new Error('task cancelled'));
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
onError: (error) => {
|
|
124
|
+
reject(error);
|
|
125
|
+
streamManager.stop();
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
streamManager.connect();
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Update task visibility
|
|
133
|
+
*/
|
|
134
|
+
async updateVisibility(taskId, visibility) {
|
|
135
|
+
return this.http.request('put', `/tasks/${taskId}/visibility`, { data: { visibility } });
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Feature/unfeature a task
|
|
139
|
+
*/
|
|
140
|
+
async feature(taskId, featured) {
|
|
141
|
+
return this.http.request('put', `/tasks/${taskId}/feature`, { data: { featured } });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.TasksAPI = TasksAPI;
|
|
145
|
+
function createTasksAPI(http) {
|
|
146
|
+
return new TasksAPI(http);
|
|
147
|
+
}
|
package/dist/client.test.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
4
|
-
const errors_1 = require("./errors");
|
|
3
|
+
const index_1 = require("./index");
|
|
4
|
+
const errors_1 = require("./http/errors");
|
|
5
5
|
// Mock fetch globally
|
|
6
6
|
const mockFetch = jest.fn();
|
|
7
7
|
global.fetch = mockFetch;
|
|
@@ -11,19 +11,19 @@ describe('Inference', () => {
|
|
|
11
11
|
});
|
|
12
12
|
describe('constructor', () => {
|
|
13
13
|
it('should create an instance with valid config', () => {
|
|
14
|
-
const client = new
|
|
15
|
-
expect(client).toBeInstanceOf(
|
|
14
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
15
|
+
expect(client).toBeInstanceOf(index_1.Inference);
|
|
16
16
|
});
|
|
17
17
|
it('should throw error when neither apiKey nor proxyUrl is provided', () => {
|
|
18
|
-
expect(() => new
|
|
19
|
-
expect(() => new
|
|
18
|
+
expect(() => new index_1.Inference({ apiKey: '' })).toThrow('Either apiKey, getToken, or proxyUrl is required');
|
|
19
|
+
expect(() => new index_1.Inference({})).toThrow('Either apiKey, getToken, or proxyUrl is required');
|
|
20
20
|
});
|
|
21
21
|
it('should use default baseUrl when not provided', () => {
|
|
22
|
-
const client = new
|
|
22
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
23
23
|
expect(client).toBeDefined();
|
|
24
24
|
});
|
|
25
25
|
it('should accept custom baseUrl', () => {
|
|
26
|
-
const client = new
|
|
26
|
+
const client = new index_1.Inference({
|
|
27
27
|
apiKey: 'test-api-key',
|
|
28
28
|
baseUrl: 'https://custom-api.example.com',
|
|
29
29
|
});
|
|
@@ -47,7 +47,7 @@ describe('Inference', () => {
|
|
|
47
47
|
text: () => Promise.resolve(JSON.stringify(responseData)),
|
|
48
48
|
json: () => Promise.resolve(responseData),
|
|
49
49
|
});
|
|
50
|
-
const client = new
|
|
50
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
51
51
|
// Use input that won't trigger base64 detection (contains spaces/special chars)
|
|
52
52
|
const result = await client.run({ app: 'test-app', input: { message: 'hello world!' } }, { wait: false });
|
|
53
53
|
expect(result.id).toBe('task-123');
|
|
@@ -67,7 +67,7 @@ describe('Inference', () => {
|
|
|
67
67
|
text: () => Promise.resolve(JSON.stringify(responseData)),
|
|
68
68
|
json: () => Promise.resolve(responseData),
|
|
69
69
|
});
|
|
70
|
-
const client = new
|
|
70
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
71
71
|
await expect(client.run({ app: 'invalid-app', input: { message: 'test!' } }, { wait: false })).rejects.toThrow('Invalid app');
|
|
72
72
|
});
|
|
73
73
|
it('should throw RequirementsNotMetException on 412 with errors', async () => {
|
|
@@ -92,7 +92,7 @@ describe('Inference', () => {
|
|
|
92
92
|
text: () => Promise.resolve(JSON.stringify(responseData)),
|
|
93
93
|
json: () => Promise.resolve(responseData),
|
|
94
94
|
});
|
|
95
|
-
const client = new
|
|
95
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
96
96
|
try {
|
|
97
97
|
await client.run({ app: 'test-app', input: { message: 'test!' } }, { wait: false });
|
|
98
98
|
fail('Expected RequirementsNotMetException to be thrown');
|
|
@@ -128,7 +128,7 @@ describe('Inference', () => {
|
|
|
128
128
|
text: () => Promise.resolve(JSON.stringify(responseData)),
|
|
129
129
|
json: () => Promise.resolve(responseData),
|
|
130
130
|
});
|
|
131
|
-
const client = new
|
|
131
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
132
132
|
try {
|
|
133
133
|
await client.run({ app: 'test-app', input: {} }, { wait: false });
|
|
134
134
|
fail('Expected RequirementsNotMetException to be thrown');
|
|
@@ -150,18 +150,143 @@ describe('Inference', () => {
|
|
|
150
150
|
text: () => Promise.resolve(JSON.stringify(responseData)),
|
|
151
151
|
json: () => Promise.resolve(responseData),
|
|
152
152
|
});
|
|
153
|
-
const client = new
|
|
153
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
154
154
|
await client.cancel('task-123');
|
|
155
155
|
expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining('/tasks/task-123/cancel'), expect.objectContaining({ method: 'POST' }));
|
|
156
156
|
});
|
|
157
157
|
});
|
|
158
158
|
describe('lowercase factory', () => {
|
|
159
159
|
it('should export lowercase inference factory', () => {
|
|
160
|
-
expect(typeof
|
|
160
|
+
expect(typeof index_1.inference).toBe('function');
|
|
161
161
|
});
|
|
162
162
|
it('should work with lowercase inference factory', () => {
|
|
163
|
-
const client = (0,
|
|
164
|
-
expect(client).toBeInstanceOf(
|
|
163
|
+
const client = (0, index_1.inference)({ apiKey: 'test-api-key' });
|
|
164
|
+
expect(client).toBeInstanceOf(index_1.Inference);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
describe('namespaced APIs', () => {
|
|
169
|
+
beforeEach(() => {
|
|
170
|
+
jest.clearAllMocks();
|
|
171
|
+
});
|
|
172
|
+
describe('client.tasks', () => {
|
|
173
|
+
it('should have tasks namespace', () => {
|
|
174
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
175
|
+
expect(client.tasks).toBeDefined();
|
|
176
|
+
expect(typeof client.tasks.run).toBe('function');
|
|
177
|
+
expect(typeof client.tasks.get).toBe('function');
|
|
178
|
+
expect(typeof client.tasks.cancel).toBe('function');
|
|
179
|
+
expect(typeof client.tasks.list).toBe('function');
|
|
180
|
+
expect(typeof client.tasks.create).toBe('function');
|
|
181
|
+
});
|
|
182
|
+
it('should create task via tasks.create()', async () => {
|
|
183
|
+
const mockTask = {
|
|
184
|
+
id: 'task-123',
|
|
185
|
+
status: 1,
|
|
186
|
+
created_at: new Date().toISOString(),
|
|
187
|
+
updated_at: new Date().toISOString(),
|
|
188
|
+
input: { message: 'hello world' },
|
|
189
|
+
};
|
|
190
|
+
const responseData = { success: true, data: mockTask };
|
|
191
|
+
mockFetch.mockResolvedValueOnce({
|
|
192
|
+
ok: true,
|
|
193
|
+
status: 200,
|
|
194
|
+
text: () => Promise.resolve(JSON.stringify(responseData)),
|
|
195
|
+
json: () => Promise.resolve(responseData),
|
|
196
|
+
});
|
|
197
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
198
|
+
const result = await client.tasks.create({
|
|
199
|
+
app_id: 'test-app',
|
|
200
|
+
input: { message: 'hello world!' },
|
|
201
|
+
});
|
|
202
|
+
expect(result.id).toBe('task-123');
|
|
203
|
+
expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining('/tasks'), expect.objectContaining({ method: 'POST' }));
|
|
204
|
+
});
|
|
205
|
+
it('should get task via tasks.get()', async () => {
|
|
206
|
+
const mockTask = { id: 'task-123', status: 7 };
|
|
207
|
+
const responseData = { success: true, data: mockTask };
|
|
208
|
+
mockFetch.mockResolvedValueOnce({
|
|
209
|
+
ok: true,
|
|
210
|
+
status: 200,
|
|
211
|
+
text: () => Promise.resolve(JSON.stringify(responseData)),
|
|
212
|
+
json: () => Promise.resolve(responseData),
|
|
213
|
+
});
|
|
214
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
215
|
+
const result = await client.tasks.get('task-123');
|
|
216
|
+
expect(result.id).toBe('task-123');
|
|
217
|
+
expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining('/tasks/task-123'), expect.objectContaining({ method: 'GET' }));
|
|
218
|
+
});
|
|
219
|
+
it('should cancel task via tasks.cancel()', async () => {
|
|
220
|
+
const responseData = { success: true, data: null };
|
|
221
|
+
mockFetch.mockResolvedValueOnce({
|
|
222
|
+
ok: true,
|
|
223
|
+
status: 200,
|
|
224
|
+
text: () => Promise.resolve(JSON.stringify(responseData)),
|
|
225
|
+
json: () => Promise.resolve(responseData),
|
|
226
|
+
});
|
|
227
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
228
|
+
await client.tasks.cancel('task-123');
|
|
229
|
+
expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining('/tasks/task-123/cancel'), expect.objectContaining({ method: 'POST' }));
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
describe('client.files', () => {
|
|
233
|
+
it('should have files namespace', () => {
|
|
234
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
235
|
+
expect(client.files).toBeDefined();
|
|
236
|
+
expect(typeof client.files.upload).toBe('function');
|
|
237
|
+
expect(typeof client.files.list).toBe('function');
|
|
238
|
+
expect(typeof client.files.get).toBe('function');
|
|
239
|
+
expect(typeof client.files.delete).toBe('function');
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
describe('client.agents', () => {
|
|
243
|
+
it('should have agents namespace', () => {
|
|
244
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
245
|
+
expect(client.agents).toBeDefined();
|
|
246
|
+
expect(typeof client.agents.list).toBe('function');
|
|
247
|
+
expect(typeof client.agents.get).toBe('function');
|
|
248
|
+
expect(typeof client.agents.create).toBe('function');
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
describe('client.apps', () => {
|
|
252
|
+
it('should have apps namespace', () => {
|
|
253
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
254
|
+
expect(client.apps).toBeDefined();
|
|
255
|
+
expect(typeof client.apps.list).toBe('function');
|
|
256
|
+
expect(typeof client.apps.get).toBe('function');
|
|
257
|
+
expect(typeof client.apps.getByName).toBe('function');
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
describe('client.chats', () => {
|
|
261
|
+
it('should have chats namespace', () => {
|
|
262
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
263
|
+
expect(client.chats).toBeDefined();
|
|
264
|
+
expect(typeof client.chats.list).toBe('function');
|
|
265
|
+
expect(typeof client.chats.get).toBe('function');
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
describe('client.flows', () => {
|
|
269
|
+
it('should have flows namespace', () => {
|
|
270
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
271
|
+
expect(client.flows).toBeDefined();
|
|
272
|
+
expect(typeof client.flows.list).toBe('function');
|
|
273
|
+
expect(typeof client.flows.get).toBe('function');
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
describe('client.flowRuns', () => {
|
|
277
|
+
it('should have flowRuns namespace', () => {
|
|
278
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
279
|
+
expect(client.flowRuns).toBeDefined();
|
|
280
|
+
expect(typeof client.flowRuns.list).toBe('function');
|
|
281
|
+
expect(typeof client.flowRuns.get).toBe('function');
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
describe('client.engines', () => {
|
|
285
|
+
it('should have engines namespace', () => {
|
|
286
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
287
|
+
expect(client.engines).toBeDefined();
|
|
288
|
+
expect(typeof client.engines.list).toBe('function');
|
|
289
|
+
expect(typeof client.engines.get).toBe('function');
|
|
165
290
|
});
|
|
166
291
|
});
|
|
167
292
|
});
|
|
@@ -184,7 +309,7 @@ describe('uploadFile', () => {
|
|
|
184
309
|
json: () => Promise.resolve(responseData),
|
|
185
310
|
})
|
|
186
311
|
.mockResolvedValueOnce({ ok: true });
|
|
187
|
-
const client = new
|
|
312
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
188
313
|
// Use valid base64 that won't be mistaken for regular text
|
|
189
314
|
const result = await client.uploadFile('SGVsbG8gV29ybGQh', {
|
|
190
315
|
filename: 'test.txt',
|
|
@@ -206,7 +331,7 @@ describe('uploadFile', () => {
|
|
|
206
331
|
text: () => Promise.resolve(JSON.stringify(responseData)),
|
|
207
332
|
json: () => Promise.resolve(responseData),
|
|
208
333
|
});
|
|
209
|
-
const client = new
|
|
334
|
+
const client = new index_1.Inference({ apiKey: 'test-api-key' });
|
|
210
335
|
await expect(client.uploadFile('SGVsbG8gV29ybGQh', { filename: 'test.txt' })).rejects.toThrow('No upload URL provided by the server');
|
|
211
336
|
});
|
|
212
337
|
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { EventSource } from 'eventsource';
|
|
2
|
+
export interface HttpClientConfig {
|
|
3
|
+
/** Your inference.sh API key (required unless using proxyUrl) */
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
/** Custom API base URL (defaults to https://api.inference.sh) */
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Proxy URL for frontend apps.
|
|
9
|
+
* When set, requests are routed through your proxy server to protect API keys.
|
|
10
|
+
*/
|
|
11
|
+
proxyUrl?: string;
|
|
12
|
+
/** Dynamic token getter (alternative to apiKey) */
|
|
13
|
+
getToken?: () => string | null | undefined;
|
|
14
|
+
/** Dynamic headers */
|
|
15
|
+
headers?: Record<string, string | (() => string | undefined)>;
|
|
16
|
+
/** Request credentials mode */
|
|
17
|
+
credentials?: RequestCredentials;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Low-level HTTP client for inference.sh API
|
|
21
|
+
*
|
|
22
|
+
* This client handles authentication, proxy mode, and error handling.
|
|
23
|
+
* It's designed to be extended by higher-level API modules.
|
|
24
|
+
*/
|
|
25
|
+
export declare class HttpClient {
|
|
26
|
+
private readonly apiKey;
|
|
27
|
+
private readonly baseUrl;
|
|
28
|
+
private readonly proxyUrl;
|
|
29
|
+
private readonly getToken;
|
|
30
|
+
private readonly customHeaders;
|
|
31
|
+
private readonly credentials;
|
|
32
|
+
constructor(config: HttpClientConfig);
|
|
33
|
+
/** Get the base URL */
|
|
34
|
+
getBaseUrl(): string;
|
|
35
|
+
/** Check if in proxy mode */
|
|
36
|
+
isProxyMode(): boolean;
|
|
37
|
+
/** Resolve dynamic headers */
|
|
38
|
+
private resolveHeaders;
|
|
39
|
+
/** Get authorization token */
|
|
40
|
+
private getAuthToken;
|
|
41
|
+
/**
|
|
42
|
+
* Make an HTTP request to the API
|
|
43
|
+
*/
|
|
44
|
+
request<T, P extends object = Record<string, unknown>>(method: 'get' | 'post' | 'put' | 'delete', endpoint: string, options?: {
|
|
45
|
+
params?: P;
|
|
46
|
+
data?: unknown;
|
|
47
|
+
}): Promise<T>;
|
|
48
|
+
/**
|
|
49
|
+
* Create an EventSource for SSE streaming
|
|
50
|
+
*/
|
|
51
|
+
createEventSource(endpoint: string): Promise<EventSource | null>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Create an HTTP client instance
|
|
55
|
+
*/
|
|
56
|
+
export declare function createHttpClient(config: HttpClientConfig): HttpClient;
|