@inferencesh/sdk 0.6.12 → 0.6.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/agent/actions.test.js +225 -1
- package/dist/agent/api.test.js +18 -1
- package/dist/api/agents.test.js +285 -0
- package/dist/api/knowledge.test.js +144 -0
- package/dist/api/mcp-servers.test.js +34 -0
- package/dist/api/projects.test.js +9 -0
- package/dist/api/sessions.test.js +12 -0
- package/dist/api/tasks.test.js +37 -0
- package/dist/api/teams.test.js +60 -0
- package/dist/client.test.js +112 -1
- package/dist/proxy/hono.test.d.ts +1 -0
- package/dist/proxy/hono.test.js +90 -0
- package/dist/proxy/nextjs.test.d.ts +1 -0
- package/dist/proxy/nextjs.test.js +125 -0
- package/dist/proxy/remix.test.d.ts +1 -0
- package/dist/proxy/remix.test.js +66 -0
- package/dist/proxy/svelte.test.d.ts +1 -0
- package/dist/proxy/svelte.test.js +69 -0
- package/package.json +3 -3
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { INF_TARGET_HEADER } from './index';
|
|
2
|
+
import { handlers, pageHandler } from './nextjs';
|
|
3
|
+
function createMockPageResponse() {
|
|
4
|
+
const res = {
|
|
5
|
+
statusCode: 200,
|
|
6
|
+
headers: {},
|
|
7
|
+
body: undefined,
|
|
8
|
+
status(code) {
|
|
9
|
+
this.statusCode = code;
|
|
10
|
+
return this;
|
|
11
|
+
},
|
|
12
|
+
setHeader(name, value) {
|
|
13
|
+
this.headers[name] = value;
|
|
14
|
+
},
|
|
15
|
+
json(data) {
|
|
16
|
+
this.body = data;
|
|
17
|
+
return this;
|
|
18
|
+
},
|
|
19
|
+
send(data) {
|
|
20
|
+
this.body = data;
|
|
21
|
+
return this;
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
return res;
|
|
25
|
+
}
|
|
26
|
+
function createMockNextRequest(overrides = {}) {
|
|
27
|
+
const headers = new Headers(overrides.headers ?? {});
|
|
28
|
+
return {
|
|
29
|
+
method: overrides.method ?? 'POST',
|
|
30
|
+
url: overrides.url ?? 'http://localhost/api/inference/proxy',
|
|
31
|
+
headers,
|
|
32
|
+
text: () => Promise.resolve(overrides.body ?? '{"prompt":"hi"}'),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
describe('nextjs pageHandler', () => {
|
|
36
|
+
const originalFetch = global.fetch;
|
|
37
|
+
beforeEach(() => {
|
|
38
|
+
jest.clearAllMocks();
|
|
39
|
+
process.env.INFERENCE_API_KEY = 'nextjs-test-key';
|
|
40
|
+
});
|
|
41
|
+
afterEach(() => {
|
|
42
|
+
global.fetch = originalFetch;
|
|
43
|
+
});
|
|
44
|
+
it('should return 400 when target URL is missing', async () => {
|
|
45
|
+
const req = { method: 'POST', body: {}, headers: {}, query: {} };
|
|
46
|
+
const res = createMockPageResponse();
|
|
47
|
+
await pageHandler(req, res);
|
|
48
|
+
expect(res.statusCode).toBe(400);
|
|
49
|
+
expect(res.body).toEqual({
|
|
50
|
+
error: `Missing ${INF_TARGET_HEADER} header or __inf_target query param`,
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
it('should proxy JSON responses through res.json()', async () => {
|
|
54
|
+
global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
|
|
55
|
+
status: 200,
|
|
56
|
+
headers: { 'content-type': 'application/json' },
|
|
57
|
+
}));
|
|
58
|
+
const target = 'https://api.inference.sh/v1/run';
|
|
59
|
+
const req = {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
body: { prompt: 'hi' },
|
|
62
|
+
headers: { [INF_TARGET_HEADER]: target },
|
|
63
|
+
query: {},
|
|
64
|
+
};
|
|
65
|
+
const res = createMockPageResponse();
|
|
66
|
+
await pageHandler(req, res);
|
|
67
|
+
expect(res.statusCode).toBe(200);
|
|
68
|
+
expect(res.body).toEqual({ ok: true });
|
|
69
|
+
});
|
|
70
|
+
it('should proxy non-JSON responses through res.send()', async () => {
|
|
71
|
+
global.fetch = jest.fn().mockResolvedValue(new Response('plain text', {
|
|
72
|
+
status: 200,
|
|
73
|
+
headers: { 'content-type': 'text/plain' },
|
|
74
|
+
}));
|
|
75
|
+
const target = 'https://api.inference.sh/v1/run';
|
|
76
|
+
const req = {
|
|
77
|
+
method: 'POST',
|
|
78
|
+
body: {},
|
|
79
|
+
headers: { [INF_TARGET_HEADER]: target },
|
|
80
|
+
query: {},
|
|
81
|
+
};
|
|
82
|
+
const res = createMockPageResponse();
|
|
83
|
+
await pageHandler(req, res);
|
|
84
|
+
expect(res.statusCode).toBe(200);
|
|
85
|
+
expect(res.body).toBe('plain text');
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
describe('nextjs handlers (App Router)', () => {
|
|
89
|
+
const originalFetch = global.fetch;
|
|
90
|
+
beforeEach(() => {
|
|
91
|
+
jest.clearAllMocks();
|
|
92
|
+
process.env.INFERENCE_API_KEY = 'nextjs-test-key';
|
|
93
|
+
});
|
|
94
|
+
afterEach(() => {
|
|
95
|
+
global.fetch = originalFetch;
|
|
96
|
+
});
|
|
97
|
+
it('should return 400 when target URL is missing', async () => {
|
|
98
|
+
const response = await handlers.GET(createMockNextRequest());
|
|
99
|
+
expect(response.status).toBe(400);
|
|
100
|
+
expect(await response.json()).toEqual({
|
|
101
|
+
error: `Missing ${INF_TARGET_HEADER} header or __inf_target query param`,
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
it('should passthrough streaming responses via Response body', async () => {
|
|
105
|
+
const encoder = new TextEncoder();
|
|
106
|
+
const stream = new ReadableStream({
|
|
107
|
+
start(controller) {
|
|
108
|
+
controller.enqueue(encoder.encode('data: {"x":1}\n\n'));
|
|
109
|
+
controller.close();
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
global.fetch = jest.fn().mockResolvedValue(new Response(stream, {
|
|
113
|
+
status: 200,
|
|
114
|
+
headers: { 'content-type': 'text/event-stream' },
|
|
115
|
+
}));
|
|
116
|
+
const target = 'https://api.inference.sh/v1/stream';
|
|
117
|
+
const response = await handlers.GET(createMockNextRequest({
|
|
118
|
+
method: 'GET',
|
|
119
|
+
headers: { [INF_TARGET_HEADER]: target },
|
|
120
|
+
}));
|
|
121
|
+
expect(response.status).toBe(200);
|
|
122
|
+
expect(response.body).toBeDefined();
|
|
123
|
+
expect(response.headers.get('content-type')).toContain('text/event-stream');
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { INF_TARGET_HEADER } from './index';
|
|
2
|
+
import { createHandler } from './remix';
|
|
3
|
+
describe('remix createHandler', () => {
|
|
4
|
+
const originalFetch = global.fetch;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
jest.clearAllMocks();
|
|
7
|
+
process.env.INFERENCE_API_KEY = 'remix-test-key';
|
|
8
|
+
});
|
|
9
|
+
afterEach(() => {
|
|
10
|
+
global.fetch = originalFetch;
|
|
11
|
+
});
|
|
12
|
+
it('should return 400 when target URL is missing', async () => {
|
|
13
|
+
const handler = createHandler();
|
|
14
|
+
const request = new Request('http://localhost/api/inference/proxy', {
|
|
15
|
+
method: 'POST',
|
|
16
|
+
body: '{}',
|
|
17
|
+
});
|
|
18
|
+
const response = await handler({ request });
|
|
19
|
+
expect(response.status).toBe(400);
|
|
20
|
+
expect(await response.json()).toEqual({
|
|
21
|
+
error: `Missing ${INF_TARGET_HEADER} header or __inf_target query param`,
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
it('should proxy JSON responses with framework remix', async () => {
|
|
25
|
+
global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
|
|
26
|
+
status: 200,
|
|
27
|
+
headers: { 'content-type': 'application/json' },
|
|
28
|
+
}));
|
|
29
|
+
const target = 'https://api.inference.sh/v1/run';
|
|
30
|
+
const handler = createHandler();
|
|
31
|
+
const request = new Request('http://localhost/api/inference/proxy', {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: { [INF_TARGET_HEADER]: target },
|
|
34
|
+
body: '{"prompt":"hi"}',
|
|
35
|
+
});
|
|
36
|
+
const response = await handler({ request });
|
|
37
|
+
expect(response.status).toBe(200);
|
|
38
|
+
expect(await response.json()).toEqual({ ok: true });
|
|
39
|
+
expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
|
|
40
|
+
headers: expect.objectContaining({
|
|
41
|
+
authorization: 'Bearer remix-test-key',
|
|
42
|
+
}),
|
|
43
|
+
}));
|
|
44
|
+
});
|
|
45
|
+
it('should use custom resolveApiKey when provided', async () => {
|
|
46
|
+
global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
|
|
47
|
+
status: 200,
|
|
48
|
+
headers: { 'content-type': 'application/json' },
|
|
49
|
+
}));
|
|
50
|
+
const handler = createHandler({
|
|
51
|
+
resolveApiKey: async () => 'custom-remix-key',
|
|
52
|
+
});
|
|
53
|
+
const target = 'https://api.inference.sh/v1/run';
|
|
54
|
+
const request = new Request('http://localhost/api/inference/proxy', {
|
|
55
|
+
method: 'POST',
|
|
56
|
+
headers: { [INF_TARGET_HEADER]: target },
|
|
57
|
+
body: '{}',
|
|
58
|
+
});
|
|
59
|
+
await handler({ request });
|
|
60
|
+
expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
|
|
61
|
+
headers: expect.objectContaining({
|
|
62
|
+
authorization: 'Bearer custom-remix-key',
|
|
63
|
+
}),
|
|
64
|
+
}));
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { INF_TARGET_HEADER } from './index';
|
|
2
|
+
import { createHandler } from './svelte';
|
|
3
|
+
function createMockRequestEvent(request) {
|
|
4
|
+
return { request };
|
|
5
|
+
}
|
|
6
|
+
describe('svelte createHandler', () => {
|
|
7
|
+
const originalFetch = global.fetch;
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
jest.clearAllMocks();
|
|
10
|
+
process.env.INFERENCE_API_KEY = 'svelte-test-key';
|
|
11
|
+
});
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
global.fetch = originalFetch;
|
|
14
|
+
});
|
|
15
|
+
it('should return 400 when target URL is missing', async () => {
|
|
16
|
+
const handler = createHandler();
|
|
17
|
+
const request = new Request('http://localhost/api/inference/proxy', {
|
|
18
|
+
method: 'POST',
|
|
19
|
+
body: '{}',
|
|
20
|
+
});
|
|
21
|
+
const response = await handler(createMockRequestEvent(request));
|
|
22
|
+
expect(response.status).toBe(400);
|
|
23
|
+
expect(await response.json()).toEqual({
|
|
24
|
+
error: `Missing ${INF_TARGET_HEADER} header or __inf_target query param`,
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
it('should proxy JSON responses with framework sveltekit', async () => {
|
|
28
|
+
global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
|
|
29
|
+
status: 200,
|
|
30
|
+
headers: { 'content-type': 'application/json' },
|
|
31
|
+
}));
|
|
32
|
+
const target = 'https://api.inference.sh/v1/run';
|
|
33
|
+
const handler = createHandler();
|
|
34
|
+
const request = new Request('http://localhost/api/inference/proxy', {
|
|
35
|
+
method: 'POST',
|
|
36
|
+
headers: { [INF_TARGET_HEADER]: target },
|
|
37
|
+
body: '{"prompt":"hi"}',
|
|
38
|
+
});
|
|
39
|
+
const response = await handler(createMockRequestEvent(request));
|
|
40
|
+
expect(response.status).toBe(200);
|
|
41
|
+
expect(await response.json()).toEqual({ ok: true });
|
|
42
|
+
expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
|
|
43
|
+
headers: expect.objectContaining({
|
|
44
|
+
authorization: 'Bearer svelte-test-key',
|
|
45
|
+
}),
|
|
46
|
+
}));
|
|
47
|
+
});
|
|
48
|
+
it('should use custom resolveApiKey when provided', async () => {
|
|
49
|
+
global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
|
|
50
|
+
status: 200,
|
|
51
|
+
headers: { 'content-type': 'application/json' },
|
|
52
|
+
}));
|
|
53
|
+
const handler = createHandler({
|
|
54
|
+
resolveApiKey: async () => 'custom-svelte-key',
|
|
55
|
+
});
|
|
56
|
+
const target = 'https://api.inference.sh/v1/run';
|
|
57
|
+
const request = new Request('http://localhost/api/inference/proxy', {
|
|
58
|
+
method: 'POST',
|
|
59
|
+
headers: { [INF_TARGET_HEADER]: target },
|
|
60
|
+
body: '{}',
|
|
61
|
+
});
|
|
62
|
+
await handler(createMockRequestEvent(request));
|
|
63
|
+
expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
|
|
64
|
+
headers: expect.objectContaining({
|
|
65
|
+
authorization: 'Bearer custom-svelte-key',
|
|
66
|
+
}),
|
|
67
|
+
}));
|
|
68
|
+
});
|
|
69
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inferencesh/sdk",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.13",
|
|
4
4
|
"description": "Official JavaScript/TypeScript SDK for inference.sh - Run AI models with a simple API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"@sveltejs/kit": "^2.60.1",
|
|
90
90
|
"svelte": "^5.55.7",
|
|
91
91
|
"@types/express": "^5.0.0",
|
|
92
|
-
"@types/jest": "^
|
|
92
|
+
"@types/jest": "^30.0.0",
|
|
93
93
|
"@types/node": "^24.1.0",
|
|
94
94
|
"@types/react": "^19.1.12",
|
|
95
95
|
"@typescript-eslint/eslint-plugin": "^8.38.0",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"eslint": "^9.32.0",
|
|
98
98
|
"eslint-config-prettier": "^10.1.8",
|
|
99
99
|
"hono": "^4.0.0",
|
|
100
|
-
"jest": "^
|
|
100
|
+
"jest": "^30.4.2",
|
|
101
101
|
"next": "^16.2.6",
|
|
102
102
|
"prettier": "^3.6.2",
|
|
103
103
|
"react": "^19.2.3",
|