skedyul 1.7.2 → 1.7.5
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 -0
- package/dist/cli/index.js +24 -1
- package/dist/config/types/navigation.d.ts +12 -0
- package/dist/core/client.d.ts +4 -0
- package/dist/dedicated/server.js +24 -1
- package/dist/esm/index.mjs +49 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +49 -2
- package/dist/ratelimit/context.d.ts +1 -1
- package/dist/ratelimit/types.d.ts +10 -0
- package/dist/server/tool-handler.d.ts +4 -0
- package/dist/server.js +24 -1
- package/dist/serverless/server.mjs +24 -1
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1785810690937
|
package/dist/cli/index.js
CHANGED
|
@@ -3111,6 +3111,26 @@ function parsePreAcquiredLeases(raw) {
|
|
|
3111
3111
|
return void 0;
|
|
3112
3112
|
}
|
|
3113
3113
|
}
|
|
3114
|
+
function parseHeldMutexQueueKeys(raw) {
|
|
3115
|
+
if (!raw) {
|
|
3116
|
+
return void 0;
|
|
3117
|
+
}
|
|
3118
|
+
try {
|
|
3119
|
+
const parsed = JSON.parse(raw);
|
|
3120
|
+
if (!Array.isArray(parsed)) {
|
|
3121
|
+
return void 0;
|
|
3122
|
+
}
|
|
3123
|
+
const keys = parsed.filter(
|
|
3124
|
+
(item) => item != null && typeof item === "object" && typeof item.queueKey === "string" && typeof item.queueName === "string"
|
|
3125
|
+
).map((item) => ({
|
|
3126
|
+
queueKey: item.queueKey,
|
|
3127
|
+
queueName: item.queueName
|
|
3128
|
+
}));
|
|
3129
|
+
return keys.length > 0 ? keys : void 0;
|
|
3130
|
+
} catch {
|
|
3131
|
+
return void 0;
|
|
3132
|
+
}
|
|
3133
|
+
}
|
|
3114
3134
|
function buildToolMetadata(registry) {
|
|
3115
3135
|
return Object.values(registry).map((tool) => {
|
|
3116
3136
|
const toolConfig = tool.config ?? {};
|
|
@@ -3248,7 +3268,10 @@ function createCallToolHandler(registry, state, onMaxRequests) {
|
|
|
3248
3268
|
appInstallationId: trigger === "provision" ? void 0 : rawContext.appInstallationId,
|
|
3249
3269
|
invocation,
|
|
3250
3270
|
isProvisionContext: trigger === "provision",
|
|
3251
|
-
preAcquiredLeases: parsePreAcquiredLeases(toolEnv.SKEDYUL_RATE_LIMIT_LEASES)
|
|
3271
|
+
preAcquiredLeases: parsePreAcquiredLeases(toolEnv.SKEDYUL_RATE_LIMIT_LEASES),
|
|
3272
|
+
heldMutexQueueKeys: parseHeldMutexQueueKeys(
|
|
3273
|
+
toolEnv.SKEDYUL_HELD_MUTEX_QUEUE_KEYS
|
|
3274
|
+
)
|
|
3252
3275
|
};
|
|
3253
3276
|
const functionResult = await runWithConfig(requestConfig, async () => {
|
|
3254
3277
|
return await runWithRateLimitExecutionContext(rateLimitContext, async () => {
|
|
@@ -49,10 +49,22 @@ export interface NavigationBreadcrumb {
|
|
|
49
49
|
/** Breadcrumb items from left to right */
|
|
50
50
|
items: BreadcrumbItem[];
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Optional Liquid context for base navigation (model lookups).
|
|
54
|
+
* Setup capabilities are always injected by the platform as `capabilities`.
|
|
55
|
+
*/
|
|
56
|
+
export type NavigationContextDefinition = Record<string, {
|
|
57
|
+
model: string;
|
|
58
|
+
mode?: 'first' | 'list' | 'count';
|
|
59
|
+
filters?: Record<string, Record<string, unknown>>;
|
|
60
|
+
limit?: number;
|
|
61
|
+
}>;
|
|
52
62
|
/**
|
|
53
63
|
* Full navigation configuration.
|
|
54
64
|
*/
|
|
55
65
|
export interface NavigationConfig {
|
|
66
|
+
/** Optional model context for Liquid in sidebar items (e.g. studio) */
|
|
67
|
+
context?: NavigationContextDefinition;
|
|
56
68
|
/** Sidebar navigation */
|
|
57
69
|
sidebar?: NavigationSidebar;
|
|
58
70
|
/** Breadcrumb navigation */
|
package/dist/core/client.d.ts
CHANGED
|
@@ -1269,6 +1269,9 @@ export type SetupListResult = {
|
|
|
1269
1269
|
steps: SetupStepView[];
|
|
1270
1270
|
capabilities: Record<string, boolean>;
|
|
1271
1271
|
};
|
|
1272
|
+
export type SetupReconcileResult = {
|
|
1273
|
+
completed: number;
|
|
1274
|
+
};
|
|
1272
1275
|
/**
|
|
1273
1276
|
* Install setup checklist API (requires sk_wkp_ token).
|
|
1274
1277
|
*/
|
|
@@ -1278,6 +1281,7 @@ export declare const setup: {
|
|
|
1278
1281
|
complete(handle: string, metadata?: Record<string, unknown>): Promise<SetupStepView>;
|
|
1279
1282
|
skip(handle: string, metadata?: Record<string, unknown>): Promise<SetupStepView>;
|
|
1280
1283
|
invalidate(handle: string, reason?: string, metadata?: Record<string, unknown>): Promise<SetupStepView>;
|
|
1284
|
+
reconcile(): Promise<SetupReconcileResult>;
|
|
1281
1285
|
capabilities(): Promise<Record<string, boolean>>;
|
|
1282
1286
|
};
|
|
1283
1287
|
export {};
|
package/dist/dedicated/server.js
CHANGED
|
@@ -441,6 +441,26 @@ function parsePreAcquiredLeases(raw) {
|
|
|
441
441
|
return void 0;
|
|
442
442
|
}
|
|
443
443
|
}
|
|
444
|
+
function parseHeldMutexQueueKeys(raw) {
|
|
445
|
+
if (!raw) {
|
|
446
|
+
return void 0;
|
|
447
|
+
}
|
|
448
|
+
try {
|
|
449
|
+
const parsed = JSON.parse(raw);
|
|
450
|
+
if (!Array.isArray(parsed)) {
|
|
451
|
+
return void 0;
|
|
452
|
+
}
|
|
453
|
+
const keys = parsed.filter(
|
|
454
|
+
(item) => item != null && typeof item === "object" && typeof item.queueKey === "string" && typeof item.queueName === "string"
|
|
455
|
+
).map((item) => ({
|
|
456
|
+
queueKey: item.queueKey,
|
|
457
|
+
queueName: item.queueName
|
|
458
|
+
}));
|
|
459
|
+
return keys.length > 0 ? keys : void 0;
|
|
460
|
+
} catch {
|
|
461
|
+
return void 0;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
444
464
|
function buildToolMetadata(registry) {
|
|
445
465
|
return Object.values(registry).map((tool) => {
|
|
446
466
|
const toolConfig = tool.config ?? {};
|
|
@@ -578,7 +598,10 @@ function createCallToolHandler(registry, state, onMaxRequests) {
|
|
|
578
598
|
appInstallationId: trigger === "provision" ? void 0 : rawContext.appInstallationId,
|
|
579
599
|
invocation,
|
|
580
600
|
isProvisionContext: trigger === "provision",
|
|
581
|
-
preAcquiredLeases: parsePreAcquiredLeases(toolEnv.SKEDYUL_RATE_LIMIT_LEASES)
|
|
601
|
+
preAcquiredLeases: parsePreAcquiredLeases(toolEnv.SKEDYUL_RATE_LIMIT_LEASES),
|
|
602
|
+
heldMutexQueueKeys: parseHeldMutexQueueKeys(
|
|
603
|
+
toolEnv.SKEDYUL_HELD_MUTEX_QUEUE_KEYS
|
|
604
|
+
)
|
|
582
605
|
};
|
|
583
606
|
const functionResult = await runWithConfig(requestConfig, async () => {
|
|
584
607
|
return await runWithRateLimitExecutionContext(rateLimitContext, async () => {
|
package/dist/esm/index.mjs
CHANGED
|
@@ -3597,6 +3597,13 @@ var setup = {
|
|
|
3597
3597
|
});
|
|
3598
3598
|
return data;
|
|
3599
3599
|
},
|
|
3600
|
+
async reconcile() {
|
|
3601
|
+
const { data } = await callCore(
|
|
3602
|
+
"setup.reconcile",
|
|
3603
|
+
{}
|
|
3604
|
+
);
|
|
3605
|
+
return data;
|
|
3606
|
+
},
|
|
3600
3607
|
async capabilities() {
|
|
3601
3608
|
const { data } = await callCore(
|
|
3602
3609
|
"setup.capabilities",
|
|
@@ -3642,6 +3649,14 @@ function getActiveMutexQueueNames() {
|
|
|
3642
3649
|
names.add(operation.resolved.name);
|
|
3643
3650
|
}
|
|
3644
3651
|
}
|
|
3652
|
+
const held = getRateLimitExecutionContext()?.heldMutexQueueKeys;
|
|
3653
|
+
if (held?.length) {
|
|
3654
|
+
for (const entry of held) {
|
|
3655
|
+
if (entry.queueName) {
|
|
3656
|
+
names.add(entry.queueName);
|
|
3657
|
+
}
|
|
3658
|
+
}
|
|
3659
|
+
}
|
|
3645
3660
|
return [...names];
|
|
3646
3661
|
}
|
|
3647
3662
|
function shouldSkipNestedAcquire(queueName) {
|
|
@@ -3880,6 +3895,26 @@ function parsePreAcquiredLeases(raw) {
|
|
|
3880
3895
|
return void 0;
|
|
3881
3896
|
}
|
|
3882
3897
|
}
|
|
3898
|
+
function parseHeldMutexQueueKeys(raw) {
|
|
3899
|
+
if (!raw) {
|
|
3900
|
+
return void 0;
|
|
3901
|
+
}
|
|
3902
|
+
try {
|
|
3903
|
+
const parsed = JSON.parse(raw);
|
|
3904
|
+
if (!Array.isArray(parsed)) {
|
|
3905
|
+
return void 0;
|
|
3906
|
+
}
|
|
3907
|
+
const keys = parsed.filter(
|
|
3908
|
+
(item) => item != null && typeof item === "object" && typeof item.queueKey === "string" && typeof item.queueName === "string"
|
|
3909
|
+
).map((item) => ({
|
|
3910
|
+
queueKey: item.queueKey,
|
|
3911
|
+
queueName: item.queueName
|
|
3912
|
+
}));
|
|
3913
|
+
return keys.length > 0 ? keys : void 0;
|
|
3914
|
+
} catch {
|
|
3915
|
+
return void 0;
|
|
3916
|
+
}
|
|
3917
|
+
}
|
|
3883
3918
|
function buildToolMetadata(registry) {
|
|
3884
3919
|
return Object.values(registry).map((tool) => {
|
|
3885
3920
|
const toolConfig = tool.config ?? {};
|
|
@@ -4017,7 +4052,10 @@ function createCallToolHandler(registry, state, onMaxRequests) {
|
|
|
4017
4052
|
appInstallationId: trigger === "provision" ? void 0 : rawContext.appInstallationId,
|
|
4018
4053
|
invocation,
|
|
4019
4054
|
isProvisionContext: trigger === "provision",
|
|
4020
|
-
preAcquiredLeases: parsePreAcquiredLeases(toolEnv.SKEDYUL_RATE_LIMIT_LEASES)
|
|
4055
|
+
preAcquiredLeases: parsePreAcquiredLeases(toolEnv.SKEDYUL_RATE_LIMIT_LEASES),
|
|
4056
|
+
heldMutexQueueKeys: parseHeldMutexQueueKeys(
|
|
4057
|
+
toolEnv.SKEDYUL_HELD_MUTEX_QUEUE_KEYS
|
|
4058
|
+
)
|
|
4021
4059
|
};
|
|
4022
4060
|
const functionResult = await runWithConfig(requestConfig, async () => {
|
|
4023
4061
|
return await runWithRateLimitExecutionContext(rateLimitContext, async () => {
|
|
@@ -6409,6 +6447,11 @@ async function queuedFetch(queueInput, fnOrPromise) {
|
|
|
6409
6447
|
function findPreAcquiredLease(queueKey, ctx) {
|
|
6410
6448
|
return ctx?.preAcquiredLeases?.find((lease) => lease.queueKey === queueKey);
|
|
6411
6449
|
}
|
|
6450
|
+
function isHeldMutexQueueKey(queueKey, ctx) {
|
|
6451
|
+
return Boolean(
|
|
6452
|
+
ctx?.heldMutexQueueKeys?.some((entry) => entry.queueKey === queueKey)
|
|
6453
|
+
);
|
|
6454
|
+
}
|
|
6412
6455
|
function shouldRethrowRateLimitCause(maxRetries, error, attempt, shouldRetryFn) {
|
|
6413
6456
|
if (maxRetries !== 0 || !shouldRetryFn(error, attempt)) {
|
|
6414
6457
|
return false;
|
|
@@ -6426,10 +6469,14 @@ async function executeWithRetries(operation, maxRetries) {
|
|
|
6426
6469
|
operation.resolved.queueKey,
|
|
6427
6470
|
rateLimitCtx
|
|
6428
6471
|
);
|
|
6472
|
+
const heldByPlatform = isHeldMutexQueueKey(
|
|
6473
|
+
operation.resolved.queueKey,
|
|
6474
|
+
rateLimitCtx
|
|
6475
|
+
);
|
|
6429
6476
|
if (shouldSkipNestedAcquire(operation.resolved.name)) {
|
|
6430
6477
|
return operation.fn();
|
|
6431
6478
|
}
|
|
6432
|
-
if (preAcquired) {
|
|
6479
|
+
if (preAcquired || heldByPlatform) {
|
|
6433
6480
|
try {
|
|
6434
6481
|
return await operation.fn();
|
|
6435
6482
|
} catch (error) {
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export { InstallError, MissingRequiredFieldError, AuthenticationError, InvalidCo
|
|
|
9
9
|
export type { InstallErrorCode } from './errors';
|
|
10
10
|
export { z };
|
|
11
11
|
export { workplace, communicationChannel, instance, token, file, webhook, cron, event, resource, ai, call, report, setup, configure, getConfig, runWithConfig, createInstanceClient, } from './core/client';
|
|
12
|
-
export type { InstanceClient, InstanceContext, InstanceData, InstanceEnv, InstanceWriteOptions, InstanceGetOptions, InstanceCreateManyItem, InstanceUpdateManyItem, InstanceMeta, InstancePagination, InstanceListResult, InstanceListArgs, FileInfo, FileUrlResponse, FileUploadParams, FileUploadResult, WebhookCreateResult, WebhookListItem, WebhookDeleteByNameOptions, WebhookListOptions, CallStartParams, CallStartResult, CallAppendTranscriptParams, CallEndParams, CallSummarizeResult, CronSubscribeParams, CronSubscribeResult, CronSubscriptionItem, CronListOptions, EventCreateResult, EventCreateOptions, ResourceLinkParams, ResourceLinkResult, AITextContent, AIFileContent, AIImageContent, AIMessageContent, AIMessage, GenerateObjectOptions, GenerateObjectResult, ReportGenerateParams, ReportGenerateResult, ReportDefineParams, ReportDefineResult, ReportListParams, ReportListItem, ReportListResult, ReportDefinition, SetupStepStatus, SetupStepKindApi, SetupStepView, SetupListResult, } from './core/client';
|
|
12
|
+
export type { InstanceClient, InstanceContext, InstanceData, InstanceEnv, InstanceWriteOptions, InstanceGetOptions, InstanceCreateManyItem, InstanceUpdateManyItem, InstanceMeta, InstancePagination, InstanceListResult, InstanceListArgs, FileInfo, FileUrlResponse, FileUploadParams, FileUploadResult, WebhookCreateResult, WebhookListItem, WebhookDeleteByNameOptions, WebhookListOptions, CallStartParams, CallStartResult, CallAppendTranscriptParams, CallEndParams, CallSummarizeResult, CronSubscribeParams, CronSubscribeResult, CronSubscriptionItem, CronListOptions, EventCreateResult, EventCreateOptions, ResourceLinkParams, ResourceLinkResult, AITextContent, AIFileContent, AIImageContent, AIMessageContent, AIMessage, GenerateObjectOptions, GenerateObjectResult, ReportGenerateParams, ReportGenerateResult, ReportDefineParams, ReportDefineResult, ReportListParams, ReportListItem, ReportListResult, ReportDefinition, SetupStepStatus, SetupStepKindApi, SetupStepView, SetupListResult, SetupReconcileResult, } from './core/client';
|
|
13
13
|
export { createContextLogger } from './server/logger';
|
|
14
14
|
export type { ContextLogger } from './server/logger';
|
|
15
15
|
declare const _default: {
|
package/dist/index.js
CHANGED
|
@@ -3971,6 +3971,13 @@ var setup = {
|
|
|
3971
3971
|
});
|
|
3972
3972
|
return data;
|
|
3973
3973
|
},
|
|
3974
|
+
async reconcile() {
|
|
3975
|
+
const { data } = await callCore(
|
|
3976
|
+
"setup.reconcile",
|
|
3977
|
+
{}
|
|
3978
|
+
);
|
|
3979
|
+
return data;
|
|
3980
|
+
},
|
|
3974
3981
|
async capabilities() {
|
|
3975
3982
|
const { data } = await callCore(
|
|
3976
3983
|
"setup.capabilities",
|
|
@@ -4016,6 +4023,14 @@ function getActiveMutexQueueNames() {
|
|
|
4016
4023
|
names.add(operation.resolved.name);
|
|
4017
4024
|
}
|
|
4018
4025
|
}
|
|
4026
|
+
const held = getRateLimitExecutionContext()?.heldMutexQueueKeys;
|
|
4027
|
+
if (held?.length) {
|
|
4028
|
+
for (const entry of held) {
|
|
4029
|
+
if (entry.queueName) {
|
|
4030
|
+
names.add(entry.queueName);
|
|
4031
|
+
}
|
|
4032
|
+
}
|
|
4033
|
+
}
|
|
4019
4034
|
return [...names];
|
|
4020
4035
|
}
|
|
4021
4036
|
function shouldSkipNestedAcquire(queueName) {
|
|
@@ -4254,6 +4269,26 @@ function parsePreAcquiredLeases(raw) {
|
|
|
4254
4269
|
return void 0;
|
|
4255
4270
|
}
|
|
4256
4271
|
}
|
|
4272
|
+
function parseHeldMutexQueueKeys(raw) {
|
|
4273
|
+
if (!raw) {
|
|
4274
|
+
return void 0;
|
|
4275
|
+
}
|
|
4276
|
+
try {
|
|
4277
|
+
const parsed = JSON.parse(raw);
|
|
4278
|
+
if (!Array.isArray(parsed)) {
|
|
4279
|
+
return void 0;
|
|
4280
|
+
}
|
|
4281
|
+
const keys = parsed.filter(
|
|
4282
|
+
(item) => item != null && typeof item === "object" && typeof item.queueKey === "string" && typeof item.queueName === "string"
|
|
4283
|
+
).map((item) => ({
|
|
4284
|
+
queueKey: item.queueKey,
|
|
4285
|
+
queueName: item.queueName
|
|
4286
|
+
}));
|
|
4287
|
+
return keys.length > 0 ? keys : void 0;
|
|
4288
|
+
} catch {
|
|
4289
|
+
return void 0;
|
|
4290
|
+
}
|
|
4291
|
+
}
|
|
4257
4292
|
function buildToolMetadata(registry) {
|
|
4258
4293
|
return Object.values(registry).map((tool) => {
|
|
4259
4294
|
const toolConfig = tool.config ?? {};
|
|
@@ -4391,7 +4426,10 @@ function createCallToolHandler(registry, state, onMaxRequests) {
|
|
|
4391
4426
|
appInstallationId: trigger === "provision" ? void 0 : rawContext.appInstallationId,
|
|
4392
4427
|
invocation,
|
|
4393
4428
|
isProvisionContext: trigger === "provision",
|
|
4394
|
-
preAcquiredLeases: parsePreAcquiredLeases(toolEnv.SKEDYUL_RATE_LIMIT_LEASES)
|
|
4429
|
+
preAcquiredLeases: parsePreAcquiredLeases(toolEnv.SKEDYUL_RATE_LIMIT_LEASES),
|
|
4430
|
+
heldMutexQueueKeys: parseHeldMutexQueueKeys(
|
|
4431
|
+
toolEnv.SKEDYUL_HELD_MUTEX_QUEUE_KEYS
|
|
4432
|
+
)
|
|
4395
4433
|
};
|
|
4396
4434
|
const functionResult = await runWithConfig(requestConfig, async () => {
|
|
4397
4435
|
return await runWithRateLimitExecutionContext(rateLimitContext, async () => {
|
|
@@ -6783,6 +6821,11 @@ async function queuedFetch(queueInput, fnOrPromise) {
|
|
|
6783
6821
|
function findPreAcquiredLease(queueKey, ctx) {
|
|
6784
6822
|
return ctx?.preAcquiredLeases?.find((lease) => lease.queueKey === queueKey);
|
|
6785
6823
|
}
|
|
6824
|
+
function isHeldMutexQueueKey(queueKey, ctx) {
|
|
6825
|
+
return Boolean(
|
|
6826
|
+
ctx?.heldMutexQueueKeys?.some((entry) => entry.queueKey === queueKey)
|
|
6827
|
+
);
|
|
6828
|
+
}
|
|
6786
6829
|
function shouldRethrowRateLimitCause(maxRetries, error, attempt, shouldRetryFn) {
|
|
6787
6830
|
if (maxRetries !== 0 || !shouldRetryFn(error, attempt)) {
|
|
6788
6831
|
return false;
|
|
@@ -6800,10 +6843,14 @@ async function executeWithRetries(operation, maxRetries) {
|
|
|
6800
6843
|
operation.resolved.queueKey,
|
|
6801
6844
|
rateLimitCtx
|
|
6802
6845
|
);
|
|
6846
|
+
const heldByPlatform = isHeldMutexQueueKey(
|
|
6847
|
+
operation.resolved.queueKey,
|
|
6848
|
+
rateLimitCtx
|
|
6849
|
+
);
|
|
6803
6850
|
if (shouldSkipNestedAcquire(operation.resolved.name)) {
|
|
6804
6851
|
return operation.fn();
|
|
6805
6852
|
}
|
|
6806
|
-
if (preAcquired) {
|
|
6853
|
+
if (preAcquired || heldByPlatform) {
|
|
6807
6854
|
try {
|
|
6808
6855
|
return await operation.fn();
|
|
6809
6856
|
} catch (error) {
|
|
@@ -4,7 +4,7 @@ export declare function getRateLimitExecutionContext(): RateLimitExecutionContex
|
|
|
4
4
|
export declare function runWithActiveQueuedOperation<T>(operation: ActiveQueuedOperation<T>, fn: () => Promise<T>): Promise<T>;
|
|
5
5
|
export declare function getActiveQueuedOperation<T>(): ActiveQueuedOperation<T> | undefined;
|
|
6
6
|
export declare function getActiveQueuedOperationStack(): ActiveQueuedOperation<unknown>[];
|
|
7
|
-
/** Active mutex queue names holding a lease in an outer queuedFetch. */
|
|
7
|
+
/** Active mutex queue names holding a lease in an outer queuedFetch or platform-held. */
|
|
8
8
|
export declare function getActiveMutexQueueNames(): string[];
|
|
9
9
|
/** True when an active mutex queue suppresses acquire for the target queue name. */
|
|
10
10
|
export declare function shouldSkipNestedAcquire(queueName: string): boolean;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { SerializableQueueConfig } from '../config/queue-config';
|
|
2
2
|
import type { AppInfo } from '../types/shared';
|
|
3
3
|
import type { InvocationContext } from '../types/invocation';
|
|
4
|
+
export interface HeldMutexQueueKey {
|
|
5
|
+
queueKey: string;
|
|
6
|
+
queueName: string;
|
|
7
|
+
}
|
|
4
8
|
export interface RateLimitExecutionContext {
|
|
5
9
|
app: AppInfo;
|
|
6
10
|
appInstallationId?: string;
|
|
@@ -11,6 +15,12 @@ export interface RateLimitExecutionContext {
|
|
|
11
15
|
queueKey: string;
|
|
12
16
|
leaseId: string;
|
|
13
17
|
}>;
|
|
18
|
+
/**
|
|
19
|
+
* Mutex queue keys held by platform Temporal orchestration for this tool call.
|
|
20
|
+
* queuedFetch skips acquire/release for matching keys; queue names count as active mutexes
|
|
21
|
+
* for suppressesQueues.
|
|
22
|
+
*/
|
|
23
|
+
heldMutexQueueKeys?: HeldMutexQueueKey[];
|
|
14
24
|
}
|
|
15
25
|
export interface QueueSelector {
|
|
16
26
|
queue: string;
|
|
@@ -4,6 +4,10 @@ export declare function parsePreAcquiredLeases(raw: string | undefined): Array<{
|
|
|
4
4
|
queueKey: string;
|
|
5
5
|
leaseId: string;
|
|
6
6
|
}> | undefined;
|
|
7
|
+
export declare function parseHeldMutexQueueKeys(raw: string | undefined): Array<{
|
|
8
|
+
queueKey: string;
|
|
9
|
+
queueName: string;
|
|
10
|
+
}> | undefined;
|
|
7
11
|
/**
|
|
8
12
|
* Builds tool metadata array from a tool registry
|
|
9
13
|
*/
|
package/dist/server.js
CHANGED
|
@@ -441,6 +441,26 @@ function parsePreAcquiredLeases(raw) {
|
|
|
441
441
|
return void 0;
|
|
442
442
|
}
|
|
443
443
|
}
|
|
444
|
+
function parseHeldMutexQueueKeys(raw) {
|
|
445
|
+
if (!raw) {
|
|
446
|
+
return void 0;
|
|
447
|
+
}
|
|
448
|
+
try {
|
|
449
|
+
const parsed = JSON.parse(raw);
|
|
450
|
+
if (!Array.isArray(parsed)) {
|
|
451
|
+
return void 0;
|
|
452
|
+
}
|
|
453
|
+
const keys = parsed.filter(
|
|
454
|
+
(item) => item != null && typeof item === "object" && typeof item.queueKey === "string" && typeof item.queueName === "string"
|
|
455
|
+
).map((item) => ({
|
|
456
|
+
queueKey: item.queueKey,
|
|
457
|
+
queueName: item.queueName
|
|
458
|
+
}));
|
|
459
|
+
return keys.length > 0 ? keys : void 0;
|
|
460
|
+
} catch {
|
|
461
|
+
return void 0;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
444
464
|
function buildToolMetadata(registry) {
|
|
445
465
|
return Object.values(registry).map((tool) => {
|
|
446
466
|
const toolConfig = tool.config ?? {};
|
|
@@ -578,7 +598,10 @@ function createCallToolHandler(registry, state, onMaxRequests) {
|
|
|
578
598
|
appInstallationId: trigger === "provision" ? void 0 : rawContext.appInstallationId,
|
|
579
599
|
invocation,
|
|
580
600
|
isProvisionContext: trigger === "provision",
|
|
581
|
-
preAcquiredLeases: parsePreAcquiredLeases(toolEnv.SKEDYUL_RATE_LIMIT_LEASES)
|
|
601
|
+
preAcquiredLeases: parsePreAcquiredLeases(toolEnv.SKEDYUL_RATE_LIMIT_LEASES),
|
|
602
|
+
heldMutexQueueKeys: parseHeldMutexQueueKeys(
|
|
603
|
+
toolEnv.SKEDYUL_HELD_MUTEX_QUEUE_KEYS
|
|
604
|
+
)
|
|
582
605
|
};
|
|
583
606
|
const functionResult = await runWithConfig(requestConfig, async () => {
|
|
584
607
|
return await runWithRateLimitExecutionContext(rateLimitContext, async () => {
|
|
@@ -402,6 +402,26 @@ function parsePreAcquiredLeases(raw) {
|
|
|
402
402
|
return void 0;
|
|
403
403
|
}
|
|
404
404
|
}
|
|
405
|
+
function parseHeldMutexQueueKeys(raw) {
|
|
406
|
+
if (!raw) {
|
|
407
|
+
return void 0;
|
|
408
|
+
}
|
|
409
|
+
try {
|
|
410
|
+
const parsed = JSON.parse(raw);
|
|
411
|
+
if (!Array.isArray(parsed)) {
|
|
412
|
+
return void 0;
|
|
413
|
+
}
|
|
414
|
+
const keys = parsed.filter(
|
|
415
|
+
(item) => item != null && typeof item === "object" && typeof item.queueKey === "string" && typeof item.queueName === "string"
|
|
416
|
+
).map((item) => ({
|
|
417
|
+
queueKey: item.queueKey,
|
|
418
|
+
queueName: item.queueName
|
|
419
|
+
}));
|
|
420
|
+
return keys.length > 0 ? keys : void 0;
|
|
421
|
+
} catch {
|
|
422
|
+
return void 0;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
405
425
|
function buildToolMetadata(registry) {
|
|
406
426
|
return Object.values(registry).map((tool) => {
|
|
407
427
|
const toolConfig = tool.config ?? {};
|
|
@@ -539,7 +559,10 @@ function createCallToolHandler(registry, state, onMaxRequests) {
|
|
|
539
559
|
appInstallationId: trigger === "provision" ? void 0 : rawContext.appInstallationId,
|
|
540
560
|
invocation,
|
|
541
561
|
isProvisionContext: trigger === "provision",
|
|
542
|
-
preAcquiredLeases: parsePreAcquiredLeases(toolEnv.SKEDYUL_RATE_LIMIT_LEASES)
|
|
562
|
+
preAcquiredLeases: parsePreAcquiredLeases(toolEnv.SKEDYUL_RATE_LIMIT_LEASES),
|
|
563
|
+
heldMutexQueueKeys: parseHeldMutexQueueKeys(
|
|
564
|
+
toolEnv.SKEDYUL_HELD_MUTEX_QUEUE_KEYS
|
|
565
|
+
)
|
|
543
566
|
};
|
|
544
567
|
const functionResult = await runWithConfig(requestConfig, async () => {
|
|
545
568
|
return await runWithRateLimitExecutionContext(rateLimitContext, async () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skedyul",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.5",
|
|
4
4
|
"description": "The Skedyul SDK for Node.js",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -73,9 +73,9 @@
|
|
|
73
73
|
"dist"
|
|
74
74
|
],
|
|
75
75
|
"scripts": {
|
|
76
|
-
"build": "rm -rf dist tsconfig.tsbuildinfo && tsc --emitDeclarationOnly && pnpm exec tsup-node",
|
|
76
|
+
"build": "rm -rf dist tsconfig.tsbuildinfo && tsc --emitDeclarationOnly && pnpm exec tsup-node && node -e \"require('fs').mkdirSync('dist',{recursive:true}); require('fs').writeFileSync('dist/.build-stamp', String(Date.now()))\"",
|
|
77
77
|
"db:generate": "echo 'No database generation needed for this package'",
|
|
78
|
-
"dev": "npx nodemon --watch src --ext js,ts --exec \"pnpm run build\"",
|
|
78
|
+
"dev:watch": "npx nodemon --watch src --ext js,ts --exec \"pnpm run build\"",
|
|
79
79
|
"test": "tsc --project tsconfig.tests.json && node --test dist-tests/tests/server.test.js dist-tests/tests/cli.test.js dist-tests/tests/agent-schema-v3.test.js dist-tests/tests/ratelimit.test.js dist-tests/tests/sequencer.test.js dist-tests/tests/config-loader.test.js dist-tests/tests/gsm7.test.js"
|
|
80
80
|
},
|
|
81
81
|
"keywords": [
|