deepline 0.1.168 → 0.1.170
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/dist/bundling-sources/apps/play-runner-workers/src/coordinator-entry.ts +317 -26
- package/dist/bundling-sources/apps/play-runner-workers/src/dedup-do.ts +100 -8
- package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +294 -81
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/map-chunk-plan.ts +119 -33
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/receipts.ts +4 -1
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-receipts.ts +56 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/workflow-instance-create.ts +3 -0
- package/dist/bundling-sources/sdk/src/client.ts +29 -1
- package/dist/bundling-sources/sdk/src/play.ts +4 -0
- package/dist/bundling-sources/sdk/src/release.ts +2 -2
- package/dist/bundling-sources/sdk/src/types.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-data-plane/column-names.ts +50 -8
- package/dist/bundling-sources/shared_libs/play-data-plane/sheet-contract.ts +40 -1
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +135 -4
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +9 -3
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +1 -0
- package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +202 -45
- package/dist/cli/index.js +70 -113
- package/dist/cli/index.mjs +70 -113
- package/dist/{compiler-manifest-VhtM9n24.d.mts → compiler-manifest-OwORQ07f.d.mts} +1 -0
- package/dist/{compiler-manifest-VhtM9n24.d.ts → compiler-manifest-OwORQ07f.d.ts} +1 -0
- package/dist/index.d.mts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +26 -5
- package/dist/index.mjs +26 -5
- package/dist/plays/bundle-play-file.d.mts +2 -2
- package/dist/plays/bundle-play-file.d.ts +2 -2
- package/package.json +1 -1
|
@@ -72,6 +72,7 @@ import {
|
|
|
72
72
|
import {
|
|
73
73
|
RuntimeReceiptWaitTimeoutError,
|
|
74
74
|
executeWithDurableRuntimeReceipt,
|
|
75
|
+
resolveRuntimeToolReceiptWaitMaxAttempts,
|
|
75
76
|
runtimeReceiptOutput as durableRuntimeReceiptOutput,
|
|
76
77
|
waitForCompletedRuntimeReceipt,
|
|
77
78
|
type DurableReceiptExecutionStore,
|
|
@@ -709,6 +710,8 @@ export class PlayContextImpl {
|
|
|
709
710
|
description?: string;
|
|
710
711
|
force?: boolean;
|
|
711
712
|
staleAfterSeconds?: number;
|
|
713
|
+
timeoutMs?: number;
|
|
714
|
+
receiptWaitMs?: number;
|
|
712
715
|
}): Promise<TOutput> => {
|
|
713
716
|
if (!request || typeof request !== 'object' || Array.isArray(request)) {
|
|
714
717
|
throw new Error(
|
|
@@ -735,7 +738,9 @@ export class PlayContextImpl {
|
|
|
735
738
|
request.input,
|
|
736
739
|
request.description ||
|
|
737
740
|
request.force === true ||
|
|
738
|
-
request.staleAfterSeconds !== undefined
|
|
741
|
+
request.staleAfterSeconds !== undefined ||
|
|
742
|
+
request.timeoutMs !== undefined ||
|
|
743
|
+
request.receiptWaitMs !== undefined
|
|
739
744
|
? {
|
|
740
745
|
...(request.description
|
|
741
746
|
? { description: request.description }
|
|
@@ -744,6 +749,12 @@ export class PlayContextImpl {
|
|
|
744
749
|
...(request.staleAfterSeconds !== undefined
|
|
745
750
|
? { staleAfterSeconds: request.staleAfterSeconds }
|
|
746
751
|
: {}),
|
|
752
|
+
...(request.timeoutMs !== undefined
|
|
753
|
+
? { timeoutMs: request.timeoutMs }
|
|
754
|
+
: {}),
|
|
755
|
+
...(request.receiptWaitMs !== undefined
|
|
756
|
+
? { receiptWaitMs: request.receiptWaitMs }
|
|
757
|
+
: {}),
|
|
747
758
|
}
|
|
748
759
|
: undefined,
|
|
749
760
|
) as Promise<TOutput>;
|
|
@@ -1283,10 +1294,12 @@ export class PlayContextImpl {
|
|
|
1283
1294
|
|
|
1284
1295
|
private async waitForCompletedRuntimeToolReceipt(
|
|
1285
1296
|
key: string,
|
|
1297
|
+
maxAttempts?: number,
|
|
1286
1298
|
): Promise<RuntimeStepReceipt> {
|
|
1287
1299
|
return await waitForCompletedRuntimeReceipt({
|
|
1288
1300
|
receiptKey: key,
|
|
1289
1301
|
store: this.durableReceiptExecutionStore(),
|
|
1302
|
+
maxAttempts,
|
|
1290
1303
|
});
|
|
1291
1304
|
}
|
|
1292
1305
|
|
|
@@ -1301,6 +1314,7 @@ export class PlayContextImpl {
|
|
|
1301
1314
|
staleAfterSeconds?: number | null;
|
|
1302
1315
|
repairRunningReceiptForSameRun?: boolean;
|
|
1303
1316
|
repairRunningReceiptForSameRunAfterWaitTimeout?: boolean;
|
|
1317
|
+
runningReceiptWaitMaxAttempts?: number;
|
|
1304
1318
|
reclaimRunning?: boolean;
|
|
1305
1319
|
markSkipped?: (output: T) => Promise<void> | void;
|
|
1306
1320
|
onRecovered?: (
|
|
@@ -1332,6 +1346,7 @@ export class PlayContextImpl {
|
|
|
1332
1346
|
repairRunningReceiptForSameRun: opts.repairRunningReceiptForSameRun,
|
|
1333
1347
|
repairRunningReceiptForSameRunAfterWaitTimeout:
|
|
1334
1348
|
opts.repairRunningReceiptForSameRunAfterWaitTimeout,
|
|
1349
|
+
runningReceiptWaitMaxAttempts: opts.runningReceiptWaitMaxAttempts,
|
|
1335
1350
|
reclaimRunning: opts.reclaimRunning,
|
|
1336
1351
|
markSkipped: opts.markSkipped,
|
|
1337
1352
|
onRecovered: opts.onRecovered,
|
|
@@ -3449,7 +3464,9 @@ export class PlayContextImpl {
|
|
|
3449
3464
|
});
|
|
3450
3465
|
}
|
|
3451
3466
|
this.log(`Calling tool: ${toolId}`);
|
|
3452
|
-
const execution = await this.callToolExecutionAPI(toolId, input
|
|
3467
|
+
const execution = await this.callToolExecutionAPI(toolId, input, {
|
|
3468
|
+
timeoutMs: options?.timeoutMs,
|
|
3469
|
+
});
|
|
3453
3470
|
const wrapped = await this.wrapToolExecutionResult({
|
|
3454
3471
|
toolId,
|
|
3455
3472
|
status: execution.status,
|
|
@@ -3535,6 +3552,12 @@ export class PlayContextImpl {
|
|
|
3535
3552
|
fieldName,
|
|
3536
3553
|
toolId,
|
|
3537
3554
|
input,
|
|
3555
|
+
...(typeof options?.timeoutMs === 'number'
|
|
3556
|
+
? { timeoutMs: options.timeoutMs }
|
|
3557
|
+
: {}),
|
|
3558
|
+
...(typeof options?.receiptWaitMs === 'number'
|
|
3559
|
+
? { receiptWaitMs: options.receiptWaitMs }
|
|
3560
|
+
: {}),
|
|
3538
3561
|
tableNamespace: store.tableNamespace,
|
|
3539
3562
|
rowKey: store.rowKey ?? null,
|
|
3540
3563
|
description: normalizeStepDescription(options?.description),
|
|
@@ -3573,6 +3596,11 @@ export class PlayContextImpl {
|
|
|
3573
3596
|
receiptKey: durableCacheKey,
|
|
3574
3597
|
}),
|
|
3575
3598
|
),
|
|
3599
|
+
runningReceiptWaitMaxAttempts: resolveRuntimeToolReceiptWaitMaxAttempts(
|
|
3600
|
+
typeof options?.receiptWaitMs === 'number'
|
|
3601
|
+
? { max_wait_ms: options.receiptWaitMs }
|
|
3602
|
+
: input,
|
|
3603
|
+
),
|
|
3576
3604
|
execute: executeTool,
|
|
3577
3605
|
},
|
|
3578
3606
|
);
|
|
@@ -4334,6 +4362,49 @@ export class PlayContextImpl {
|
|
|
4334
4362
|
await this.rejectToolCall(toolId, request, error);
|
|
4335
4363
|
}
|
|
4336
4364
|
};
|
|
4365
|
+
const requestsWithLiveFollowers = (
|
|
4366
|
+
owner: ToolCallRequest,
|
|
4367
|
+
): ToolCallRequest[] => [
|
|
4368
|
+
owner,
|
|
4369
|
+
...(liveFollowersByOwnerCallId.get(owner.callId) ?? []),
|
|
4370
|
+
];
|
|
4371
|
+
const resolveRuntimeTimeoutMsForRequests = (
|
|
4372
|
+
requests: ToolCallRequest[],
|
|
4373
|
+
): number | undefined => {
|
|
4374
|
+
const timeoutMs = Math.max(
|
|
4375
|
+
...requests
|
|
4376
|
+
.map((request) => request.timeoutMs)
|
|
4377
|
+
.filter(
|
|
4378
|
+
(candidate): candidate is number =>
|
|
4379
|
+
typeof candidate === 'number' &&
|
|
4380
|
+
Number.isFinite(candidate) &&
|
|
4381
|
+
candidate > 0,
|
|
4382
|
+
),
|
|
4383
|
+
0,
|
|
4384
|
+
);
|
|
4385
|
+
return timeoutMs > 0 ? timeoutMs : undefined;
|
|
4386
|
+
};
|
|
4387
|
+
const resolveRuntimeTimeoutMsForClaimedOwners = (
|
|
4388
|
+
owners: ToolCallRequest[],
|
|
4389
|
+
): number | undefined => {
|
|
4390
|
+
let timeoutMs = 0;
|
|
4391
|
+
for (const owner of owners) {
|
|
4392
|
+
if (
|
|
4393
|
+
typeof owner.timeoutMs !== 'number' ||
|
|
4394
|
+
!Number.isFinite(owner.timeoutMs) ||
|
|
4395
|
+
owner.timeoutMs <= 0
|
|
4396
|
+
) {
|
|
4397
|
+
return undefined;
|
|
4398
|
+
}
|
|
4399
|
+
timeoutMs = Math.max(
|
|
4400
|
+
timeoutMs,
|
|
4401
|
+
resolveRuntimeTimeoutMsForRequests(
|
|
4402
|
+
requestsWithLiveFollowers(owner),
|
|
4403
|
+
) ?? 0,
|
|
4404
|
+
);
|
|
4405
|
+
}
|
|
4406
|
+
return timeoutMs > 0 ? timeoutMs : undefined;
|
|
4407
|
+
};
|
|
4337
4408
|
|
|
4338
4409
|
const durableExistingRunningHandlers: Promise<void>[] = [];
|
|
4339
4410
|
if (
|
|
@@ -4452,10 +4523,25 @@ export class PlayContextImpl {
|
|
|
4452
4523
|
receiptKey: string,
|
|
4453
4524
|
requestsForKey: ToolCallRequest[],
|
|
4454
4525
|
): Promise<void> => {
|
|
4526
|
+
const waitMaxAttempts =
|
|
4527
|
+
requestsForKey.length > 0
|
|
4528
|
+
? Math.max(
|
|
4529
|
+
...requestsForKey.map((request) =>
|
|
4530
|
+
resolveRuntimeToolReceiptWaitMaxAttempts(
|
|
4531
|
+
typeof request.receiptWaitMs === 'number'
|
|
4532
|
+
? { max_wait_ms: request.receiptWaitMs }
|
|
4533
|
+
: request.input,
|
|
4534
|
+
),
|
|
4535
|
+
),
|
|
4536
|
+
)
|
|
4537
|
+
: undefined;
|
|
4455
4538
|
try {
|
|
4456
4539
|
await resolveRequestsFromReceipt(
|
|
4457
4540
|
requestsForKey,
|
|
4458
|
-
await this.waitForCompletedRuntimeToolReceipt(
|
|
4541
|
+
await this.waitForCompletedRuntimeToolReceipt(
|
|
4542
|
+
receiptKey,
|
|
4543
|
+
waitMaxAttempts,
|
|
4544
|
+
),
|
|
4459
4545
|
'in_flight',
|
|
4460
4546
|
);
|
|
4461
4547
|
return;
|
|
@@ -4511,6 +4597,9 @@ export class PlayContextImpl {
|
|
|
4511
4597
|
const execution = await this.callToolExecutionAPI(
|
|
4512
4598
|
toolId,
|
|
4513
4599
|
owner.input,
|
|
4600
|
+
{
|
|
4601
|
+
timeoutMs: resolveRuntimeTimeoutMsForClaimedOwners([owner]),
|
|
4602
|
+
},
|
|
4514
4603
|
);
|
|
4515
4604
|
const result = await this.resolveToolCall(
|
|
4516
4605
|
toolId,
|
|
@@ -4619,6 +4708,11 @@ export class PlayContextImpl {
|
|
|
4619
4708
|
await this.callToolAPI(
|
|
4620
4709
|
batch.batchOperation,
|
|
4621
4710
|
batch.batchPayload,
|
|
4711
|
+
{
|
|
4712
|
+
timeoutMs: resolveRuntimeTimeoutMsForClaimedOwners(
|
|
4713
|
+
batch.memberRequests,
|
|
4714
|
+
),
|
|
4715
|
+
},
|
|
4622
4716
|
),
|
|
4623
4717
|
onChunkComplete: async (chunkResults) => {
|
|
4624
4718
|
for (const entry of chunkResults) {
|
|
@@ -4674,6 +4768,11 @@ export class PlayContextImpl {
|
|
|
4674
4768
|
const execution = await this.callToolExecutionAPI(
|
|
4675
4769
|
toolId,
|
|
4676
4770
|
request.input,
|
|
4771
|
+
{
|
|
4772
|
+
timeoutMs: resolveRuntimeTimeoutMsForClaimedOwners([
|
|
4773
|
+
request,
|
|
4774
|
+
]),
|
|
4775
|
+
},
|
|
4677
4776
|
);
|
|
4678
4777
|
const result = await this.resolveToolCall(
|
|
4679
4778
|
toolId,
|
|
@@ -4778,8 +4877,9 @@ export class PlayContextImpl {
|
|
|
4778
4877
|
private async callToolAPI(
|
|
4779
4878
|
toolId: string,
|
|
4780
4879
|
input: Record<string, unknown>,
|
|
4880
|
+
options?: { timeoutMs?: number },
|
|
4781
4881
|
): Promise<unknown> {
|
|
4782
|
-
const execution = await this.callToolExecutionAPI(toolId, input);
|
|
4882
|
+
const execution = await this.callToolExecutionAPI(toolId, input, options);
|
|
4783
4883
|
if (execution.toolResponse && 'raw' in execution.toolResponse) {
|
|
4784
4884
|
return execution.toolResponse.raw;
|
|
4785
4885
|
}
|
|
@@ -4794,6 +4894,7 @@ export class PlayContextImpl {
|
|
|
4794
4894
|
private async callToolExecutionAPI(
|
|
4795
4895
|
toolId: string,
|
|
4796
4896
|
input: Record<string, unknown>,
|
|
4897
|
+
options?: { timeoutMs?: number },
|
|
4797
4898
|
): Promise<ParsedToolExecuteResponse> {
|
|
4798
4899
|
if (!this.#options.executorToken || !this.#options.baseUrl) {
|
|
4799
4900
|
throw new Error(
|
|
@@ -4801,6 +4902,11 @@ export class PlayContextImpl {
|
|
|
4801
4902
|
);
|
|
4802
4903
|
}
|
|
4803
4904
|
const url = `${this.#options.baseUrl}/api/v2/integrations/${encodeURIComponent(toolId)}/execute`;
|
|
4905
|
+
const timeoutMs =
|
|
4906
|
+
typeof options?.timeoutMs === 'number' &&
|
|
4907
|
+
Number.isFinite(options.timeoutMs)
|
|
4908
|
+
? Math.max(1, Math.ceil(options.timeoutMs))
|
|
4909
|
+
: undefined;
|
|
4804
4910
|
|
|
4805
4911
|
// The Governor's tool slot is the single seam for tool-call budget + the
|
|
4806
4912
|
// global tool-concurrency backstop + per-(org, provider) pacing. It blocks
|
|
@@ -4831,9 +4937,20 @@ export class PlayContextImpl {
|
|
|
4831
4937
|
|
|
4832
4938
|
while (true) {
|
|
4833
4939
|
let response: Response;
|
|
4940
|
+
const abortController = timeoutMs ? new AbortController() : null;
|
|
4941
|
+
const timeoutHandle = timeoutMs
|
|
4942
|
+
? setTimeout(() => {
|
|
4943
|
+
abortController?.abort(
|
|
4944
|
+
new Error(
|
|
4945
|
+
`Tool ${toolId} runtime API call timed out after ${timeoutMs}ms.`,
|
|
4946
|
+
),
|
|
4947
|
+
);
|
|
4948
|
+
}, timeoutMs)
|
|
4949
|
+
: null;
|
|
4834
4950
|
try {
|
|
4835
4951
|
response = await fetch(url, {
|
|
4836
4952
|
method: 'POST',
|
|
4953
|
+
signal: abortController?.signal,
|
|
4837
4954
|
headers: {
|
|
4838
4955
|
'Content-Type': 'application/json',
|
|
4839
4956
|
Authorization: `Bearer ${this.#options.executorToken}`,
|
|
@@ -4850,9 +4967,19 @@ export class PlayContextImpl {
|
|
|
4850
4967
|
body: JSON.stringify({
|
|
4851
4968
|
payload: input,
|
|
4852
4969
|
metadata: { parent_run_id: this.#options.runId },
|
|
4970
|
+
...(this.#options.integrationMode
|
|
4971
|
+
? { integration_mode: this.#options.integrationMode }
|
|
4972
|
+
: {}),
|
|
4853
4973
|
}),
|
|
4854
4974
|
});
|
|
4855
4975
|
} catch (error) {
|
|
4976
|
+
if (abortController?.signal.aborted) {
|
|
4977
|
+
throw abortController.signal.reason instanceof Error
|
|
4978
|
+
? abortController.signal.reason
|
|
4979
|
+
: new Error(
|
|
4980
|
+
`Tool ${toolId} runtime API call timed out after ${timeoutMs}ms.`,
|
|
4981
|
+
);
|
|
4982
|
+
}
|
|
4856
4983
|
transportAttempt += 1;
|
|
4857
4984
|
const message =
|
|
4858
4985
|
error instanceof Error ? error.message : String(error);
|
|
@@ -4873,6 +5000,10 @@ export class PlayContextImpl {
|
|
|
4873
5000
|
throw new Error(
|
|
4874
5001
|
`Tool ${toolId} transport failed calling ${url} after ${transportAttempt}/${TOOL_EXECUTE_TRANSPORT_MAX_ATTEMPTS} attempts: ${message}`,
|
|
4875
5002
|
);
|
|
5003
|
+
} finally {
|
|
5004
|
+
if (timeoutHandle) {
|
|
5005
|
+
clearTimeout(timeoutHandle);
|
|
5006
|
+
}
|
|
4876
5007
|
}
|
|
4877
5008
|
|
|
4878
5009
|
span.setAttribute('plays.http_status_code', response.status);
|
|
@@ -28,6 +28,8 @@ export interface ToolCallRequest {
|
|
|
28
28
|
fieldName?: string;
|
|
29
29
|
toolId: string;
|
|
30
30
|
input: Record<string, unknown>;
|
|
31
|
+
timeoutMs?: number;
|
|
32
|
+
receiptWaitMs?: number;
|
|
31
33
|
tableNamespace?: string;
|
|
32
34
|
rowKey?: string | null;
|
|
33
35
|
description?: string;
|
|
@@ -169,6 +171,8 @@ export interface ToolCallOptions {
|
|
|
169
171
|
description?: string;
|
|
170
172
|
force?: boolean;
|
|
171
173
|
staleAfterSeconds?: number;
|
|
174
|
+
timeoutMs?: number;
|
|
175
|
+
receiptWaitMs?: number;
|
|
172
176
|
}
|
|
173
177
|
|
|
174
178
|
export interface ToolExecutionRequest {
|
|
@@ -178,6 +182,8 @@ export interface ToolExecutionRequest {
|
|
|
178
182
|
description?: string;
|
|
179
183
|
force?: boolean;
|
|
180
184
|
staleAfterSeconds?: number;
|
|
185
|
+
timeoutMs?: number;
|
|
186
|
+
receiptWaitMs?: number;
|
|
181
187
|
}
|
|
182
188
|
|
|
183
189
|
export type SqlQuery = {
|
|
@@ -388,6 +394,8 @@ export interface ContextOptions {
|
|
|
388
394
|
executorToken?: string;
|
|
389
395
|
baseUrl?: string;
|
|
390
396
|
vercelProtectionBypassToken?: string | null;
|
|
397
|
+
/** Optional per-run integration execution mode for provider calls. */
|
|
398
|
+
integrationMode?: 'live' | 'eval_stub' | 'fixture';
|
|
391
399
|
orgId?: string;
|
|
392
400
|
userEmail?: string;
|
|
393
401
|
playName?: string;
|
|
@@ -451,9 +459,7 @@ export interface ContextOptions {
|
|
|
451
459
|
getToolRetryPolicy?: (toolId: string) => Promise<{
|
|
452
460
|
retrySafeTransientHttp?: boolean;
|
|
453
461
|
} | null>;
|
|
454
|
-
getToolActionCacheVersion?: (
|
|
455
|
-
toolId: string,
|
|
456
|
-
) => Promise<string> | string;
|
|
462
|
+
getToolActionCacheVersion?: (toolId: string) => Promise<string> | string;
|
|
457
463
|
getToolTargetGetters?: (
|
|
458
464
|
toolId: string,
|
|
459
465
|
output: string,
|
|
@@ -83,6 +83,7 @@ type RuntimeApiContext = {
|
|
|
83
83
|
playName?: string | null;
|
|
84
84
|
runId?: string | null;
|
|
85
85
|
userEmail?: string | null;
|
|
86
|
+
integrationMode?: 'live' | 'eval_stub' | 'fixture' | null;
|
|
86
87
|
dbSessionStrategy?: 'preloaded' | 'sandbox_public_key' | null;
|
|
87
88
|
preloadedDbSessions?: PreloadedRuntimeDbSession[] | null;
|
|
88
89
|
vercelProtectionBypassToken?: string | null;
|
|
@@ -1512,6 +1513,7 @@ function mapRuntimeWorkReceiptRow(raw: Record<string, unknown>): WorkReceipt {
|
|
|
1512
1513
|
output: raw.output == null ? null : raw.output,
|
|
1513
1514
|
error: raw.error == null ? null : String(raw.error),
|
|
1514
1515
|
runId: raw.run_id == null ? null : String(raw.run_id),
|
|
1516
|
+
updatedAt: raw.updated_at == null ? null : String(raw.updated_at),
|
|
1515
1517
|
};
|
|
1516
1518
|
}
|
|
1517
1519
|
|
|
@@ -124,6 +124,8 @@ export type PlaySchedulerSubmitInput = {
|
|
|
124
124
|
dynamicWorkerCode?: string | null;
|
|
125
125
|
executorToken: string;
|
|
126
126
|
baseUrl: string;
|
|
127
|
+
/** Optional per-run provider execution mode. Defaults to server policy when omitted. */
|
|
128
|
+
integrationMode?: 'live' | 'eval_stub' | 'fixture';
|
|
127
129
|
orgId: string;
|
|
128
130
|
userEmail: string;
|
|
129
131
|
userId?: string | null;
|