@valon-technologies/gestalt 0.0.1-alpha.13 → 0.0.1-alpha.16
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/gen/google/rpc/status_pb.ts +76 -0
- package/gen/v1/agent_pb.ts +561 -65
- package/gen/v1/datastore_pb.ts +457 -2
- package/gen/v1/plugin_pb.ts +31 -14
- package/gen/v1/pluginruntime_pb.ts +120 -81
- package/gen/v1/runtime_pb.ts +29 -1
- package/gen/v1/s3_pb.ts +101 -1
- package/gen/v1/workflow_pb.ts +644 -58
- package/package.json +5 -3
- package/src/agent.ts +168 -15
- package/src/api.ts +4 -1
- package/src/build.ts +2 -0
- package/src/index.ts +69 -18
- package/src/indexeddb.ts +481 -1
- package/src/invoker.ts +3 -0
- package/src/plugin.ts +3 -184
- package/src/pluginruntime.ts +220 -0
- package/src/provider-kind.ts +6 -0
- package/src/provider.ts +16 -0
- package/src/runtime-log-host.ts +244 -0
- package/src/runtime.ts +46 -26
- package/src/s3.ts +81 -0
- package/src/telemetry.ts +429 -0
- package/src/workflow-manager.ts +11 -0
- package/src/manifest-metadata.ts +0 -107
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,
|
|
@@ -46,7 +37,7 @@ export type ConnectionMode =
|
|
|
46
37
|
| "unspecified"
|
|
47
38
|
| "none"
|
|
48
39
|
| "user"
|
|
49
|
-
| "
|
|
40
|
+
| "platform";
|
|
50
41
|
|
|
51
42
|
/**
|
|
52
43
|
* Metadata for a single connection parameter exposed by a provider.
|
|
@@ -131,8 +122,6 @@ export interface PluginDefinitionOptions extends RuntimeProviderOptions {
|
|
|
131
122
|
connectionMode?: ConnectionMode;
|
|
132
123
|
authTypes?: string[];
|
|
133
124
|
connectionParams?: Record<string, ConnectionParamDefinition>;
|
|
134
|
-
securitySchemes?: Record<string, HTTPSecurityScheme>;
|
|
135
|
-
http?: Record<string, HTTPBinding>;
|
|
136
125
|
resolveHTTPSubject?: HTTPSubjectResolver;
|
|
137
126
|
postConnect?: PostConnectHandler;
|
|
138
127
|
iconSvg?: string;
|
|
@@ -187,8 +176,6 @@ export class PluginProvider extends RuntimeProvider {
|
|
|
187
176
|
readonly connectionMode: ConnectionMode;
|
|
188
177
|
readonly authTypes: string[];
|
|
189
178
|
readonly connectionParams: Record<string, ConnectionParamDefinition>;
|
|
190
|
-
readonly securitySchemes: Record<string, HTTPSecurityScheme>;
|
|
191
|
-
readonly http: Record<string, HTTPBinding>;
|
|
192
179
|
|
|
193
180
|
private readonly sessionCatalogHandler: SessionCatalogHandler | undefined;
|
|
194
181
|
private readonly httpSubjectResolver: HTTPSubjectResolver | undefined;
|
|
@@ -201,8 +188,6 @@ export class PluginProvider extends RuntimeProvider {
|
|
|
201
188
|
this.connectionMode = options.connectionMode ?? "unspecified";
|
|
202
189
|
this.authTypes = [...(options.authTypes ?? [])];
|
|
203
190
|
this.connectionParams = normalizeConnectionParams(options.connectionParams);
|
|
204
|
-
this.securitySchemes = normalizeHTTPSecuritySchemes(options.securitySchemes);
|
|
205
|
-
this.http = normalizeHTTPBindings(options.http);
|
|
206
191
|
this.httpSubjectResolver = options.resolveHTTPSubject;
|
|
207
192
|
this.postConnectHandler = options.postConnect;
|
|
208
193
|
this.sessionCatalogHandler = options.sessionCatalog;
|
|
@@ -346,38 +331,6 @@ export class PluginProvider extends RuntimeProvider {
|
|
|
346
331
|
return catalogToJson(this.staticCatalog());
|
|
347
332
|
}
|
|
348
333
|
|
|
349
|
-
/**
|
|
350
|
-
* Returns generated manifest-backed HTTP/security metadata for the provider.
|
|
351
|
-
*/
|
|
352
|
-
staticManifestMetadata(): PluginManifestMetadata {
|
|
353
|
-
const metadata: PluginManifestMetadata = {};
|
|
354
|
-
if (Object.keys(this.securitySchemes).length > 0) {
|
|
355
|
-
metadata.securitySchemes = cloneHTTPSecuritySchemes(this.securitySchemes);
|
|
356
|
-
}
|
|
357
|
-
if (Object.keys(this.http).length > 0) {
|
|
358
|
-
metadata.http = cloneHTTPBindings(this.http);
|
|
359
|
-
}
|
|
360
|
-
return metadata;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Reports whether the provider emits manifest metadata in addition to catalog metadata.
|
|
365
|
-
*/
|
|
366
|
-
supportsManifestMetadata(): boolean {
|
|
367
|
-
return hasPluginManifestMetadata(this.staticManifestMetadata());
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* Writes generated manifest metadata to disk as YAML.
|
|
372
|
-
*/
|
|
373
|
-
writeManifestMetadata(path: string): void {
|
|
374
|
-
const metadata = this.staticManifestMetadata();
|
|
375
|
-
if (!hasPluginManifestMetadata(metadata)) {
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
writeManifestMetadataYaml(path, metadata);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
334
|
/**
|
|
382
335
|
* Executes an operation against validated input and request metadata.
|
|
383
336
|
*/
|
|
@@ -448,10 +401,6 @@ export function isPluginProvider(
|
|
|
448
401
|
typeof (value as { supportsSessionCatalog?: unknown }).supportsSessionCatalog === "function" &&
|
|
449
402
|
"catalogForRequest" in value &&
|
|
450
403
|
typeof (value as { catalogForRequest?: unknown }).catalogForRequest === "function" &&
|
|
451
|
-
"supportsManifestMetadata" in value &&
|
|
452
|
-
typeof (value as { supportsManifestMetadata?: unknown }).supportsManifestMetadata === "function" &&
|
|
453
|
-
"writeManifestMetadata" in value &&
|
|
454
|
-
typeof (value as { writeManifestMetadata?: unknown }).writeManifestMetadata === "function" &&
|
|
455
404
|
"supportsPostConnect" in value &&
|
|
456
405
|
typeof (value as { supportsPostConnect?: unknown }).supportsPostConnect === "function" &&
|
|
457
406
|
"postConnectMetadata" in value &&
|
|
@@ -502,136 +451,6 @@ function cloneConnectedToken(token: ConnectedToken): ConnectedToken {
|
|
|
502
451
|
};
|
|
503
452
|
}
|
|
504
453
|
|
|
505
|
-
function normalizeHTTPSecuritySchemes(
|
|
506
|
-
input: Record<string, HTTPSecurityScheme> | undefined,
|
|
507
|
-
): Record<string, HTTPSecurityScheme> {
|
|
508
|
-
const output: Record<string, HTTPSecurityScheme> = {};
|
|
509
|
-
for (const [key, value] of Object.entries(input ?? {})) {
|
|
510
|
-
output[key] = cloneHTTPSecurityScheme(value);
|
|
511
|
-
}
|
|
512
|
-
return output;
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
function cloneHTTPSecuritySchemes(
|
|
516
|
-
input: Record<string, HTTPSecurityScheme>,
|
|
517
|
-
): Record<string, HTTPSecurityScheme> {
|
|
518
|
-
const output: Record<string, HTTPSecurityScheme> = {};
|
|
519
|
-
for (const [key, value] of Object.entries(input)) {
|
|
520
|
-
output[key] = cloneHTTPSecurityScheme(value);
|
|
521
|
-
}
|
|
522
|
-
return output;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
function cloneHTTPSecurityScheme(value: HTTPSecurityScheme): HTTPSecurityScheme {
|
|
526
|
-
const output: HTTPSecurityScheme = {};
|
|
527
|
-
if (value.type !== undefined) {
|
|
528
|
-
output.type = value.type;
|
|
529
|
-
}
|
|
530
|
-
if (value.description !== undefined) {
|
|
531
|
-
output.description = value.description;
|
|
532
|
-
}
|
|
533
|
-
if (value.signatureHeader !== undefined) {
|
|
534
|
-
output.signatureHeader = value.signatureHeader;
|
|
535
|
-
}
|
|
536
|
-
if (value.signaturePrefix !== undefined) {
|
|
537
|
-
output.signaturePrefix = value.signaturePrefix;
|
|
538
|
-
}
|
|
539
|
-
if (value.payloadTemplate !== undefined) {
|
|
540
|
-
output.payloadTemplate = value.payloadTemplate;
|
|
541
|
-
}
|
|
542
|
-
if (value.timestampHeader !== undefined) {
|
|
543
|
-
output.timestampHeader = value.timestampHeader;
|
|
544
|
-
}
|
|
545
|
-
if (value.maxAgeSeconds !== undefined) {
|
|
546
|
-
output.maxAgeSeconds = value.maxAgeSeconds;
|
|
547
|
-
}
|
|
548
|
-
if (value.name !== undefined) {
|
|
549
|
-
output.name = value.name;
|
|
550
|
-
}
|
|
551
|
-
if (value.in !== undefined) {
|
|
552
|
-
output.in = value.in;
|
|
553
|
-
}
|
|
554
|
-
if (value.scheme !== undefined) {
|
|
555
|
-
output.scheme = value.scheme;
|
|
556
|
-
}
|
|
557
|
-
if (value.secret) {
|
|
558
|
-
output.secret = {
|
|
559
|
-
...value.secret,
|
|
560
|
-
};
|
|
561
|
-
}
|
|
562
|
-
return output;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
function normalizeHTTPBindings(
|
|
566
|
-
input: Record<string, HTTPBinding> | undefined,
|
|
567
|
-
): Record<string, HTTPBinding> {
|
|
568
|
-
const output: Record<string, HTTPBinding> = {};
|
|
569
|
-
for (const [key, value] of Object.entries(input ?? {})) {
|
|
570
|
-
output[key] = cloneHTTPBinding(value);
|
|
571
|
-
}
|
|
572
|
-
return output;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
function cloneHTTPBindings(
|
|
576
|
-
input: Record<string, HTTPBinding>,
|
|
577
|
-
): Record<string, HTTPBinding> {
|
|
578
|
-
const output: Record<string, HTTPBinding> = {};
|
|
579
|
-
for (const [key, value] of Object.entries(input)) {
|
|
580
|
-
output[key] = cloneHTTPBinding(value);
|
|
581
|
-
}
|
|
582
|
-
return output;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
function cloneHTTPBinding(value: HTTPBinding): HTTPBinding {
|
|
586
|
-
const output: HTTPBinding = {
|
|
587
|
-
path: value.path,
|
|
588
|
-
method: value.method,
|
|
589
|
-
security: value.security,
|
|
590
|
-
target: value.target,
|
|
591
|
-
};
|
|
592
|
-
if (value.requestBody) {
|
|
593
|
-
output.requestBody = cloneHTTPRequestBody(value.requestBody);
|
|
594
|
-
}
|
|
595
|
-
if (value.ack) {
|
|
596
|
-
output.ack = cloneHTTPAck(value.ack);
|
|
597
|
-
}
|
|
598
|
-
return output;
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
function cloneHTTPRequestBody(value: HTTPRequestBody): HTTPRequestBody {
|
|
602
|
-
const output: HTTPRequestBody = {};
|
|
603
|
-
if (value.required !== undefined) {
|
|
604
|
-
output.required = value.required;
|
|
605
|
-
}
|
|
606
|
-
if (value.content) {
|
|
607
|
-
output.content = {};
|
|
608
|
-
for (const key of Object.keys(value.content)) {
|
|
609
|
-
output.content[key] = {};
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
return output;
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
function cloneHTTPAck(value: HTTPAck): HTTPAck {
|
|
616
|
-
const output: HTTPAck = {};
|
|
617
|
-
if (value.status !== undefined) {
|
|
618
|
-
output.status = value.status;
|
|
619
|
-
}
|
|
620
|
-
if (value.headers) {
|
|
621
|
-
output.headers = {
|
|
622
|
-
...value.headers,
|
|
623
|
-
};
|
|
624
|
-
}
|
|
625
|
-
if (value.body !== undefined) {
|
|
626
|
-
output.body = cloneHTTPBodyValue(value.body);
|
|
627
|
-
}
|
|
628
|
-
return output;
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
function cloneHTTPBodyValue<T>(value: T): T {
|
|
632
|
-
return structuredClone(value);
|
|
633
|
-
}
|
|
634
|
-
|
|
635
454
|
function isResponse(value: unknown): value is Response<unknown> {
|
|
636
455
|
if (typeof value !== "object" || value === null) {
|
|
637
456
|
return false;
|
|
@@ -696,8 +515,8 @@ export function connectionModeToProtoValue(mode: ConnectionMode): number {
|
|
|
696
515
|
return 1;
|
|
697
516
|
case "user":
|
|
698
517
|
return 2;
|
|
699
|
-
case "
|
|
700
|
-
return
|
|
518
|
+
case "platform":
|
|
519
|
+
return 5;
|
|
701
520
|
case "unspecified":
|
|
702
521
|
default:
|
|
703
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,6 +38,12 @@ 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",
|
package/src/provider.ts
CHANGED
|
@@ -9,6 +9,7 @@ export type ProviderKind =
|
|
|
9
9
|
| "cache"
|
|
10
10
|
| "secrets"
|
|
11
11
|
| "s3"
|
|
12
|
+
| "runtime"
|
|
12
13
|
| "workflow"
|
|
13
14
|
| "agent"
|
|
14
15
|
| "telemetry";
|
|
@@ -42,6 +43,12 @@ export type HealthCheckHandler = () => MaybePromise<void>;
|
|
|
42
43
|
*/
|
|
43
44
|
export type WarningsHandler = () => MaybePromise<string[]>;
|
|
44
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
|
+
|
|
45
52
|
/**
|
|
46
53
|
* Optional shutdown hook invoked when the provider process exits.
|
|
47
54
|
*/
|
|
@@ -58,6 +65,7 @@ export interface RuntimeProviderOptions {
|
|
|
58
65
|
configure?: ConfigureHandler;
|
|
59
66
|
healthCheck?: HealthCheckHandler;
|
|
60
67
|
warnings?: string[] | WarningsHandler;
|
|
68
|
+
start?: StartHandler;
|
|
61
69
|
close?: CloseHandler;
|
|
62
70
|
}
|
|
63
71
|
|
|
@@ -75,6 +83,7 @@ export abstract class RuntimeProvider {
|
|
|
75
83
|
private readonly configureHandler: ConfigureHandler | undefined;
|
|
76
84
|
private readonly healthCheckHandler: HealthCheckHandler | undefined;
|
|
77
85
|
private readonly warningsSource: string[] | WarningsHandler | undefined;
|
|
86
|
+
private readonly startHandler: StartHandler | undefined;
|
|
78
87
|
private readonly closeHandler: CloseHandler | undefined;
|
|
79
88
|
|
|
80
89
|
protected constructor(options: RuntimeProviderOptions) {
|
|
@@ -87,6 +96,7 @@ export abstract class RuntimeProvider {
|
|
|
87
96
|
this.warningsSource = Array.isArray(options.warnings)
|
|
88
97
|
? [...options.warnings]
|
|
89
98
|
: options.warnings;
|
|
99
|
+
this.startHandler = options.start;
|
|
90
100
|
this.closeHandler = options.close;
|
|
91
101
|
}
|
|
92
102
|
|
|
@@ -127,6 +137,10 @@ export abstract class RuntimeProvider {
|
|
|
127
137
|
await this.healthCheckHandler?.();
|
|
128
138
|
}
|
|
129
139
|
|
|
140
|
+
async startProvider(): Promise<void> {
|
|
141
|
+
await this.startHandler?.();
|
|
142
|
+
}
|
|
143
|
+
|
|
130
144
|
async warnings(): Promise<string[]> {
|
|
131
145
|
if (!this.warningsSource) {
|
|
132
146
|
return [];
|
|
@@ -159,6 +173,8 @@ export function isRuntimeProvider(value: unknown): value is RuntimeProvider {
|
|
|
159
173
|
typeof (value as { supportsHealthCheck?: unknown }).supportsHealthCheck === "function" &&
|
|
160
174
|
"healthCheck" in value &&
|
|
161
175
|
typeof (value as { healthCheck?: unknown }).healthCheck === "function" &&
|
|
176
|
+
"startProvider" in value &&
|
|
177
|
+
typeof (value as { startProvider?: unknown }).startProvider === "function" &&
|
|
162
178
|
"warnings" in value &&
|
|
163
179
|
typeof (value as { warnings?: unknown }).warnings === "function" &&
|
|
164
180
|
"closeProvider" in value &&
|