@valon-technologies/gestalt 0.0.1-alpha.12 → 0.0.1-alpha.13
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/v1/agent_pb.ts +1916 -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 +10 -10
- package/gen/v1/external_credential_pb.ts +274 -0
- package/gen/v1/plugin_pb.ts +35 -30
- package/gen/v1/pluginruntime_pb.ts +593 -0
- package/gen/v1/runtime_pb.ts +18 -3
- package/gen/v1/s3_pb.ts +19 -19
- package/gen/v1/secrets_pb.ts +1 -1
- package/gen/v1/workflow_pb.ts +248 -82
- package/package.json +1 -1
- package/src/agent-manager.ts +247 -0
- package/src/agent.ts +492 -0
- package/src/authorization.ts +88 -18
- package/src/index.ts +67 -0
- package/src/manifest-metadata.ts +1 -0
- package/src/plugin.ts +85 -4
- package/src/provider-kind.ts +6 -0
- package/src/provider.ts +12 -1
- package/src/runtime.ts +153 -44
- package/src/s3.ts +89 -38
- package/src/workflow-manager.ts +67 -9
package/src/index.ts
CHANGED
|
@@ -32,6 +32,7 @@ export {
|
|
|
32
32
|
Authorization,
|
|
33
33
|
AuthorizationClient,
|
|
34
34
|
ENV_AUTHORIZATION_SOCKET,
|
|
35
|
+
ENV_AUTHORIZATION_SOCKET_TOKEN,
|
|
35
36
|
type AuthorizationActionSearchMessage,
|
|
36
37
|
type AuthorizationDecisionMessage,
|
|
37
38
|
type AuthorizationEvaluateInput,
|
|
@@ -105,8 +106,25 @@ export {
|
|
|
105
106
|
type PluginInvocationGrant,
|
|
106
107
|
type PluginInvokeOptions,
|
|
107
108
|
} from "./invoker.ts";
|
|
109
|
+
export {
|
|
110
|
+
ENV_AGENT_MANAGER_SOCKET,
|
|
111
|
+
ENV_AGENT_MANAGER_SOCKET_TOKEN,
|
|
112
|
+
AgentManager,
|
|
113
|
+
type AgentManagerCancelTurnInput,
|
|
114
|
+
type AgentManagerCreateSessionInput,
|
|
115
|
+
type AgentManagerCreateTurnInput,
|
|
116
|
+
type AgentManagerGetSessionInput,
|
|
117
|
+
type AgentManagerGetTurnInput,
|
|
118
|
+
type AgentManagerListInteractionsInput,
|
|
119
|
+
type AgentManagerListSessionsInput,
|
|
120
|
+
type AgentManagerListTurnEventsInput,
|
|
121
|
+
type AgentManagerListTurnsInput,
|
|
122
|
+
type AgentManagerResolveInteractionInput,
|
|
123
|
+
type AgentManagerUpdateSessionInput,
|
|
124
|
+
} from "./agent-manager.ts";
|
|
108
125
|
export {
|
|
109
126
|
ENV_WORKFLOW_MANAGER_SOCKET,
|
|
127
|
+
ENV_WORKFLOW_MANAGER_SOCKET_TOKEN,
|
|
110
128
|
WorkflowManager,
|
|
111
129
|
type ManagedWorkflowEventTriggerMessage,
|
|
112
130
|
type ManagedWorkflowScheduleMessage,
|
|
@@ -155,6 +173,7 @@ export {
|
|
|
155
173
|
type SecretsProviderOptions,
|
|
156
174
|
} from "./secrets.ts";
|
|
157
175
|
export {
|
|
176
|
+
type ConnectedToken,
|
|
158
177
|
PluginProvider,
|
|
159
178
|
connectionModeToProtoValue,
|
|
160
179
|
connectionParamToProto,
|
|
@@ -165,6 +184,7 @@ export {
|
|
|
165
184
|
type ConnectionParamDefinition,
|
|
166
185
|
type OperationDefinition,
|
|
167
186
|
type OperationOptions,
|
|
187
|
+
type PostConnectHandler,
|
|
168
188
|
type PluginDefinitionOptions,
|
|
169
189
|
type SessionCatalog,
|
|
170
190
|
type SessionCatalogHandler,
|
|
@@ -255,7 +275,10 @@ export {
|
|
|
255
275
|
createS3Service,
|
|
256
276
|
defineS3Provider,
|
|
257
277
|
isS3Provider,
|
|
278
|
+
ENV_S3_SOCKET,
|
|
279
|
+
ENV_S3_SOCKET_TOKEN,
|
|
258
280
|
s3SocketEnv,
|
|
281
|
+
s3SocketTokenEnv,
|
|
259
282
|
type ByteRange,
|
|
260
283
|
type CopyOptions,
|
|
261
284
|
type ListOptions,
|
|
@@ -271,6 +294,50 @@ export {
|
|
|
271
294
|
type S3ProviderOptions,
|
|
272
295
|
type WriteOptions,
|
|
273
296
|
} from "./s3.ts";
|
|
297
|
+
export {
|
|
298
|
+
ENV_AGENT_HOST_SOCKET,
|
|
299
|
+
AgentHost,
|
|
300
|
+
AgentExecutionStatus,
|
|
301
|
+
AgentInteractionState,
|
|
302
|
+
AgentInteractionType,
|
|
303
|
+
AgentMessagePartType,
|
|
304
|
+
AgentProvider,
|
|
305
|
+
AgentSessionState,
|
|
306
|
+
AgentToolSourceMode,
|
|
307
|
+
createAgentProviderService,
|
|
308
|
+
defineAgentProvider,
|
|
309
|
+
isAgentProvider,
|
|
310
|
+
type AgentActor,
|
|
311
|
+
type AgentInteraction,
|
|
312
|
+
type AgentMessage,
|
|
313
|
+
type AgentMessagePart,
|
|
314
|
+
type AgentMessagePartImageRef,
|
|
315
|
+
type AgentMessagePartToolCall,
|
|
316
|
+
type AgentMessagePartToolResult,
|
|
317
|
+
type AgentProviderCapabilities,
|
|
318
|
+
type AgentProviderOptions,
|
|
319
|
+
type AgentSession,
|
|
320
|
+
type AgentToolRef,
|
|
321
|
+
type AgentTurn,
|
|
322
|
+
type AgentTurnEvent,
|
|
323
|
+
type BoundAgentToolTarget,
|
|
324
|
+
type CancelAgentProviderTurnRequest,
|
|
325
|
+
type CreateAgentProviderSessionRequest,
|
|
326
|
+
type CreateAgentProviderTurnRequest,
|
|
327
|
+
type ExecuteAgentToolRequest,
|
|
328
|
+
type ExecuteAgentToolResponse,
|
|
329
|
+
type GetAgentProviderCapabilitiesRequest,
|
|
330
|
+
type GetAgentProviderInteractionRequest,
|
|
331
|
+
type GetAgentProviderSessionRequest,
|
|
332
|
+
type GetAgentProviderTurnRequest,
|
|
333
|
+
type ListAgentProviderInteractionsRequest,
|
|
334
|
+
type ListAgentProviderSessionsRequest,
|
|
335
|
+
type ListAgentProviderTurnEventsRequest,
|
|
336
|
+
type ListAgentProviderTurnsRequest,
|
|
337
|
+
type ResolvedAgentTool,
|
|
338
|
+
type ResolveAgentProviderInteractionRequest,
|
|
339
|
+
type UpdateAgentProviderSessionRequest,
|
|
340
|
+
} from "./agent.ts";
|
|
274
341
|
export {
|
|
275
342
|
ENV_WORKFLOW_HOST_SOCKET,
|
|
276
343
|
WorkflowHost,
|
package/src/manifest-metadata.ts
CHANGED
package/src/plugin.ts
CHANGED
|
@@ -32,7 +32,11 @@ import {
|
|
|
32
32
|
type HTTPSubjectResolutionContext,
|
|
33
33
|
type HTTPSubjectResolver,
|
|
34
34
|
} from "./http-subject.ts";
|
|
35
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
isRuntimeProvider,
|
|
37
|
+
RuntimeProvider,
|
|
38
|
+
type RuntimeProviderOptions,
|
|
39
|
+
} from "./provider.ts";
|
|
36
40
|
import type { Schema } from "./schema.ts";
|
|
37
41
|
|
|
38
42
|
/**
|
|
@@ -92,6 +96,34 @@ export type SessionCatalogHandler = (
|
|
|
92
96
|
request: Request,
|
|
93
97
|
) => MaybePromise<SessionCatalog | null | undefined>;
|
|
94
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Host-managed connection payload passed into a provider post-connect hook.
|
|
101
|
+
*/
|
|
102
|
+
export interface ConnectedToken {
|
|
103
|
+
id: string;
|
|
104
|
+
subjectId: string;
|
|
105
|
+
integration: string;
|
|
106
|
+
connection: string;
|
|
107
|
+
instance: string;
|
|
108
|
+
accessToken: string;
|
|
109
|
+
refreshToken: string;
|
|
110
|
+
scopes: string;
|
|
111
|
+
expiresAt?: Date | undefined;
|
|
112
|
+
lastRefreshedAt?: Date | undefined;
|
|
113
|
+
refreshErrorCount: number;
|
|
114
|
+
metadataJson: string;
|
|
115
|
+
metadata: Record<string, string>;
|
|
116
|
+
createdAt?: Date | undefined;
|
|
117
|
+
updatedAt?: Date | undefined;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Callback used to add derived metadata after a connection is established.
|
|
122
|
+
*/
|
|
123
|
+
export type PostConnectHandler = (
|
|
124
|
+
token: ConnectedToken,
|
|
125
|
+
) => MaybePromise<Record<string, string> | null | undefined>;
|
|
126
|
+
|
|
95
127
|
/**
|
|
96
128
|
* Runtime hooks required to implement a plugin provider.
|
|
97
129
|
*/
|
|
@@ -102,6 +134,7 @@ export interface PluginDefinitionOptions extends RuntimeProviderOptions {
|
|
|
102
134
|
securitySchemes?: Record<string, HTTPSecurityScheme>;
|
|
103
135
|
http?: Record<string, HTTPBinding>;
|
|
104
136
|
resolveHTTPSubject?: HTTPSubjectResolver;
|
|
137
|
+
postConnect?: PostConnectHandler;
|
|
105
138
|
iconSvg?: string;
|
|
106
139
|
operations: Array<OperationDefinition<any, any>>;
|
|
107
140
|
sessionCatalog?: SessionCatalogHandler;
|
|
@@ -159,6 +192,7 @@ export class PluginProvider extends RuntimeProvider {
|
|
|
159
192
|
|
|
160
193
|
private readonly sessionCatalogHandler: SessionCatalogHandler | undefined;
|
|
161
194
|
private readonly httpSubjectResolver: HTTPSubjectResolver | undefined;
|
|
195
|
+
private readonly postConnectHandler: PostConnectHandler | undefined;
|
|
162
196
|
private readonly operations = new Map<string, OperationDefinition<any, any>>();
|
|
163
197
|
|
|
164
198
|
constructor(options: PluginDefinitionOptions) {
|
|
@@ -170,6 +204,7 @@ export class PluginProvider extends RuntimeProvider {
|
|
|
170
204
|
this.securitySchemes = normalizeHTTPSecuritySchemes(options.securitySchemes);
|
|
171
205
|
this.http = normalizeHTTPBindings(options.http);
|
|
172
206
|
this.httpSubjectResolver = options.resolveHTTPSubject;
|
|
207
|
+
this.postConnectHandler = options.postConnect;
|
|
173
208
|
this.sessionCatalogHandler = options.sessionCatalog;
|
|
174
209
|
|
|
175
210
|
for (const rawEntry of options.operations) {
|
|
@@ -200,6 +235,22 @@ export class PluginProvider extends RuntimeProvider {
|
|
|
200
235
|
return await this.sessionCatalogHandler?.(request);
|
|
201
236
|
}
|
|
202
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Reports whether the provider exposes a connect-time metadata hook.
|
|
240
|
+
*/
|
|
241
|
+
supportsPostConnect(): boolean {
|
|
242
|
+
return this.postConnectHandler !== undefined;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Computes additional connection metadata after a successful connect flow.
|
|
247
|
+
*/
|
|
248
|
+
async postConnectMetadata(
|
|
249
|
+
token: ConnectedToken,
|
|
250
|
+
): Promise<Record<string, string> | null | undefined> {
|
|
251
|
+
return await this.postConnectHandler?.(cloneConnectedToken(token));
|
|
252
|
+
}
|
|
253
|
+
|
|
203
254
|
/**
|
|
204
255
|
* Resolves the concrete Gestalt subject for a verified hosted HTTP request,
|
|
205
256
|
* if the plugin opts into subject resolution.
|
|
@@ -386,12 +437,27 @@ export function isPluginProvider(
|
|
|
386
437
|
): value is PluginProvider {
|
|
387
438
|
return (
|
|
388
439
|
value instanceof PluginProvider ||
|
|
389
|
-
(
|
|
390
|
-
value !== null &&
|
|
440
|
+
(isRuntimeProvider(value) &&
|
|
391
441
|
"kind" in value &&
|
|
392
442
|
(value as { kind?: unknown }).kind === "integration" &&
|
|
393
443
|
"staticCatalog" in value &&
|
|
394
|
-
"
|
|
444
|
+
typeof (value as { staticCatalog?: unknown }).staticCatalog === "function" &&
|
|
445
|
+
"execute" in value &&
|
|
446
|
+
typeof (value as { execute?: unknown }).execute === "function" &&
|
|
447
|
+
"supportsSessionCatalog" in value &&
|
|
448
|
+
typeof (value as { supportsSessionCatalog?: unknown }).supportsSessionCatalog === "function" &&
|
|
449
|
+
"catalogForRequest" in value &&
|
|
450
|
+
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
|
+
"supportsPostConnect" in value &&
|
|
456
|
+
typeof (value as { supportsPostConnect?: unknown }).supportsPostConnect === "function" &&
|
|
457
|
+
"postConnectMetadata" in value &&
|
|
458
|
+
typeof (value as { postConnectMetadata?: unknown }).postConnectMetadata === "function" &&
|
|
459
|
+
"resolveHTTPSubject" in value &&
|
|
460
|
+
typeof (value as { resolveHTTPSubject?: unknown }).resolveHTTPSubject === "function")
|
|
395
461
|
);
|
|
396
462
|
}
|
|
397
463
|
|
|
@@ -421,6 +487,21 @@ function normalizeConnectionParams(
|
|
|
421
487
|
return output;
|
|
422
488
|
}
|
|
423
489
|
|
|
490
|
+
function cloneConnectedToken(token: ConnectedToken): ConnectedToken {
|
|
491
|
+
return {
|
|
492
|
+
...token,
|
|
493
|
+
metadata: {
|
|
494
|
+
...(token.metadata ?? {}),
|
|
495
|
+
},
|
|
496
|
+
expiresAt: token.expiresAt ? new Date(token.expiresAt) : undefined,
|
|
497
|
+
lastRefreshedAt: token.lastRefreshedAt
|
|
498
|
+
? new Date(token.lastRefreshedAt)
|
|
499
|
+
: undefined,
|
|
500
|
+
createdAt: token.createdAt ? new Date(token.createdAt) : undefined,
|
|
501
|
+
updatedAt: token.updatedAt ? new Date(token.updatedAt) : undefined,
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
|
|
424
505
|
function normalizeHTTPSecuritySchemes(
|
|
425
506
|
input: Record<string, HTTPSecurityScheme> | undefined,
|
|
426
507
|
): Record<string, HTTPSecurityScheme> {
|
package/src/provider-kind.ts
CHANGED
|
@@ -44,6 +44,12 @@ const PROVIDER_KIND_DEFINITIONS = {
|
|
|
44
44
|
defaultExportNames: ["workflow", "provider"],
|
|
45
45
|
label: "workflow provider",
|
|
46
46
|
},
|
|
47
|
+
agent: {
|
|
48
|
+
tokens: ["agent"],
|
|
49
|
+
formatToken: "agent",
|
|
50
|
+
defaultExportNames: ["agent", "provider"],
|
|
51
|
+
label: "agent provider",
|
|
52
|
+
},
|
|
47
53
|
telemetry: {
|
|
48
54
|
tokens: ["telemetry"],
|
|
49
55
|
formatToken: "telemetry",
|
package/src/provider.ts
CHANGED
|
@@ -10,6 +10,7 @@ export type ProviderKind =
|
|
|
10
10
|
| "secrets"
|
|
11
11
|
| "s3"
|
|
12
12
|
| "workflow"
|
|
13
|
+
| "agent"
|
|
13
14
|
| "telemetry";
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -151,7 +152,17 @@ export function isRuntimeProvider(value: unknown): value is RuntimeProvider {
|
|
|
151
152
|
value !== null &&
|
|
152
153
|
"kind" in value &&
|
|
153
154
|
"resolveName" in value &&
|
|
154
|
-
"
|
|
155
|
+
typeof (value as { resolveName?: unknown }).resolveName === "function" &&
|
|
156
|
+
"configureProvider" in value &&
|
|
157
|
+
typeof (value as { configureProvider?: unknown }).configureProvider === "function" &&
|
|
158
|
+
"supportsHealthCheck" in value &&
|
|
159
|
+
typeof (value as { supportsHealthCheck?: unknown }).supportsHealthCheck === "function" &&
|
|
160
|
+
"healthCheck" in value &&
|
|
161
|
+
typeof (value as { healthCheck?: unknown }).healthCheck === "function" &&
|
|
162
|
+
"warnings" in value &&
|
|
163
|
+
typeof (value as { warnings?: unknown }).warnings === "function" &&
|
|
164
|
+
"closeProvider" in value &&
|
|
165
|
+
typeof (value as { closeProvider?: unknown }).closeProvider === "function")
|
|
155
166
|
);
|
|
156
167
|
}
|
|
157
168
|
|
package/src/runtime.ts
CHANGED
|
@@ -12,6 +12,9 @@ import {
|
|
|
12
12
|
} from "@connectrpc/connect";
|
|
13
13
|
import { connectNodeAdapter } from "@connectrpc/connect-node";
|
|
14
14
|
|
|
15
|
+
import {
|
|
16
|
+
AgentProvider as AgentProviderService,
|
|
17
|
+
} from "../gen/v1/agent_pb.ts";
|
|
15
18
|
import {
|
|
16
19
|
AuthenticationProvider as AuthenticationProviderService,
|
|
17
20
|
AuthSessionSettingsSchema,
|
|
@@ -40,10 +43,12 @@ import {
|
|
|
40
43
|
CatalogSchema as ProtoCatalogSchema,
|
|
41
44
|
ConnectionMode as ProviderConnectionMode,
|
|
42
45
|
GetSessionCatalogResponseSchema,
|
|
46
|
+
PostConnectResponseSchema,
|
|
43
47
|
ResolveHTTPSubjectResponseSchema,
|
|
44
48
|
OperationResultSchema,
|
|
45
49
|
ProviderMetadataSchema,
|
|
46
50
|
type HTTPSubjectRequest as ProtoHTTPSubjectRequest,
|
|
51
|
+
type IntegrationToken as ProtoIntegrationToken,
|
|
47
52
|
type RequestContext as ProtoRequestContext,
|
|
48
53
|
type ResolveHTTPSubjectRequest as ProtoResolveHTTPSubjectRequest,
|
|
49
54
|
IntegrationProvider as IntegrationProviderService,
|
|
@@ -63,6 +68,11 @@ import {
|
|
|
63
68
|
import { S3 as S3Service } from "../gen/v1/s3_pb.ts";
|
|
64
69
|
import { WorkflowProvider as WorkflowProviderService } from "../gen/v1/workflow_pb.ts";
|
|
65
70
|
import { errorMessage, type Request } from "./api.ts";
|
|
71
|
+
import {
|
|
72
|
+
AgentProvider,
|
|
73
|
+
createAgentProviderService,
|
|
74
|
+
isAgentProvider,
|
|
75
|
+
} from "./agent.ts";
|
|
66
76
|
import {
|
|
67
77
|
AuthenticationProvider,
|
|
68
78
|
isAuthenticationProvider,
|
|
@@ -77,6 +87,7 @@ import {
|
|
|
77
87
|
type HTTPSubjectResolutionContext,
|
|
78
88
|
} from "./http-subject.ts";
|
|
79
89
|
import {
|
|
90
|
+
type ConnectedToken,
|
|
80
91
|
PluginProvider,
|
|
81
92
|
connectionModeToProtoValue,
|
|
82
93
|
connectionParamToProto,
|
|
@@ -127,6 +138,7 @@ export const CURRENT_PROTOCOL_VERSION = 3;
|
|
|
127
138
|
* Command-line usage for the runtime entrypoint.
|
|
128
139
|
*/
|
|
129
140
|
export const USAGE = "usage: bun run runtime.ts ROOT PROVIDER_TARGET";
|
|
141
|
+
export { createAgentProviderService } from "./agent.ts";
|
|
130
142
|
export { createWorkflowProviderService } from "./workflow.ts";
|
|
131
143
|
|
|
132
144
|
/**
|
|
@@ -146,6 +158,7 @@ export type LoadedProvider =
|
|
|
146
158
|
| CacheProvider
|
|
147
159
|
| SecretsProvider
|
|
148
160
|
| S3Provider
|
|
161
|
+
| AgentProvider
|
|
149
162
|
| WorkflowProvider;
|
|
150
163
|
|
|
151
164
|
type ProviderRuntimeEntry = {
|
|
@@ -205,6 +218,16 @@ const PROVIDER_RUNTIME_ENTRIES: Partial<
|
|
|
205
218
|
router.service(S3Service, createS3Service(provider as S3Provider));
|
|
206
219
|
},
|
|
207
220
|
},
|
|
221
|
+
agent: {
|
|
222
|
+
isProvider: isAgentProvider as (value: unknown) => value is LoadedProvider,
|
|
223
|
+
protoKind: ProtoProviderKind.AGENT,
|
|
224
|
+
registerService(router, provider) {
|
|
225
|
+
router.service(
|
|
226
|
+
AgentProviderService,
|
|
227
|
+
createAgentProviderService(provider as AgentProvider),
|
|
228
|
+
);
|
|
229
|
+
},
|
|
230
|
+
},
|
|
208
231
|
workflow: {
|
|
209
232
|
isProvider: isWorkflowProvider as (value: unknown) => value is LoadedProvider,
|
|
210
233
|
protoKind: ProtoProviderKind.WORKFLOW,
|
|
@@ -412,16 +435,20 @@ export function createRuntimeService(
|
|
|
412
435
|
): Partial<ServiceImpl<typeof ProviderLifecycle>> {
|
|
413
436
|
return {
|
|
414
437
|
async getProviderIdentity() {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
438
|
+
try {
|
|
439
|
+
return create(ProviderIdentitySchema, {
|
|
440
|
+
kind: providerRuntimeEntry(provider.kind).protoKind,
|
|
441
|
+
name: provider.name,
|
|
442
|
+
displayName: provider.displayName,
|
|
443
|
+
description: provider.description,
|
|
444
|
+
version: provider.version,
|
|
445
|
+
warnings: await provider.warnings(),
|
|
446
|
+
minProtocolVersion: CURRENT_PROTOCOL_VERSION,
|
|
447
|
+
maxProtocolVersion: CURRENT_PROTOCOL_VERSION,
|
|
448
|
+
});
|
|
449
|
+
} catch (error) {
|
|
450
|
+
throw providerRuntimeError("provider identity", error);
|
|
451
|
+
}
|
|
425
452
|
},
|
|
426
453
|
async configureProvider(request: ConfigureProviderRequest) {
|
|
427
454
|
assertProtocolVersion(request.protocolVersion);
|
|
@@ -431,10 +458,7 @@ export function createRuntimeService(
|
|
|
431
458
|
objectFromUnknown(request.config),
|
|
432
459
|
);
|
|
433
460
|
} catch (error) {
|
|
434
|
-
throw
|
|
435
|
-
`configure provider: ${errorMessage(error)}`,
|
|
436
|
-
Code.Unknown,
|
|
437
|
-
);
|
|
461
|
+
throw providerRuntimeError("configure provider", error);
|
|
438
462
|
}
|
|
439
463
|
return create(ConfigureProviderResponseSchema, {
|
|
440
464
|
protocolVersion: CURRENT_PROTOCOL_VERSION,
|
|
@@ -473,27 +497,31 @@ export function createProviderService(
|
|
|
473
497
|
throw new Error("provider is not a plugin provider");
|
|
474
498
|
}
|
|
475
499
|
return {
|
|
476
|
-
getMetadata() {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
Object.
|
|
487
|
-
key,
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
500
|
+
async getMetadata() {
|
|
501
|
+
try {
|
|
502
|
+
return create(ProviderMetadataSchema, {
|
|
503
|
+
name: provider.name,
|
|
504
|
+
displayName: provider.displayName,
|
|
505
|
+
description: provider.description,
|
|
506
|
+
connectionMode: connectionModeToProtoValue(
|
|
507
|
+
provider.connectionMode,
|
|
508
|
+
) as ProviderConnectionMode,
|
|
509
|
+
authTypes: [...provider.authTypes],
|
|
510
|
+
connectionParams: Object.fromEntries(
|
|
511
|
+
Object.entries(provider.connectionParams).map(([key, value]) => [
|
|
512
|
+
key,
|
|
513
|
+
connectionParamToProto(value),
|
|
514
|
+
]),
|
|
515
|
+
),
|
|
516
|
+
staticCatalog: catalogToProto(provider.staticCatalog()),
|
|
517
|
+
supportsSessionCatalog: provider.supportsSessionCatalog(),
|
|
518
|
+
supportsPostConnect: provider.supportsPostConnect(),
|
|
519
|
+
minProtocolVersion: CURRENT_PROTOCOL_VERSION,
|
|
520
|
+
maxProtocolVersion: CURRENT_PROTOCOL_VERSION,
|
|
521
|
+
});
|
|
522
|
+
} catch (error) {
|
|
523
|
+
throw providerRuntimeError("provider metadata", error);
|
|
524
|
+
}
|
|
497
525
|
},
|
|
498
526
|
async startProvider(request: StartProviderRequest) {
|
|
499
527
|
assertProtocolVersion(request.protocolVersion);
|
|
@@ -503,10 +531,7 @@ export function createProviderService(
|
|
|
503
531
|
objectFromUnknown(request.config),
|
|
504
532
|
);
|
|
505
533
|
} catch (error) {
|
|
506
|
-
throw
|
|
507
|
-
`configure provider: ${errorMessage(error)}`,
|
|
508
|
-
Code.Unknown,
|
|
509
|
-
);
|
|
534
|
+
throw providerRuntimeError("configure provider", error);
|
|
510
535
|
}
|
|
511
536
|
return create(StartProviderResponseSchema, {
|
|
512
537
|
protocolVersion: CURRENT_PROTOCOL_VERSION,
|
|
@@ -583,11 +608,29 @@ export function createProviderService(
|
|
|
583
608
|
catalog: catalogToProto(catalog),
|
|
584
609
|
});
|
|
585
610
|
},
|
|
586
|
-
async postConnect() {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
611
|
+
async postConnect(request) {
|
|
612
|
+
if (!provider.supportsPostConnect()) {
|
|
613
|
+
throw new ConnectError(
|
|
614
|
+
"provider does not support post connect",
|
|
615
|
+
Code.Unimplemented,
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
let metadata: Record<string, string> | null | undefined;
|
|
619
|
+
try {
|
|
620
|
+
metadata = await provider.postConnectMetadata(
|
|
621
|
+
providerConnectedToken(request.token),
|
|
622
|
+
);
|
|
623
|
+
} catch (error) {
|
|
624
|
+
throw new ConnectError(
|
|
625
|
+
`post connect: ${errorMessage(error)}`,
|
|
626
|
+
Code.Unknown,
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
return create(PostConnectResponseSchema, {
|
|
630
|
+
metadata: {
|
|
631
|
+
...(metadata ?? {}),
|
|
632
|
+
},
|
|
633
|
+
});
|
|
591
634
|
},
|
|
592
635
|
};
|
|
593
636
|
}
|
|
@@ -822,6 +865,29 @@ function providerHTTPSubjectResolutionContext(
|
|
|
822
865
|
};
|
|
823
866
|
}
|
|
824
867
|
|
|
868
|
+
function providerConnectedToken(
|
|
869
|
+
token?: ProtoIntegrationToken,
|
|
870
|
+
): ConnectedToken {
|
|
871
|
+
const metadataJson = token?.metadataJson ?? "";
|
|
872
|
+
return {
|
|
873
|
+
id: token?.id ?? "",
|
|
874
|
+
subjectId: token?.userId ?? "",
|
|
875
|
+
integration: token?.integration ?? "",
|
|
876
|
+
connection: token?.connection ?? "",
|
|
877
|
+
instance: token?.instance ?? "",
|
|
878
|
+
accessToken: token?.accessToken ?? "",
|
|
879
|
+
refreshToken: token?.refreshToken ?? "",
|
|
880
|
+
scopes: token?.scopes ?? "",
|
|
881
|
+
expiresAt: timestampToDate(token?.expiresAt),
|
|
882
|
+
lastRefreshedAt: timestampToDate(token?.lastRefreshedAt),
|
|
883
|
+
refreshErrorCount: token?.refreshErrorCount ?? 0,
|
|
884
|
+
metadataJson,
|
|
885
|
+
metadata: stringRecordFromJSON(metadataJson),
|
|
886
|
+
createdAt: timestampToDate(token?.createdAt),
|
|
887
|
+
updatedAt: timestampToDate(token?.updatedAt),
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
|
|
825
891
|
function providerStringLists(
|
|
826
892
|
input: Record<string, { values?: string[] }> | undefined,
|
|
827
893
|
): Record<string, string[]> {
|
|
@@ -844,6 +910,10 @@ function providerRuntimeEntry(
|
|
|
844
910
|
return entry;
|
|
845
911
|
}
|
|
846
912
|
|
|
913
|
+
function providerRuntimeError(label: string, error: unknown): ConnectError {
|
|
914
|
+
return new ConnectError(`${label}: ${errorMessage(error)}`, Code.Unknown);
|
|
915
|
+
}
|
|
916
|
+
|
|
847
917
|
function resolveLoadedProvider(
|
|
848
918
|
candidate: unknown,
|
|
849
919
|
kind: ProviderKind,
|
|
@@ -930,6 +1000,45 @@ function normalizeBigInt(value: number | bigint): bigint {
|
|
|
930
1000
|
return BigInt(Math.max(0, Math.trunc(value)));
|
|
931
1001
|
}
|
|
932
1002
|
|
|
1003
|
+
function timestampToDate(
|
|
1004
|
+
value: { seconds: bigint; nanos: number } | undefined,
|
|
1005
|
+
): Date | undefined {
|
|
1006
|
+
if (!value) {
|
|
1007
|
+
return undefined;
|
|
1008
|
+
}
|
|
1009
|
+
const seconds = Number(value.seconds ?? 0n);
|
|
1010
|
+
const nanos = Number(value.nanos ?? 0);
|
|
1011
|
+
if (!Number.isFinite(seconds) || !Number.isFinite(nanos)) {
|
|
1012
|
+
return undefined;
|
|
1013
|
+
}
|
|
1014
|
+
const millis = (seconds * 1000) + Math.trunc(nanos / 1_000_000);
|
|
1015
|
+
if (!Number.isFinite(millis)) {
|
|
1016
|
+
return undefined;
|
|
1017
|
+
}
|
|
1018
|
+
return new Date(millis);
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
function stringRecordFromJSON(value: string): Record<string, string> {
|
|
1022
|
+
if (!value.trim()) {
|
|
1023
|
+
return {};
|
|
1024
|
+
}
|
|
1025
|
+
try {
|
|
1026
|
+
const parsed = JSON.parse(value) as unknown;
|
|
1027
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
1028
|
+
return {};
|
|
1029
|
+
}
|
|
1030
|
+
const output: Record<string, string> = {};
|
|
1031
|
+
for (const [key, entry] of Object.entries(parsed)) {
|
|
1032
|
+
if (typeof entry === "string") {
|
|
1033
|
+
output[key] = entry;
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
return output;
|
|
1037
|
+
} catch {
|
|
1038
|
+
return {};
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
|
|
933
1042
|
function cloneUint8Array(value: Uint8Array | undefined): Uint8Array {
|
|
934
1043
|
if (!value) {
|
|
935
1044
|
return new Uint8Array();
|