skedyul 1.7.8 → 1.7.9
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/.build-stamp +1 -1
- package/dist/cli/index.js +154 -69
- package/dist/config/types/batch-operation.d.ts +33 -4
- package/dist/dedicated/server.js +154 -69
- package/dist/esm/index.mjs +166 -69
- package/dist/index.js +167 -69
- package/dist/server/route-handlers/handlers.d.ts +2 -2
- package/dist/server.js +154 -69
- package/dist/serverless/server.mjs +154 -69
- package/dist/types/index.d.ts +1 -1
- package/dist/types/invocation.d.ts +16 -1
- package/package.json +2 -2
package/dist/esm/index.mjs
CHANGED
|
@@ -41,6 +41,17 @@ function createWorkflowStepContext(params) {
|
|
|
41
41
|
workflowStepId: params.workflowStepId
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
|
+
function createBatchOperationContext(params) {
|
|
45
|
+
return {
|
|
46
|
+
invocationId: params.invocationId,
|
|
47
|
+
invocationType: "batch_operation",
|
|
48
|
+
batchOperationHandle: params.batchOperationHandle,
|
|
49
|
+
batchOperationMethod: params.batchOperationMethod,
|
|
50
|
+
appInstallationId: params.appInstallationId,
|
|
51
|
+
workflowId: params.workflowId,
|
|
52
|
+
workflowRunId: params.workflowRunId
|
|
53
|
+
};
|
|
54
|
+
}
|
|
44
55
|
|
|
45
56
|
// src/types/tool-context.ts
|
|
46
57
|
function isProvisionContext(ctx) {
|
|
@@ -5464,6 +5475,39 @@ async function handleMcpBatchRoute(req, ctx) {
|
|
|
5464
5475
|
}
|
|
5465
5476
|
};
|
|
5466
5477
|
}
|
|
5478
|
+
function isBatchOperationFailure(result) {
|
|
5479
|
+
return result != null && typeof result === "object" && result.success === false && typeof result.error === "object" && result.error != null;
|
|
5480
|
+
}
|
|
5481
|
+
function toStringEnv(env) {
|
|
5482
|
+
const out = {};
|
|
5483
|
+
for (const [key, value] of Object.entries(env)) {
|
|
5484
|
+
if (value !== void 0) {
|
|
5485
|
+
out[key] = value;
|
|
5486
|
+
}
|
|
5487
|
+
}
|
|
5488
|
+
return out;
|
|
5489
|
+
}
|
|
5490
|
+
function stripBillingFields(result) {
|
|
5491
|
+
const {
|
|
5492
|
+
billing: _billing,
|
|
5493
|
+
success: _success,
|
|
5494
|
+
error: _error,
|
|
5495
|
+
retry: _retry,
|
|
5496
|
+
...domain
|
|
5497
|
+
} = result;
|
|
5498
|
+
return domain;
|
|
5499
|
+
}
|
|
5500
|
+
function softFailureResponse(error, retry, billing) {
|
|
5501
|
+
return {
|
|
5502
|
+
status: 200,
|
|
5503
|
+
body: {
|
|
5504
|
+
success: false,
|
|
5505
|
+
error,
|
|
5506
|
+
...retry ? { retry } : {},
|
|
5507
|
+
billing: normalizeBilling(billing)
|
|
5508
|
+
}
|
|
5509
|
+
};
|
|
5510
|
+
}
|
|
5467
5511
|
async function handleBatchOperationRoute(req, ctx) {
|
|
5468
5512
|
const bodyResult = parseJsonBody(req);
|
|
5469
5513
|
if (!bodyResult.success) {
|
|
@@ -5472,49 +5516,80 @@ async function handleBatchOperationRoute(req, ctx) {
|
|
|
5472
5516
|
const body = bodyResult.data;
|
|
5473
5517
|
const registry = ctx.batchOperationRegistry;
|
|
5474
5518
|
if (!registry) {
|
|
5475
|
-
return {
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
}
|
|
5481
|
-
};
|
|
5519
|
+
return softFailureResponse({
|
|
5520
|
+
code: "NOT_FOUND",
|
|
5521
|
+
message: "No batch operations registered",
|
|
5522
|
+
category: "validation"
|
|
5523
|
+
});
|
|
5482
5524
|
}
|
|
5483
5525
|
const operation = registry[body.handle];
|
|
5484
5526
|
if (!operation) {
|
|
5485
|
-
return {
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
}
|
|
5491
|
-
};
|
|
5527
|
+
return softFailureResponse({
|
|
5528
|
+
code: "NOT_FOUND",
|
|
5529
|
+
message: `Batch operation not found: ${body.handle}`,
|
|
5530
|
+
category: "validation"
|
|
5531
|
+
});
|
|
5492
5532
|
}
|
|
5493
5533
|
const context = body.context;
|
|
5494
5534
|
if (!context?.workplaceId || !context?.appInstallationId || !context?.appId) {
|
|
5495
|
-
return {
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
}
|
|
5501
|
-
};
|
|
5535
|
+
return softFailureResponse({
|
|
5536
|
+
code: "VALIDATION_ERROR",
|
|
5537
|
+
message: "Missing context (workplaceId, appInstallationId, and appId required)",
|
|
5538
|
+
category: "validation"
|
|
5539
|
+
});
|
|
5502
5540
|
}
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5541
|
+
if (body.method !== "setup" && body.method !== "iterate") {
|
|
5542
|
+
return softFailureResponse({
|
|
5543
|
+
code: "VALIDATION_ERROR",
|
|
5544
|
+
message: `Unknown method: ${body.method}`,
|
|
5545
|
+
category: "validation"
|
|
5546
|
+
});
|
|
5547
|
+
}
|
|
5548
|
+
const requestEnv = body.env ?? {};
|
|
5549
|
+
const mergedEnv = toStringEnv(buildToolExecutionEnv(requestEnv));
|
|
5550
|
+
const originalEnv = { ...process.env };
|
|
5551
|
+
Object.assign(process.env, mergedEnv);
|
|
5552
|
+
const log = createContextLogger();
|
|
5553
|
+
const app = context.app ?? {
|
|
5554
|
+
id: context.appId,
|
|
5555
|
+
versionId: context.appId
|
|
5556
|
+
};
|
|
5557
|
+
const workplace2 = context.workplace ?? {
|
|
5558
|
+
id: context.workplaceId,
|
|
5559
|
+
subdomain: ""
|
|
5560
|
+
};
|
|
5561
|
+
const invocation = body.invocation ?? {
|
|
5562
|
+
invocationId: `${body.handle}-${body.method}-${Date.now()}`,
|
|
5563
|
+
invocationType: "batch_operation",
|
|
5564
|
+
batchOperationHandle: body.handle,
|
|
5565
|
+
batchOperationMethod: body.method,
|
|
5566
|
+
appInstallationId: context.appInstallationId
|
|
5514
5567
|
};
|
|
5515
5568
|
const requestConfig = {
|
|
5516
|
-
baseUrl:
|
|
5517
|
-
apiToken:
|
|
5569
|
+
baseUrl: mergedEnv.SKEDYUL_API_URL ?? process.env.SKEDYUL_API_URL ?? "",
|
|
5570
|
+
apiToken: mergedEnv.SKEDYUL_API_TOKEN ?? process.env.SKEDYUL_API_TOKEN ?? ""
|
|
5571
|
+
};
|
|
5572
|
+
const rateLimitContext = {
|
|
5573
|
+
app,
|
|
5574
|
+
appInstallationId: context.appInstallationId,
|
|
5575
|
+
invocation,
|
|
5576
|
+
preAcquiredLeases: parsePreAcquiredLeases(
|
|
5577
|
+
mergedEnv.SKEDYUL_RATE_LIMIT_LEASES
|
|
5578
|
+
),
|
|
5579
|
+
heldMutexQueueKeys: parseHeldMutexQueueKeys(
|
|
5580
|
+
mergedEnv.SKEDYUL_HELD_MUTEX_QUEUE_KEYS
|
|
5581
|
+
)
|
|
5582
|
+
};
|
|
5583
|
+
const opContextBase = {
|
|
5584
|
+
workplaceId: context.workplaceId,
|
|
5585
|
+
appInstallationId: context.appInstallationId,
|
|
5586
|
+
appId: context.appId,
|
|
5587
|
+
app,
|
|
5588
|
+
workplace: workplace2,
|
|
5589
|
+
input: body.input,
|
|
5590
|
+
env: mergedEnv,
|
|
5591
|
+
invocation,
|
|
5592
|
+
log
|
|
5518
5593
|
};
|
|
5519
5594
|
try {
|
|
5520
5595
|
if (body.method === "setup") {
|
|
@@ -5523,67 +5598,88 @@ async function handleBatchOperationRoute(req, ctx) {
|
|
|
5523
5598
|
status: 200,
|
|
5524
5599
|
body: {
|
|
5525
5600
|
success: true,
|
|
5526
|
-
result: { state: {}, total: void 0 }
|
|
5601
|
+
result: { state: {}, total: void 0 },
|
|
5602
|
+
billing: normalizeBilling(void 0)
|
|
5527
5603
|
}
|
|
5528
5604
|
};
|
|
5529
5605
|
}
|
|
5530
|
-
const
|
|
5531
|
-
return
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
input: body.input,
|
|
5536
|
-
env,
|
|
5537
|
-
log
|
|
5606
|
+
const raw2 = await runWithConfig(requestConfig, async () => {
|
|
5607
|
+
return runWithRateLimitExecutionContext(rateLimitContext, async () => {
|
|
5608
|
+
return runWithLogContext({ invocation }, async () => {
|
|
5609
|
+
return operation.setup(opContextBase);
|
|
5610
|
+
});
|
|
5538
5611
|
});
|
|
5539
5612
|
});
|
|
5613
|
+
if (isBatchOperationFailure(raw2)) {
|
|
5614
|
+
return softFailureResponse(raw2.error, raw2.retry, raw2.billing);
|
|
5615
|
+
}
|
|
5616
|
+
const setupResult = raw2;
|
|
5617
|
+
const domain2 = stripBillingFields(
|
|
5618
|
+
setupResult
|
|
5619
|
+
);
|
|
5540
5620
|
return {
|
|
5541
5621
|
status: 200,
|
|
5542
5622
|
body: {
|
|
5543
5623
|
success: true,
|
|
5544
|
-
result
|
|
5624
|
+
result: domain2,
|
|
5625
|
+
billing: normalizeBilling(setupResult.billing)
|
|
5545
5626
|
}
|
|
5546
5627
|
};
|
|
5547
5628
|
}
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
return
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
limit: body.limit,
|
|
5559
|
-
env,
|
|
5560
|
-
log
|
|
5629
|
+
const raw = await runWithConfig(requestConfig, async () => {
|
|
5630
|
+
return runWithRateLimitExecutionContext(rateLimitContext, async () => {
|
|
5631
|
+
return runWithLogContext({ invocation }, async () => {
|
|
5632
|
+
return operation.iterate({
|
|
5633
|
+
...opContextBase,
|
|
5634
|
+
state: body.state,
|
|
5635
|
+
page: body.page,
|
|
5636
|
+
cursor: body.cursor,
|
|
5637
|
+
limit: body.limit
|
|
5638
|
+
});
|
|
5561
5639
|
});
|
|
5562
5640
|
});
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
success: true,
|
|
5567
|
-
result
|
|
5568
|
-
}
|
|
5569
|
-
};
|
|
5641
|
+
});
|
|
5642
|
+
if (isBatchOperationFailure(raw)) {
|
|
5643
|
+
return softFailureResponse(raw.error, raw.retry, raw.billing);
|
|
5570
5644
|
}
|
|
5645
|
+
const iterateResult = raw;
|
|
5646
|
+
const domain = stripBillingFields(
|
|
5647
|
+
iterateResult
|
|
5648
|
+
);
|
|
5571
5649
|
return {
|
|
5572
|
-
status:
|
|
5650
|
+
status: 200,
|
|
5573
5651
|
body: {
|
|
5574
|
-
success:
|
|
5575
|
-
|
|
5652
|
+
success: true,
|
|
5653
|
+
result: domain,
|
|
5654
|
+
billing: normalizeBilling(iterateResult.billing)
|
|
5576
5655
|
}
|
|
5577
5656
|
};
|
|
5578
5657
|
} catch (err) {
|
|
5579
|
-
|
|
5658
|
+
if (err instanceof RateLimitExceededError) {
|
|
5659
|
+
return softFailureResponse(
|
|
5660
|
+
{
|
|
5661
|
+
code: "RATE_LIMITED",
|
|
5662
|
+
message: err.message,
|
|
5663
|
+
category: "external"
|
|
5664
|
+
},
|
|
5665
|
+
{ allowed: true, afterMs: err.retryAfterMs }
|
|
5666
|
+
);
|
|
5667
|
+
}
|
|
5668
|
+
log.error("Batch operation failed", err);
|
|
5580
5669
|
return {
|
|
5581
5670
|
status: 500,
|
|
5582
5671
|
body: {
|
|
5583
5672
|
success: false,
|
|
5584
|
-
error:
|
|
5673
|
+
error: {
|
|
5674
|
+
code: "INTERNAL_ERROR",
|
|
5675
|
+
message: err instanceof Error ? err.message : String(err),
|
|
5676
|
+
category: "internal"
|
|
5677
|
+
},
|
|
5678
|
+
billing: normalizeBilling(void 0)
|
|
5585
5679
|
}
|
|
5586
5680
|
};
|
|
5681
|
+
} finally {
|
|
5682
|
+
process.env = originalEnv;
|
|
5587
5683
|
}
|
|
5588
5684
|
}
|
|
5589
5685
|
function createNotFoundResponse() {
|
|
@@ -8813,6 +8909,7 @@ export {
|
|
|
8813
8909
|
computeSkewedExpectedMinorUnits,
|
|
8814
8910
|
configure,
|
|
8815
8911
|
createAuthError,
|
|
8912
|
+
createBatchOperationContext,
|
|
8816
8913
|
createConflictError,
|
|
8817
8914
|
createContextLogger,
|
|
8818
8915
|
createErrorResponse,
|
package/dist/index.js
CHANGED
|
@@ -273,6 +273,7 @@ __export(index_exports, {
|
|
|
273
273
|
computeSkewedExpectedMinorUnits: () => computeSkewedExpectedMinorUnits,
|
|
274
274
|
configure: () => configure,
|
|
275
275
|
createAuthError: () => createAuthError,
|
|
276
|
+
createBatchOperationContext: () => createBatchOperationContext,
|
|
276
277
|
createConflictError: () => createConflictError,
|
|
277
278
|
createContextLogger: () => createContextLogger,
|
|
278
279
|
createErrorResponse: () => createErrorResponse,
|
|
@@ -420,6 +421,17 @@ function createWorkflowStepContext(params) {
|
|
|
420
421
|
workflowStepId: params.workflowStepId
|
|
421
422
|
};
|
|
422
423
|
}
|
|
424
|
+
function createBatchOperationContext(params) {
|
|
425
|
+
return {
|
|
426
|
+
invocationId: params.invocationId,
|
|
427
|
+
invocationType: "batch_operation",
|
|
428
|
+
batchOperationHandle: params.batchOperationHandle,
|
|
429
|
+
batchOperationMethod: params.batchOperationMethod,
|
|
430
|
+
appInstallationId: params.appInstallationId,
|
|
431
|
+
workflowId: params.workflowId,
|
|
432
|
+
workflowRunId: params.workflowRunId
|
|
433
|
+
};
|
|
434
|
+
}
|
|
423
435
|
|
|
424
436
|
// src/types/tool-context.ts
|
|
425
437
|
function isProvisionContext(ctx) {
|
|
@@ -5843,6 +5855,39 @@ async function handleMcpBatchRoute(req, ctx) {
|
|
|
5843
5855
|
}
|
|
5844
5856
|
};
|
|
5845
5857
|
}
|
|
5858
|
+
function isBatchOperationFailure(result) {
|
|
5859
|
+
return result != null && typeof result === "object" && result.success === false && typeof result.error === "object" && result.error != null;
|
|
5860
|
+
}
|
|
5861
|
+
function toStringEnv(env) {
|
|
5862
|
+
const out = {};
|
|
5863
|
+
for (const [key, value] of Object.entries(env)) {
|
|
5864
|
+
if (value !== void 0) {
|
|
5865
|
+
out[key] = value;
|
|
5866
|
+
}
|
|
5867
|
+
}
|
|
5868
|
+
return out;
|
|
5869
|
+
}
|
|
5870
|
+
function stripBillingFields(result) {
|
|
5871
|
+
const {
|
|
5872
|
+
billing: _billing,
|
|
5873
|
+
success: _success,
|
|
5874
|
+
error: _error,
|
|
5875
|
+
retry: _retry,
|
|
5876
|
+
...domain
|
|
5877
|
+
} = result;
|
|
5878
|
+
return domain;
|
|
5879
|
+
}
|
|
5880
|
+
function softFailureResponse(error, retry, billing) {
|
|
5881
|
+
return {
|
|
5882
|
+
status: 200,
|
|
5883
|
+
body: {
|
|
5884
|
+
success: false,
|
|
5885
|
+
error,
|
|
5886
|
+
...retry ? { retry } : {},
|
|
5887
|
+
billing: normalizeBilling(billing)
|
|
5888
|
+
}
|
|
5889
|
+
};
|
|
5890
|
+
}
|
|
5846
5891
|
async function handleBatchOperationRoute(req, ctx) {
|
|
5847
5892
|
const bodyResult = parseJsonBody(req);
|
|
5848
5893
|
if (!bodyResult.success) {
|
|
@@ -5851,49 +5896,80 @@ async function handleBatchOperationRoute(req, ctx) {
|
|
|
5851
5896
|
const body = bodyResult.data;
|
|
5852
5897
|
const registry = ctx.batchOperationRegistry;
|
|
5853
5898
|
if (!registry) {
|
|
5854
|
-
return {
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
}
|
|
5860
|
-
};
|
|
5899
|
+
return softFailureResponse({
|
|
5900
|
+
code: "NOT_FOUND",
|
|
5901
|
+
message: "No batch operations registered",
|
|
5902
|
+
category: "validation"
|
|
5903
|
+
});
|
|
5861
5904
|
}
|
|
5862
5905
|
const operation = registry[body.handle];
|
|
5863
5906
|
if (!operation) {
|
|
5864
|
-
return {
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
}
|
|
5870
|
-
};
|
|
5907
|
+
return softFailureResponse({
|
|
5908
|
+
code: "NOT_FOUND",
|
|
5909
|
+
message: `Batch operation not found: ${body.handle}`,
|
|
5910
|
+
category: "validation"
|
|
5911
|
+
});
|
|
5871
5912
|
}
|
|
5872
5913
|
const context = body.context;
|
|
5873
5914
|
if (!context?.workplaceId || !context?.appInstallationId || !context?.appId) {
|
|
5874
|
-
return {
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
}
|
|
5880
|
-
};
|
|
5915
|
+
return softFailureResponse({
|
|
5916
|
+
code: "VALIDATION_ERROR",
|
|
5917
|
+
message: "Missing context (workplaceId, appInstallationId, and appId required)",
|
|
5918
|
+
category: "validation"
|
|
5919
|
+
});
|
|
5881
5920
|
}
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5921
|
+
if (body.method !== "setup" && body.method !== "iterate") {
|
|
5922
|
+
return softFailureResponse({
|
|
5923
|
+
code: "VALIDATION_ERROR",
|
|
5924
|
+
message: `Unknown method: ${body.method}`,
|
|
5925
|
+
category: "validation"
|
|
5926
|
+
});
|
|
5927
|
+
}
|
|
5928
|
+
const requestEnv = body.env ?? {};
|
|
5929
|
+
const mergedEnv = toStringEnv(buildToolExecutionEnv(requestEnv));
|
|
5930
|
+
const originalEnv = { ...process.env };
|
|
5931
|
+
Object.assign(process.env, mergedEnv);
|
|
5932
|
+
const log = createContextLogger();
|
|
5933
|
+
const app = context.app ?? {
|
|
5934
|
+
id: context.appId,
|
|
5935
|
+
versionId: context.appId
|
|
5936
|
+
};
|
|
5937
|
+
const workplace2 = context.workplace ?? {
|
|
5938
|
+
id: context.workplaceId,
|
|
5939
|
+
subdomain: ""
|
|
5940
|
+
};
|
|
5941
|
+
const invocation = body.invocation ?? {
|
|
5942
|
+
invocationId: `${body.handle}-${body.method}-${Date.now()}`,
|
|
5943
|
+
invocationType: "batch_operation",
|
|
5944
|
+
batchOperationHandle: body.handle,
|
|
5945
|
+
batchOperationMethod: body.method,
|
|
5946
|
+
appInstallationId: context.appInstallationId
|
|
5893
5947
|
};
|
|
5894
5948
|
const requestConfig = {
|
|
5895
|
-
baseUrl:
|
|
5896
|
-
apiToken:
|
|
5949
|
+
baseUrl: mergedEnv.SKEDYUL_API_URL ?? process.env.SKEDYUL_API_URL ?? "",
|
|
5950
|
+
apiToken: mergedEnv.SKEDYUL_API_TOKEN ?? process.env.SKEDYUL_API_TOKEN ?? ""
|
|
5951
|
+
};
|
|
5952
|
+
const rateLimitContext = {
|
|
5953
|
+
app,
|
|
5954
|
+
appInstallationId: context.appInstallationId,
|
|
5955
|
+
invocation,
|
|
5956
|
+
preAcquiredLeases: parsePreAcquiredLeases(
|
|
5957
|
+
mergedEnv.SKEDYUL_RATE_LIMIT_LEASES
|
|
5958
|
+
),
|
|
5959
|
+
heldMutexQueueKeys: parseHeldMutexQueueKeys(
|
|
5960
|
+
mergedEnv.SKEDYUL_HELD_MUTEX_QUEUE_KEYS
|
|
5961
|
+
)
|
|
5962
|
+
};
|
|
5963
|
+
const opContextBase = {
|
|
5964
|
+
workplaceId: context.workplaceId,
|
|
5965
|
+
appInstallationId: context.appInstallationId,
|
|
5966
|
+
appId: context.appId,
|
|
5967
|
+
app,
|
|
5968
|
+
workplace: workplace2,
|
|
5969
|
+
input: body.input,
|
|
5970
|
+
env: mergedEnv,
|
|
5971
|
+
invocation,
|
|
5972
|
+
log
|
|
5897
5973
|
};
|
|
5898
5974
|
try {
|
|
5899
5975
|
if (body.method === "setup") {
|
|
@@ -5902,67 +5978,88 @@ async function handleBatchOperationRoute(req, ctx) {
|
|
|
5902
5978
|
status: 200,
|
|
5903
5979
|
body: {
|
|
5904
5980
|
success: true,
|
|
5905
|
-
result: { state: {}, total: void 0 }
|
|
5981
|
+
result: { state: {}, total: void 0 },
|
|
5982
|
+
billing: normalizeBilling(void 0)
|
|
5906
5983
|
}
|
|
5907
5984
|
};
|
|
5908
5985
|
}
|
|
5909
|
-
const
|
|
5910
|
-
return
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
input: body.input,
|
|
5915
|
-
env,
|
|
5916
|
-
log
|
|
5986
|
+
const raw2 = await runWithConfig(requestConfig, async () => {
|
|
5987
|
+
return runWithRateLimitExecutionContext(rateLimitContext, async () => {
|
|
5988
|
+
return runWithLogContext({ invocation }, async () => {
|
|
5989
|
+
return operation.setup(opContextBase);
|
|
5990
|
+
});
|
|
5917
5991
|
});
|
|
5918
5992
|
});
|
|
5993
|
+
if (isBatchOperationFailure(raw2)) {
|
|
5994
|
+
return softFailureResponse(raw2.error, raw2.retry, raw2.billing);
|
|
5995
|
+
}
|
|
5996
|
+
const setupResult = raw2;
|
|
5997
|
+
const domain2 = stripBillingFields(
|
|
5998
|
+
setupResult
|
|
5999
|
+
);
|
|
5919
6000
|
return {
|
|
5920
6001
|
status: 200,
|
|
5921
6002
|
body: {
|
|
5922
6003
|
success: true,
|
|
5923
|
-
result
|
|
6004
|
+
result: domain2,
|
|
6005
|
+
billing: normalizeBilling(setupResult.billing)
|
|
5924
6006
|
}
|
|
5925
6007
|
};
|
|
5926
6008
|
}
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
return
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
limit: body.limit,
|
|
5938
|
-
env,
|
|
5939
|
-
log
|
|
6009
|
+
const raw = await runWithConfig(requestConfig, async () => {
|
|
6010
|
+
return runWithRateLimitExecutionContext(rateLimitContext, async () => {
|
|
6011
|
+
return runWithLogContext({ invocation }, async () => {
|
|
6012
|
+
return operation.iterate({
|
|
6013
|
+
...opContextBase,
|
|
6014
|
+
state: body.state,
|
|
6015
|
+
page: body.page,
|
|
6016
|
+
cursor: body.cursor,
|
|
6017
|
+
limit: body.limit
|
|
6018
|
+
});
|
|
5940
6019
|
});
|
|
5941
6020
|
});
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
success: true,
|
|
5946
|
-
result
|
|
5947
|
-
}
|
|
5948
|
-
};
|
|
6021
|
+
});
|
|
6022
|
+
if (isBatchOperationFailure(raw)) {
|
|
6023
|
+
return softFailureResponse(raw.error, raw.retry, raw.billing);
|
|
5949
6024
|
}
|
|
6025
|
+
const iterateResult = raw;
|
|
6026
|
+
const domain = stripBillingFields(
|
|
6027
|
+
iterateResult
|
|
6028
|
+
);
|
|
5950
6029
|
return {
|
|
5951
|
-
status:
|
|
6030
|
+
status: 200,
|
|
5952
6031
|
body: {
|
|
5953
|
-
success:
|
|
5954
|
-
|
|
6032
|
+
success: true,
|
|
6033
|
+
result: domain,
|
|
6034
|
+
billing: normalizeBilling(iterateResult.billing)
|
|
5955
6035
|
}
|
|
5956
6036
|
};
|
|
5957
6037
|
} catch (err) {
|
|
5958
|
-
|
|
6038
|
+
if (err instanceof RateLimitExceededError) {
|
|
6039
|
+
return softFailureResponse(
|
|
6040
|
+
{
|
|
6041
|
+
code: "RATE_LIMITED",
|
|
6042
|
+
message: err.message,
|
|
6043
|
+
category: "external"
|
|
6044
|
+
},
|
|
6045
|
+
{ allowed: true, afterMs: err.retryAfterMs }
|
|
6046
|
+
);
|
|
6047
|
+
}
|
|
6048
|
+
log.error("Batch operation failed", err);
|
|
5959
6049
|
return {
|
|
5960
6050
|
status: 500,
|
|
5961
6051
|
body: {
|
|
5962
6052
|
success: false,
|
|
5963
|
-
error:
|
|
6053
|
+
error: {
|
|
6054
|
+
code: "INTERNAL_ERROR",
|
|
6055
|
+
message: err instanceof Error ? err.message : String(err),
|
|
6056
|
+
category: "internal"
|
|
6057
|
+
},
|
|
6058
|
+
billing: normalizeBilling(void 0)
|
|
5964
6059
|
}
|
|
5965
6060
|
};
|
|
6061
|
+
} finally {
|
|
6062
|
+
process.env = originalEnv;
|
|
5966
6063
|
}
|
|
5967
6064
|
}
|
|
5968
6065
|
function createNotFoundResponse() {
|
|
@@ -9193,6 +9290,7 @@ var index_default = { z: import_v414.z };
|
|
|
9193
9290
|
computeSkewedExpectedMinorUnits,
|
|
9194
9291
|
configure,
|
|
9195
9292
|
createAuthError,
|
|
9293
|
+
createBatchOperationContext,
|
|
9196
9294
|
createConflictError,
|
|
9197
9295
|
createContextLogger,
|
|
9198
9296
|
createErrorResponse,
|
|
@@ -63,8 +63,8 @@ export declare function handleMcpBatchRoute(req: UnifiedRequest, ctx: RouteConte
|
|
|
63
63
|
/**
|
|
64
64
|
* Handle /batch-operation route for invoking batch operation setup/iterate.
|
|
65
65
|
*
|
|
66
|
-
* Mirrors tool
|
|
67
|
-
*
|
|
66
|
+
* Mirrors tool handlers: buildToolExecutionEnv, process.env assign/restore,
|
|
67
|
+
* runWithConfig + rate-limit + log ALS wrappers, tool-shaped billing/error envelope.
|
|
68
68
|
*/
|
|
69
69
|
export declare function handleBatchOperationRoute(req: UnifiedRequest, ctx: RouteContext): Promise<UnifiedResponse>;
|
|
70
70
|
/**
|