@valon-technologies/gestalt 0.0.1-alpha.18 → 0.0.1-alpha.20
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 +34 -12
- package/package.json +5 -3
- package/src/agent-conversions.ts +201 -0
- package/src/agent-manager.ts +272 -83
- package/src/agent.ts +1023 -224
- package/src/api.ts +42 -0
- package/src/auth.ts +3 -3
- package/src/authorization.ts +1700 -51
- package/src/cache.ts +3 -3
- package/src/catalog.ts +22 -0
- package/src/http-subject.ts +9 -2
- package/src/index.ts +191 -17
- package/src/indexeddb.ts +3 -15
- package/src/internal/gen/v1/agent_pb.ts +137 -51
- package/src/internal/gen/v1/authorization_pb.ts +505 -27
- package/src/internal/gen/v1/plugin_pb.ts +67 -21
- package/src/internal/gen/v1/pluginruntime_pb.ts +95 -6
- package/src/internal/gen/v1/workflow_pb.ts +344 -62
- package/src/invoker.ts +6 -35
- package/src/plugin.ts +12 -12
- package/src/pluginruntime.ts +337 -49
- package/src/protocol/v1.ts +19 -0
- package/src/protocol-internal.ts +19 -0
- package/src/protocol.ts +186 -0
- package/src/provider-kind.ts +7 -3
- package/src/provider.ts +21 -13
- package/src/runtime-log-host.ts +80 -52
- package/src/runtime.ts +67 -0
- package/src/s3.ts +13 -28
- package/src/secrets.ts +3 -3
- package/src/workflow-manager.ts +350 -121
- package/src/workflow.ts +2598 -389
package/src/invoker.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { JsonObject, JsonValue } from "@bufbuild/protobuf";
|
|
2
1
|
import { createClient, type Client, type Interceptor } from "@connectrpc/connect";
|
|
3
2
|
import { createGrpcTransport } from "@connectrpc/connect-node";
|
|
4
3
|
|
|
5
4
|
import { PluginInvoker as PluginInvokerService } from "./internal/gen/v1/plugin_pb.ts";
|
|
6
5
|
import type { OperationResult, Request } from "./api.ts";
|
|
6
|
+
import { structFromObject, type JsonObjectInput } from "./protocol.ts";
|
|
7
7
|
|
|
8
8
|
/** Environment variable containing the plugin-invoker host-service target. */
|
|
9
9
|
export const ENV_PLUGIN_INVOKER_SOCKET = "GESTALT_PLUGIN_INVOKER_SOCKET";
|
|
@@ -37,7 +37,7 @@ export interface PluginInvocationGrant {
|
|
|
37
37
|
/** Options for invoking a plugin GraphQL surface. */
|
|
38
38
|
export interface PluginGraphQLInvokeOptions extends PluginInvokeOptions {
|
|
39
39
|
/** GraphQL variables encoded as a JSON object. */
|
|
40
|
-
variables?:
|
|
40
|
+
variables?: JsonObjectInput;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
@@ -72,14 +72,14 @@ export class PluginInvoker {
|
|
|
72
72
|
async invoke(
|
|
73
73
|
plugin: string,
|
|
74
74
|
operation: string,
|
|
75
|
-
params:
|
|
75
|
+
params: JsonObjectInput = {},
|
|
76
76
|
options?: PluginInvokeOptions,
|
|
77
77
|
): Promise<OperationResult> {
|
|
78
78
|
const response = await this.client.invoke({
|
|
79
79
|
invocationToken: this.invocationToken,
|
|
80
80
|
plugin,
|
|
81
81
|
operation,
|
|
82
|
-
params:
|
|
82
|
+
params: structFromObject(params),
|
|
83
83
|
connection: options?.connection ?? "",
|
|
84
84
|
instance: options?.instance ?? "",
|
|
85
85
|
idempotencyKey: options?.idempotencyKey?.trim() ?? "",
|
|
@@ -105,8 +105,8 @@ export class PluginInvoker {
|
|
|
105
105
|
invocationToken: this.invocationToken,
|
|
106
106
|
plugin,
|
|
107
107
|
document: trimmedDocument,
|
|
108
|
-
...(options?.variables
|
|
109
|
-
? { variables:
|
|
108
|
+
...(options?.variables !== undefined
|
|
109
|
+
? { variables: structFromObject(options.variables) }
|
|
110
110
|
: {}),
|
|
111
111
|
connection: options?.connection ?? "",
|
|
112
112
|
instance: options?.instance ?? "",
|
|
@@ -199,32 +199,3 @@ function normalizeInvocationToken(requestOrToken: Request | string): string {
|
|
|
199
199
|
}
|
|
200
200
|
return trimmed;
|
|
201
201
|
}
|
|
202
|
-
|
|
203
|
-
function toJsonObject(params: Record<string, unknown>): JsonObject {
|
|
204
|
-
const output: JsonObject = {};
|
|
205
|
-
for (const [key, value] of Object.entries(params ?? {})) {
|
|
206
|
-
if (value === undefined) {
|
|
207
|
-
continue;
|
|
208
|
-
}
|
|
209
|
-
output[key] = toJsonValue(value);
|
|
210
|
-
}
|
|
211
|
-
return output;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function toJsonValue(value: unknown): JsonValue {
|
|
215
|
-
if (
|
|
216
|
-
value === null ||
|
|
217
|
-
typeof value === "string" ||
|
|
218
|
-
typeof value === "number" ||
|
|
219
|
-
typeof value === "boolean"
|
|
220
|
-
) {
|
|
221
|
-
return value as JsonValue;
|
|
222
|
-
}
|
|
223
|
-
if (Array.isArray(value)) {
|
|
224
|
-
return value.map((entry) => toJsonValue(entry));
|
|
225
|
-
}
|
|
226
|
-
if (typeof value === "object") {
|
|
227
|
-
return toJsonObject(value as Record<string, unknown>);
|
|
228
|
-
}
|
|
229
|
-
throw new Error("plugin invoker: params must be JSON-serializable");
|
|
230
|
-
}
|
package/src/plugin.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
type Request,
|
|
15
15
|
responseBrand,
|
|
16
16
|
type Response,
|
|
17
|
-
type
|
|
17
|
+
type SubjectInput,
|
|
18
18
|
} from "./api.ts";
|
|
19
19
|
import {
|
|
20
20
|
cloneHTTPSubjectRequest,
|
|
@@ -24,9 +24,9 @@ import {
|
|
|
24
24
|
type HTTPSubjectResolver,
|
|
25
25
|
} from "./http-subject.ts";
|
|
26
26
|
import {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
type
|
|
27
|
+
isProviderBase,
|
|
28
|
+
ProviderBase,
|
|
29
|
+
type ProviderBaseOptions,
|
|
30
30
|
} from "./provider.ts";
|
|
31
31
|
import type { Schema } from "./schema.ts";
|
|
32
32
|
|
|
@@ -36,8 +36,8 @@ import type { Schema } from "./schema.ts";
|
|
|
36
36
|
export type ConnectionMode =
|
|
37
37
|
| "unspecified"
|
|
38
38
|
| "none"
|
|
39
|
-
| "
|
|
40
|
-
| "
|
|
39
|
+
| "subject"
|
|
40
|
+
| "user";
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* Metadata for a single connection parameter exposed by a provider.
|
|
@@ -118,7 +118,7 @@ export type PostConnectHandler = (
|
|
|
118
118
|
/**
|
|
119
119
|
* Runtime hooks required to implement a plugin provider.
|
|
120
120
|
*/
|
|
121
|
-
export interface PluginDefinitionOptions extends
|
|
121
|
+
export interface PluginDefinitionOptions extends ProviderBaseOptions {
|
|
122
122
|
connectionMode?: ConnectionMode;
|
|
123
123
|
authTypes?: string[];
|
|
124
124
|
connectionParams?: Record<string, ConnectionParamDefinition>;
|
|
@@ -170,7 +170,7 @@ export function operation<In, Out>(
|
|
|
170
170
|
* });
|
|
171
171
|
* ```
|
|
172
172
|
*/
|
|
173
|
-
export class PluginProvider extends
|
|
173
|
+
export class PluginProvider extends ProviderBase {
|
|
174
174
|
readonly kind = "integration" as const;
|
|
175
175
|
readonly iconSvg: string;
|
|
176
176
|
readonly connectionMode: ConnectionMode;
|
|
@@ -243,7 +243,7 @@ export class PluginProvider extends RuntimeProvider {
|
|
|
243
243
|
async resolveHTTPSubject(
|
|
244
244
|
request: HTTPSubjectRequest,
|
|
245
245
|
context: HTTPSubjectResolutionContext,
|
|
246
|
-
): Promise<
|
|
246
|
+
): Promise<SubjectInput | null | undefined> {
|
|
247
247
|
return await this.httpSubjectResolver?.(
|
|
248
248
|
cloneHTTPSubjectRequest(request),
|
|
249
249
|
cloneHTTPSubjectResolutionContext(context),
|
|
@@ -390,7 +390,7 @@ export function isPluginProvider(
|
|
|
390
390
|
): value is PluginProvider {
|
|
391
391
|
return (
|
|
392
392
|
value instanceof PluginProvider ||
|
|
393
|
-
(
|
|
393
|
+
(isProviderBase(value) &&
|
|
394
394
|
"kind" in value &&
|
|
395
395
|
(value as { kind?: unknown }).kind === "integration" &&
|
|
396
396
|
"staticCatalog" in value &&
|
|
@@ -513,10 +513,10 @@ export function connectionModeToProtoValue(mode: ConnectionMode): number {
|
|
|
513
513
|
switch (mode) {
|
|
514
514
|
case "none":
|
|
515
515
|
return 1;
|
|
516
|
+
case "subject":
|
|
517
|
+
return 2;
|
|
516
518
|
case "user":
|
|
517
519
|
return 2;
|
|
518
|
-
case "platform":
|
|
519
|
-
return 5;
|
|
520
520
|
case "unspecified":
|
|
521
521
|
default:
|
|
522
522
|
return 0;
|
package/src/pluginruntime.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { create
|
|
1
|
+
import { create } from "@bufbuild/protobuf";
|
|
2
2
|
import { EmptySchema } from "@bufbuild/protobuf/wkt";
|
|
3
3
|
import {
|
|
4
4
|
Code,
|
|
@@ -9,52 +9,155 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
HostedPluginSchema,
|
|
11
11
|
ListPluginRuntimeSessionsResponseSchema,
|
|
12
|
-
|
|
12
|
+
PreparePluginRuntimeWorkspaceResponseSchema,
|
|
13
|
+
PluginRuntimeEgressMode as ProtoPluginRuntimeEgressMode,
|
|
13
14
|
PluginRuntimeProvider as PluginRuntimeProviderService,
|
|
14
15
|
PluginRuntimeSessionSchema,
|
|
15
16
|
PluginRuntimeSupportSchema,
|
|
16
|
-
type GetPluginRuntimeSessionRequest,
|
|
17
|
-
type
|
|
18
|
-
type
|
|
19
|
-
type
|
|
20
|
-
type
|
|
21
|
-
type
|
|
22
|
-
type
|
|
23
|
-
type StopPluginRuntimeSessionRequest,
|
|
17
|
+
type GetPluginRuntimeSessionRequest as ProtoGetPluginRuntimeSessionRequest,
|
|
18
|
+
type ListPluginRuntimeSessionsRequest as ProtoListPluginRuntimeSessionsRequest,
|
|
19
|
+
type PreparePluginRuntimeWorkspaceRequest as ProtoPreparePluginRuntimeWorkspaceRequest,
|
|
20
|
+
type RemovePluginRuntimeWorkspaceRequest as ProtoRemovePluginRuntimeWorkspaceRequest,
|
|
21
|
+
type StartHostedPluginRequest as ProtoStartHostedPluginRequest,
|
|
22
|
+
type StartPluginRuntimeSessionRequest as ProtoStartPluginRuntimeSessionRequest,
|
|
23
|
+
type StopPluginRuntimeSessionRequest as ProtoStopPluginRuntimeSessionRequest,
|
|
24
24
|
} from "./internal/gen/v1/pluginruntime_pb.ts";
|
|
25
|
+
import {
|
|
26
|
+
timestampFromDate,
|
|
27
|
+
} from "./protocol.ts";
|
|
25
28
|
import { errorMessage, type MaybePromise } from "./api.ts";
|
|
26
|
-
import {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
29
|
+
import { ProviderBase, type ProviderBaseOptions } from "./provider.ts";
|
|
30
|
+
|
|
31
|
+
type PluginRuntimeProviderServiceImpl = Partial<
|
|
32
|
+
ServiceImpl<typeof PluginRuntimeProviderService>
|
|
33
|
+
>;
|
|
34
|
+
|
|
35
|
+
/** Native egress-mode constants for authored plugin runtime providers. */
|
|
36
|
+
export const PluginRuntimeEgressMode = {
|
|
37
|
+
UNSPECIFIED: ProtoPluginRuntimeEgressMode.UNSPECIFIED,
|
|
38
|
+
NONE: ProtoPluginRuntimeEgressMode.NONE,
|
|
39
|
+
CIDR: ProtoPluginRuntimeEgressMode.CIDR,
|
|
40
|
+
HOSTNAME: ProtoPluginRuntimeEgressMode.HOSTNAME,
|
|
41
|
+
} as const;
|
|
42
|
+
export type PluginRuntimeEgressMode =
|
|
43
|
+
(typeof PluginRuntimeEgressMode)[keyof typeof PluginRuntimeEgressMode];
|
|
44
|
+
|
|
45
|
+
export interface PluginRuntimeSupport {
|
|
46
|
+
canHostPlugins?: boolean | undefined;
|
|
47
|
+
egressMode?: PluginRuntimeEgressMode | undefined;
|
|
48
|
+
supportsPrepareWorkspace?: boolean | undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface PluginRuntimeSessionLifecycle {
|
|
52
|
+
startedAt?: Date | undefined;
|
|
53
|
+
recommendedDrainAt?: Date | undefined;
|
|
54
|
+
expiresAt?: Date | undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface PluginRuntimeSession {
|
|
58
|
+
id?: string | undefined;
|
|
59
|
+
state?: string | undefined;
|
|
60
|
+
metadata?: Record<string, string> | undefined;
|
|
61
|
+
lifecycle?: PluginRuntimeSessionLifecycle | undefined;
|
|
62
|
+
stateReason?: string | undefined;
|
|
63
|
+
stateMessage?: string | undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface PluginRuntimeImagePullAuth {
|
|
67
|
+
dockerConfigJson?: string | undefined;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface StartPluginRuntimeSessionRequest {
|
|
71
|
+
pluginName: string;
|
|
72
|
+
template?: string | undefined;
|
|
73
|
+
image?: string | undefined;
|
|
74
|
+
metadata?: Record<string, string> | undefined;
|
|
75
|
+
imagePullAuth?: PluginRuntimeImagePullAuth | undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface GetPluginRuntimeSessionRequest {
|
|
79
|
+
sessionId: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface ListPluginRuntimeSessionsRequest {}
|
|
83
|
+
|
|
84
|
+
export interface StopPluginRuntimeSessionRequest {
|
|
85
|
+
sessionId: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface PluginRuntimeAgentWorkspaceGitCheckout {
|
|
89
|
+
url?: string | undefined;
|
|
90
|
+
ref?: string | undefined;
|
|
91
|
+
path?: string | undefined;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface PluginRuntimeAgentWorkspace {
|
|
95
|
+
checkouts?: readonly PluginRuntimeAgentWorkspaceGitCheckout[] | undefined;
|
|
96
|
+
cwd?: string | undefined;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface PluginRuntimePreparedAgentWorkspace {
|
|
100
|
+
root?: string | undefined;
|
|
101
|
+
cwd?: string | undefined;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface PreparePluginRuntimeWorkspaceRequest {
|
|
105
|
+
sessionId: string;
|
|
106
|
+
agentSessionId: string;
|
|
107
|
+
workspace?: PluginRuntimeAgentWorkspace | undefined;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface PreparePluginRuntimeWorkspaceResponse {
|
|
111
|
+
workspace?: PluginRuntimePreparedAgentWorkspace | undefined;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface RemovePluginRuntimeWorkspaceRequest {
|
|
115
|
+
sessionId: string;
|
|
116
|
+
agentSessionId: string;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface StartHostedPluginRequest {
|
|
120
|
+
sessionId: string;
|
|
121
|
+
pluginName: string;
|
|
122
|
+
command?: string | undefined;
|
|
123
|
+
args?: readonly string[] | undefined;
|
|
124
|
+
env?: Record<string, string> | undefined;
|
|
125
|
+
allowedHosts?: readonly string[] | undefined;
|
|
126
|
+
defaultAction?: string | undefined;
|
|
127
|
+
hostBinary?: string | undefined;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface HostedPlugin {
|
|
131
|
+
id?: string | undefined;
|
|
132
|
+
sessionId?: string | undefined;
|
|
133
|
+
pluginName?: string | undefined;
|
|
134
|
+
dialTarget?: string | undefined;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface PluginRuntimeProviderOptions extends ProviderBaseOptions {
|
|
138
|
+
getSupport: () => MaybePromise<PluginRuntimeSupport>;
|
|
42
139
|
startSession: (
|
|
43
140
|
request: StartPluginRuntimeSessionRequest,
|
|
44
|
-
) => MaybePromise<
|
|
141
|
+
) => MaybePromise<PluginRuntimeSession>;
|
|
45
142
|
getSession: (
|
|
46
143
|
request: GetPluginRuntimeSessionRequest,
|
|
47
|
-
) => MaybePromise<
|
|
144
|
+
) => MaybePromise<PluginRuntimeSession>;
|
|
48
145
|
listSessions: (
|
|
49
146
|
request: ListPluginRuntimeSessionsRequest,
|
|
50
|
-
) => MaybePromise<
|
|
147
|
+
) => MaybePromise<readonly PluginRuntimeSession[]>;
|
|
51
148
|
stopSession: (request: StopPluginRuntimeSessionRequest) => MaybePromise<void>;
|
|
149
|
+
prepareWorkspace?: (
|
|
150
|
+
request: PreparePluginRuntimeWorkspaceRequest,
|
|
151
|
+
) => MaybePromise<PreparePluginRuntimeWorkspaceResponse>;
|
|
152
|
+
removeWorkspace?: (
|
|
153
|
+
request: RemovePluginRuntimeWorkspaceRequest,
|
|
154
|
+
) => MaybePromise<void>;
|
|
52
155
|
startPlugin: (
|
|
53
156
|
request: StartHostedPluginRequest,
|
|
54
|
-
) => MaybePromise<
|
|
157
|
+
) => MaybePromise<HostedPlugin>;
|
|
55
158
|
}
|
|
56
159
|
|
|
57
|
-
export class PluginRuntimeProvider extends
|
|
160
|
+
export class PluginRuntimeProvider extends ProviderBase {
|
|
58
161
|
readonly kind = "runtime" as const;
|
|
59
162
|
|
|
60
163
|
private readonly getSupportHandler: PluginRuntimeProviderOptions["getSupport"];
|
|
@@ -62,6 +165,8 @@ export class PluginRuntimeProvider extends RuntimeProvider {
|
|
|
62
165
|
private readonly getSessionHandler: PluginRuntimeProviderOptions["getSession"];
|
|
63
166
|
private readonly listSessionsHandler: PluginRuntimeProviderOptions["listSessions"];
|
|
64
167
|
private readonly stopSessionHandler: PluginRuntimeProviderOptions["stopSession"];
|
|
168
|
+
private readonly prepareWorkspaceHandler: PluginRuntimeProviderOptions["prepareWorkspace"];
|
|
169
|
+
private readonly removeWorkspaceHandler: PluginRuntimeProviderOptions["removeWorkspace"];
|
|
65
170
|
private readonly startPluginHandler: PluginRuntimeProviderOptions["startPlugin"];
|
|
66
171
|
|
|
67
172
|
constructor(options: PluginRuntimeProviderOptions) {
|
|
@@ -71,28 +176,30 @@ export class PluginRuntimeProvider extends RuntimeProvider {
|
|
|
71
176
|
this.getSessionHandler = options.getSession;
|
|
72
177
|
this.listSessionsHandler = options.listSessions;
|
|
73
178
|
this.stopSessionHandler = options.stopSession;
|
|
179
|
+
this.prepareWorkspaceHandler = options.prepareWorkspace;
|
|
180
|
+
this.removeWorkspaceHandler = options.removeWorkspace;
|
|
74
181
|
this.startPluginHandler = options.startPlugin;
|
|
75
182
|
}
|
|
76
183
|
|
|
77
|
-
async getSupport(): Promise<
|
|
184
|
+
async getSupport(): Promise<PluginRuntimeSupport> {
|
|
78
185
|
return await this.getSupportHandler();
|
|
79
186
|
}
|
|
80
187
|
|
|
81
188
|
async startSession(
|
|
82
189
|
request: StartPluginRuntimeSessionRequest,
|
|
83
|
-
): Promise<
|
|
190
|
+
): Promise<PluginRuntimeSession> {
|
|
84
191
|
return await this.startSessionHandler(request);
|
|
85
192
|
}
|
|
86
193
|
|
|
87
194
|
async getSession(
|
|
88
195
|
request: GetPluginRuntimeSessionRequest,
|
|
89
|
-
): Promise<
|
|
196
|
+
): Promise<PluginRuntimeSession> {
|
|
90
197
|
return await this.getSessionHandler(request);
|
|
91
198
|
}
|
|
92
199
|
|
|
93
200
|
async listSessions(
|
|
94
201
|
request: ListPluginRuntimeSessionsRequest,
|
|
95
|
-
): Promise<
|
|
202
|
+
): Promise<readonly PluginRuntimeSession[]> {
|
|
96
203
|
return await this.listSessionsHandler(request);
|
|
97
204
|
}
|
|
98
205
|
|
|
@@ -100,9 +207,33 @@ export class PluginRuntimeProvider extends RuntimeProvider {
|
|
|
100
207
|
await this.stopSessionHandler(request);
|
|
101
208
|
}
|
|
102
209
|
|
|
210
|
+
async prepareWorkspace(
|
|
211
|
+
request: PreparePluginRuntimeWorkspaceRequest,
|
|
212
|
+
): Promise<PreparePluginRuntimeWorkspaceResponse> {
|
|
213
|
+
if (!this.prepareWorkspaceHandler) {
|
|
214
|
+
throw new ConnectError(
|
|
215
|
+
"plugin runtime provider prepare workspace is not implemented",
|
|
216
|
+
Code.Unimplemented,
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
return await this.prepareWorkspaceHandler(request);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async removeWorkspace(
|
|
223
|
+
request: RemovePluginRuntimeWorkspaceRequest,
|
|
224
|
+
): Promise<void> {
|
|
225
|
+
if (!this.removeWorkspaceHandler) {
|
|
226
|
+
throw new ConnectError(
|
|
227
|
+
"plugin runtime provider remove workspace is not implemented",
|
|
228
|
+
Code.Unimplemented,
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
await this.removeWorkspaceHandler(request);
|
|
232
|
+
}
|
|
233
|
+
|
|
103
234
|
async startPlugin(
|
|
104
235
|
request: StartHostedPluginRequest,
|
|
105
|
-
): Promise<
|
|
236
|
+
): Promise<HostedPlugin> {
|
|
106
237
|
return await this.startPluginHandler(request);
|
|
107
238
|
}
|
|
108
239
|
}
|
|
@@ -130,56 +261,210 @@ export function isPluginRuntimeProvider(
|
|
|
130
261
|
|
|
131
262
|
export function createPluginRuntimeProviderService(
|
|
132
263
|
provider: PluginRuntimeProvider,
|
|
133
|
-
):
|
|
264
|
+
): PluginRuntimeProviderServiceImpl {
|
|
134
265
|
return {
|
|
135
266
|
async getSupport() {
|
|
136
267
|
return create(
|
|
137
268
|
PluginRuntimeSupportSchema,
|
|
138
|
-
|
|
139
|
-
|
|
269
|
+
pluginRuntimeSupportToProto(
|
|
270
|
+
await invokePluginRuntimeProvider("get support", () =>
|
|
271
|
+
provider.getSupport(),
|
|
272
|
+
),
|
|
140
273
|
),
|
|
141
274
|
);
|
|
142
275
|
},
|
|
143
276
|
async startSession(request) {
|
|
144
277
|
return create(
|
|
145
278
|
PluginRuntimeSessionSchema,
|
|
146
|
-
|
|
147
|
-
|
|
279
|
+
pluginRuntimeSessionToProto(
|
|
280
|
+
await invokePluginRuntimeProvider("start session", () =>
|
|
281
|
+
provider.startSession(startSessionRequestFromProto(request)),
|
|
282
|
+
),
|
|
148
283
|
),
|
|
149
284
|
);
|
|
150
285
|
},
|
|
151
286
|
async getSession(request) {
|
|
152
287
|
return create(
|
|
153
288
|
PluginRuntimeSessionSchema,
|
|
154
|
-
|
|
155
|
-
|
|
289
|
+
pluginRuntimeSessionToProto(
|
|
290
|
+
await invokePluginRuntimeProvider("get session", () =>
|
|
291
|
+
provider.getSession(getSessionRequestFromProto(request)),
|
|
292
|
+
),
|
|
156
293
|
),
|
|
157
294
|
);
|
|
158
295
|
},
|
|
159
296
|
async listSessions(request) {
|
|
160
297
|
return create(ListPluginRuntimeSessionsResponseSchema, {
|
|
161
|
-
sessions:
|
|
162
|
-
|
|
163
|
-
|
|
298
|
+
sessions: (
|
|
299
|
+
await invokePluginRuntimeProvider("list sessions", () =>
|
|
300
|
+
provider.listSessions(listSessionsRequestFromProto(request)),
|
|
301
|
+
)
|
|
302
|
+
).map(pluginRuntimeSessionToProto),
|
|
164
303
|
});
|
|
165
304
|
},
|
|
166
305
|
async stopSession(request) {
|
|
167
306
|
await invokePluginRuntimeProvider("stop session", () =>
|
|
168
|
-
provider.stopSession(request),
|
|
307
|
+
provider.stopSession(stopSessionRequestFromProto(request)),
|
|
308
|
+
);
|
|
309
|
+
return create(EmptySchema);
|
|
310
|
+
},
|
|
311
|
+
async prepareWorkspace(request) {
|
|
312
|
+
return create(
|
|
313
|
+
PreparePluginRuntimeWorkspaceResponseSchema,
|
|
314
|
+
prepareWorkspaceResponseToProto(
|
|
315
|
+
await invokePluginRuntimeProvider("prepare workspace", () =>
|
|
316
|
+
provider.prepareWorkspace(prepareWorkspaceRequestFromProto(request)),
|
|
317
|
+
),
|
|
318
|
+
),
|
|
319
|
+
);
|
|
320
|
+
},
|
|
321
|
+
async removeWorkspace(request) {
|
|
322
|
+
await invokePluginRuntimeProvider("remove workspace", () =>
|
|
323
|
+
provider.removeWorkspace(removeWorkspaceRequestFromProto(request)),
|
|
169
324
|
);
|
|
170
325
|
return create(EmptySchema);
|
|
171
326
|
},
|
|
172
327
|
async startPlugin(request) {
|
|
173
328
|
return create(
|
|
174
329
|
HostedPluginSchema,
|
|
175
|
-
|
|
176
|
-
|
|
330
|
+
hostedPluginToProto(
|
|
331
|
+
await invokePluginRuntimeProvider("start plugin", () =>
|
|
332
|
+
provider.startPlugin(startHostedPluginRequestFromProto(request)),
|
|
333
|
+
),
|
|
177
334
|
),
|
|
178
335
|
);
|
|
179
336
|
},
|
|
180
337
|
};
|
|
181
338
|
}
|
|
182
339
|
|
|
340
|
+
function startSessionRequestFromProto(
|
|
341
|
+
request: ProtoStartPluginRuntimeSessionRequest,
|
|
342
|
+
): StartPluginRuntimeSessionRequest {
|
|
343
|
+
return {
|
|
344
|
+
pluginName: request.pluginName,
|
|
345
|
+
template: request.template,
|
|
346
|
+
image: request.image,
|
|
347
|
+
metadata: { ...request.metadata },
|
|
348
|
+
imagePullAuth: request.imagePullAuth === undefined
|
|
349
|
+
? undefined
|
|
350
|
+
: { dockerConfigJson: request.imagePullAuth.dockerConfigJson },
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function getSessionRequestFromProto(
|
|
355
|
+
request: ProtoGetPluginRuntimeSessionRequest,
|
|
356
|
+
): GetPluginRuntimeSessionRequest {
|
|
357
|
+
return { sessionId: request.sessionId };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function listSessionsRequestFromProto(
|
|
361
|
+
_request: ProtoListPluginRuntimeSessionsRequest,
|
|
362
|
+
): ListPluginRuntimeSessionsRequest {
|
|
363
|
+
return {};
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function stopSessionRequestFromProto(
|
|
367
|
+
request: ProtoStopPluginRuntimeSessionRequest,
|
|
368
|
+
): StopPluginRuntimeSessionRequest {
|
|
369
|
+
return { sessionId: request.sessionId };
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function prepareWorkspaceRequestFromProto(
|
|
373
|
+
request: ProtoPreparePluginRuntimeWorkspaceRequest,
|
|
374
|
+
): PreparePluginRuntimeWorkspaceRequest {
|
|
375
|
+
return {
|
|
376
|
+
sessionId: request.sessionId,
|
|
377
|
+
agentSessionId: request.agentSessionId,
|
|
378
|
+
workspace: request.workspace === undefined
|
|
379
|
+
? undefined
|
|
380
|
+
: {
|
|
381
|
+
checkouts: request.workspace.checkouts.map((checkout) => ({
|
|
382
|
+
url: checkout.url,
|
|
383
|
+
ref: checkout.ref,
|
|
384
|
+
path: checkout.path,
|
|
385
|
+
})),
|
|
386
|
+
cwd: request.workspace.cwd,
|
|
387
|
+
},
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function removeWorkspaceRequestFromProto(
|
|
392
|
+
request: ProtoRemovePluginRuntimeWorkspaceRequest,
|
|
393
|
+
): RemovePluginRuntimeWorkspaceRequest {
|
|
394
|
+
return {
|
|
395
|
+
sessionId: request.sessionId,
|
|
396
|
+
agentSessionId: request.agentSessionId,
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function startHostedPluginRequestFromProto(
|
|
401
|
+
request: ProtoStartHostedPluginRequest,
|
|
402
|
+
): StartHostedPluginRequest {
|
|
403
|
+
return {
|
|
404
|
+
sessionId: request.sessionId,
|
|
405
|
+
pluginName: request.pluginName,
|
|
406
|
+
command: request.command,
|
|
407
|
+
args: [...request.args],
|
|
408
|
+
env: { ...request.env },
|
|
409
|
+
allowedHosts: [...request.allowedHosts],
|
|
410
|
+
defaultAction: request.defaultAction,
|
|
411
|
+
hostBinary: request.hostBinary,
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function pluginRuntimeSupportToProto(support: PluginRuntimeSupport) {
|
|
416
|
+
return {
|
|
417
|
+
canHostPlugins: support.canHostPlugins ?? false,
|
|
418
|
+
egressMode: support.egressMode ?? PluginRuntimeEgressMode.UNSPECIFIED,
|
|
419
|
+
supportsPrepareWorkspace: support.supportsPrepareWorkspace ?? false,
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function pluginRuntimeSessionToProto(session: PluginRuntimeSession) {
|
|
424
|
+
return {
|
|
425
|
+
id: session.id ?? "",
|
|
426
|
+
state: session.state ?? "",
|
|
427
|
+
metadata: { ...(session.metadata ?? {}) },
|
|
428
|
+
lifecycle: session.lifecycle === undefined
|
|
429
|
+
? undefined
|
|
430
|
+
: {
|
|
431
|
+
startedAt: session.lifecycle.startedAt === undefined
|
|
432
|
+
? undefined
|
|
433
|
+
: timestampFromDate(session.lifecycle.startedAt),
|
|
434
|
+
recommendedDrainAt: session.lifecycle.recommendedDrainAt === undefined
|
|
435
|
+
? undefined
|
|
436
|
+
: timestampFromDate(session.lifecycle.recommendedDrainAt),
|
|
437
|
+
expiresAt: session.lifecycle.expiresAt === undefined
|
|
438
|
+
? undefined
|
|
439
|
+
: timestampFromDate(session.lifecycle.expiresAt),
|
|
440
|
+
},
|
|
441
|
+
stateReason: session.stateReason ?? "",
|
|
442
|
+
stateMessage: session.stateMessage ?? "",
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
function prepareWorkspaceResponseToProto(
|
|
447
|
+
response: PreparePluginRuntimeWorkspaceResponse,
|
|
448
|
+
) {
|
|
449
|
+
return {
|
|
450
|
+
workspace: response.workspace === undefined
|
|
451
|
+
? undefined
|
|
452
|
+
: {
|
|
453
|
+
root: response.workspace.root ?? "",
|
|
454
|
+
cwd: response.workspace.cwd ?? "",
|
|
455
|
+
},
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
function hostedPluginToProto(plugin: HostedPlugin) {
|
|
460
|
+
return {
|
|
461
|
+
id: plugin.id ?? "",
|
|
462
|
+
sessionId: plugin.sessionId ?? "",
|
|
463
|
+
pluginName: plugin.pluginName ?? "",
|
|
464
|
+
dialTarget: plugin.dialTarget ?? "",
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
|
|
183
468
|
async function invokePluginRuntimeProvider<T>(
|
|
184
469
|
label: string,
|
|
185
470
|
fn: () => MaybePromise<T>,
|
|
@@ -187,6 +472,9 @@ async function invokePluginRuntimeProvider<T>(
|
|
|
187
472
|
try {
|
|
188
473
|
return await fn();
|
|
189
474
|
} catch (error) {
|
|
475
|
+
if (error instanceof ConnectError) {
|
|
476
|
+
throw error;
|
|
477
|
+
}
|
|
190
478
|
throw new ConnectError(
|
|
191
479
|
`plugin runtime provider ${label}: ${errorMessage(error)}`,
|
|
192
480
|
Code.Unknown,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level Gestalt v1 protocol bindings for advanced integration tests.
|
|
3
|
+
*
|
|
4
|
+
* Provider authoring code should prefer the root SDK exports. This module
|
|
5
|
+
* deliberately re-exports generated schemas, services, and message types for
|
|
6
|
+
* test harnesses and protocol fixtures.
|
|
7
|
+
*/
|
|
8
|
+
export * from "../internal/gen/v1/agent_pb.ts";
|
|
9
|
+
export * from "../internal/gen/v1/authentication_pb.ts";
|
|
10
|
+
export * from "../internal/gen/v1/authorization_pb.ts";
|
|
11
|
+
export * from "../internal/gen/v1/cache_pb.ts";
|
|
12
|
+
export * from "../internal/gen/v1/datastore_pb.ts";
|
|
13
|
+
export * from "../internal/gen/v1/external_credential_pb.ts";
|
|
14
|
+
export * from "../internal/gen/v1/plugin_pb.ts";
|
|
15
|
+
export * from "../internal/gen/v1/pluginruntime_pb.ts";
|
|
16
|
+
export * from "../internal/gen/v1/runtime_pb.ts";
|
|
17
|
+
export * from "../internal/gen/v1/s3_pb.ts";
|
|
18
|
+
export * from "../internal/gen/v1/secrets_pb.ts";
|
|
19
|
+
export * from "../internal/gen/v1/workflow_pb.ts";
|