@vertesia/client 1.6.0-dev.20261014.015055Z → 1.6.0-dev.20261022.120426Z
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/lib/ApiKeysApi.d.ts +4 -7
- package/lib/ApiKeysApi.d.ts.map +1 -1
- package/lib/ApiKeysApi.js +5 -4
- package/lib/ApiKeysApi.js.map +1 -1
- package/lib/AppsApi.d.ts +35 -2
- package/lib/AppsApi.d.ts.map +1 -1
- package/lib/AppsApi.js +76 -1
- package/lib/AppsApi.js.map +1 -1
- package/lib/InteractionsApi.d.ts +3 -1
- package/lib/InteractionsApi.d.ts.map +1 -1
- package/lib/InteractionsApi.js +2 -1
- package/lib/InteractionsApi.js.map +1 -1
- package/lib/OAuthServerApi.d.ts +7 -1
- package/lib/OAuthServerApi.d.ts.map +1 -1
- package/lib/OAuthServerApi.js +21 -0
- package/lib/OAuthServerApi.js.map +1 -1
- package/lib/OidcFederationApi.d.ts +11 -0
- package/lib/OidcFederationApi.d.ts.map +1 -0
- package/lib/OidcFederationApi.js +22 -0
- package/lib/OidcFederationApi.js.map +1 -0
- package/lib/RunsApi.d.ts +3 -2
- package/lib/RunsApi.d.ts.map +1 -1
- package/lib/RunsApi.js +3 -2
- package/lib/RunsApi.js.map +1 -1
- package/lib/client.d.ts +2 -0
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +3 -0
- package/lib/client.js.map +1 -1
- package/lib/execute.d.ts +16 -2
- package/lib/execute.d.ts.map +1 -1
- package/lib/execute.js +13 -2
- package/lib/execute.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/nodejs/NodeStreamSource.d.ts +1 -0
- package/lib/nodejs/NodeStreamSource.d.ts.map +1 -1
- package/lib/nodejs/NodeStreamSource.js +17 -15
- package/lib/nodejs/NodeStreamSource.js.map +1 -1
- package/lib/store/AgentsApi.d.ts +3 -0
- package/lib/store/AgentsApi.d.ts.map +1 -1
- package/lib/store/AgentsApi.js +7 -1
- package/lib/store/AgentsApi.js.map +1 -1
- package/lib/store/FilesApi.d.ts.map +1 -1
- package/lib/store/FilesApi.js +8 -2
- package/lib/store/FilesApi.js.map +1 -1
- package/lib/store/IndexingApi.d.ts +0 -6
- package/lib/store/IndexingApi.d.ts.map +1 -1
- package/lib/store/IndexingApi.js +3 -17
- package/lib/store/IndexingApi.js.map +1 -1
- package/lib/store/ObjectsApi.d.ts +0 -6
- package/lib/store/ObjectsApi.d.ts.map +1 -1
- package/lib/store/ObjectsApi.js +2 -16
- package/lib/store/ObjectsApi.js.map +1 -1
- package/lib/store/ProcessApi.d.ts +4 -0
- package/lib/store/ProcessApi.d.ts.map +1 -1
- package/lib/store/ProcessApi.js +8 -1
- package/lib/store/ProcessApi.js.map +1 -1
- package/lib/store/zeno-bulk.d.ts +9 -0
- package/lib/store/zeno-bulk.d.ts.map +1 -0
- package/lib/store/zeno-bulk.js +26 -0
- package/lib/store/zeno-bulk.js.map +1 -0
- package/lib/vertesia-client.js +4 -4
- package/lib/vertesia-client.js.map +1 -1
- package/package.json +13 -8
- package/src/ApiKeysApi.ts +4 -12
- package/src/AppsApi.ts +106 -0
- package/src/InteractionsApi.ts +9 -2
- package/src/OAuthServerApi.ts +31 -0
- package/src/OidcFederationApi.ts +23 -0
- package/src/RunsApi.ts +7 -2
- package/src/client.ts +3 -0
- package/src/execute.ts +30 -3
- package/src/index.ts +2 -0
- package/src/nodejs/NodeStreamSource.ts +28 -24
- package/src/store/AgentsApi.ts +10 -1
- package/src/store/FilesApi.ts +8 -2
- package/src/store/IndexingApi.ts +3 -18
- package/src/store/ObjectsApi.ts +2 -17
- package/src/store/ProcessApi.ts +8 -1
- package/src/store/zeno-bulk.ts +30 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertesia/client",
|
|
3
|
-
"version": "1.6.0-dev.
|
|
3
|
+
"version": "1.6.0-dev.20261022.120426Z",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -12,16 +12,16 @@
|
|
|
12
12
|
],
|
|
13
13
|
"license": "Apache-2.0",
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@types/node": "^24.19.
|
|
15
|
+
"@types/node": "^24.19.2",
|
|
16
16
|
"@vertesia/tsconfig": "0.1.0",
|
|
17
|
-
"rolldown": "1.2.
|
|
17
|
+
"rolldown": "1.2.14",
|
|
18
18
|
"typescript": "7.0.2",
|
|
19
|
-
"vitest": "5.0.
|
|
19
|
+
"vitest": "5.0.4"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@llumiverse/common": "1.6.0-dev.
|
|
23
|
-
"@vertesia/api-fetch-client": "1.6.0-dev.
|
|
24
|
-
"@vertesia/common": "1.6.0-dev.
|
|
22
|
+
"@llumiverse/common": "1.6.0-dev.20261022.120426Z",
|
|
23
|
+
"@vertesia/api-fetch-client": "1.6.0-dev.20261022.120426Z",
|
|
24
|
+
"@vertesia/common": "1.6.0-dev.20261022.120426Z",
|
|
25
25
|
"eventsource": "^5.1.2"
|
|
26
26
|
},
|
|
27
27
|
"exports": {
|
|
@@ -49,7 +49,12 @@
|
|
|
49
49
|
"ai",
|
|
50
50
|
"typescript"
|
|
51
51
|
],
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "bcaa7879b601ce9ccc394bcd3257822da13869cd",
|
|
53
|
+
"releaseIdentity": {
|
|
54
|
+
"source_sha": "bcaa7879b601ce9ccc394bcd3257822da13869cd",
|
|
55
|
+
"dependency_sha": "93466e47b06db23ac3c800e248d170afe65e5006",
|
|
56
|
+
"lock_sha256": "117e1c8068aa07d59117323a51ceccfc96cab543e50c03eb7efc19709d6f5e6b"
|
|
57
|
+
},
|
|
53
58
|
"scripts": {
|
|
54
59
|
"lint": "biome lint src",
|
|
55
60
|
"clean:lib": "rimraf ./lib ./tsconfig.tsbuildinfo",
|
package/src/ApiKeysApi.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ApiTopic, type ClientBase } from '@vertesia/api-fetch-client';
|
|
2
2
|
import type {
|
|
3
3
|
ApiKey,
|
|
4
|
-
ApiKeyReadResponse,
|
|
5
4
|
ApiKeyWithValue,
|
|
6
5
|
AuthTokenResponse,
|
|
7
6
|
CreateApiKeyPayload,
|
|
@@ -42,17 +41,10 @@ export class ApiKeysApi extends ApiTopic {
|
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
/**
|
|
45
|
-
* Retrieve an ApiKey
|
|
46
|
-
*
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* */
|
|
50
|
-
retrieve(id: string, withValue: true): Promise<ApiKeyWithValue>;
|
|
51
|
-
retrieve(id: string, withValue?: false): Promise<ApiKey>;
|
|
52
|
-
retrieve(id: string, withValue: boolean = false): Promise<ApiKeyReadResponse> {
|
|
53
|
-
if (withValue) {
|
|
54
|
-
return this.get(`/${id}`, { query: { withValue: true } });
|
|
55
|
-
}
|
|
44
|
+
* Retrieve an ApiKey without its value. The raw value is returned only once, by `create`.
|
|
45
|
+
* @returns ApiKey
|
|
46
|
+
*/
|
|
47
|
+
retrieve(id: string): Promise<ApiKey> {
|
|
56
48
|
return this.get(`/${id}`);
|
|
57
49
|
}
|
|
58
50
|
|
package/src/AppsApi.ts
CHANGED
|
@@ -6,12 +6,16 @@ import type {
|
|
|
6
6
|
AppDeleteSummary,
|
|
7
7
|
AppDevelopmentTaskDetails,
|
|
8
8
|
AppDevelopmentTaskList,
|
|
9
|
+
AppGithubConfiguration,
|
|
10
|
+
AppGithubRepositoryList,
|
|
11
|
+
AppGithubRepositorySetup,
|
|
9
12
|
AppInspectionResult,
|
|
10
13
|
AppInstallation,
|
|
11
14
|
AppInstallationKind,
|
|
12
15
|
AppInstallationListEntry,
|
|
13
16
|
AppInstallationPayload,
|
|
14
17
|
AppInstallationWithManifest,
|
|
18
|
+
AppInstanceAvailability,
|
|
15
19
|
AppManifest,
|
|
16
20
|
AppManifestData,
|
|
17
21
|
AppPackage,
|
|
@@ -29,6 +33,7 @@ import type {
|
|
|
29
33
|
CountResult,
|
|
30
34
|
CreateAppRepoBranchRequest,
|
|
31
35
|
DeleteAppVersionResponse,
|
|
36
|
+
ExchangeAppGithubAuthorizationResponse,
|
|
32
37
|
McpApiKeyStatus,
|
|
33
38
|
ProjectRef,
|
|
34
39
|
PromoteAppVersionResponse,
|
|
@@ -37,6 +42,7 @@ import type {
|
|
|
37
42
|
StartAppBuildRequest,
|
|
38
43
|
StartAppBuildResponse,
|
|
39
44
|
StartAppDevelopmentTaskRequest,
|
|
45
|
+
StartAppGithubAuthorizationResponse,
|
|
40
46
|
StartAppScaffoldRequest,
|
|
41
47
|
StartAppScaffoldResponse,
|
|
42
48
|
UpdateAppInstallationOAuthApprovalPayload,
|
|
@@ -75,6 +81,27 @@ export default class AppsApi extends ApiTopic {
|
|
|
75
81
|
* The key is write-only: it is encrypted server-side and never returned by any endpoint,
|
|
76
82
|
* so the response carries only the configured flag and a masked hint.
|
|
77
83
|
*/
|
|
84
|
+
setInstallationMcpApiKey(installationId: string, collectionId: string, apiKey: string): Promise<McpApiKeyStatus> {
|
|
85
|
+
return this.put(
|
|
86
|
+
`/installations/${encodeURIComponent(installationId)}/collections/${encodeURIComponent(collectionId)}/api-key`,
|
|
87
|
+
{
|
|
88
|
+
payload: { api_key: apiKey },
|
|
89
|
+
},
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
getInstallationMcpApiKeyStatus(installationId: string, collectionId: string): Promise<McpApiKeyStatus> {
|
|
94
|
+
return this.get(
|
|
95
|
+
`/installations/${encodeURIComponent(installationId)}/collections/${encodeURIComponent(collectionId)}/api-key`,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
deleteInstallationMcpApiKey(installationId: string, collectionId: string): Promise<McpApiKeyStatus> {
|
|
100
|
+
return this.del(
|
|
101
|
+
`/installations/${encodeURIComponent(installationId)}/collections/${encodeURIComponent(collectionId)}/api-key`,
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
78
105
|
setMcpCollectionApiKey(appId: string, collectionId: string, apiKey: string): Promise<McpApiKeyStatus> {
|
|
79
106
|
return this.put(`/${encodeURIComponent(appId)}/collections/${encodeURIComponent(collectionId)}/api-key`, {
|
|
80
107
|
payload: { api_key: apiKey } satisfies SetMcpApiKeyRequest,
|
|
@@ -149,6 +176,63 @@ export default class AppsApi extends ApiTopic {
|
|
|
149
176
|
return this.get(`/scaffolds/${encodeURIComponent(workflowId)}/${encodeURIComponent(runId)}/progress`);
|
|
150
177
|
}
|
|
151
178
|
|
|
179
|
+
/**
|
|
180
|
+
* Return whether the global App Builder GitHub App is configured, together with its slug and
|
|
181
|
+
* installation URL when available.
|
|
182
|
+
*/
|
|
183
|
+
getGithubConfiguration(): Promise<AppGithubConfiguration> {
|
|
184
|
+
return this.get('/source-providers/github');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Start GitHub user authorization. The server creates a short-lived, single-use OAuth state
|
|
189
|
+
* bound to the current Vertesia user/account/project and returns the GitHub authorization URL.
|
|
190
|
+
*/
|
|
191
|
+
startGithubAuthorization(): Promise<StartAppGithubAuthorizationResponse> {
|
|
192
|
+
return this.post('/source-providers/github/authorize', {});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Complete GitHub authorization with the callback code and state. The server consumes the state,
|
|
197
|
+
* verifies the current user's writable GitHub App installations, discards the GitHub user token,
|
|
198
|
+
* and returns those installations plus an opaque `connection_id`. That id references a
|
|
199
|
+
* short-lived server-side snapshot of the writable repositories verified for this Vertesia
|
|
200
|
+
* user/account/project; selecting a repository consumes it once.
|
|
201
|
+
*/
|
|
202
|
+
exchangeGithubAuthorization(code: string, state: string): Promise<ExchangeAppGithubAuthorizationResponse> {
|
|
203
|
+
return this.post('/source-providers/github/exchange', { payload: { code, state } });
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* List repositories with push access for one installation verified during authorization. The
|
|
208
|
+
* connection id is scoped to the current Vertesia user/account/project and expires shortly.
|
|
209
|
+
*/
|
|
210
|
+
listGithubRepositories(connectionId: string, installationId: string): Promise<AppGithubRepositoryList> {
|
|
211
|
+
return this.get('/source-providers/github/repositories', {
|
|
212
|
+
query: { connection_id: connectionId, installation_id: installationId },
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* List branches and verify whether a selected branch can safely receive generated source.
|
|
218
|
+
* The verified connection remains reusable until app creation consumes it.
|
|
219
|
+
*/
|
|
220
|
+
getGithubRepositorySetup(
|
|
221
|
+
connectionId: string,
|
|
222
|
+
installationId: string,
|
|
223
|
+
repository: string,
|
|
224
|
+
branch: string,
|
|
225
|
+
): Promise<AppGithubRepositorySetup> {
|
|
226
|
+
return this.get('/source-providers/github/repository-setup', {
|
|
227
|
+
query: {
|
|
228
|
+
connection_id: connectionId,
|
|
229
|
+
installation_id: installationId,
|
|
230
|
+
repository,
|
|
231
|
+
branch,
|
|
232
|
+
},
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
152
236
|
/**
|
|
153
237
|
* Get the list if tools provided by the given app.
|
|
154
238
|
* @param appId
|
|
@@ -328,14 +412,20 @@ export default class AppsApi extends ApiTopic {
|
|
|
328
412
|
oauthParams?: Record<string, { client_id?: string; client_secret?: string; scopes?: string[] }>,
|
|
329
413
|
oauthProviderParams?: Record<string, { client_id?: string; client_secret?: string; scopes?: string[] }>,
|
|
330
414
|
apiKeyParams?: AppApiKeyCollectionParams,
|
|
415
|
+
mcpParameters?: AppInstallationPayload['mcp_parameters'],
|
|
416
|
+
mcpSharedParameters?: AppInstallationPayload['mcp_shared_parameters'],
|
|
417
|
+
instance?: Pick<AppInstallationPayload, 'instance_key' | 'display_name' | 'namespace_overrides'>,
|
|
331
418
|
): Promise<AppInstallation> {
|
|
332
419
|
return this.post(`/install`, {
|
|
333
420
|
payload: {
|
|
334
421
|
app_id: appId,
|
|
422
|
+
...instance,
|
|
335
423
|
settings,
|
|
336
424
|
oauth_params: oauthParams,
|
|
337
425
|
oauth_provider_params: oauthProviderParams,
|
|
338
426
|
api_key_params: apiKeyParams,
|
|
427
|
+
mcp_parameters: mcpParameters,
|
|
428
|
+
mcp_shared_parameters: mcpSharedParameters,
|
|
339
429
|
} satisfies AppInstallationPayload,
|
|
340
430
|
});
|
|
341
431
|
}
|
|
@@ -353,6 +443,14 @@ export default class AppsApi extends ApiTopic {
|
|
|
353
443
|
* get an app unstallation given its name or null if the app is not installed
|
|
354
444
|
* @returns
|
|
355
445
|
*/
|
|
446
|
+
getAppInstanceAvailability(): Promise<AppInstanceAvailability> {
|
|
447
|
+
return this.get('/instance-availability');
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
getAppInstallation(installationId: string): Promise<AppInstallationWithManifest> {
|
|
451
|
+
return this.get(`/installations/id/${encodeURIComponent(installationId)}`);
|
|
452
|
+
}
|
|
453
|
+
|
|
356
454
|
getAppInstallationByName(appName: string): Promise<AppInstallationWithManifest | null> {
|
|
357
455
|
return this.get<AppInstallationWithManifest>(`/installations/name/${appName}`).catch((err: ServerError) => {
|
|
358
456
|
if (err.status === 404) {
|
|
@@ -426,6 +524,14 @@ export default class AppsApi extends ApiTopic {
|
|
|
426
524
|
// clear an override). The server uses `'access_control' in payload` to distinguish
|
|
427
525
|
// "leave unchanged" from "clear", so only spread the key when it was supplied.
|
|
428
526
|
...('access_control' in settingsPayload ? { access_control: settingsPayload.access_control } : {}),
|
|
527
|
+
...('display_name' in settingsPayload ? { display_name: settingsPayload.display_name } : {}),
|
|
528
|
+
...('namespace_overrides' in settingsPayload
|
|
529
|
+
? { namespace_overrides: settingsPayload.namespace_overrides }
|
|
530
|
+
: {}),
|
|
531
|
+
...('mcp_parameters' in settingsPayload ? { mcp_parameters: settingsPayload.mcp_parameters } : {}),
|
|
532
|
+
...('mcp_shared_parameters' in settingsPayload
|
|
533
|
+
? { mcp_shared_parameters: settingsPayload.mcp_shared_parameters }
|
|
534
|
+
: {}),
|
|
429
535
|
} satisfies AppInstallationPayload,
|
|
430
536
|
});
|
|
431
537
|
}
|
package/src/InteractionsApi.ts
CHANGED
|
@@ -33,7 +33,13 @@ import type {
|
|
|
33
33
|
ResolveInteractionQuery,
|
|
34
34
|
} from '@vertesia/common';
|
|
35
35
|
import type { VertesiaClient } from './client.js';
|
|
36
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
checkRateLimit,
|
|
38
|
+
type ExecuteInteractionRequestOptions,
|
|
39
|
+
executeInteraction,
|
|
40
|
+
executeInteractionAsync,
|
|
41
|
+
executeInteractionByName,
|
|
42
|
+
} from './execute.js';
|
|
37
43
|
import { InteractionCatalogApi } from './InteractionCatalogApi.js';
|
|
38
44
|
import { type EnhancedInteractionExecutionResult, enhanceInteractionExecutionResult } from './InteractionOutput.js';
|
|
39
45
|
|
|
@@ -222,13 +228,14 @@ export default class InteractionsApi extends ApiTopic {
|
|
|
222
228
|
* @param nameWithTag
|
|
223
229
|
* @param payload
|
|
224
230
|
* @param onChunk
|
|
231
|
+
* @param requestOptions request options, e.g. `{ query: { include_prompt: false } }` to omit the rendered prompt
|
|
225
232
|
* @returns
|
|
226
233
|
*/
|
|
227
234
|
async executeByName<ResultT = unknown, ParamsT = unknown>(
|
|
228
235
|
nameWithTag: string,
|
|
229
236
|
payload: InteractionExecutionPayload = {},
|
|
230
237
|
onChunk?: (chunk: string) => void,
|
|
231
|
-
requestOptions?:
|
|
238
|
+
requestOptions?: ExecuteInteractionRequestOptions,
|
|
232
239
|
): Promise<EnhancedInteractionExecutionResult<ResultT, ParamsT>> {
|
|
233
240
|
const r = await executeInteractionByName<ParamsT>(
|
|
234
241
|
this.client as VertesiaClient,
|
package/src/OAuthServerApi.ts
CHANGED
|
@@ -9,6 +9,9 @@ import type {
|
|
|
9
9
|
OAuthGrantableScopesResponse,
|
|
10
10
|
OAuthLoginDecisionResponse,
|
|
11
11
|
OAuthLoginPayload,
|
|
12
|
+
OAuthTokenExchangeRequest,
|
|
13
|
+
OAuthTokenExchangeResponse,
|
|
14
|
+
ProjectRef,
|
|
12
15
|
} from '@vertesia/common';
|
|
13
16
|
|
|
14
17
|
export default class OAuthServerApi extends ClientBase {
|
|
@@ -22,6 +25,30 @@ export default class OAuthServerApi extends ClientBase {
|
|
|
22
25
|
this.verboseErrors = parent.verboseErrors;
|
|
23
26
|
}
|
|
24
27
|
|
|
28
|
+
/** Exchange a signed IdP assertion; optional client authentication follows the connection policy. */
|
|
29
|
+
exchangeToken(
|
|
30
|
+
payload: OAuthTokenExchangeRequest,
|
|
31
|
+
basic?: { client_id: string; client_secret: string },
|
|
32
|
+
): Promise<OAuthTokenExchangeResponse> {
|
|
33
|
+
if (
|
|
34
|
+
basic &&
|
|
35
|
+
(payload.client_secret !== undefined ||
|
|
36
|
+
payload.client_assertion !== undefined ||
|
|
37
|
+
(payload.client_id !== undefined && payload.client_id !== basic.client_id))
|
|
38
|
+
)
|
|
39
|
+
throw new Error('Use exactly one client authentication method');
|
|
40
|
+
return this.post('/token', {
|
|
41
|
+
payload,
|
|
42
|
+
...(basic
|
|
43
|
+
? {
|
|
44
|
+
headers: {
|
|
45
|
+
Authorization: `Basic ${btoa(`${encodeURIComponent(basic.client_id)}:${encodeURIComponent(basic.client_secret)}`)}`,
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
: {}),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
25
52
|
login(requestId: string, payload: OAuthLoginPayload): Promise<OAuthLoginDecisionResponse> {
|
|
26
53
|
return this.post(`/requests/${encodeURIComponent(requestId)}/login`, { payload });
|
|
27
54
|
}
|
|
@@ -76,6 +103,10 @@ export default class OAuthServerApi extends ClientBase {
|
|
|
76
103
|
return this.get(`/requests/${requestId}`);
|
|
77
104
|
}
|
|
78
105
|
|
|
106
|
+
retrieveGrantableProjects(requestId: string): Promise<ProjectRef[]> {
|
|
107
|
+
return this.get(`/requests/${encodeURIComponent(requestId)}/grantable-projects`);
|
|
108
|
+
}
|
|
109
|
+
|
|
79
110
|
retrieveGrantableScopes(requestId: string, projectId: string): Promise<OAuthGrantableScopesResponse> {
|
|
80
111
|
return this.get(`/requests/${requestId}/grantable-scopes`, { query: { project_id: projectId } });
|
|
81
112
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ApiTopic, type ClientBase } from '@vertesia/api-fetch-client';
|
|
2
|
+
import type { OidcFederationConnection, OidcFederationConnectionPayload, SuccessResponse } from '@vertesia/common';
|
|
3
|
+
|
|
4
|
+
export default class OidcFederationApi extends ApiTopic {
|
|
5
|
+
constructor(parent: ClientBase) {
|
|
6
|
+
super(parent, '/api/v1/oidc-federation');
|
|
7
|
+
}
|
|
8
|
+
retrieve(id: string): Promise<OidcFederationConnection> {
|
|
9
|
+
return this.get(`/${encodeURIComponent(id)}`);
|
|
10
|
+
}
|
|
11
|
+
list(): Promise<OidcFederationConnection[]> {
|
|
12
|
+
return this.get('/');
|
|
13
|
+
}
|
|
14
|
+
create(payload: OidcFederationConnectionPayload): Promise<OidcFederationConnection> {
|
|
15
|
+
return this.post('/', { payload });
|
|
16
|
+
}
|
|
17
|
+
update(id: string, payload: OidcFederationConnectionPayload): Promise<OidcFederationConnection> {
|
|
18
|
+
return this.put(`/${encodeURIComponent(id)}`, { payload });
|
|
19
|
+
}
|
|
20
|
+
remove(id: string): Promise<SuccessResponse> {
|
|
21
|
+
return this.del(`/${encodeURIComponent(id)}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/RunsApi.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
ExecutionRunRef,
|
|
9
9
|
FindPayload,
|
|
10
10
|
FindRunResult,
|
|
11
|
+
GetRunQuery,
|
|
11
12
|
InteractionExecutionResult,
|
|
12
13
|
PopulatedExecutionRun,
|
|
13
14
|
RunClonePayload,
|
|
@@ -67,10 +68,14 @@ export class RunsApi extends ApiTopic {
|
|
|
67
68
|
* Get a run by id
|
|
68
69
|
*
|
|
69
70
|
* @param id
|
|
71
|
+
* @param query response options, e.g. `{ include_prompt: false }` to omit the rendered prompt
|
|
70
72
|
* @returns InteractionResult
|
|
71
73
|
**/
|
|
72
|
-
async retrieve<ResultT = unknown, ParamsT = unknown>(
|
|
73
|
-
|
|
74
|
+
async retrieve<ResultT = unknown, ParamsT = unknown>(
|
|
75
|
+
id: string,
|
|
76
|
+
query?: GetRunQuery,
|
|
77
|
+
): Promise<EnhancedExecutionRun<ResultT, ParamsT>> {
|
|
78
|
+
const r = await this.get<ExecutionRun<ParamsT>>(`/${id}`, { query });
|
|
74
79
|
return enhanceExecutionRun<ResultT, ParamsT>(r);
|
|
75
80
|
}
|
|
76
81
|
|
package/src/client.ts
CHANGED
|
@@ -18,6 +18,7 @@ import OAuthClientsApi from './OAuthClientsApi.js';
|
|
|
18
18
|
import OAuthGrantsApi from './OAuthGrantsApi.js';
|
|
19
19
|
import OAuthProvidersApi from './OAuthProvidersApi.js';
|
|
20
20
|
import OAuthServerApi from './OAuthServerApi.js';
|
|
21
|
+
import OidcFederationApi from './OidcFederationApi.js';
|
|
21
22
|
import ProjectsApi from './ProjectsApi.js';
|
|
22
23
|
import PromptsApi from './PromptsApi.js';
|
|
23
24
|
import QuotaApi from './QuotaApi.js';
|
|
@@ -120,6 +121,7 @@ export class VertesiaClient extends AbstractFetchClient<VertesiaClient> {
|
|
|
120
121
|
*/
|
|
121
122
|
tokenServerUrl: string;
|
|
122
123
|
|
|
124
|
+
oidcFederation: OidcFederationApi;
|
|
123
125
|
oauthClients: OAuthClientsApi;
|
|
124
126
|
oauthGrants: OAuthGrantsApi;
|
|
125
127
|
oauthServer: OAuthServerApi;
|
|
@@ -251,6 +253,7 @@ export class VertesiaClient extends AbstractFetchClient<VertesiaClient> {
|
|
|
251
253
|
this.onRequest = opts.onRequest;
|
|
252
254
|
this.onResponse = opts.onResponse;
|
|
253
255
|
this.sessionTags = opts.sessionTags;
|
|
256
|
+
this.oidcFederation = new OidcFederationApi(this);
|
|
254
257
|
this.oauthClients = new OAuthClientsApi(this);
|
|
255
258
|
this.oauthGrants = new OAuthGrantsApi(this);
|
|
256
259
|
this.oauthServer = new OAuthServerApi(this, this.tokenServerUrl);
|
package/src/execute.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { IRequestParams } from '@vertesia/api-fetch-client';
|
|
|
2
2
|
import {
|
|
3
3
|
type AsyncExecutionPayload,
|
|
4
4
|
type AsyncExecutionResult,
|
|
5
|
+
type ExecuteNamedInteractionQuery,
|
|
5
6
|
ExecutionRunStatus,
|
|
6
7
|
type InteractionExecutionPayload,
|
|
7
8
|
type InteractionExecutionResult,
|
|
@@ -23,6 +24,20 @@ const INTERACTION_EXECUTION_TIMEOUT_MS = (() => {
|
|
|
23
24
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : 30 * 60 * 1000; // 30 minutes
|
|
24
25
|
})();
|
|
25
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Per-request options for a synchronous named-interaction execution: the request options this method
|
|
29
|
+
* can honour, plus the published execute query.
|
|
30
|
+
*
|
|
31
|
+
* `reader` and `jsonPayload` are left out: the method parses the JSON execution result and serializes
|
|
32
|
+
* the payload it builds, so either would break the call. `query` is the typed execute query instead of
|
|
33
|
+
* a free-form record, so a misspelt parameter fails to compile rather than being ignored by the server.
|
|
34
|
+
* With `onChunk`, the options apply to the initial request only; the stream that follows is a separate
|
|
35
|
+
* connection.
|
|
36
|
+
*/
|
|
37
|
+
export type ExecuteInteractionRequestOptions = Omit<IRequestParams, 'reader' | 'jsonPayload' | 'query'> & {
|
|
38
|
+
query?: ExecuteNamedInteractionQuery;
|
|
39
|
+
};
|
|
40
|
+
|
|
26
41
|
export async function EventSourceProvider(): Promise<typeof EventSource> {
|
|
27
42
|
if (typeof globalThis.EventSource === 'function') {
|
|
28
43
|
return globalThis.EventSource;
|
|
@@ -81,6 +96,7 @@ export async function executeInteraction<P = unknown>(
|
|
|
81
96
|
* @param interaction
|
|
82
97
|
* @param payload
|
|
83
98
|
* @param onChunk
|
|
99
|
+
* @param requestOptions request options, e.g. `{ query: { include_prompt: false } }` to omit the rendered prompt
|
|
84
100
|
* @returns
|
|
85
101
|
*/
|
|
86
102
|
export async function executeInteractionByName<P = unknown>(
|
|
@@ -88,7 +104,7 @@ export async function executeInteractionByName<P = unknown>(
|
|
|
88
104
|
interaction: string,
|
|
89
105
|
payload: InteractionExecutionPayload = {},
|
|
90
106
|
onChunk?: (chunk: string) => void,
|
|
91
|
-
requestOptions?:
|
|
107
|
+
requestOptions?: ExecuteInteractionRequestOptions,
|
|
92
108
|
): Promise<InteractionExecutionResult<P>> {
|
|
93
109
|
const stream = !!onChunk;
|
|
94
110
|
const response = await client.post<InteractionExecutionResult<P>>('/api/v1/execute', {
|
|
@@ -98,8 +114,14 @@ export async function executeInteractionByName<P = unknown>(
|
|
|
98
114
|
interaction,
|
|
99
115
|
stream,
|
|
100
116
|
} as NamedInteractionExecutionPayload,
|
|
101
|
-
// Synchronous interaction execution blocks on the model; keep a long client timeout.
|
|
102
|
-
|
|
117
|
+
// Synchronous interaction execution blocks on the model; keep a long client timeout. An explicit
|
|
118
|
+
// timeout wins, including `null`, `false` or `0`, which disable it.
|
|
119
|
+
timeoutMs:
|
|
120
|
+
requestOptions?.timeoutMs !== undefined
|
|
121
|
+
? requestOptions.timeoutMs
|
|
122
|
+
: stream
|
|
123
|
+
? undefined
|
|
124
|
+
: INTERACTION_EXECUTION_TIMEOUT_MS,
|
|
103
125
|
});
|
|
104
126
|
if (stream) {
|
|
105
127
|
if (response.status === ExecutionRunStatus.failed) {
|
|
@@ -167,8 +189,13 @@ export async function executeInteractionAsync(
|
|
|
167
189
|
client: VertesiaClient,
|
|
168
190
|
payload: AsyncExecutionPayload,
|
|
169
191
|
): Promise<AsyncExecutionResult> {
|
|
192
|
+
// A conversation starts an agent run: without `idempotency_key` a replay could start a second one,
|
|
193
|
+
// so opt out of any client-level retry policy (see `AgentsApi.start`). With a key, a replay
|
|
194
|
+
// returns the run the first request started.
|
|
195
|
+
const unkeyedConversation = payload.type === 'conversation' && !payload.idempotency_key;
|
|
170
196
|
return await client.post('/api/v1/execute/async', {
|
|
171
197
|
payload,
|
|
198
|
+
retryPolicy: unkeyedConversation ? false : undefined,
|
|
172
199
|
});
|
|
173
200
|
}
|
|
174
201
|
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ export type { EnableEnvironmentModelPayload, OrphanedAppInstallation } from '@ve
|
|
|
4
4
|
export { getOAuthPermissionScopes, Permission } from '@vertesia/common';
|
|
5
5
|
export * from './client.js';
|
|
6
6
|
export { default as DelegationGrantsApi } from './DelegationGrantsApi.js';
|
|
7
|
+
export type { ExecuteInteractionRequestOptions } from './execute.js';
|
|
7
8
|
export type { GroupsQueryOptions } from './GroupsApi.js';
|
|
8
9
|
export * from './InteractionBase.js';
|
|
9
10
|
export * from './InteractionOutput.js';
|
|
@@ -12,6 +13,7 @@ export { default as OAuthClientsApi } from './OAuthClientsApi.js';
|
|
|
12
13
|
export { default as OAuthGrantsApi } from './OAuthGrantsApi.js';
|
|
13
14
|
export { default as OAuthProvidersApi } from './OAuthProvidersApi.js';
|
|
14
15
|
export { default as OAuthServerApi } from './OAuthServerApi.js';
|
|
16
|
+
export { default as OidcFederationApi } from './OidcFederationApi.js';
|
|
15
17
|
export type { ComputePromptFacetsResponse, ListInteractionsResponse } from './PromptsApi.js';
|
|
16
18
|
export { default as RemoteMcpConnectionsApi } from './RemoteMcpConnectionsApi.js';
|
|
17
19
|
export type { ComputeRunFacetsResponse, FilterOption } from './RunsApi.js';
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { Readable } from 'node:stream';
|
|
2
|
-
import {
|
|
2
|
+
import { finished } from 'node:stream/promises';
|
|
3
3
|
import { StreamSource } from '../StreamSource.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* A stream source that wraps a Node.js Readable stream.
|
|
7
7
|
* This class is only works in Node.js environments.
|
|
8
|
+
* Cancelling the web stream destroys the Node.js stream, releasing its underlying resource (e.g. a file descriptor).
|
|
8
9
|
*/
|
|
9
10
|
export class NodeStreamSource extends StreamSource {
|
|
10
11
|
constructor(stream: Readable, name: string, type?: string, id?: string) {
|
|
@@ -12,31 +13,34 @@ export class NodeStreamSource extends StreamSource {
|
|
|
12
13
|
}
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
function readableToWebStream<T = string | Buffer>(stream: Readable): ReadableStream<T> {
|
|
16
|
-
if (NodeReadableStream.from) {
|
|
17
|
-
return NodeReadableStream.from(stream) as ReadableStream<T>;
|
|
18
|
-
} else {
|
|
19
|
-
return readableToWebStream_BUN(stream);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
16
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
17
|
+
* Not ReadableStream.from: it cancels by calling return() on the Node.js async iterator, which is a no-op
|
|
18
|
+
* when nothing was read yet, so the Node.js stream would stay open. Also covers Bun, which lacks ReadableStream.from.
|
|
26
19
|
*/
|
|
27
|
-
function
|
|
20
|
+
function readableToWebStream<T = string | Buffer>(stream: Readable): ReadableStream<T> {
|
|
21
|
+
// Nothing listens until the first read, so an error before it (e.g. a failed lazy file open) would otherwise
|
|
22
|
+
// crash the process. The iterator still reports the error on the next read.
|
|
23
|
+
stream.on('error', () => undefined);
|
|
28
24
|
const it = stream[Symbol.asyncIterator]();
|
|
29
|
-
return new ReadableStream<T>(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
25
|
+
return new ReadableStream<T>(
|
|
26
|
+
{
|
|
27
|
+
async pull(controller) {
|
|
28
|
+
const { value, done } = await it.next();
|
|
29
|
+
if (done) {
|
|
30
|
+
controller.close();
|
|
31
|
+
} else {
|
|
32
|
+
controller.enqueue(value);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
async cancel() {
|
|
36
|
+
// no error argument: it would emit 'error', which the caller may not listen for
|
|
37
|
+
stream.destroy();
|
|
38
|
+
// resolve once the underlying resource is released, so callers can remove the file afterwards;
|
|
39
|
+
// bounded because some streams never report their close
|
|
40
|
+
await finished(stream, { signal: AbortSignal.timeout(5_000) }).catch(() => undefined);
|
|
41
|
+
},
|
|
40
42
|
},
|
|
41
|
-
|
|
43
|
+
// read on demand, like ReadableStream.from
|
|
44
|
+
{ highWaterMark: 0 },
|
|
45
|
+
);
|
|
42
46
|
}
|
package/src/store/AgentsApi.ts
CHANGED
|
@@ -87,13 +87,22 @@ export class AgentsApi extends ApiTopic {
|
|
|
87
87
|
/**
|
|
88
88
|
* Create and start a new agent run.
|
|
89
89
|
* Returns the created AgentRun with its stable id.
|
|
90
|
+
*
|
|
91
|
+
* Set `idempotency_key` on an agent run to make the call safe to retry: the client's retry policy
|
|
92
|
+
* then applies, and a replayed request returns the run the first one started.
|
|
90
93
|
*/
|
|
91
94
|
start<TData = Record<string, unknown>>(payload: CreateAgentRunPayload<TData>): Promise<AgentRun<TData>>;
|
|
92
95
|
start<TData = Record<string, unknown>>(payload: CreateProcessRunPayload<TData>): Promise<ProcessRun>;
|
|
93
96
|
start<TData = Record<string, unknown>>(
|
|
94
97
|
payload: CreateAgentRunPayload<TData> | CreateProcessRunPayload<TData>,
|
|
95
98
|
): Promise<AgentRun<TData> | ProcessRun> {
|
|
96
|
-
|
|
99
|
+
// Without a key, starting an agent run is not idempotent: a request abandoned client-side can
|
|
100
|
+
// still complete server-side, so a replay would start a second run. Opt out of any client-level
|
|
101
|
+
// retry policy explicitly rather than relying on POST being absent from its method list.
|
|
102
|
+
// Rate-limiter pacing retries are unaffected: those happen before the request reaches the
|
|
103
|
+
// handler. Process starts take no key and keep the client's policy.
|
|
104
|
+
const unkeyedAgentStart = 'interaction' in payload && !payload.idempotency_key;
|
|
105
|
+
return this.post('/', { payload, retryPolicy: unkeyedAgentStart ? false : undefined });
|
|
97
106
|
}
|
|
98
107
|
|
|
99
108
|
/**
|
package/src/store/FilesApi.ts
CHANGED
|
@@ -258,11 +258,17 @@ export class FilesApi extends ApiTopic {
|
|
|
258
258
|
'Content-Type': sourceMimeType,
|
|
259
259
|
},
|
|
260
260
|
}).catch((err) => {
|
|
261
|
-
console.error('Failed to upload file', { err, url, id, path });
|
|
261
|
+
console.error('Failed to upload file', { err, location: fileLocationForError(url), id, path });
|
|
262
262
|
throw err;
|
|
263
263
|
});
|
|
264
264
|
if (!res.ok) {
|
|
265
|
-
console.
|
|
265
|
+
console.error('Failed to upload file', {
|
|
266
|
+
status: res.status,
|
|
267
|
+
statusText: res.statusText,
|
|
268
|
+
location: fileLocationForError(url),
|
|
269
|
+
id,
|
|
270
|
+
path,
|
|
271
|
+
});
|
|
266
272
|
throw new Error(`Failed to upload file: ${res.statusText}`);
|
|
267
273
|
}
|
|
268
274
|
|
package/src/store/IndexingApi.ts
CHANGED
|
@@ -27,6 +27,7 @@ import type {
|
|
|
27
27
|
SwapAliasResult,
|
|
28
28
|
TriggerReindexResult,
|
|
29
29
|
} from '@vertesia/common';
|
|
30
|
+
import { zenoBulkBaseUrl } from './zeno-bulk.js';
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* API for indexing operations on content objects.
|
|
@@ -274,30 +275,14 @@ export class IndexingApi extends ApiTopic {
|
|
|
274
275
|
|
|
275
276
|
// ========================================================================
|
|
276
277
|
// Zeno Bulk endpoints (Go migration service)
|
|
277
|
-
// Routes via LB path rules in prod, or derived URL in dev.
|
|
278
|
+
// Routes via LB path rules in prod, or derived URL in dev (see zenoBulkBaseUrl).
|
|
278
279
|
// ========================================================================
|
|
279
280
|
|
|
280
|
-
/**
|
|
281
|
-
* Get the zeno-bulk base URL.
|
|
282
|
-
* Dev branches: store URL contains "zeno-server" -> replace with "zeno-bulk".
|
|
283
|
-
* Production/preview: same domain, LB routes /reindex/* to zeno-bulk.
|
|
284
|
-
*/
|
|
285
|
-
private get zenoBulkBaseUrl(): string {
|
|
286
|
-
const storeBaseUrl = this.client.baseUrl;
|
|
287
|
-
if (storeBaseUrl.includes('localhost:') || storeBaseUrl.includes('127.0.0.1:')) {
|
|
288
|
-
return 'https://zeno-bulk-dev-main.api.dev1.vertesia.io';
|
|
289
|
-
}
|
|
290
|
-
if (storeBaseUrl.includes('zeno-server')) {
|
|
291
|
-
return storeBaseUrl.replace(/zeno-server/, 'zeno-bulk');
|
|
292
|
-
}
|
|
293
|
-
return storeBaseUrl;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
281
|
/**
|
|
297
282
|
* POST to a zeno-bulk endpoint. Resolves the path against the zeno-bulk base URL.
|
|
298
283
|
*/
|
|
299
284
|
private zenoBulkPost<T>(path: string, body: object): Promise<T> {
|
|
300
|
-
return this.client.post(this.
|
|
285
|
+
return this.client.post(zenoBulkBaseUrl(this.client.baseUrl) + path, { payload: body });
|
|
301
286
|
}
|
|
302
287
|
|
|
303
288
|
/**
|