@valon-technologies/gestalt 0.0.1-alpha.12 → 0.0.1-alpha.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/gen/google/rpc/status_pb.ts +76 -0
- package/gen/v1/agent_pb.ts +2412 -0
- package/gen/v1/authentication_pb.ts +1 -1
- package/gen/v1/authorization_pb.ts +28 -28
- package/gen/v1/cache_pb.ts +4 -4
- package/gen/v1/datastore_pb.ts +467 -12
- package/gen/v1/external_credential_pb.ts +274 -0
- package/gen/v1/plugin_pb.ts +64 -42
- package/gen/v1/pluginruntime_pb.ts +632 -0
- package/gen/v1/runtime_pb.ts +46 -3
- package/gen/v1/s3_pb.ts +120 -20
- package/gen/v1/secrets_pb.ts +1 -1
- package/gen/v1/workflow_pb.ts +849 -97
- package/package.json +5 -3
- package/src/agent-manager.ts +247 -0
- package/src/agent.ts +645 -0
- package/src/api.ts +4 -1
- package/src/authorization.ts +88 -18
- package/src/index.ts +134 -16
- package/src/indexeddb.ts +481 -1
- package/src/invoker.ts +3 -0
- package/src/plugin.ts +81 -181
- package/src/pluginruntime.ts +220 -0
- package/src/provider-kind.ts +12 -0
- package/src/provider.ts +28 -1
- package/src/runtime-log-host.ts +244 -0
- package/src/runtime.ts +194 -67
- package/src/s3.ts +170 -38
- package/src/telemetry.ts +429 -0
- package/src/workflow-manager.ts +78 -9
- package/src/manifest-metadata.ts +0 -106
package/src/plugin.ts
CHANGED
|
@@ -7,15 +7,6 @@ import {
|
|
|
7
7
|
schemaToParameters,
|
|
8
8
|
writeCatalogYaml,
|
|
9
9
|
} from "./catalog.ts";
|
|
10
|
-
import {
|
|
11
|
-
type HTTPAck,
|
|
12
|
-
type HTTPBinding,
|
|
13
|
-
type HTTPRequestBody,
|
|
14
|
-
type HTTPSecurityScheme,
|
|
15
|
-
type PluginManifestMetadata,
|
|
16
|
-
hasPluginManifestMetadata,
|
|
17
|
-
writeManifestMetadataYaml,
|
|
18
|
-
} from "./manifest-metadata.ts";
|
|
19
10
|
import {
|
|
20
11
|
errorMessage,
|
|
21
12
|
type MaybePromise,
|
|
@@ -32,7 +23,11 @@ import {
|
|
|
32
23
|
type HTTPSubjectResolutionContext,
|
|
33
24
|
type HTTPSubjectResolver,
|
|
34
25
|
} from "./http-subject.ts";
|
|
35
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
isRuntimeProvider,
|
|
28
|
+
RuntimeProvider,
|
|
29
|
+
type RuntimeProviderOptions,
|
|
30
|
+
} from "./provider.ts";
|
|
36
31
|
import type { Schema } from "./schema.ts";
|
|
37
32
|
|
|
38
33
|
/**
|
|
@@ -42,7 +37,7 @@ export type ConnectionMode =
|
|
|
42
37
|
| "unspecified"
|
|
43
38
|
| "none"
|
|
44
39
|
| "user"
|
|
45
|
-
| "
|
|
40
|
+
| "platform";
|
|
46
41
|
|
|
47
42
|
/**
|
|
48
43
|
* Metadata for a single connection parameter exposed by a provider.
|
|
@@ -92,6 +87,34 @@ export type SessionCatalogHandler = (
|
|
|
92
87
|
request: Request,
|
|
93
88
|
) => MaybePromise<SessionCatalog | null | undefined>;
|
|
94
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Host-managed connection payload passed into a provider post-connect hook.
|
|
92
|
+
*/
|
|
93
|
+
export interface ConnectedToken {
|
|
94
|
+
id: string;
|
|
95
|
+
subjectId: string;
|
|
96
|
+
integration: string;
|
|
97
|
+
connection: string;
|
|
98
|
+
instance: string;
|
|
99
|
+
accessToken: string;
|
|
100
|
+
refreshToken: string;
|
|
101
|
+
scopes: string;
|
|
102
|
+
expiresAt?: Date | undefined;
|
|
103
|
+
lastRefreshedAt?: Date | undefined;
|
|
104
|
+
refreshErrorCount: number;
|
|
105
|
+
metadataJson: string;
|
|
106
|
+
metadata: Record<string, string>;
|
|
107
|
+
createdAt?: Date | undefined;
|
|
108
|
+
updatedAt?: Date | undefined;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Callback used to add derived metadata after a connection is established.
|
|
113
|
+
*/
|
|
114
|
+
export type PostConnectHandler = (
|
|
115
|
+
token: ConnectedToken,
|
|
116
|
+
) => MaybePromise<Record<string, string> | null | undefined>;
|
|
117
|
+
|
|
95
118
|
/**
|
|
96
119
|
* Runtime hooks required to implement a plugin provider.
|
|
97
120
|
*/
|
|
@@ -99,9 +122,8 @@ export interface PluginDefinitionOptions extends RuntimeProviderOptions {
|
|
|
99
122
|
connectionMode?: ConnectionMode;
|
|
100
123
|
authTypes?: string[];
|
|
101
124
|
connectionParams?: Record<string, ConnectionParamDefinition>;
|
|
102
|
-
securitySchemes?: Record<string, HTTPSecurityScheme>;
|
|
103
|
-
http?: Record<string, HTTPBinding>;
|
|
104
125
|
resolveHTTPSubject?: HTTPSubjectResolver;
|
|
126
|
+
postConnect?: PostConnectHandler;
|
|
105
127
|
iconSvg?: string;
|
|
106
128
|
operations: Array<OperationDefinition<any, any>>;
|
|
107
129
|
sessionCatalog?: SessionCatalogHandler;
|
|
@@ -154,11 +176,10 @@ export class PluginProvider extends RuntimeProvider {
|
|
|
154
176
|
readonly connectionMode: ConnectionMode;
|
|
155
177
|
readonly authTypes: string[];
|
|
156
178
|
readonly connectionParams: Record<string, ConnectionParamDefinition>;
|
|
157
|
-
readonly securitySchemes: Record<string, HTTPSecurityScheme>;
|
|
158
|
-
readonly http: Record<string, HTTPBinding>;
|
|
159
179
|
|
|
160
180
|
private readonly sessionCatalogHandler: SessionCatalogHandler | undefined;
|
|
161
181
|
private readonly httpSubjectResolver: HTTPSubjectResolver | undefined;
|
|
182
|
+
private readonly postConnectHandler: PostConnectHandler | undefined;
|
|
162
183
|
private readonly operations = new Map<string, OperationDefinition<any, any>>();
|
|
163
184
|
|
|
164
185
|
constructor(options: PluginDefinitionOptions) {
|
|
@@ -167,9 +188,8 @@ export class PluginProvider extends RuntimeProvider {
|
|
|
167
188
|
this.connectionMode = options.connectionMode ?? "unspecified";
|
|
168
189
|
this.authTypes = [...(options.authTypes ?? [])];
|
|
169
190
|
this.connectionParams = normalizeConnectionParams(options.connectionParams);
|
|
170
|
-
this.securitySchemes = normalizeHTTPSecuritySchemes(options.securitySchemes);
|
|
171
|
-
this.http = normalizeHTTPBindings(options.http);
|
|
172
191
|
this.httpSubjectResolver = options.resolveHTTPSubject;
|
|
192
|
+
this.postConnectHandler = options.postConnect;
|
|
173
193
|
this.sessionCatalogHandler = options.sessionCatalog;
|
|
174
194
|
|
|
175
195
|
for (const rawEntry of options.operations) {
|
|
@@ -200,6 +220,22 @@ export class PluginProvider extends RuntimeProvider {
|
|
|
200
220
|
return await this.sessionCatalogHandler?.(request);
|
|
201
221
|
}
|
|
202
222
|
|
|
223
|
+
/**
|
|
224
|
+
* Reports whether the provider exposes a connect-time metadata hook.
|
|
225
|
+
*/
|
|
226
|
+
supportsPostConnect(): boolean {
|
|
227
|
+
return this.postConnectHandler !== undefined;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Computes additional connection metadata after a successful connect flow.
|
|
232
|
+
*/
|
|
233
|
+
async postConnectMetadata(
|
|
234
|
+
token: ConnectedToken,
|
|
235
|
+
): Promise<Record<string, string> | null | undefined> {
|
|
236
|
+
return await this.postConnectHandler?.(cloneConnectedToken(token));
|
|
237
|
+
}
|
|
238
|
+
|
|
203
239
|
/**
|
|
204
240
|
* Resolves the concrete Gestalt subject for a verified hosted HTTP request,
|
|
205
241
|
* if the plugin opts into subject resolution.
|
|
@@ -295,38 +331,6 @@ export class PluginProvider extends RuntimeProvider {
|
|
|
295
331
|
return catalogToJson(this.staticCatalog());
|
|
296
332
|
}
|
|
297
333
|
|
|
298
|
-
/**
|
|
299
|
-
* Returns generated manifest-backed HTTP/security metadata for the provider.
|
|
300
|
-
*/
|
|
301
|
-
staticManifestMetadata(): PluginManifestMetadata {
|
|
302
|
-
const metadata: PluginManifestMetadata = {};
|
|
303
|
-
if (Object.keys(this.securitySchemes).length > 0) {
|
|
304
|
-
metadata.securitySchemes = cloneHTTPSecuritySchemes(this.securitySchemes);
|
|
305
|
-
}
|
|
306
|
-
if (Object.keys(this.http).length > 0) {
|
|
307
|
-
metadata.http = cloneHTTPBindings(this.http);
|
|
308
|
-
}
|
|
309
|
-
return metadata;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* Reports whether the provider emits manifest metadata in addition to catalog metadata.
|
|
314
|
-
*/
|
|
315
|
-
supportsManifestMetadata(): boolean {
|
|
316
|
-
return hasPluginManifestMetadata(this.staticManifestMetadata());
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
/**
|
|
320
|
-
* Writes generated manifest metadata to disk as YAML.
|
|
321
|
-
*/
|
|
322
|
-
writeManifestMetadata(path: string): void {
|
|
323
|
-
const metadata = this.staticManifestMetadata();
|
|
324
|
-
if (!hasPluginManifestMetadata(metadata)) {
|
|
325
|
-
return;
|
|
326
|
-
}
|
|
327
|
-
writeManifestMetadataYaml(path, metadata);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
334
|
/**
|
|
331
335
|
* Executes an operation against validated input and request metadata.
|
|
332
336
|
*/
|
|
@@ -386,12 +390,23 @@ export function isPluginProvider(
|
|
|
386
390
|
): value is PluginProvider {
|
|
387
391
|
return (
|
|
388
392
|
value instanceof PluginProvider ||
|
|
389
|
-
(
|
|
390
|
-
value !== null &&
|
|
393
|
+
(isRuntimeProvider(value) &&
|
|
391
394
|
"kind" in value &&
|
|
392
395
|
(value as { kind?: unknown }).kind === "integration" &&
|
|
393
396
|
"staticCatalog" in value &&
|
|
394
|
-
"
|
|
397
|
+
typeof (value as { staticCatalog?: unknown }).staticCatalog === "function" &&
|
|
398
|
+
"execute" in value &&
|
|
399
|
+
typeof (value as { execute?: unknown }).execute === "function" &&
|
|
400
|
+
"supportsSessionCatalog" in value &&
|
|
401
|
+
typeof (value as { supportsSessionCatalog?: unknown }).supportsSessionCatalog === "function" &&
|
|
402
|
+
"catalogForRequest" in value &&
|
|
403
|
+
typeof (value as { catalogForRequest?: unknown }).catalogForRequest === "function" &&
|
|
404
|
+
"supportsPostConnect" in value &&
|
|
405
|
+
typeof (value as { supportsPostConnect?: unknown }).supportsPostConnect === "function" &&
|
|
406
|
+
"postConnectMetadata" in value &&
|
|
407
|
+
typeof (value as { postConnectMetadata?: unknown }).postConnectMetadata === "function" &&
|
|
408
|
+
"resolveHTTPSubject" in value &&
|
|
409
|
+
typeof (value as { resolveHTTPSubject?: unknown }).resolveHTTPSubject === "function")
|
|
395
410
|
);
|
|
396
411
|
}
|
|
397
412
|
|
|
@@ -421,134 +436,19 @@ function normalizeConnectionParams(
|
|
|
421
436
|
return output;
|
|
422
437
|
}
|
|
423
438
|
|
|
424
|
-
function
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
): Record<string, HTTPSecurityScheme> {
|
|
437
|
-
const output: Record<string, HTTPSecurityScheme> = {};
|
|
438
|
-
for (const [key, value] of Object.entries(input)) {
|
|
439
|
-
output[key] = cloneHTTPSecurityScheme(value);
|
|
440
|
-
}
|
|
441
|
-
return output;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
function cloneHTTPSecurityScheme(value: HTTPSecurityScheme): HTTPSecurityScheme {
|
|
445
|
-
const output: HTTPSecurityScheme = {};
|
|
446
|
-
if (value.type !== undefined) {
|
|
447
|
-
output.type = value.type;
|
|
448
|
-
}
|
|
449
|
-
if (value.description !== undefined) {
|
|
450
|
-
output.description = value.description;
|
|
451
|
-
}
|
|
452
|
-
if (value.signatureHeader !== undefined) {
|
|
453
|
-
output.signatureHeader = value.signatureHeader;
|
|
454
|
-
}
|
|
455
|
-
if (value.signaturePrefix !== undefined) {
|
|
456
|
-
output.signaturePrefix = value.signaturePrefix;
|
|
457
|
-
}
|
|
458
|
-
if (value.payloadTemplate !== undefined) {
|
|
459
|
-
output.payloadTemplate = value.payloadTemplate;
|
|
460
|
-
}
|
|
461
|
-
if (value.timestampHeader !== undefined) {
|
|
462
|
-
output.timestampHeader = value.timestampHeader;
|
|
463
|
-
}
|
|
464
|
-
if (value.maxAgeSeconds !== undefined) {
|
|
465
|
-
output.maxAgeSeconds = value.maxAgeSeconds;
|
|
466
|
-
}
|
|
467
|
-
if (value.name !== undefined) {
|
|
468
|
-
output.name = value.name;
|
|
469
|
-
}
|
|
470
|
-
if (value.in !== undefined) {
|
|
471
|
-
output.in = value.in;
|
|
472
|
-
}
|
|
473
|
-
if (value.scheme !== undefined) {
|
|
474
|
-
output.scheme = value.scheme;
|
|
475
|
-
}
|
|
476
|
-
if (value.secret) {
|
|
477
|
-
output.secret = {
|
|
478
|
-
...value.secret,
|
|
479
|
-
};
|
|
480
|
-
}
|
|
481
|
-
return output;
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
function normalizeHTTPBindings(
|
|
485
|
-
input: Record<string, HTTPBinding> | undefined,
|
|
486
|
-
): Record<string, HTTPBinding> {
|
|
487
|
-
const output: Record<string, HTTPBinding> = {};
|
|
488
|
-
for (const [key, value] of Object.entries(input ?? {})) {
|
|
489
|
-
output[key] = cloneHTTPBinding(value);
|
|
490
|
-
}
|
|
491
|
-
return output;
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
function cloneHTTPBindings(
|
|
495
|
-
input: Record<string, HTTPBinding>,
|
|
496
|
-
): Record<string, HTTPBinding> {
|
|
497
|
-
const output: Record<string, HTTPBinding> = {};
|
|
498
|
-
for (const [key, value] of Object.entries(input)) {
|
|
499
|
-
output[key] = cloneHTTPBinding(value);
|
|
500
|
-
}
|
|
501
|
-
return output;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
function cloneHTTPBinding(value: HTTPBinding): HTTPBinding {
|
|
505
|
-
const output: HTTPBinding = {
|
|
506
|
-
path: value.path,
|
|
507
|
-
method: value.method,
|
|
508
|
-
security: value.security,
|
|
509
|
-
target: value.target,
|
|
439
|
+
function cloneConnectedToken(token: ConnectedToken): ConnectedToken {
|
|
440
|
+
return {
|
|
441
|
+
...token,
|
|
442
|
+
metadata: {
|
|
443
|
+
...(token.metadata ?? {}),
|
|
444
|
+
},
|
|
445
|
+
expiresAt: token.expiresAt ? new Date(token.expiresAt) : undefined,
|
|
446
|
+
lastRefreshedAt: token.lastRefreshedAt
|
|
447
|
+
? new Date(token.lastRefreshedAt)
|
|
448
|
+
: undefined,
|
|
449
|
+
createdAt: token.createdAt ? new Date(token.createdAt) : undefined,
|
|
450
|
+
updatedAt: token.updatedAt ? new Date(token.updatedAt) : undefined,
|
|
510
451
|
};
|
|
511
|
-
if (value.requestBody) {
|
|
512
|
-
output.requestBody = cloneHTTPRequestBody(value.requestBody);
|
|
513
|
-
}
|
|
514
|
-
if (value.ack) {
|
|
515
|
-
output.ack = cloneHTTPAck(value.ack);
|
|
516
|
-
}
|
|
517
|
-
return output;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
function cloneHTTPRequestBody(value: HTTPRequestBody): HTTPRequestBody {
|
|
521
|
-
const output: HTTPRequestBody = {};
|
|
522
|
-
if (value.required !== undefined) {
|
|
523
|
-
output.required = value.required;
|
|
524
|
-
}
|
|
525
|
-
if (value.content) {
|
|
526
|
-
output.content = {};
|
|
527
|
-
for (const key of Object.keys(value.content)) {
|
|
528
|
-
output.content[key] = {};
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
return output;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
function cloneHTTPAck(value: HTTPAck): HTTPAck {
|
|
535
|
-
const output: HTTPAck = {};
|
|
536
|
-
if (value.status !== undefined) {
|
|
537
|
-
output.status = value.status;
|
|
538
|
-
}
|
|
539
|
-
if (value.headers) {
|
|
540
|
-
output.headers = {
|
|
541
|
-
...value.headers,
|
|
542
|
-
};
|
|
543
|
-
}
|
|
544
|
-
if (value.body !== undefined) {
|
|
545
|
-
output.body = cloneHTTPBodyValue(value.body);
|
|
546
|
-
}
|
|
547
|
-
return output;
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
function cloneHTTPBodyValue<T>(value: T): T {
|
|
551
|
-
return structuredClone(value);
|
|
552
452
|
}
|
|
553
453
|
|
|
554
454
|
function isResponse(value: unknown): value is Response<unknown> {
|
|
@@ -615,8 +515,8 @@ export function connectionModeToProtoValue(mode: ConnectionMode): number {
|
|
|
615
515
|
return 1;
|
|
616
516
|
case "user":
|
|
617
517
|
return 2;
|
|
618
|
-
case "
|
|
619
|
-
return
|
|
518
|
+
case "platform":
|
|
519
|
+
return 5;
|
|
620
520
|
case "unspecified":
|
|
621
521
|
default:
|
|
622
522
|
return 0;
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { create, type MessageInitShape } from "@bufbuild/protobuf";
|
|
2
|
+
import { EmptySchema } from "@bufbuild/protobuf/wkt";
|
|
3
|
+
import {
|
|
4
|
+
Code,
|
|
5
|
+
ConnectError,
|
|
6
|
+
type ServiceImpl,
|
|
7
|
+
} from "@connectrpc/connect";
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
HostedPluginSchema,
|
|
11
|
+
ListPluginRuntimeSessionsResponseSchema,
|
|
12
|
+
PluginRuntimeEgressMode,
|
|
13
|
+
PluginRuntimeHostServiceAccess,
|
|
14
|
+
PluginRuntimeHostServiceBindingSchema,
|
|
15
|
+
PluginRuntimeProvider as PluginRuntimeProviderService,
|
|
16
|
+
PluginRuntimeSessionSchema,
|
|
17
|
+
PluginRuntimeSupportSchema,
|
|
18
|
+
type BindPluginRuntimeHostServiceRequest,
|
|
19
|
+
type GetPluginRuntimeSessionRequest,
|
|
20
|
+
type HostedPlugin,
|
|
21
|
+
type ListPluginRuntimeSessionsRequest,
|
|
22
|
+
type PluginRuntimeHostServiceBinding,
|
|
23
|
+
type PluginRuntimeSession,
|
|
24
|
+
type PluginRuntimeSupport,
|
|
25
|
+
type StartHostedPluginRequest,
|
|
26
|
+
type StartPluginRuntimeSessionRequest,
|
|
27
|
+
type StopPluginRuntimeSessionRequest,
|
|
28
|
+
} from "../gen/v1/pluginruntime_pb.ts";
|
|
29
|
+
import { errorMessage, type MaybePromise } from "./api.ts";
|
|
30
|
+
import { RuntimeProvider, type RuntimeProviderOptions } from "./provider.ts";
|
|
31
|
+
|
|
32
|
+
export type {
|
|
33
|
+
BindPluginRuntimeHostServiceRequest,
|
|
34
|
+
GetPluginRuntimeSessionRequest,
|
|
35
|
+
HostedPlugin,
|
|
36
|
+
ListPluginRuntimeSessionsRequest,
|
|
37
|
+
PluginRuntimeHostServiceBinding,
|
|
38
|
+
PluginRuntimeSession,
|
|
39
|
+
PluginRuntimeSupport,
|
|
40
|
+
StartHostedPluginRequest,
|
|
41
|
+
StartPluginRuntimeSessionRequest,
|
|
42
|
+
StopPluginRuntimeSessionRequest,
|
|
43
|
+
};
|
|
44
|
+
export { PluginRuntimeEgressMode, PluginRuntimeHostServiceAccess };
|
|
45
|
+
|
|
46
|
+
export interface PluginRuntimeProviderOptions extends RuntimeProviderOptions {
|
|
47
|
+
getSupport: () => MaybePromise<MessageInitShape<typeof PluginRuntimeSupportSchema>>;
|
|
48
|
+
startSession: (
|
|
49
|
+
request: StartPluginRuntimeSessionRequest,
|
|
50
|
+
) => MaybePromise<MessageInitShape<typeof PluginRuntimeSessionSchema>>;
|
|
51
|
+
getSession: (
|
|
52
|
+
request: GetPluginRuntimeSessionRequest,
|
|
53
|
+
) => MaybePromise<MessageInitShape<typeof PluginRuntimeSessionSchema>>;
|
|
54
|
+
listSessions: (
|
|
55
|
+
request: ListPluginRuntimeSessionsRequest,
|
|
56
|
+
) => MaybePromise<MessageInitShape<typeof PluginRuntimeSessionSchema>[]>;
|
|
57
|
+
stopSession: (request: StopPluginRuntimeSessionRequest) => MaybePromise<void>;
|
|
58
|
+
bindHostService: (
|
|
59
|
+
request: BindPluginRuntimeHostServiceRequest,
|
|
60
|
+
) => MaybePromise<MessageInitShape<typeof PluginRuntimeHostServiceBindingSchema>>;
|
|
61
|
+
startPlugin: (
|
|
62
|
+
request: StartHostedPluginRequest,
|
|
63
|
+
) => MaybePromise<MessageInitShape<typeof HostedPluginSchema>>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export class PluginRuntimeProvider extends RuntimeProvider {
|
|
67
|
+
readonly kind = "runtime" as const;
|
|
68
|
+
|
|
69
|
+
private readonly getSupportHandler: PluginRuntimeProviderOptions["getSupport"];
|
|
70
|
+
private readonly startSessionHandler: PluginRuntimeProviderOptions["startSession"];
|
|
71
|
+
private readonly getSessionHandler: PluginRuntimeProviderOptions["getSession"];
|
|
72
|
+
private readonly listSessionsHandler: PluginRuntimeProviderOptions["listSessions"];
|
|
73
|
+
private readonly stopSessionHandler: PluginRuntimeProviderOptions["stopSession"];
|
|
74
|
+
private readonly bindHostServiceHandler: PluginRuntimeProviderOptions["bindHostService"];
|
|
75
|
+
private readonly startPluginHandler: PluginRuntimeProviderOptions["startPlugin"];
|
|
76
|
+
|
|
77
|
+
constructor(options: PluginRuntimeProviderOptions) {
|
|
78
|
+
super(options);
|
|
79
|
+
this.getSupportHandler = options.getSupport;
|
|
80
|
+
this.startSessionHandler = options.startSession;
|
|
81
|
+
this.getSessionHandler = options.getSession;
|
|
82
|
+
this.listSessionsHandler = options.listSessions;
|
|
83
|
+
this.stopSessionHandler = options.stopSession;
|
|
84
|
+
this.bindHostServiceHandler = options.bindHostService;
|
|
85
|
+
this.startPluginHandler = options.startPlugin;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async getSupport(): Promise<MessageInitShape<typeof PluginRuntimeSupportSchema>> {
|
|
89
|
+
return await this.getSupportHandler();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async startSession(
|
|
93
|
+
request: StartPluginRuntimeSessionRequest,
|
|
94
|
+
): Promise<MessageInitShape<typeof PluginRuntimeSessionSchema>> {
|
|
95
|
+
return await this.startSessionHandler(request);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async getSession(
|
|
99
|
+
request: GetPluginRuntimeSessionRequest,
|
|
100
|
+
): Promise<MessageInitShape<typeof PluginRuntimeSessionSchema>> {
|
|
101
|
+
return await this.getSessionHandler(request);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async listSessions(
|
|
105
|
+
request: ListPluginRuntimeSessionsRequest,
|
|
106
|
+
): Promise<MessageInitShape<typeof PluginRuntimeSessionSchema>[]> {
|
|
107
|
+
return await this.listSessionsHandler(request);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async stopSession(request: StopPluginRuntimeSessionRequest): Promise<void> {
|
|
111
|
+
await this.stopSessionHandler(request);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async bindHostService(
|
|
115
|
+
request: BindPluginRuntimeHostServiceRequest,
|
|
116
|
+
): Promise<MessageInitShape<typeof PluginRuntimeHostServiceBindingSchema>> {
|
|
117
|
+
return await this.bindHostServiceHandler(request);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async startPlugin(
|
|
121
|
+
request: StartHostedPluginRequest,
|
|
122
|
+
): Promise<MessageInitShape<typeof HostedPluginSchema>> {
|
|
123
|
+
return await this.startPluginHandler(request);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function definePluginRuntimeProvider(
|
|
128
|
+
options: PluginRuntimeProviderOptions,
|
|
129
|
+
): PluginRuntimeProvider {
|
|
130
|
+
return new PluginRuntimeProvider(options);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function isPluginRuntimeProvider(
|
|
134
|
+
value: unknown,
|
|
135
|
+
): value is PluginRuntimeProvider {
|
|
136
|
+
return (
|
|
137
|
+
value instanceof PluginRuntimeProvider ||
|
|
138
|
+
(typeof value === "object" &&
|
|
139
|
+
value !== null &&
|
|
140
|
+
"kind" in value &&
|
|
141
|
+
(value as { kind?: unknown }).kind === "runtime" &&
|
|
142
|
+
"getSupport" in value &&
|
|
143
|
+
"startSession" in value &&
|
|
144
|
+
"startPlugin" in value)
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function createPluginRuntimeProviderService(
|
|
149
|
+
provider: PluginRuntimeProvider,
|
|
150
|
+
): Partial<ServiceImpl<typeof PluginRuntimeProviderService>> {
|
|
151
|
+
return {
|
|
152
|
+
async getSupport() {
|
|
153
|
+
return create(
|
|
154
|
+
PluginRuntimeSupportSchema,
|
|
155
|
+
await invokePluginRuntimeProvider("get support", () =>
|
|
156
|
+
provider.getSupport(),
|
|
157
|
+
),
|
|
158
|
+
);
|
|
159
|
+
},
|
|
160
|
+
async startSession(request) {
|
|
161
|
+
return create(
|
|
162
|
+
PluginRuntimeSessionSchema,
|
|
163
|
+
await invokePluginRuntimeProvider("start session", () =>
|
|
164
|
+
provider.startSession(request),
|
|
165
|
+
),
|
|
166
|
+
);
|
|
167
|
+
},
|
|
168
|
+
async getSession(request) {
|
|
169
|
+
return create(
|
|
170
|
+
PluginRuntimeSessionSchema,
|
|
171
|
+
await invokePluginRuntimeProvider("get session", () =>
|
|
172
|
+
provider.getSession(request),
|
|
173
|
+
),
|
|
174
|
+
);
|
|
175
|
+
},
|
|
176
|
+
async listSessions(request) {
|
|
177
|
+
return create(ListPluginRuntimeSessionsResponseSchema, {
|
|
178
|
+
sessions: await invokePluginRuntimeProvider("list sessions", () =>
|
|
179
|
+
provider.listSessions(request),
|
|
180
|
+
),
|
|
181
|
+
});
|
|
182
|
+
},
|
|
183
|
+
async stopSession(request) {
|
|
184
|
+
await invokePluginRuntimeProvider("stop session", () =>
|
|
185
|
+
provider.stopSession(request),
|
|
186
|
+
);
|
|
187
|
+
return create(EmptySchema);
|
|
188
|
+
},
|
|
189
|
+
async bindHostService(request) {
|
|
190
|
+
return create(
|
|
191
|
+
PluginRuntimeHostServiceBindingSchema,
|
|
192
|
+
await invokePluginRuntimeProvider("bind host service", () =>
|
|
193
|
+
provider.bindHostService(request),
|
|
194
|
+
),
|
|
195
|
+
);
|
|
196
|
+
},
|
|
197
|
+
async startPlugin(request) {
|
|
198
|
+
return create(
|
|
199
|
+
HostedPluginSchema,
|
|
200
|
+
await invokePluginRuntimeProvider("start plugin", () =>
|
|
201
|
+
provider.startPlugin(request),
|
|
202
|
+
),
|
|
203
|
+
);
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
async function invokePluginRuntimeProvider<T>(
|
|
209
|
+
label: string,
|
|
210
|
+
fn: () => MaybePromise<T>,
|
|
211
|
+
): Promise<T> {
|
|
212
|
+
try {
|
|
213
|
+
return await fn();
|
|
214
|
+
} catch (error) {
|
|
215
|
+
throw new ConnectError(
|
|
216
|
+
`plugin runtime provider ${label}: ${errorMessage(error)}`,
|
|
217
|
+
Code.Unknown,
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
package/src/provider-kind.ts
CHANGED
|
@@ -38,12 +38,24 @@ const PROVIDER_KIND_DEFINITIONS = {
|
|
|
38
38
|
defaultExportNames: ["s3", "provider"],
|
|
39
39
|
label: "s3 provider",
|
|
40
40
|
},
|
|
41
|
+
runtime: {
|
|
42
|
+
tokens: ["runtime"],
|
|
43
|
+
formatToken: "runtime",
|
|
44
|
+
defaultExportNames: ["runtime", "provider"],
|
|
45
|
+
label: "runtime provider",
|
|
46
|
+
},
|
|
41
47
|
workflow: {
|
|
42
48
|
tokens: ["workflow"],
|
|
43
49
|
formatToken: "workflow",
|
|
44
50
|
defaultExportNames: ["workflow", "provider"],
|
|
45
51
|
label: "workflow provider",
|
|
46
52
|
},
|
|
53
|
+
agent: {
|
|
54
|
+
tokens: ["agent"],
|
|
55
|
+
formatToken: "agent",
|
|
56
|
+
defaultExportNames: ["agent", "provider"],
|
|
57
|
+
label: "agent provider",
|
|
58
|
+
},
|
|
47
59
|
telemetry: {
|
|
48
60
|
tokens: ["telemetry"],
|
|
49
61
|
formatToken: "telemetry",
|
package/src/provider.ts
CHANGED
|
@@ -9,7 +9,9 @@ export type ProviderKind =
|
|
|
9
9
|
| "cache"
|
|
10
10
|
| "secrets"
|
|
11
11
|
| "s3"
|
|
12
|
+
| "runtime"
|
|
12
13
|
| "workflow"
|
|
14
|
+
| "agent"
|
|
13
15
|
| "telemetry";
|
|
14
16
|
|
|
15
17
|
/**
|
|
@@ -41,6 +43,12 @@ export type HealthCheckHandler = () => MaybePromise<void>;
|
|
|
41
43
|
*/
|
|
42
44
|
export type WarningsHandler = () => MaybePromise<string[]>;
|
|
43
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Optional hook invoked after configuration when the host is ready for
|
|
48
|
+
* provider-owned background work to begin.
|
|
49
|
+
*/
|
|
50
|
+
export type StartHandler = () => MaybePromise<void>;
|
|
51
|
+
|
|
44
52
|
/**
|
|
45
53
|
* Optional shutdown hook invoked when the provider process exits.
|
|
46
54
|
*/
|
|
@@ -57,6 +65,7 @@ export interface RuntimeProviderOptions {
|
|
|
57
65
|
configure?: ConfigureHandler;
|
|
58
66
|
healthCheck?: HealthCheckHandler;
|
|
59
67
|
warnings?: string[] | WarningsHandler;
|
|
68
|
+
start?: StartHandler;
|
|
60
69
|
close?: CloseHandler;
|
|
61
70
|
}
|
|
62
71
|
|
|
@@ -74,6 +83,7 @@ export abstract class RuntimeProvider {
|
|
|
74
83
|
private readonly configureHandler: ConfigureHandler | undefined;
|
|
75
84
|
private readonly healthCheckHandler: HealthCheckHandler | undefined;
|
|
76
85
|
private readonly warningsSource: string[] | WarningsHandler | undefined;
|
|
86
|
+
private readonly startHandler: StartHandler | undefined;
|
|
77
87
|
private readonly closeHandler: CloseHandler | undefined;
|
|
78
88
|
|
|
79
89
|
protected constructor(options: RuntimeProviderOptions) {
|
|
@@ -86,6 +96,7 @@ export abstract class RuntimeProvider {
|
|
|
86
96
|
this.warningsSource = Array.isArray(options.warnings)
|
|
87
97
|
? [...options.warnings]
|
|
88
98
|
: options.warnings;
|
|
99
|
+
this.startHandler = options.start;
|
|
89
100
|
this.closeHandler = options.close;
|
|
90
101
|
}
|
|
91
102
|
|
|
@@ -126,6 +137,10 @@ export abstract class RuntimeProvider {
|
|
|
126
137
|
await this.healthCheckHandler?.();
|
|
127
138
|
}
|
|
128
139
|
|
|
140
|
+
async startProvider(): Promise<void> {
|
|
141
|
+
await this.startHandler?.();
|
|
142
|
+
}
|
|
143
|
+
|
|
129
144
|
async warnings(): Promise<string[]> {
|
|
130
145
|
if (!this.warningsSource) {
|
|
131
146
|
return [];
|
|
@@ -151,7 +166,19 @@ export function isRuntimeProvider(value: unknown): value is RuntimeProvider {
|
|
|
151
166
|
value !== null &&
|
|
152
167
|
"kind" in value &&
|
|
153
168
|
"resolveName" in value &&
|
|
154
|
-
"
|
|
169
|
+
typeof (value as { resolveName?: unknown }).resolveName === "function" &&
|
|
170
|
+
"configureProvider" in value &&
|
|
171
|
+
typeof (value as { configureProvider?: unknown }).configureProvider === "function" &&
|
|
172
|
+
"supportsHealthCheck" in value &&
|
|
173
|
+
typeof (value as { supportsHealthCheck?: unknown }).supportsHealthCheck === "function" &&
|
|
174
|
+
"healthCheck" in value &&
|
|
175
|
+
typeof (value as { healthCheck?: unknown }).healthCheck === "function" &&
|
|
176
|
+
"startProvider" in value &&
|
|
177
|
+
typeof (value as { startProvider?: unknown }).startProvider === "function" &&
|
|
178
|
+
"warnings" in value &&
|
|
179
|
+
typeof (value as { warnings?: unknown }).warnings === "function" &&
|
|
180
|
+
"closeProvider" in value &&
|
|
181
|
+
typeof (value as { closeProvider?: unknown }).closeProvider === "function")
|
|
155
182
|
);
|
|
156
183
|
}
|
|
157
184
|
|