@inferencesh/sdk 0.6.15 → 0.6.19
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/provider.d.ts +2 -1
- package/dist/api/apps.d.ts +4 -0
- package/dist/api/apps.js +6 -0
- package/dist/api/index.d.ts +3 -3
- package/dist/http/index.d.ts +3 -3
- package/dist/index.d.ts +9 -9
- package/dist/types.d.ts +30 -4
- package/dist/types.js +4 -0
- package/package.json +8 -5
- package/dist/agent/actions.test.d.ts +0 -1
- package/dist/agent/actions.test.js +0 -820
- package/dist/agent/api.test.d.ts +0 -1
- package/dist/agent/api.test.js +0 -246
- package/dist/agent/reducer.test.d.ts +0 -1
- package/dist/agent/reducer.test.js +0 -131
- package/dist/agent/types.test.d.ts +0 -1
- package/dist/agent/types.test.js +0 -75
- package/dist/api/agents.test.d.ts +0 -1
- package/dist/api/agents.test.js +0 -1014
- package/dist/api/api-keys.test.d.ts +0 -1
- package/dist/api/api-keys.test.js +0 -44
- package/dist/api/apps.test.d.ts +0 -1
- package/dist/api/apps.test.js +0 -135
- package/dist/api/chats.test.d.ts +0 -1
- package/dist/api/chats.test.js +0 -85
- package/dist/api/engines.test.d.ts +0 -1
- package/dist/api/engines.test.js +0 -133
- package/dist/api/files.test.d.ts +0 -1
- package/dist/api/files.test.js +0 -256
- package/dist/api/flow-runs.test.d.ts +0 -1
- package/dist/api/flow-runs.test.js +0 -97
- package/dist/api/flows.test.d.ts +0 -1
- package/dist/api/flows.test.js +0 -118
- package/dist/api/integrations.test.d.ts +0 -1
- package/dist/api/integrations.test.js +0 -109
- package/dist/api/knowledge.test.d.ts +0 -1
- package/dist/api/knowledge.test.js +0 -238
- package/dist/api/mcp-servers.test.d.ts +0 -1
- package/dist/api/mcp-servers.test.js +0 -98
- package/dist/api/projects.test.d.ts +0 -1
- package/dist/api/projects.test.js +0 -61
- package/dist/api/search.test.d.ts +0 -1
- package/dist/api/search.test.js +0 -50
- package/dist/api/secrets.test.d.ts +0 -1
- package/dist/api/secrets.test.js +0 -61
- package/dist/api/sessions.test.d.ts +0 -1
- package/dist/api/sessions.test.js +0 -61
- package/dist/api/tasks.test.d.ts +0 -1
- package/dist/api/tasks.test.js +0 -381
- package/dist/api/teams.test.d.ts +0 -1
- package/dist/api/teams.test.js +0 -139
- package/dist/client.test.d.ts +0 -1
- package/dist/client.test.js +0 -446
- package/dist/http/client.test.d.ts +0 -1
- package/dist/http/client.test.js +0 -435
- package/dist/http/errors.test.d.ts +0 -1
- package/dist/http/errors.test.js +0 -66
- package/dist/http/poll.test.d.ts +0 -1
- package/dist/http/poll.test.js +0 -146
- package/dist/http/streamable.test.d.ts +0 -4
- package/dist/http/streamable.test.js +0 -510
- package/dist/integration.test.d.ts +0 -9
- package/dist/integration.test.js +0 -107
- package/dist/proxy/express.test.d.ts +0 -1
- package/dist/proxy/express.test.js +0 -106
- package/dist/proxy/hono.test.d.ts +0 -1
- package/dist/proxy/hono.test.js +0 -90
- package/dist/proxy/index.test.d.ts +0 -1
- package/dist/proxy/index.test.js +0 -173
- package/dist/proxy/nextjs.test.d.ts +0 -1
- package/dist/proxy/nextjs.test.js +0 -125
- package/dist/proxy/remix.test.d.ts +0 -1
- package/dist/proxy/remix.test.js +0 -66
- package/dist/proxy/svelte.test.d.ts +0 -1
- package/dist/proxy/svelte.test.js +0 -69
- package/dist/sessions.integration.test.d.ts +0 -13
- package/dist/sessions.integration.test.js +0 -310
- package/dist/stream.test.d.ts +0 -1
- package/dist/stream.test.js +0 -363
- package/dist/streamable.integration.test.d.ts +0 -11
- package/dist/streamable.integration.test.js +0 -150
- package/dist/tool-builder.test.d.ts +0 -1
- package/dist/tool-builder.test.js +0 -407
- package/dist/utils.test.d.ts +0 -1
- package/dist/utils.test.js +0 -43
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { HttpClient } from '../http/client';
|
|
2
|
-
import { ApiKeysAPI } from './api-keys';
|
|
3
|
-
const mockFetch = jest.fn();
|
|
4
|
-
global.fetch = mockFetch;
|
|
5
|
-
function mockJsonResponse(body) {
|
|
6
|
-
mockFetch.mockResolvedValueOnce({
|
|
7
|
-
ok: true,
|
|
8
|
-
status: 200,
|
|
9
|
-
text: () => Promise.resolve(JSON.stringify(body)),
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
describe('ApiKeysAPI', () => {
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
jest.clearAllMocks();
|
|
15
|
-
});
|
|
16
|
-
const api = () => new ApiKeysAPI(new HttpClient({ apiKey: 'test-key' }));
|
|
17
|
-
it('should POST /apikeys/list for list()', async () => {
|
|
18
|
-
const page = { items: [{ id: 'key-1', name: 'CI' }], next_cursor: null };
|
|
19
|
-
mockJsonResponse(page);
|
|
20
|
-
const result = await api().list();
|
|
21
|
-
expect(result).toEqual(page);
|
|
22
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
23
|
-
expect(url).toContain('/apikeys/list');
|
|
24
|
-
expect(init.method).toBe('POST');
|
|
25
|
-
});
|
|
26
|
-
it('should POST /apikeys for create()', async () => {
|
|
27
|
-
const payload = { name: 'deploy-bot', scopes: ['tasks:read'] };
|
|
28
|
-
const key = { id: 'key-new', ...payload, key: 'inf_sk_abc' };
|
|
29
|
-
mockJsonResponse(key);
|
|
30
|
-
const result = await api().create(payload);
|
|
31
|
-
expect(result).toEqual(key);
|
|
32
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
33
|
-
expect(url).toContain('/apikeys');
|
|
34
|
-
expect(init.method).toBe('POST');
|
|
35
|
-
expect(JSON.parse(init.body)).toEqual(payload);
|
|
36
|
-
});
|
|
37
|
-
it('should DELETE /apikeys/{id} for delete()', async () => {
|
|
38
|
-
mockJsonResponse(null);
|
|
39
|
-
await api().delete('key-9');
|
|
40
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
41
|
-
expect(url).toContain('/apikeys/key-9');
|
|
42
|
-
expect(init.method).toBe('DELETE');
|
|
43
|
-
});
|
|
44
|
-
});
|
package/dist/api/apps.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/api/apps.test.js
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { HttpClient } from '../http/client';
|
|
2
|
-
import { AppsAPI } from './apps';
|
|
3
|
-
const mockFetch = jest.fn();
|
|
4
|
-
global.fetch = mockFetch;
|
|
5
|
-
function mockJsonResponse(body) {
|
|
6
|
-
mockFetch.mockResolvedValueOnce({
|
|
7
|
-
ok: true,
|
|
8
|
-
status: 200,
|
|
9
|
-
text: () => Promise.resolve(JSON.stringify(body)),
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
describe('AppsAPI', () => {
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
jest.clearAllMocks();
|
|
15
|
-
});
|
|
16
|
-
const api = () => new AppsAPI(new HttpClient({ apiKey: 'test-key' }));
|
|
17
|
-
it('should POST /apps/list for list()', async () => {
|
|
18
|
-
const apps = { items: [{ id: 'app-1' }], next_cursor: null };
|
|
19
|
-
mockJsonResponse(apps);
|
|
20
|
-
const result = await api().list({ limit: 10 });
|
|
21
|
-
expect(result).toEqual(apps);
|
|
22
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
23
|
-
expect(url).toContain('/apps/list');
|
|
24
|
-
expect(init.method).toBe('POST');
|
|
25
|
-
expect(JSON.parse(init.body)).toEqual({ limit: 10 });
|
|
26
|
-
});
|
|
27
|
-
it('should GET /apps/{name} for getByName()', async () => {
|
|
28
|
-
const app = { id: 'app-1', name: 'inference/claude-haiku' };
|
|
29
|
-
mockJsonResponse(app);
|
|
30
|
-
const result = await api().getByName('inference/claude-haiku');
|
|
31
|
-
expect(result).toEqual(app);
|
|
32
|
-
const [url] = mockFetch.mock.calls[0];
|
|
33
|
-
expect(url).toContain('/apps/inference/claude-haiku');
|
|
34
|
-
});
|
|
35
|
-
it('should POST transfer with team_id for transferOwnership()', async () => {
|
|
36
|
-
const app = { id: 'app-1' };
|
|
37
|
-
mockJsonResponse(app);
|
|
38
|
-
await api().transferOwnership('app-1', 'team-99');
|
|
39
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
40
|
-
expect(url).toContain('/apps/app-1/transfer');
|
|
41
|
-
expect(JSON.parse(init.body)).toEqual({ team_id: 'team-99' });
|
|
42
|
-
});
|
|
43
|
-
it('should POST license payload for saveLicense()', async () => {
|
|
44
|
-
const license = { app_id: 'app-1', license: 'key-abc' };
|
|
45
|
-
mockJsonResponse(license);
|
|
46
|
-
const result = await api().saveLicense('app-1', 'key-abc');
|
|
47
|
-
expect(result).toEqual(license);
|
|
48
|
-
const [, init] = mockFetch.mock.calls[0];
|
|
49
|
-
expect(JSON.parse(init.body)).toEqual({ license: 'key-abc' });
|
|
50
|
-
});
|
|
51
|
-
it('should PUT /apps/{id}/versions/{versionId}/current for setCurrentVersion()', async () => {
|
|
52
|
-
const app = { id: 'app-1', current_version_id: 'ver-2' };
|
|
53
|
-
mockJsonResponse(app);
|
|
54
|
-
await api().setCurrentVersion('app-1', 'ver-2');
|
|
55
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
56
|
-
expect(url).toContain('/apps/app-1/versions/ver-2/current');
|
|
57
|
-
expect(init.method).toBe('PUT');
|
|
58
|
-
});
|
|
59
|
-
it('should POST /apps/{id}/duplicate for duplicate()', async () => {
|
|
60
|
-
const app = { id: 'app-copy' };
|
|
61
|
-
mockJsonResponse(app);
|
|
62
|
-
const result = await api().duplicate('app-1');
|
|
63
|
-
expect(result).toEqual(app);
|
|
64
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
65
|
-
expect(url).toContain('/apps/app-1/duplicate');
|
|
66
|
-
expect(init.method).toBe('POST');
|
|
67
|
-
});
|
|
68
|
-
it('should GET /apps/{id} for get()', async () => {
|
|
69
|
-
const app = { id: 'app-1', name: 'demo' };
|
|
70
|
-
mockJsonResponse(app);
|
|
71
|
-
const result = await api().get('app-1');
|
|
72
|
-
expect(result).toEqual(app);
|
|
73
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
74
|
-
expect(url).toContain('/apps/app-1');
|
|
75
|
-
expect(init.method).toBe('GET');
|
|
76
|
-
});
|
|
77
|
-
it('should GET versioned app for getByVersionId()', async () => {
|
|
78
|
-
const app = { id: 'app-1', version_id: 'ver-1' };
|
|
79
|
-
mockJsonResponse(app);
|
|
80
|
-
const result = await api().getByVersionId('app-1', 'ver-1');
|
|
81
|
-
expect(result).toEqual(app);
|
|
82
|
-
const [url] = mockFetch.mock.calls[0];
|
|
83
|
-
expect(url).toContain('/apps/app-1/versions/ver-1');
|
|
84
|
-
});
|
|
85
|
-
it('should POST /apps for create()', async () => {
|
|
86
|
-
const app = { id: 'app-new', name: 'New App' };
|
|
87
|
-
mockJsonResponse(app);
|
|
88
|
-
const result = await api().create({ name: 'New App' });
|
|
89
|
-
expect(result).toEqual(app);
|
|
90
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
91
|
-
expect(url).toContain('/apps');
|
|
92
|
-
expect(init.method).toBe('POST');
|
|
93
|
-
expect(JSON.parse(init.body)).toEqual({ name: 'New App' });
|
|
94
|
-
});
|
|
95
|
-
it('should POST /apps/{id} for update()', async () => {
|
|
96
|
-
const app = { id: 'app-1', description: 'updated' };
|
|
97
|
-
mockJsonResponse(app);
|
|
98
|
-
const result = await api().update('app-1', { description: 'updated' });
|
|
99
|
-
expect(result).toEqual(app);
|
|
100
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
101
|
-
expect(url).toContain('/apps/app-1');
|
|
102
|
-
expect(JSON.parse(init.body)).toEqual({ description: 'updated' });
|
|
103
|
-
});
|
|
104
|
-
it('should DELETE /apps/{id} for delete()', async () => {
|
|
105
|
-
mockJsonResponse(null);
|
|
106
|
-
await api().delete('app-1');
|
|
107
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
108
|
-
expect(url).toContain('/apps/app-1');
|
|
109
|
-
expect(init.method).toBe('DELETE');
|
|
110
|
-
});
|
|
111
|
-
it('should POST /apps/{id}/versions/list for listVersions()', async () => {
|
|
112
|
-
const versions = { items: [{ id: 'ver-1' }], next_cursor: null };
|
|
113
|
-
mockJsonResponse(versions);
|
|
114
|
-
const result = await api().listVersions('app-1', { limit: 20 });
|
|
115
|
-
expect(result).toEqual(versions);
|
|
116
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
117
|
-
expect(url).toContain('/apps/app-1/versions/list');
|
|
118
|
-
expect(JSON.parse(init.body)).toEqual({ limit: 20 });
|
|
119
|
-
});
|
|
120
|
-
it('should POST visibility for updateVisibility()', async () => {
|
|
121
|
-
const app = { id: 'app-1', visibility: 'private' };
|
|
122
|
-
mockJsonResponse(app);
|
|
123
|
-
await api().updateVisibility('app-1', 'private');
|
|
124
|
-
const [, init] = mockFetch.mock.calls[0];
|
|
125
|
-
expect(JSON.parse(init.body)).toEqual({ visibility: 'private' });
|
|
126
|
-
});
|
|
127
|
-
it('should GET /apps/{id}/license for getLicense()', async () => {
|
|
128
|
-
const license = { app_id: 'app-1', license: 'MIT' };
|
|
129
|
-
mockJsonResponse(license);
|
|
130
|
-
const result = await api().getLicense('app-1');
|
|
131
|
-
expect(result).toEqual(license);
|
|
132
|
-
const [url] = mockFetch.mock.calls[0];
|
|
133
|
-
expect(url).toContain('/apps/app-1/license');
|
|
134
|
-
});
|
|
135
|
-
});
|
package/dist/api/chats.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/api/chats.test.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { HttpClient } from '../http/client';
|
|
2
|
-
import { ChatsAPI } from './chats';
|
|
3
|
-
const mockFetch = jest.fn();
|
|
4
|
-
global.fetch = mockFetch;
|
|
5
|
-
function mockJsonResponse(body) {
|
|
6
|
-
mockFetch.mockResolvedValueOnce({
|
|
7
|
-
ok: true,
|
|
8
|
-
status: 200,
|
|
9
|
-
text: () => Promise.resolve(JSON.stringify(body)),
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
describe('ChatsAPI', () => {
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
jest.clearAllMocks();
|
|
15
|
-
});
|
|
16
|
-
const api = () => new ChatsAPI(new HttpClient({ apiKey: 'test-key' }));
|
|
17
|
-
it('should GET /chats/{id}/trace for getTrace()', async () => {
|
|
18
|
-
const trace = { chat_id: 'chat-1', spans: [] };
|
|
19
|
-
mockJsonResponse(trace);
|
|
20
|
-
const result = await api().getTrace('chat-1');
|
|
21
|
-
expect(result).toEqual(trace);
|
|
22
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
23
|
-
expect(url).toContain('/chats/chat-1/trace');
|
|
24
|
-
expect(init.method).toBe('GET');
|
|
25
|
-
});
|
|
26
|
-
it('should DELETE /chats/{id} for delete()', async () => {
|
|
27
|
-
mockJsonResponse(null);
|
|
28
|
-
await api().delete('chat-9');
|
|
29
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
30
|
-
expect(url).toContain('/chats/chat-9');
|
|
31
|
-
expect(init.method).toBe('DELETE');
|
|
32
|
-
});
|
|
33
|
-
it('should POST /chats/list for list()', async () => {
|
|
34
|
-
const page = { items: [{ id: 'chat-1' }], next_cursor: null };
|
|
35
|
-
mockJsonResponse(page);
|
|
36
|
-
const result = await api().list({ limit: 25 });
|
|
37
|
-
expect(result).toEqual(page);
|
|
38
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
39
|
-
expect(url).toContain('/chats/list');
|
|
40
|
-
expect(init.method).toBe('POST');
|
|
41
|
-
expect(JSON.parse(init.body)).toEqual({ limit: 25 });
|
|
42
|
-
});
|
|
43
|
-
it('should GET /chats/{id} for get()', async () => {
|
|
44
|
-
const chat = { id: 'chat-1', status: 'open' };
|
|
45
|
-
mockJsonResponse(chat);
|
|
46
|
-
const result = await api().get('chat-1');
|
|
47
|
-
expect(result).toEqual(chat);
|
|
48
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
49
|
-
expect(url).toContain('/chats/chat-1');
|
|
50
|
-
expect(init.method).toBe('GET');
|
|
51
|
-
});
|
|
52
|
-
it('should POST /chats/{id} for update()', async () => {
|
|
53
|
-
const chat = { id: 'chat-1', name: 'Renamed' };
|
|
54
|
-
mockJsonResponse(chat);
|
|
55
|
-
const result = await api().update('chat-1', { name: 'Renamed' });
|
|
56
|
-
expect(result).toEqual(chat);
|
|
57
|
-
const [, init] = mockFetch.mock.calls[0];
|
|
58
|
-
expect(JSON.parse(init.body)).toEqual({ name: 'Renamed' });
|
|
59
|
-
});
|
|
60
|
-
it('should GET /chats/{id}/status for getStatus()', async () => {
|
|
61
|
-
mockJsonResponse({ status: 'busy' });
|
|
62
|
-
const result = await api().getStatus('chat-1');
|
|
63
|
-
expect(result).toEqual({ status: 'busy' });
|
|
64
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
65
|
-
expect(url).toContain('/chats/chat-1/status');
|
|
66
|
-
expect(init.method).toBe('GET');
|
|
67
|
-
});
|
|
68
|
-
it('should POST /chats/{id}/stop for stop()', async () => {
|
|
69
|
-
mockJsonResponse(null);
|
|
70
|
-
await api().stop('chat-1');
|
|
71
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
72
|
-
expect(url).toContain('/chats/chat-1/stop');
|
|
73
|
-
expect(init.method).toBe('POST');
|
|
74
|
-
});
|
|
75
|
-
it('should open SSE on /chats/{id}/stream for stream()', async () => {
|
|
76
|
-
const http = new HttpClient({ apiKey: 'test-key' });
|
|
77
|
-
const createEventSource = jest
|
|
78
|
-
.spyOn(http, 'createEventSource')
|
|
79
|
-
.mockResolvedValue(null);
|
|
80
|
-
const chats = new ChatsAPI(http);
|
|
81
|
-
await chats.stream('chat-42');
|
|
82
|
-
expect(createEventSource).toHaveBeenCalledWith('/chats/chat-42/stream');
|
|
83
|
-
createEventSource.mockRestore();
|
|
84
|
-
});
|
|
85
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/api/engines.test.js
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { HttpClient } from '../http/client';
|
|
2
|
-
import { EnginesAPI } from './engines';
|
|
3
|
-
const mockFetch = jest.fn();
|
|
4
|
-
global.fetch = mockFetch;
|
|
5
|
-
function mockJsonResponse(body) {
|
|
6
|
-
mockFetch.mockResolvedValueOnce({
|
|
7
|
-
ok: true,
|
|
8
|
-
status: 200,
|
|
9
|
-
text: () => Promise.resolve(JSON.stringify(body)),
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
describe('EnginesAPI', () => {
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
jest.clearAllMocks();
|
|
15
|
-
});
|
|
16
|
-
const api = () => new EnginesAPI(new HttpClient({ apiKey: 'test-key' }));
|
|
17
|
-
it('should POST resource ids for getForResources()', async () => {
|
|
18
|
-
const engines = [{ id: 'eng-1' }];
|
|
19
|
-
mockJsonResponse(engines);
|
|
20
|
-
const result = await api().getForResources({
|
|
21
|
-
app_ids: ['app-1'],
|
|
22
|
-
agent_ids: ['agent-1'],
|
|
23
|
-
});
|
|
24
|
-
expect(result).toEqual(engines);
|
|
25
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
26
|
-
expect(url).toContain('/engines/resources');
|
|
27
|
-
expect(JSON.parse(init.body)).toEqual({
|
|
28
|
-
app_ids: ['app-1'],
|
|
29
|
-
agent_ids: ['agent-1'],
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
it('should POST /engines/{id}/stop for stop()', async () => {
|
|
33
|
-
mockJsonResponse(null);
|
|
34
|
-
await api().stop('eng-1');
|
|
35
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
36
|
-
expect(url).toContain('/engines/eng-1/stop');
|
|
37
|
-
expect(init.method).toBe('POST');
|
|
38
|
-
});
|
|
39
|
-
it('should POST /engines/{id}/restart for restart()', async () => {
|
|
40
|
-
mockJsonResponse(null);
|
|
41
|
-
await api().restart('eng-1');
|
|
42
|
-
const [url] = mockFetch.mock.calls[0];
|
|
43
|
-
expect(url).toContain('/engines/eng-1/restart');
|
|
44
|
-
});
|
|
45
|
-
it('should open SSE on /engines/{id}/stream for stream()', async () => {
|
|
46
|
-
const http = new HttpClient({ apiKey: 'test-key' });
|
|
47
|
-
const createEventSource = jest
|
|
48
|
-
.spyOn(http, 'createEventSource')
|
|
49
|
-
.mockResolvedValue(null);
|
|
50
|
-
const engines = new EnginesAPI(http);
|
|
51
|
-
await engines.stream('eng-7');
|
|
52
|
-
expect(createEventSource).toHaveBeenCalledWith('/engines/eng-7/stream');
|
|
53
|
-
createEventSource.mockRestore();
|
|
54
|
-
});
|
|
55
|
-
it('should POST /engines/list for list()', async () => {
|
|
56
|
-
const page = { items: [{ id: 'eng-1' }], next_cursor: null };
|
|
57
|
-
mockJsonResponse(page);
|
|
58
|
-
const result = await api().list();
|
|
59
|
-
expect(result).toEqual(page);
|
|
60
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
61
|
-
expect(url).toContain('/engines/list');
|
|
62
|
-
expect(init.method).toBe('POST');
|
|
63
|
-
});
|
|
64
|
-
it('should GET /engines/{id} for get()', async () => {
|
|
65
|
-
const engine = { id: 'eng-1' };
|
|
66
|
-
mockJsonResponse(engine);
|
|
67
|
-
const result = await api().get('eng-1');
|
|
68
|
-
expect(result).toEqual(engine);
|
|
69
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
70
|
-
expect(url).toContain('/engines/eng-1');
|
|
71
|
-
expect(init.method).toBe('GET');
|
|
72
|
-
});
|
|
73
|
-
it('should POST /engines for create()', async () => {
|
|
74
|
-
const engine = { id: 'eng-new', name: 'worker' };
|
|
75
|
-
mockJsonResponse(engine);
|
|
76
|
-
const result = await api().create({ name: 'worker' });
|
|
77
|
-
expect(result).toEqual(engine);
|
|
78
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
79
|
-
expect(url).toContain('/engines');
|
|
80
|
-
expect(init.method).toBe('POST');
|
|
81
|
-
expect(JSON.parse(init.body)).toEqual({ name: 'worker' });
|
|
82
|
-
});
|
|
83
|
-
it('should POST /engines/{id} for update()', async () => {
|
|
84
|
-
const engine = { id: 'eng-1', name: 'updated' };
|
|
85
|
-
mockJsonResponse(engine);
|
|
86
|
-
const result = await api().update('eng-1', { name: 'updated' });
|
|
87
|
-
expect(result).toEqual(engine);
|
|
88
|
-
const [, init] = mockFetch.mock.calls[0];
|
|
89
|
-
expect(JSON.parse(init.body)).toEqual({ name: 'updated' });
|
|
90
|
-
});
|
|
91
|
-
it('should DELETE /engines/{id} for delete()', async () => {
|
|
92
|
-
mockJsonResponse(null);
|
|
93
|
-
await api().delete('eng-1');
|
|
94
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
95
|
-
expect(url).toContain('/engines/eng-1');
|
|
96
|
-
expect(init.method).toBe('DELETE');
|
|
97
|
-
});
|
|
98
|
-
it('should POST visibility for updateVisibility()', async () => {
|
|
99
|
-
const engine = { id: 'eng-1', visibility: 'team' };
|
|
100
|
-
mockJsonResponse(engine);
|
|
101
|
-
await api().updateVisibility('eng-1', 'team');
|
|
102
|
-
const [, init] = mockFetch.mock.calls[0];
|
|
103
|
-
expect(JSON.parse(init.body)).toEqual({ visibility: 'team' });
|
|
104
|
-
});
|
|
105
|
-
it('should POST transfer with team_id for transferOwnership()', async () => {
|
|
106
|
-
const engine = { id: 'eng-1' };
|
|
107
|
-
mockJsonResponse(engine);
|
|
108
|
-
await api().transferOwnership('eng-1', 'team-7');
|
|
109
|
-
const [, init] = mockFetch.mock.calls[0];
|
|
110
|
-
expect(JSON.parse(init.body)).toEqual({ team_id: 'team-7' });
|
|
111
|
-
});
|
|
112
|
-
it('should POST /engines/{id}/extend for extend()', async () => {
|
|
113
|
-
mockJsonResponse(null);
|
|
114
|
-
await api().extend('eng-1');
|
|
115
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
116
|
-
expect(url).toContain('/engines/eng-1/extend');
|
|
117
|
-
expect(init.method).toBe('POST');
|
|
118
|
-
});
|
|
119
|
-
it('should POST /engines/{id}/drain for drain()', async () => {
|
|
120
|
-
mockJsonResponse(null);
|
|
121
|
-
await api().drain('eng-1');
|
|
122
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
123
|
-
expect(url).toContain('/engines/eng-1/drain');
|
|
124
|
-
expect(init.method).toBe('POST');
|
|
125
|
-
});
|
|
126
|
-
it('should POST /engines/{id}/update for updateBinary()', async () => {
|
|
127
|
-
mockJsonResponse(null);
|
|
128
|
-
await api().updateBinary('eng-1');
|
|
129
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
130
|
-
expect(url).toContain('/engines/eng-1/update');
|
|
131
|
-
expect(init.method).toBe('POST');
|
|
132
|
-
});
|
|
133
|
-
});
|
package/dist/api/files.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/api/files.test.js
DELETED
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import { HttpClient } from '../http/client';
|
|
2
|
-
import { FilesAPI } from './files';
|
|
3
|
-
const mockFetch = jest.fn();
|
|
4
|
-
global.fetch = mockFetch;
|
|
5
|
-
function mockJsonResponse(body) {
|
|
6
|
-
mockFetch.mockResolvedValueOnce({
|
|
7
|
-
ok: true,
|
|
8
|
-
status: 200,
|
|
9
|
-
text: () => Promise.resolve(JSON.stringify(body)),
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
describe('FilesAPI', () => {
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
jest.clearAllMocks();
|
|
15
|
-
});
|
|
16
|
-
const api = () => new FilesAPI(new HttpClient({ apiKey: 'test-key' }));
|
|
17
|
-
it('should POST /files/list for list()', async () => {
|
|
18
|
-
const page = { items: [{ id: 'file-1' }], next_cursor: null };
|
|
19
|
-
mockJsonResponse(page);
|
|
20
|
-
const result = await api().list({ limit: 10 });
|
|
21
|
-
expect(result).toEqual(page);
|
|
22
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
23
|
-
expect(url).toContain('/files/list');
|
|
24
|
-
expect(init.method).toBe('POST');
|
|
25
|
-
expect(JSON.parse(init.body)).toEqual({ limit: 10 });
|
|
26
|
-
});
|
|
27
|
-
it('should GET /files/{id} for get()', async () => {
|
|
28
|
-
const file = { id: 'file-1', uri: 'inf://files/abc' };
|
|
29
|
-
mockJsonResponse(file);
|
|
30
|
-
const result = await api().get('file-1');
|
|
31
|
-
expect(result).toEqual(file);
|
|
32
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
33
|
-
expect(url).toContain('/files/file-1');
|
|
34
|
-
expect(init.method).toBe('GET');
|
|
35
|
-
});
|
|
36
|
-
it('should DELETE /files/{id} for delete()', async () => {
|
|
37
|
-
mockJsonResponse(null);
|
|
38
|
-
await api().delete('file-1');
|
|
39
|
-
const [url, init] = mockFetch.mock.calls[0];
|
|
40
|
-
expect(url).toContain('/files/file-1');
|
|
41
|
-
expect(init.method).toBe('DELETE');
|
|
42
|
-
});
|
|
43
|
-
describe('processInput', () => {
|
|
44
|
-
it('should return falsy inputs unchanged without uploading', async () => {
|
|
45
|
-
await expect(api().processInput(null)).resolves.toBeNull();
|
|
46
|
-
await expect(api().processInput(undefined)).resolves.toBeUndefined();
|
|
47
|
-
await expect(api().processInput(0)).resolves.toBe(0);
|
|
48
|
-
await expect(api().processInput(false)).resolves.toBe(false);
|
|
49
|
-
await expect(api().processInput('')).resolves.toBe('');
|
|
50
|
-
expect(mockFetch).not.toHaveBeenCalled();
|
|
51
|
-
});
|
|
52
|
-
it('should not treat short plain strings as base64 file uploads', async () => {
|
|
53
|
-
const result = await api().processInput({ key: 'key1', note: 'hello' });
|
|
54
|
-
expect(result).toEqual({ key: 'key1', note: 'hello' });
|
|
55
|
-
expect(mockFetch).not.toHaveBeenCalled();
|
|
56
|
-
});
|
|
57
|
-
it('should upload data URIs embedded in nested objects', async () => {
|
|
58
|
-
const fileRecord = {
|
|
59
|
-
id: 'file-1',
|
|
60
|
-
uri: 'inf://files/abc',
|
|
61
|
-
upload_url: 'https://upload.example.com/put',
|
|
62
|
-
content_type: 'image/png',
|
|
63
|
-
};
|
|
64
|
-
mockJsonResponse([fileRecord]);
|
|
65
|
-
mockFetch.mockResolvedValueOnce({ ok: true, status: 200 });
|
|
66
|
-
const input = {
|
|
67
|
-
prompt: 'draw',
|
|
68
|
-
image: 'data:image/png;base64,iVBORw0KGgo=',
|
|
69
|
-
};
|
|
70
|
-
const result = (await api().processInput(input));
|
|
71
|
-
expect(result.prompt).toBe('draw');
|
|
72
|
-
expect(result.image).toBe('inf://files/abc');
|
|
73
|
-
expect(mockFetch).toHaveBeenCalledTimes(2);
|
|
74
|
-
});
|
|
75
|
-
it('should upload top-level Blob values', async () => {
|
|
76
|
-
const fileRecord = {
|
|
77
|
-
id: 'file-blob',
|
|
78
|
-
uri: 'inf://files/blob',
|
|
79
|
-
upload_url: 'https://upload.example.com/put',
|
|
80
|
-
content_type: 'image/png',
|
|
81
|
-
};
|
|
82
|
-
mockJsonResponse([fileRecord]);
|
|
83
|
-
mockFetch.mockResolvedValueOnce({ ok: true, status: 200 });
|
|
84
|
-
const blob = new Blob(['png-bytes'], { type: 'image/png' });
|
|
85
|
-
const result = await api().processInput(blob);
|
|
86
|
-
expect(result).toBe('inf://files/blob');
|
|
87
|
-
expect(mockFetch).toHaveBeenCalledTimes(2);
|
|
88
|
-
});
|
|
89
|
-
it('should process arrays recursively', async () => {
|
|
90
|
-
const fileRecord = {
|
|
91
|
-
id: 'file-arr',
|
|
92
|
-
uri: 'inf://files/arr',
|
|
93
|
-
upload_url: 'https://upload.example.com/put',
|
|
94
|
-
content_type: 'image/png',
|
|
95
|
-
};
|
|
96
|
-
mockJsonResponse([fileRecord]);
|
|
97
|
-
mockFetch.mockResolvedValueOnce({ ok: true, status: 200 });
|
|
98
|
-
const input = ['plain', 'data:image/png;base64,iVBORw0KGgo='];
|
|
99
|
-
const result = (await api().processInput(input));
|
|
100
|
-
expect(result[0]).toBe('plain');
|
|
101
|
-
expect(result[1]).toBe('inf://files/arr');
|
|
102
|
-
});
|
|
103
|
-
it('should upload long raw base64 strings', async () => {
|
|
104
|
-
const fileRecord = {
|
|
105
|
-
id: 'file-b64',
|
|
106
|
-
uri: 'inf://files/b64',
|
|
107
|
-
upload_url: 'https://upload.example.com/put',
|
|
108
|
-
content_type: 'application/octet-stream',
|
|
109
|
-
};
|
|
110
|
-
mockJsonResponse([fileRecord]);
|
|
111
|
-
mockFetch.mockResolvedValueOnce({ ok: true, status: 200 });
|
|
112
|
-
const rawBase64 = 'A'.repeat(64);
|
|
113
|
-
const result = await api().processInput(rawBase64);
|
|
114
|
-
expect(result).toBe('inf://files/b64');
|
|
115
|
-
expect(mockFetch).toHaveBeenCalledTimes(2);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
describe('upload', () => {
|
|
119
|
-
it('should reject invalid data URI format when uploading content', async () => {
|
|
120
|
-
mockJsonResponse([{ id: 'file-x', uri: '', upload_url: 'https://upload.example.com/put' }]);
|
|
121
|
-
await expect(api().upload('data:invalid')).rejects.toThrow('Invalid data URI format');
|
|
122
|
-
});
|
|
123
|
-
it('should decode URL-encoded (non-base64) data URIs', async () => {
|
|
124
|
-
const fileRecord = {
|
|
125
|
-
id: 'file-3',
|
|
126
|
-
uri: 'inf://files/url-encoded',
|
|
127
|
-
upload_url: 'https://upload.example.com/put',
|
|
128
|
-
content_type: 'text/plain',
|
|
129
|
-
};
|
|
130
|
-
mockJsonResponse([fileRecord]);
|
|
131
|
-
mockFetch.mockResolvedValueOnce({ ok: true, status: 200 });
|
|
132
|
-
const result = await api().upload('data:text/plain,Hello%20World');
|
|
133
|
-
expect(result.uri).toBe('inf://files/url-encoded');
|
|
134
|
-
const putCall = mockFetch.mock.calls[1];
|
|
135
|
-
expect(putCall[1]?.headers).toMatchObject({ 'Content-Type': 'text/plain' });
|
|
136
|
-
});
|
|
137
|
-
it('should default media type to text/plain for data URIs without explicit type', async () => {
|
|
138
|
-
const fileRecord = {
|
|
139
|
-
id: 'file-4',
|
|
140
|
-
uri: 'inf://files/default-mt',
|
|
141
|
-
upload_url: 'https://upload.example.com/put',
|
|
142
|
-
content_type: 'text/plain',
|
|
143
|
-
};
|
|
144
|
-
mockJsonResponse([fileRecord]);
|
|
145
|
-
mockFetch.mockResolvedValueOnce({ ok: true, status: 200 });
|
|
146
|
-
await api().upload('data:;base64,SGVsbG8=');
|
|
147
|
-
const putCall = mockFetch.mock.calls[1];
|
|
148
|
-
expect(putCall[1]?.headers).toMatchObject({ 'Content-Type': 'text/plain' });
|
|
149
|
-
});
|
|
150
|
-
it('should throw when server does not return upload_url', async () => {
|
|
151
|
-
mockJsonResponse([{ id: 'file-x', uri: '', upload_url: undefined }]);
|
|
152
|
-
await expect(api().upload('data:text/plain,hello')).rejects.toThrow('No upload URL provided by the server');
|
|
153
|
-
});
|
|
154
|
-
it('should throw when PUT to upload_url fails', async () => {
|
|
155
|
-
const fileRecord = {
|
|
156
|
-
id: 'file-5',
|
|
157
|
-
uri: 'inf://files/fail-put',
|
|
158
|
-
upload_url: 'https://upload.example.com/put',
|
|
159
|
-
content_type: 'text/plain',
|
|
160
|
-
};
|
|
161
|
-
mockJsonResponse([fileRecord]);
|
|
162
|
-
mockFetch.mockResolvedValueOnce({
|
|
163
|
-
ok: false,
|
|
164
|
-
status: 500,
|
|
165
|
-
statusText: 'Internal Server Error',
|
|
166
|
-
});
|
|
167
|
-
await expect(api().upload('data:text/plain,hello')).rejects.toThrow('Failed to upload file content');
|
|
168
|
-
});
|
|
169
|
-
it('should upload Blob content with inferred content type and size', async () => {
|
|
170
|
-
const fileRecord = {
|
|
171
|
-
id: 'file-blob',
|
|
172
|
-
uri: 'inf://files/blob-direct',
|
|
173
|
-
upload_url: 'https://upload.example.com/put',
|
|
174
|
-
content_type: 'image/jpeg',
|
|
175
|
-
};
|
|
176
|
-
mockJsonResponse([fileRecord]);
|
|
177
|
-
mockFetch.mockResolvedValueOnce({ ok: true, status: 200 });
|
|
178
|
-
const blob = new Blob(['jpeg-bytes'], { type: 'image/jpeg' });
|
|
179
|
-
const result = await api().upload(blob, { filename: 'photo.jpg' });
|
|
180
|
-
expect(result.uri).toBe('inf://files/blob-direct');
|
|
181
|
-
const [, createInit] = mockFetch.mock.calls[0];
|
|
182
|
-
const createBody = JSON.parse(createInit.body);
|
|
183
|
-
expect(createBody.files[0]).toMatchObject({
|
|
184
|
-
filename: 'photo.jpg',
|
|
185
|
-
content_type: 'image/jpeg',
|
|
186
|
-
size: blob.size,
|
|
187
|
-
});
|
|
188
|
-
const [, putInit] = mockFetch.mock.calls[1];
|
|
189
|
-
expect(putInit.method).toBe('PUT');
|
|
190
|
-
expect(putInit.body).toBe(blob);
|
|
191
|
-
expect(putInit.headers).toMatchObject({ 'Content-Type': 'image/jpeg' });
|
|
192
|
-
});
|
|
193
|
-
it('should extract filename from File objects when options.filename is omitted', async () => {
|
|
194
|
-
const fileRecord = {
|
|
195
|
-
id: 'file-named',
|
|
196
|
-
uri: 'inf://files/named',
|
|
197
|
-
upload_url: 'https://upload.example.com/put',
|
|
198
|
-
content_type: 'application/pdf',
|
|
199
|
-
};
|
|
200
|
-
mockJsonResponse([fileRecord]);
|
|
201
|
-
mockFetch.mockResolvedValueOnce({ ok: true, status: 200 });
|
|
202
|
-
const file = new File(['pdf-bytes'], 'report.pdf', { type: 'application/pdf' });
|
|
203
|
-
await api().upload(file);
|
|
204
|
-
const [, createInit] = mockFetch.mock.calls[0];
|
|
205
|
-
const createBody = JSON.parse(createInit.body);
|
|
206
|
-
expect(createBody.files[0].filename).toBe('report.pdf');
|
|
207
|
-
expect(createBody.files[0].content_type).toBe('application/pdf');
|
|
208
|
-
});
|
|
209
|
-
it('should use explicit contentType when Blob type is empty', async () => {
|
|
210
|
-
const fileRecord = {
|
|
211
|
-
id: 'file-octet',
|
|
212
|
-
uri: 'inf://files/octet',
|
|
213
|
-
upload_url: 'https://upload.example.com/put',
|
|
214
|
-
content_type: 'application/octet-stream',
|
|
215
|
-
};
|
|
216
|
-
mockJsonResponse([fileRecord]);
|
|
217
|
-
mockFetch.mockResolvedValueOnce({ ok: true, status: 200 });
|
|
218
|
-
const blob = new Blob(['raw']);
|
|
219
|
-
await api().upload(blob, { contentType: 'application/octet-stream' });
|
|
220
|
-
const [, createInit] = mockFetch.mock.calls[0];
|
|
221
|
-
const createBody = JSON.parse(createInit.body);
|
|
222
|
-
expect(createBody.files[0].content_type).toBe('application/octet-stream');
|
|
223
|
-
});
|
|
224
|
-
it('should upload clean base64 strings without a data URI prefix', async () => {
|
|
225
|
-
const fileRecord = {
|
|
226
|
-
id: 'file-b64-direct',
|
|
227
|
-
uri: 'inf://files/b64-direct',
|
|
228
|
-
upload_url: 'https://upload.example.com/put',
|
|
229
|
-
content_type: 'text/plain',
|
|
230
|
-
};
|
|
231
|
-
mockJsonResponse([fileRecord]);
|
|
232
|
-
mockFetch.mockResolvedValueOnce({ ok: true, status: 200 });
|
|
233
|
-
const result = await api().upload('SGVsbG8=', { contentType: 'text/plain' });
|
|
234
|
-
expect(result.uri).toBe('inf://files/b64-direct');
|
|
235
|
-
const [, putInit] = mockFetch.mock.calls[1];
|
|
236
|
-
expect(putInit.headers).toMatchObject({ 'Content-Type': 'text/plain' });
|
|
237
|
-
});
|
|
238
|
-
it('should decode URL-safe base64 in data URIs', async () => {
|
|
239
|
-
const fileRecord = {
|
|
240
|
-
id: 'file-2',
|
|
241
|
-
uri: 'inf://files/def',
|
|
242
|
-
upload_url: 'https://upload.example.com/put',
|
|
243
|
-
content_type: 'text/plain',
|
|
244
|
-
};
|
|
245
|
-
mockJsonResponse([fileRecord]);
|
|
246
|
-
mockFetch.mockResolvedValueOnce({ ok: true, status: 200 });
|
|
247
|
-
// "SGVsbG8" is "Hello" in standard base64; URL-safe variant uses '-' instead of '+'
|
|
248
|
-
const dataUri = 'data:text/plain;base64,SGVsbG8';
|
|
249
|
-
const result = await api().upload(dataUri);
|
|
250
|
-
expect(result.uri).toBe('inf://files/def');
|
|
251
|
-
const putCall = mockFetch.mock.calls[1];
|
|
252
|
-
expect(putCall[0]).toBe('https://upload.example.com/put');
|
|
253
|
-
expect(putCall[1]?.method).toBe('PUT');
|
|
254
|
-
});
|
|
255
|
-
});
|
|
256
|
-
});
|