@vertesia/client 0.42.2
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/LICENSE +13 -0
- package/lib/cjs/AccountApi.js +66 -0
- package/lib/cjs/AccountApi.js.map +1 -0
- package/lib/cjs/AccountsApi.js +13 -0
- package/lib/cjs/AccountsApi.js.map +1 -0
- package/lib/cjs/AnalyticsApi.js +13 -0
- package/lib/cjs/AnalyticsApi.js.map +1 -0
- package/lib/cjs/ApiKeysApi.js +63 -0
- package/lib/cjs/ApiKeysApi.js.map +1 -0
- package/lib/cjs/CommandsApi.js +19 -0
- package/lib/cjs/CommandsApi.js.map +1 -0
- package/lib/cjs/EnvironmentsApi.js +58 -0
- package/lib/cjs/EnvironmentsApi.js.map +1 -0
- package/lib/cjs/IamApi.js +51 -0
- package/lib/cjs/IamApi.js.map +1 -0
- package/lib/cjs/InteractionBase.js +44 -0
- package/lib/cjs/InteractionBase.js.map +1 -0
- package/lib/cjs/InteractionsApi.js +184 -0
- package/lib/cjs/InteractionsApi.js.map +1 -0
- package/lib/cjs/ProjectsApi.js +48 -0
- package/lib/cjs/ProjectsApi.js.map +1 -0
- package/lib/cjs/PromptsApi.js +133 -0
- package/lib/cjs/PromptsApi.js.map +1 -0
- package/lib/cjs/RefsApi.js +14 -0
- package/lib/cjs/RefsApi.js.map +1 -0
- package/lib/cjs/RunsApi.js +79 -0
- package/lib/cjs/RunsApi.js.map +1 -0
- package/lib/cjs/StreamSource.js +17 -0
- package/lib/cjs/StreamSource.js.map +1 -0
- package/lib/cjs/TrainingApi.js +54 -0
- package/lib/cjs/TrainingApi.js.map +1 -0
- package/lib/cjs/UsersApi.js +13 -0
- package/lib/cjs/UsersApi.js.map +1 -0
- package/lib/cjs/client.js +161 -0
- package/lib/cjs/client.js.map +1 -0
- package/lib/cjs/execute.js +146 -0
- package/lib/cjs/execute.js.map +1 -0
- package/lib/cjs/index.js +22 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/package.json +3 -0
- package/lib/cjs/store/CommandsApi.js +33 -0
- package/lib/cjs/store/CommandsApi.js.map +1 -0
- package/lib/cjs/store/FilesApi.js +122 -0
- package/lib/cjs/store/FilesApi.js.map +1 -0
- package/lib/cjs/store/ObjectsApi.js +185 -0
- package/lib/cjs/store/ObjectsApi.js.map +1 -0
- package/lib/cjs/store/TypesApi.js +52 -0
- package/lib/cjs/store/TypesApi.js.map +1 -0
- package/lib/cjs/store/WorkflowsApi.js +92 -0
- package/lib/cjs/store/WorkflowsApi.js.map +1 -0
- package/lib/cjs/store/client.js +49 -0
- package/lib/cjs/store/client.js.map +1 -0
- package/lib/cjs/store/errors.js +11 -0
- package/lib/cjs/store/errors.js.map +1 -0
- package/lib/cjs/store/index.js +22 -0
- package/lib/cjs/store/index.js.map +1 -0
- package/lib/esm/AccountApi.js +63 -0
- package/lib/esm/AccountApi.js.map +1 -0
- package/lib/esm/AccountsApi.js +10 -0
- package/lib/esm/AccountsApi.js.map +1 -0
- package/lib/esm/AnalyticsApi.js +10 -0
- package/lib/esm/AnalyticsApi.js.map +1 -0
- package/lib/esm/ApiKeysApi.js +59 -0
- package/lib/esm/ApiKeysApi.js.map +1 -0
- package/lib/esm/CommandsApi.js +16 -0
- package/lib/esm/CommandsApi.js.map +1 -0
- package/lib/esm/EnvironmentsApi.js +55 -0
- package/lib/esm/EnvironmentsApi.js.map +1 -0
- package/lib/esm/IamApi.js +45 -0
- package/lib/esm/IamApi.js.map +1 -0
- package/lib/esm/InteractionBase.js +40 -0
- package/lib/esm/InteractionBase.js.map +1 -0
- package/lib/esm/InteractionsApi.js +181 -0
- package/lib/esm/InteractionsApi.js.map +1 -0
- package/lib/esm/ProjectsApi.js +45 -0
- package/lib/esm/ProjectsApi.js.map +1 -0
- package/lib/esm/PromptsApi.js +130 -0
- package/lib/esm/PromptsApi.js.map +1 -0
- package/lib/esm/RefsApi.js +10 -0
- package/lib/esm/RefsApi.js.map +1 -0
- package/lib/esm/RunsApi.js +75 -0
- package/lib/esm/RunsApi.js.map +1 -0
- package/lib/esm/StreamSource.js +13 -0
- package/lib/esm/StreamSource.js.map +1 -0
- package/lib/esm/TrainingApi.js +51 -0
- package/lib/esm/TrainingApi.js.map +1 -0
- package/lib/esm/UsersApi.js +10 -0
- package/lib/esm/UsersApi.js.map +1 -0
- package/lib/esm/client.js +154 -0
- package/lib/esm/client.js.map +1 -0
- package/lib/esm/execute.js +108 -0
- package/lib/esm/execute.js.map +1 -0
- package/lib/esm/index.js +6 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/store/CommandsApi.js +28 -0
- package/lib/esm/store/CommandsApi.js.map +1 -0
- package/lib/esm/store/FilesApi.js +117 -0
- package/lib/esm/store/FilesApi.js.map +1 -0
- package/lib/esm/store/ObjectsApi.js +181 -0
- package/lib/esm/store/ObjectsApi.js.map +1 -0
- package/lib/esm/store/TypesApi.js +48 -0
- package/lib/esm/store/TypesApi.js.map +1 -0
- package/lib/esm/store/WorkflowsApi.js +86 -0
- package/lib/esm/store/WorkflowsApi.js.map +1 -0
- package/lib/esm/store/client.js +45 -0
- package/lib/esm/store/client.js.map +1 -0
- package/lib/esm/store/errors.js +7 -0
- package/lib/esm/store/errors.js.map +1 -0
- package/lib/esm/store/index.js +6 -0
- package/lib/esm/store/index.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/types/AccountApi.d.ts +43 -0
- package/lib/types/AccountApi.d.ts.map +1 -0
- package/lib/types/AccountsApi.d.ts +6 -0
- package/lib/types/AccountsApi.d.ts.map +1 -0
- package/lib/types/AnalyticsApi.d.ts +6 -0
- package/lib/types/AnalyticsApi.d.ts.map +1 -0
- package/lib/types/ApiKeysApi.d.ts +42 -0
- package/lib/types/ApiKeysApi.d.ts.map +1 -0
- package/lib/types/CommandsApi.d.ts +10 -0
- package/lib/types/CommandsApi.d.ts.map +1 -0
- package/lib/types/EnvironmentsApi.d.ts +30 -0
- package/lib/types/EnvironmentsApi.d.ts.map +1 -0
- package/lib/types/IamApi.d.ts +39 -0
- package/lib/types/IamApi.d.ts.map +1 -0
- package/lib/types/InteractionBase.d.ts +22 -0
- package/lib/types/InteractionBase.d.ts.map +1 -0
- package/lib/types/InteractionsApi.d.ts +129 -0
- package/lib/types/InteractionsApi.d.ts.map +1 -0
- package/lib/types/ProjectsApi.d.ts +17 -0
- package/lib/types/ProjectsApi.d.ts.map +1 -0
- package/lib/types/PromptsApi.d.ts +106 -0
- package/lib/types/PromptsApi.d.ts.map +1 -0
- package/lib/types/RefsApi.d.ts +6 -0
- package/lib/types/RefsApi.d.ts.map +1 -0
- package/lib/types/RunsApi.d.ts +62 -0
- package/lib/types/RunsApi.d.ts.map +1 -0
- package/lib/types/StreamSource.d.ts +7 -0
- package/lib/types/StreamSource.d.ts.map +1 -0
- package/lib/types/TrainingApi.d.ts +27 -0
- package/lib/types/TrainingApi.d.ts.map +1 -0
- package/lib/types/UsersApi.d.ts +6 -0
- package/lib/types/UsersApi.d.ts.map +1 -0
- package/lib/types/client.d.ts +85 -0
- package/lib/types/client.d.ts.map +1 -0
- package/lib/types/execute.d.ts +32 -0
- package/lib/types/execute.d.ts.map +1 -0
- package/lib/types/index.d.ts +8 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/store/CommandsApi.d.ts +13 -0
- package/lib/types/store/CommandsApi.d.ts.map +1 -0
- package/lib/types/store/FilesApi.d.ts +41 -0
- package/lib/types/store/FilesApi.d.ts.map +1 -0
- package/lib/types/store/ObjectsApi.d.ts +76 -0
- package/lib/types/store/ObjectsApi.d.ts.map +1 -0
- package/lib/types/store/TypesApi.d.ts +13 -0
- package/lib/types/store/TypesApi.d.ts.map +1 -0
- package/lib/types/store/WorkflowsApi.d.ts +39 -0
- package/lib/types/store/WorkflowsApi.d.ts.map +1 -0
- package/lib/types/store/client.d.ts +23 -0
- package/lib/types/store/client.d.ts.map +1 -0
- package/lib/types/store/errors.d.ts +4 -0
- package/lib/types/store/errors.d.ts.map +1 -0
- package/lib/types/store/index.d.ts +5 -0
- package/lib/types/store/index.d.ts.map +1 -0
- package/package.json +36 -0
- package/src/AccountApi.ts +75 -0
- package/src/AccountsApi.ts +18 -0
- package/src/AnalyticsApi.ts +20 -0
- package/src/ApiKeysApi.ts +67 -0
- package/src/CommandsApi.ts +23 -0
- package/src/EnvironmentsApi.ts +70 -0
- package/src/IamApi.ts +68 -0
- package/src/InteractionBase.ts +44 -0
- package/src/InteractionsApi.ts +210 -0
- package/src/ProjectsApi.ts +58 -0
- package/src/PromptsApi.ts +160 -0
- package/src/RefsApi.ts +18 -0
- package/src/RunsApi.ts +103 -0
- package/src/StreamSource.ts +3 -0
- package/src/TrainingApi.ts +71 -0
- package/src/UsersApi.ts +18 -0
- package/src/client.ts +191 -0
- package/src/execute.ts +114 -0
- package/src/index.ts +8 -0
- package/src/store/CommandsApi.ts +42 -0
- package/src/store/FilesApi.ts +139 -0
- package/src/store/ObjectsApi.ts +245 -0
- package/src/store/TypesApi.ts +61 -0
- package/src/store/WorkflowsApi.ts +121 -0
- package/src/store/client.ts +61 -0
- package/src/store/errors.ts +7 -0
- package/src/store/index.ts +6 -0
package/src/execute.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { ExecutionRun, ExecutionRunStatus, InteractionExecutionPayload, NamedInteractionExecutionPayload } from '@vertesia/common';
|
|
2
|
+
import { ComposableClient } from './client.js';
|
|
3
|
+
|
|
4
|
+
export function EventSourceProvider(): Promise<typeof EventSource> {
|
|
5
|
+
if (typeof globalThis.EventSource === 'function') {
|
|
6
|
+
return Promise.resolve(globalThis.EventSource)
|
|
7
|
+
} else {
|
|
8
|
+
return import('eventsource').then(module => module.default as unknown as typeof EventSource);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* Execute an interaction and return a promise which will be resolved with the executed run when
|
|
14
|
+
* the run completes or fails.
|
|
15
|
+
* If the onChunk callback is passed then the streaming of the result is enabled.
|
|
16
|
+
* The onChunk callback with be called with the next chunk of the result as soon as it is available.
|
|
17
|
+
* When all chunks are received the fucntion will return the resolved promise
|
|
18
|
+
* @param id of the interaction to execute
|
|
19
|
+
* @param payload InteractionExecutionPayload
|
|
20
|
+
* @param onChunk callback to be called when the next chunk of the response is available
|
|
21
|
+
*/
|
|
22
|
+
export async function executeInteraction<P = any, R = any>(client: ComposableClient,
|
|
23
|
+
interactionId: string,
|
|
24
|
+
payload: InteractionExecutionPayload = {},
|
|
25
|
+
onChunk?: (chunk: string) => void): Promise<ExecutionRun<P, R>> {
|
|
26
|
+
const stream = !!onChunk;
|
|
27
|
+
const response = await client.runs.create({
|
|
28
|
+
...payload, interaction: interactionId, stream
|
|
29
|
+
});
|
|
30
|
+
if (stream) {
|
|
31
|
+
if (response.status === ExecutionRunStatus.failed) {
|
|
32
|
+
return response;
|
|
33
|
+
}
|
|
34
|
+
await handleStreaming(client, response.id, onChunk);
|
|
35
|
+
}
|
|
36
|
+
return response;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Same as executeInteraction but uses the interaction name selector instead of the id.
|
|
41
|
+
* A name selector is the interaction endpoint name suffuxed with an optional tag or version wich is starting with a `@` character.
|
|
42
|
+
* The special `draft` tag is used to select the draft version of the interaction. If no tag or version is specified then the latest version is selected.
|
|
43
|
+
* Examples of selectors:
|
|
44
|
+
* - `ReviewContract` - select the latest version of the ReviewContract interaction
|
|
45
|
+
* - `ReviewContract@1` - select the version 1 of the ReviewContract interaction
|
|
46
|
+
* - `ReviewContract@draft` - select the draft version of the ReviewContract interaction
|
|
47
|
+
* - `ReviewContract@fixed` - select the ReviewContract interaction which is tagged with 'fixed' tag.
|
|
48
|
+
*
|
|
49
|
+
* @param client
|
|
50
|
+
* @param interaction
|
|
51
|
+
* @param payload
|
|
52
|
+
* @param onChunk
|
|
53
|
+
* @returns
|
|
54
|
+
*/
|
|
55
|
+
export async function executeInteractionByName<P = any, R = any>(client: ComposableClient,
|
|
56
|
+
interaction: string,
|
|
57
|
+
payload: InteractionExecutionPayload = {},
|
|
58
|
+
onChunk?: (chunk: string) => void): Promise<ExecutionRun<P, R>> {
|
|
59
|
+
const stream = !!onChunk;
|
|
60
|
+
const response = await client.post('/api/v1/execute', {
|
|
61
|
+
payload: {
|
|
62
|
+
...payload,
|
|
63
|
+
interaction,
|
|
64
|
+
stream
|
|
65
|
+
} as NamedInteractionExecutionPayload,
|
|
66
|
+
});
|
|
67
|
+
if (stream) {
|
|
68
|
+
if (response.status === ExecutionRunStatus.failed) {
|
|
69
|
+
return response;
|
|
70
|
+
}
|
|
71
|
+
await handleStreaming(client, response.id, onChunk);
|
|
72
|
+
}
|
|
73
|
+
return response;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function handleStreaming(client: ComposableClient, runId: string, onChunk: (chunk: string) => void) {
|
|
77
|
+
return new Promise(async (resolve, reject) => {
|
|
78
|
+
try {
|
|
79
|
+
const EventSourceImpl = await EventSourceProvider();
|
|
80
|
+
const streamUrl = new URL(client.runs.baseUrl + '/' + runId + '/stream');
|
|
81
|
+
const bearerToken = client._auth ? await client._auth() : undefined;
|
|
82
|
+
|
|
83
|
+
if (bearerToken) {
|
|
84
|
+
const token = bearerToken.split(' ')[1];
|
|
85
|
+
streamUrl.searchParams.set('access_token', token);
|
|
86
|
+
} else {
|
|
87
|
+
throw new Error('No auth token available');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const sse = new EventSourceImpl(streamUrl.href);
|
|
91
|
+
sse.addEventListener("message", ev => {
|
|
92
|
+
try {
|
|
93
|
+
const data = JSON.parse(ev.data);
|
|
94
|
+
if (data) {
|
|
95
|
+
onChunk && onChunk(data);
|
|
96
|
+
}
|
|
97
|
+
} catch (err) {
|
|
98
|
+
reject(err);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
sse.addEventListener("close", (ev) => {
|
|
102
|
+
try {
|
|
103
|
+
sse.close();
|
|
104
|
+
const msg = JSON.parse(ev.data)
|
|
105
|
+
resolve(msg);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
reject(err);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
} catch (err) {
|
|
111
|
+
reject(err);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './InteractionBase.js';
|
|
2
|
+
export type { ComputePromptFacetsResponse, ListInteractionsResponse } from './PromptsApi.js';
|
|
3
|
+
export type { ComputeInteractionFacetsResponse } from './InteractionsApi.js';
|
|
4
|
+
export type { ComputeRunFacetsResponse, FilterOption } from './RunsApi.js';
|
|
5
|
+
export * from './client.js';
|
|
6
|
+
export * from './InteractionBase.js';
|
|
7
|
+
export * from "./store/index.js";
|
|
8
|
+
export * from "./StreamSource.js";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ApiTopic, ClientBase } from "@vertesia/api-fetch-client";
|
|
2
|
+
import { EmbeddingsStatusResponse, GenericCommandResponse, ProjectConfigurationEmbeddings, SupportedEmbeddingTypes } from "@vertesia/common";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export class CommandsApi extends ApiTopic {
|
|
6
|
+
|
|
7
|
+
constructor(parent: ClientBase) {
|
|
8
|
+
super(parent, "/api/v1/commands");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
embeddings = new EmbeddingsApi(this);
|
|
12
|
+
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class EmbeddingsApi extends ApiTopic {
|
|
16
|
+
|
|
17
|
+
constructor(parent: ClientBase) {
|
|
18
|
+
super(parent, "/embeddings");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async status(type: SupportedEmbeddingTypes): Promise<EmbeddingsStatusResponse> {
|
|
22
|
+
return this.get(type + "/status");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async activate(type: SupportedEmbeddingTypes, config: Partial<ProjectConfigurationEmbeddings>): Promise<GenericCommandResponse> {
|
|
26
|
+
|
|
27
|
+
if (!config.environment) {
|
|
28
|
+
throw new Error("Invalid configuration: select environment");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return this.post(type + "/enable", { payload: config });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async disable(type: SupportedEmbeddingTypes): Promise<GenericCommandResponse> {
|
|
35
|
+
return this.post(type + "/disable");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async recalculate(type: SupportedEmbeddingTypes): Promise<GenericCommandResponse> {
|
|
39
|
+
return this.post(type + "/recalculate");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { ApiTopic, ClientBase } from "@vertesia/api-fetch-client";
|
|
2
|
+
import { GetFileUrlPayload, GetFileUrlResponse, GetUploadUrlPayload } from "@vertesia/common";
|
|
3
|
+
import { StreamSource } from "../StreamSource.js";
|
|
4
|
+
|
|
5
|
+
export const MEMORIES_PREFIX = 'memories';
|
|
6
|
+
|
|
7
|
+
export function getMemoryFilePath(name: string) {
|
|
8
|
+
const nameWithExt = name.endsWith(".tar.gz") ? name : name + ".tar.gz";
|
|
9
|
+
return `${MEMORIES_PREFIX}/${nameWithExt}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
export class FilesApi extends ApiTopic {
|
|
14
|
+
|
|
15
|
+
constructor(parent: ClientBase) {
|
|
16
|
+
super(parent, "/api/v1/files");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* get the metadata of a blob given its URI. Supported URI are:
|
|
21
|
+
* starting with s3:// and gs://.
|
|
22
|
+
* For s3 blobs use #region to specify the region. Ex: s3://bucket/key#us-west-2
|
|
23
|
+
* @param uri
|
|
24
|
+
* @returns
|
|
25
|
+
*/
|
|
26
|
+
getMetadata(uri: string): Promise<{
|
|
27
|
+
name: string,
|
|
28
|
+
size: number,
|
|
29
|
+
contentType: string,
|
|
30
|
+
contentDisposition?:
|
|
31
|
+
string,
|
|
32
|
+
etag?: string
|
|
33
|
+
}> {
|
|
34
|
+
return this.get("/metadata", {
|
|
35
|
+
query: {
|
|
36
|
+
file: uri
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get or create a bucket for the project. If the bucket already exists, it does nothing.
|
|
43
|
+
* The bucket URI is returned.
|
|
44
|
+
* @returns
|
|
45
|
+
*/
|
|
46
|
+
getOrCreateBucket(): Promise<{ bucket: string }> {
|
|
47
|
+
return this.post('/bucket');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
getUploadUrl(payload: GetUploadUrlPayload): Promise<GetFileUrlResponse> {
|
|
51
|
+
return this.post('/upload-url', {
|
|
52
|
+
payload
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
getDownloadUrl(file: string): Promise<GetFileUrlResponse> {
|
|
57
|
+
return this.post('/download-url', {
|
|
58
|
+
payload: {
|
|
59
|
+
file
|
|
60
|
+
} satisfies GetFileUrlPayload
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Upload content to a file and return the full path (including bucket name) of the uploaded file
|
|
66
|
+
* @param source
|
|
67
|
+
* @returns
|
|
68
|
+
*/
|
|
69
|
+
async uploadFile(source: StreamSource | File): Promise<string> {
|
|
70
|
+
const isStream = source instanceof StreamSource;
|
|
71
|
+
const { url, path } = await this.getUploadUrl(source);
|
|
72
|
+
|
|
73
|
+
await fetch(url, {
|
|
74
|
+
method: 'PUT',
|
|
75
|
+
body: isStream ? source.stream : source,
|
|
76
|
+
//@ts-ignore: duplex is not in the types. See https://github.com/node-fetch/node-fetch/issues/1769
|
|
77
|
+
duplex: isStream ? "half" : undefined,
|
|
78
|
+
headers: {
|
|
79
|
+
'Content-Type': source.type || 'application/gzip'
|
|
80
|
+
}
|
|
81
|
+
}).then((res: Response) => {
|
|
82
|
+
if (res.ok) {
|
|
83
|
+
return res;
|
|
84
|
+
} else {
|
|
85
|
+
console.log(res);
|
|
86
|
+
throw new Error(`Failed to upload file: ${res.statusText}`);
|
|
87
|
+
}
|
|
88
|
+
}).catch(err => {
|
|
89
|
+
console.error('Failed to upload file', err);
|
|
90
|
+
throw err;
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return path;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async downloadFile(name: string): Promise<ReadableStream<Uint8Array>> {
|
|
97
|
+
const { url } = await this.getDownloadUrl(name);
|
|
98
|
+
|
|
99
|
+
const res = await fetch(url, {
|
|
100
|
+
method: 'GET',
|
|
101
|
+
}).then((res: Response) => {
|
|
102
|
+
if (res.ok) {
|
|
103
|
+
return res;
|
|
104
|
+
} else {
|
|
105
|
+
console.log(res);
|
|
106
|
+
throw new Error(`Failed to download file ${name}: ${res.statusText}`);
|
|
107
|
+
}
|
|
108
|
+
}).catch(err => {
|
|
109
|
+
console.error(`Failed to download file ${name}.`, err);
|
|
110
|
+
throw err;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (!res.body) {
|
|
114
|
+
throw new Error(`No body in response while downloading memory pack ${name}`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return res.body;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async uploadMemoryPack(source: StreamSource | File): Promise<string> {
|
|
121
|
+
const fileId = getMemoryFilePath(source.name);
|
|
122
|
+
const nameWithExt = source.name.endsWith(".tar.gz") ? source.name : source.name + ".tar.gz";
|
|
123
|
+
if (source instanceof File) {
|
|
124
|
+
let file = source as File;
|
|
125
|
+
return this.uploadFile(new StreamSource(file.stream(), nameWithExt, file.type, fileId));
|
|
126
|
+
} else {
|
|
127
|
+
return this.uploadFile(new StreamSource(source.stream, nameWithExt, source.type, fileId));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async downloadMemoryPack(name: string, gunzip: boolean = false): Promise<ReadableStream<Uint8Array>> {
|
|
132
|
+
let stream = await this.downloadFile(getMemoryFilePath(name));
|
|
133
|
+
if (gunzip) {
|
|
134
|
+
const ds = new DecompressionStream("gzip");
|
|
135
|
+
stream = stream.pipeThrough(ds);
|
|
136
|
+
}
|
|
137
|
+
return stream;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { ApiTopic, ClientBase } from '@vertesia/api-fetch-client';
|
|
2
|
+
import { ComplexSearchPayload, ComputeObjectFacetPayload, ContentObject, ContentObjectItem, ContentSource, CreateContentObjectPayload, Embedding, ExportPropertiesPayload, ExportPropertiesResponse, FindPayload, GetFileUrlPayload, GetFileUrlResponse, GetRenditionResponse, GetUploadUrlPayload, ListWorkflowRunsResponse, ObjectSearchPayload, ObjectSearchQuery, SupportedEmbeddingTypes } from '@vertesia/common';
|
|
3
|
+
|
|
4
|
+
import { StreamSource } from '../StreamSource.js';
|
|
5
|
+
import { ZenoClient } from './client.js';
|
|
6
|
+
|
|
7
|
+
export interface UploadContentObjectPayload extends Omit<CreateContentObjectPayload, 'content'> {
|
|
8
|
+
content?: StreamSource | File | {
|
|
9
|
+
|
|
10
|
+
// the source URI
|
|
11
|
+
source: string,
|
|
12
|
+
// the original name of the input file if any
|
|
13
|
+
name?: string,
|
|
14
|
+
// the mime type of the content source.
|
|
15
|
+
type?: string
|
|
16
|
+
|
|
17
|
+
// the target id in the content store
|
|
18
|
+
id?: string
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ComputeFacetsResponse {
|
|
24
|
+
type?: { _id: string, count: number }[];
|
|
25
|
+
location?: { _id: string, count: number }[];
|
|
26
|
+
status?: { _id: string, count: number }[];
|
|
27
|
+
total?: { count: number }[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class ObjectsApi extends ApiTopic {
|
|
31
|
+
|
|
32
|
+
constructor(parent: ClientBase) {
|
|
33
|
+
super(parent, "/api/v1/objects");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getUploadUrl(payload: GetUploadUrlPayload): Promise<GetFileUrlResponse> {
|
|
37
|
+
return this.post('/upload-url', {
|
|
38
|
+
payload
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getDownloadUrl(fileUri: string): Promise<{ url: string }> {
|
|
43
|
+
return this.post('/download-url', {
|
|
44
|
+
payload: {
|
|
45
|
+
file: fileUri
|
|
46
|
+
} satisfies GetFileUrlPayload
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
getContentSource(objectId: string): Promise<ContentSource> {
|
|
51
|
+
return this.get(`/${objectId}/content-source`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
list(payload: ObjectSearchPayload = {}): Promise<ContentObjectItem[]> {
|
|
55
|
+
const limit = payload.limit || 100;
|
|
56
|
+
const offset = payload.offset || 0;
|
|
57
|
+
const query = payload.query || {} as ObjectSearchQuery;
|
|
58
|
+
|
|
59
|
+
return this.get("/", {
|
|
60
|
+
query: {
|
|
61
|
+
limit,
|
|
62
|
+
offset,
|
|
63
|
+
...query
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
computeFacets(query: ComputeObjectFacetPayload): Promise<ComputeFacetsResponse> {
|
|
69
|
+
return this.post("/facets", {
|
|
70
|
+
payload: query
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
listFolders(path: string = '/') {
|
|
75
|
+
path;//TODO
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
find(payload: FindPayload): Promise<ContentObject[]> {
|
|
79
|
+
return this.post("/find", {
|
|
80
|
+
payload
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
search(payload: ComplexSearchPayload): Promise<ContentObjectItem[]> {
|
|
85
|
+
return this.post("/search", {
|
|
86
|
+
payload
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
retrieve(id: string, select?: string): Promise<ContentObject> {
|
|
91
|
+
return this.get(`/${id}`, {
|
|
92
|
+
query: {
|
|
93
|
+
select
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
getObjectText(id: string): Promise<{ text: string }> {
|
|
99
|
+
return this.get(`/${id}/text`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async upload(source: StreamSource | File) {
|
|
103
|
+
const isStream = source instanceof StreamSource;
|
|
104
|
+
// get a signed URL to upload the file a computed mimeType and the file object id.
|
|
105
|
+
const { url, id, mime_type } = await this.getUploadUrl({
|
|
106
|
+
id: isStream ? source.id : undefined,
|
|
107
|
+
name: source.name,
|
|
108
|
+
mime_type: source.type
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
console.log(`Uploading file to ${url}`, { id, mime_type, isStream, source })
|
|
112
|
+
|
|
113
|
+
// upload the file content to the signed URL
|
|
114
|
+
/*const res = await this.fetch(url, {
|
|
115
|
+
method: 'PUT',
|
|
116
|
+
//@ts-ignore: duplex is not in the types. See https://github.com/node-fetch/node-fetch/issues/1769
|
|
117
|
+
duplex: isStream ? "half" : undefined,
|
|
118
|
+
body: isStream ? source.stream : source,
|
|
119
|
+
headers: {
|
|
120
|
+
'Content-Type': mime_type || 'application/octet-stream'
|
|
121
|
+
}
|
|
122
|
+
}).then((res: Response) => {
|
|
123
|
+
if (res.ok) {
|
|
124
|
+
return res;
|
|
125
|
+
} else {
|
|
126
|
+
console.log(res);
|
|
127
|
+
throw new Error(`Failed to upload file: ${res.statusText}`);
|
|
128
|
+
}
|
|
129
|
+
});*/
|
|
130
|
+
|
|
131
|
+
const res = await fetch(url, {
|
|
132
|
+
method: 'PUT',
|
|
133
|
+
body: isStream ? source.stream : source,
|
|
134
|
+
//@ts-ignore: duplex is not in the types. See https://github.com/node-fetch/node-fetch/issues/1769
|
|
135
|
+
duplex: isStream ? "half" : undefined,
|
|
136
|
+
headers: {
|
|
137
|
+
'Content-Type': mime_type || 'application/octet-stream'
|
|
138
|
+
}
|
|
139
|
+
}).then((res: Response) => {
|
|
140
|
+
if (res.ok) {
|
|
141
|
+
return res;
|
|
142
|
+
} else {
|
|
143
|
+
console.log(res);
|
|
144
|
+
throw new Error(`Failed to upload file: ${res.statusText}`);
|
|
145
|
+
}
|
|
146
|
+
}).catch(err => {
|
|
147
|
+
console.error('Failed to upload file', err);
|
|
148
|
+
throw err;
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
source: id,
|
|
154
|
+
name: source.name,
|
|
155
|
+
type: mime_type,
|
|
156
|
+
etag: res.headers.get('etag') ?? undefined
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async create(payload: UploadContentObjectPayload): Promise<ContentObject> {
|
|
161
|
+
|
|
162
|
+
const createPayload: CreateContentObjectPayload = {
|
|
163
|
+
...payload
|
|
164
|
+
};
|
|
165
|
+
if (payload.content instanceof StreamSource || payload.content instanceof File) {
|
|
166
|
+
createPayload.content = await this.upload(payload.content);
|
|
167
|
+
}
|
|
168
|
+
return await this.post('/', {
|
|
169
|
+
payload: createPayload
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Create an object which holds a reference to an external blob (i.e. not in the project bucket)
|
|
175
|
+
* The uri should starts either with gs:// or s3://. Not other protocols are supported yet.
|
|
176
|
+
* For the s3 blobs you must use a hash with the blob #region. Ex: s3://bucket/path/to/file#us-east-1
|
|
177
|
+
* @param uri
|
|
178
|
+
* @param payload
|
|
179
|
+
* @returns
|
|
180
|
+
*/
|
|
181
|
+
async createFromExternalSource(uri: string, payload: CreateContentObjectPayload = {}): Promise<ContentObject> {
|
|
182
|
+
const metadata = await ((this.client as ZenoClient).files.getMetadata(uri));
|
|
183
|
+
const createPayload: CreateContentObjectPayload = {
|
|
184
|
+
...payload,
|
|
185
|
+
content: {
|
|
186
|
+
source: uri,
|
|
187
|
+
name: metadata.name,
|
|
188
|
+
type: metadata.contentType,
|
|
189
|
+
etag: metadata.etag
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
return await this.post('/', {
|
|
193
|
+
payload: createPayload
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
update(id: string, payload: Partial<CreateContentObjectPayload>): Promise<ContentObject> {
|
|
198
|
+
return this.put(`/${id}`, {
|
|
199
|
+
payload
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
delete(id: string): Promise<{ id: string }> {
|
|
204
|
+
return this.del(`/${id}`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
listWorkflowRuns(documentId: string): Promise<ListWorkflowRunsResponse> {
|
|
208
|
+
|
|
209
|
+
return this.get(`/${documentId}/workflow-runs`)
|
|
210
|
+
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
listRenditions(documentId: string): Promise<ContentObjectItem[]> {
|
|
214
|
+
return this.get(`/${documentId}/renditions`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
getRendition(documentId: string, options: GetRenditionParams): Promise<GetRenditionResponse> {
|
|
218
|
+
|
|
219
|
+
const query = {
|
|
220
|
+
max_hw: options.max_hw,
|
|
221
|
+
generate_if_missing: options.generate_if_missing
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return this.get(`/${documentId}/renditions/${options.format}`, { query });
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
exportProperties(payload: ExportPropertiesPayload): Promise<ExportPropertiesResponse> {
|
|
228
|
+
return this.post("/export", {
|
|
229
|
+
payload
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
setEmbedding(id: string, type: SupportedEmbeddingTypes, payload: Embedding): Promise<Record<SupportedEmbeddingTypes, Embedding>> {
|
|
234
|
+
return this.put(`/${id}/embeddings/${type}`, {
|
|
235
|
+
payload
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
interface GetRenditionParams {
|
|
242
|
+
format: string;
|
|
243
|
+
max_hw?: number;
|
|
244
|
+
generate_if_missing?: boolean;
|
|
245
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ContentObjectType, ContentObjectTypeItem, ContentObjectTypeLayout, CreateContentObjectTypePayload, FindPayload, ObjectTypeSearchQuery, ObjectTypeSearchPayload } from "@vertesia/common";
|
|
2
|
+
import { ApiTopic, ClientBase } from "@vertesia/api-fetch-client";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export class TypesApi extends ApiTopic {
|
|
6
|
+
|
|
7
|
+
constructor(parent: ClientBase) {
|
|
8
|
+
super(parent, "/api/v1/types");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
list(payload: ObjectTypeSearchPayload = {}): Promise<ContentObjectTypeItem[]> {
|
|
12
|
+
const limit = payload.limit || 100;
|
|
13
|
+
const offset = payload.offset || 0;
|
|
14
|
+
const query = payload.query || {} as ObjectTypeSearchQuery;
|
|
15
|
+
|
|
16
|
+
return this.get("/", {
|
|
17
|
+
query: {
|
|
18
|
+
limit,
|
|
19
|
+
offset,
|
|
20
|
+
...query
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
find(payload: FindPayload): Promise<ContentObjectType[]> {
|
|
26
|
+
return this.post("/find", {
|
|
27
|
+
payload
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
layouts(): Promise<ContentObjectTypeLayout[]> {
|
|
32
|
+
return this.get('/', {
|
|
33
|
+
query: { layout: true }
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
retrieve(typeId: string): Promise<ContentObjectType> {
|
|
38
|
+
return this.get(`/${typeId}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getTypeByName(typeName: string): Promise<ContentObjectType> {
|
|
42
|
+
return this.get(`/name/${typeName}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
update(typeId: string, payload: Partial<CreateContentObjectTypePayload>): Promise<ContentObjectType> {
|
|
46
|
+
return this.put(`/${typeId}`, {
|
|
47
|
+
payload
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
create(payload: CreateContentObjectTypePayload): Promise<ContentObjectType> {
|
|
52
|
+
return this.post(`/`, {
|
|
53
|
+
payload
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
delete(id: string) {
|
|
58
|
+
return this.del(`/${id}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
}
|