skedyul 1.5.13 → 1.7.0
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/cli/index.js +178 -148
- package/dist/config/app-config.d.ts +12 -1
- package/dist/config/define.d.ts +23 -0
- package/dist/config/index.d.ts +2 -2
- package/dist/config/sequencer-config.d.ts +20 -0
- package/dist/config/types/entity.d.ts +59 -0
- package/dist/config/types/index.d.ts +1 -0
- package/dist/config/types/model.d.ts +2 -0
- package/dist/core/client.d.ts +23 -8
- package/dist/dedicated/server.js +35 -11
- package/dist/esm/index.mjs +573 -42
- package/dist/index.d.ts +4 -2
- package/dist/index.js +594 -42
- package/dist/schemas/crm-schema.d.ts +10 -0
- package/dist/schemas.d.ts +229 -0
- package/dist/sequencer/backends/index.d.ts +10 -0
- package/dist/sequencer/backends/memory.d.ts +26 -0
- package/dist/sequencer/backends/platform.d.ts +22 -0
- package/dist/sequencer/config-loader.d.ts +9 -0
- package/dist/sequencer/errors.d.ts +17 -0
- package/dist/sequencer/index.d.ts +24 -0
- package/dist/sequencer/resolve-sequencer-key.d.ts +7 -0
- package/dist/sequencer/types.d.ts +50 -0
- package/dist/server.js +35 -11
- package/dist/serverless/server.mjs +35 -11
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -82,6 +82,9 @@ __export(index_exports, {
|
|
|
82
82
|
DatePickerComponentDefinitionSchema: () => DatePickerComponentDefinitionSchema,
|
|
83
83
|
DayOfWeekSchema: () => DayOfWeekSchema,
|
|
84
84
|
EmptyFormComponentDefinitionSchema: () => EmptyFormComponentDefinitionSchema,
|
|
85
|
+
EntityDefinitionSchema: () => EntityDefinitionSchema,
|
|
86
|
+
EntityFieldDefinitionSchema: () => EntityFieldDefinitionSchema,
|
|
87
|
+
EntityRelationshipDefinitionSchema: () => EntityRelationshipDefinitionSchema,
|
|
85
88
|
EnvSchemaSchema: () => EnvSchemaSchema,
|
|
86
89
|
EnvVariableDefinitionSchema: () => EnvVariableDefinitionSchema,
|
|
87
90
|
EnvVisibilitySchema: () => EnvVisibilitySchema,
|
|
@@ -199,6 +202,10 @@ __export(index_exports, {
|
|
|
199
202
|
SelectComponentDefinitionSchema: () => SelectComponentDefinitionSchema,
|
|
200
203
|
SemanticMemoryConfigSchema: () => SemanticMemoryConfigSchema2,
|
|
201
204
|
SenderContextSchema: () => SenderContextSchema,
|
|
205
|
+
SequencerBackendError: () => SequencerBackendError,
|
|
206
|
+
SequencerContextError: () => SequencerContextError,
|
|
207
|
+
SequencerLockError: () => SequencerLockError,
|
|
208
|
+
SequencerNotFoundError: () => SequencerNotFoundError,
|
|
202
209
|
SkedyulConfigSchema: () => SkedyulConfigSchema,
|
|
203
210
|
SkillExampleSchema: () => SkillExampleSchema,
|
|
204
211
|
SkillMetadataSchema: () => SkillMetadataSchema,
|
|
@@ -254,6 +261,7 @@ __export(index_exports, {
|
|
|
254
261
|
buildAgentContext: () => buildAgentContext,
|
|
255
262
|
calculateWaitTime: () => calculateWaitTime,
|
|
256
263
|
call: () => call,
|
|
264
|
+
clearRegisteredSequencerConfig: () => clearRegisteredSequencerConfig,
|
|
257
265
|
communicationChannel: () => communicationChannel,
|
|
258
266
|
compileAgent: () => compileAgent,
|
|
259
267
|
compileWorkflow: () => compileWorkflow,
|
|
@@ -273,6 +281,7 @@ __export(index_exports, {
|
|
|
273
281
|
createPermissionError: () => createPermissionError,
|
|
274
282
|
createQueueHandle: () => createQueueHandle,
|
|
275
283
|
createRateLimitError: () => createRateLimitError,
|
|
284
|
+
createSequencerHandle: () => createSequencerHandle,
|
|
276
285
|
createServerHookContext: () => createServerHookContext,
|
|
277
286
|
createSuccessResponse: () => createSuccessResponse,
|
|
278
287
|
createTimeoutError: () => createTimeoutError,
|
|
@@ -286,6 +295,7 @@ __export(index_exports, {
|
|
|
286
295
|
defineAgent: () => defineAgent,
|
|
287
296
|
defineChannel: () => defineChannel,
|
|
288
297
|
defineConfig: () => defineConfig,
|
|
298
|
+
defineEntity: () => defineEntity,
|
|
289
299
|
defineEnv: () => defineEnv,
|
|
290
300
|
defineModel: () => defineModel,
|
|
291
301
|
defineNavigation: () => defineNavigation,
|
|
@@ -311,6 +321,8 @@ __export(index_exports, {
|
|
|
311
321
|
getRateLimitExecutionContext: () => getRateLimitExecutionContext,
|
|
312
322
|
getRequiredInstallEnvKeys: () => getRequiredInstallEnvKeys,
|
|
313
323
|
getRetryDelay: () => getRetryDelay,
|
|
324
|
+
getSequencerConfig: () => getSequencerConfig,
|
|
325
|
+
getSequencerDefinitions: () => getSequencerDefinitions,
|
|
314
326
|
instance: () => instance,
|
|
315
327
|
isChannelDependency: () => isChannelDependency,
|
|
316
328
|
isCronContext: () => isCronContext,
|
|
@@ -326,20 +338,29 @@ __export(index_exports, {
|
|
|
326
338
|
isTimeInWindowSlot: () => isTimeInWindowSlot2,
|
|
327
339
|
isWorkflowDependency: () => isWorkflowDependency,
|
|
328
340
|
matchesTrigger: () => matchesTrigger,
|
|
341
|
+
memorySequencerBackend: () => memorySequencerBackend,
|
|
329
342
|
parseCRMSchema: () => parseCRMSchema,
|
|
330
343
|
parseEstimationFromBilling: () => parseEstimationFromBilling,
|
|
344
|
+
platformSequencerBackend: () => platformSequencerBackend,
|
|
331
345
|
queuedFetch: () => queuedFetch,
|
|
332
346
|
queuedFetchResponse: () => queuedFetchResponse,
|
|
333
347
|
registerQueueConfig: () => registerQueueConfig,
|
|
348
|
+
registerSequencerConfig: () => registerSequencerConfig,
|
|
334
349
|
report: () => report,
|
|
335
350
|
requeue: () => requeue,
|
|
351
|
+
resetSequencerBackendForTests: () => resetSequencerBackendForTests,
|
|
336
352
|
resolveInputMappings: () => resolveInputMappings,
|
|
337
353
|
resolveQueue: () => resolveQueue,
|
|
354
|
+
resolveSequencer: () => resolveSequencer,
|
|
338
355
|
resource: () => resource,
|
|
339
356
|
runWithConfig: () => runWithConfig,
|
|
340
357
|
runWithRateLimitExecutionContext: () => runWithRateLimitExecutionContext,
|
|
341
358
|
safeParseCRMSchema: () => safeParseCRMSchema,
|
|
342
359
|
safeParseConfig: () => safeParseConfig,
|
|
360
|
+
sequencer: () => sequencer,
|
|
361
|
+
sequencerAcquire: () => acquire,
|
|
362
|
+
sequencerAllow: () => allow,
|
|
363
|
+
sequencerRelease: () => release,
|
|
343
364
|
server: () => server,
|
|
344
365
|
toGsm7: () => toGsm7,
|
|
345
366
|
token: () => token,
|
|
@@ -760,6 +781,8 @@ var CRMPageSchemaZ = import_v43.z.object({
|
|
|
760
781
|
icon: import_v43.z.string().optional(),
|
|
761
782
|
modelHandle: import_v43.z.string(),
|
|
762
783
|
parentPath: import_v43.z.string().optional(),
|
|
784
|
+
isDefault: import_v43.z.boolean().optional(),
|
|
785
|
+
visibility: import_v43.z.enum(["team", "private"]).optional(),
|
|
763
786
|
baseQuery: import_v43.z.unknown().optional(),
|
|
764
787
|
blocks: import_v43.z.array(CRMBlockSchemaZ).optional()
|
|
765
788
|
});
|
|
@@ -1635,7 +1658,45 @@ var ModelDefinitionSchema = import_v48.z.object({
|
|
|
1635
1658
|
addDefaultPages: import_v48.z.boolean().optional(),
|
|
1636
1659
|
addNavigation: import_v48.z.boolean().optional(),
|
|
1637
1660
|
/** Root path for developer resource UI (e.g., '/access_requests'). Links internal model to a provision.pages entry. */
|
|
1638
|
-
page: import_v48.z.string().optional()
|
|
1661
|
+
page: import_v48.z.string().optional(),
|
|
1662
|
+
env: EnvSchemaSchema.optional()
|
|
1663
|
+
});
|
|
1664
|
+
var EntityFieldDefinitionSchema = import_v48.z.object({
|
|
1665
|
+
handle: import_v48.z.string(),
|
|
1666
|
+
label: import_v48.z.string(),
|
|
1667
|
+
description: import_v48.z.string().optional(),
|
|
1668
|
+
type: import_v48.z.enum([
|
|
1669
|
+
"string",
|
|
1670
|
+
"long_string",
|
|
1671
|
+
"number",
|
|
1672
|
+
"boolean",
|
|
1673
|
+
"date",
|
|
1674
|
+
"datetime",
|
|
1675
|
+
"object"
|
|
1676
|
+
]).optional(),
|
|
1677
|
+
matchCandidate: import_v48.z.boolean().optional(),
|
|
1678
|
+
required: import_v48.z.boolean().optional(),
|
|
1679
|
+
options: import_v48.z.array(
|
|
1680
|
+
import_v48.z.union([
|
|
1681
|
+
import_v48.z.string(),
|
|
1682
|
+
import_v48.z.object({ value: import_v48.z.string(), label: import_v48.z.string() })
|
|
1683
|
+
])
|
|
1684
|
+
).optional()
|
|
1685
|
+
});
|
|
1686
|
+
var EntityRelationshipDefinitionSchema = import_v48.z.object({
|
|
1687
|
+
handle: import_v48.z.string(),
|
|
1688
|
+
label: import_v48.z.string(),
|
|
1689
|
+
targetEntity: import_v48.z.string().optional(),
|
|
1690
|
+
description: import_v48.z.string().optional()
|
|
1691
|
+
});
|
|
1692
|
+
var EntityDefinitionSchema = import_v48.z.object({
|
|
1693
|
+
handle: import_v48.z.string(),
|
|
1694
|
+
label: import_v48.z.string(),
|
|
1695
|
+
labelPlural: import_v48.z.string().optional(),
|
|
1696
|
+
description: import_v48.z.string().optional(),
|
|
1697
|
+
fields: import_v48.z.array(EntityFieldDefinitionSchema),
|
|
1698
|
+
contextFields: import_v48.z.array(EntityFieldDefinitionSchema).optional(),
|
|
1699
|
+
relationships: import_v48.z.array(EntityRelationshipDefinitionSchema).optional()
|
|
1639
1700
|
});
|
|
1640
1701
|
var RelationshipCardinalitySchema = import_v48.z.enum([
|
|
1641
1702
|
"ONE_TO_ONE",
|
|
@@ -2205,6 +2266,8 @@ var ProvisionConfigSchema = import_v48.z.object({
|
|
|
2205
2266
|
env: EnvSchemaSchema.optional(),
|
|
2206
2267
|
/** INTERNAL model definitions (app-owned, not visible to users) */
|
|
2207
2268
|
models: import_v48.z.array(ModelDefinitionSchema).optional(),
|
|
2269
|
+
/** App entity contracts for install-time CRM maps (not shared models) */
|
|
2270
|
+
entities: import_v48.z.array(EntityDefinitionSchema).optional(),
|
|
2208
2271
|
/** Relationship definitions between INTERNAL models */
|
|
2209
2272
|
relationships: import_v48.z.array(RelationshipDefinitionSchema).optional(),
|
|
2210
2273
|
channels: import_v48.z.array(ChannelDefinitionSchema).optional(),
|
|
@@ -2447,6 +2510,56 @@ function getQueueConfigWithRetry(queueName) {
|
|
|
2447
2510
|
return serializable;
|
|
2448
2511
|
}
|
|
2449
2512
|
|
|
2513
|
+
// src/sequencer/config-loader.ts
|
|
2514
|
+
var fs2 = __toESM(require("fs"));
|
|
2515
|
+
var path2 = __toESM(require("path"));
|
|
2516
|
+
var cachedRuntimeSequencers = null;
|
|
2517
|
+
function getRuntimeConfigPath2() {
|
|
2518
|
+
if (process.env.LAMBDA_TASK_ROOT) {
|
|
2519
|
+
return path2.join(process.env.LAMBDA_TASK_ROOT, ".skedyul", "config.json");
|
|
2520
|
+
}
|
|
2521
|
+
return path2.join(process.cwd(), ".skedyul", "config.json");
|
|
2522
|
+
}
|
|
2523
|
+
function loadRuntimeConfigFile2() {
|
|
2524
|
+
const configPath = getRuntimeConfigPath2();
|
|
2525
|
+
if (!fs2.existsSync(configPath)) {
|
|
2526
|
+
return null;
|
|
2527
|
+
}
|
|
2528
|
+
try {
|
|
2529
|
+
const raw = fs2.readFileSync(configPath, "utf-8");
|
|
2530
|
+
return JSON.parse(raw);
|
|
2531
|
+
} catch {
|
|
2532
|
+
return null;
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2535
|
+
var registeredServerConfig2 = null;
|
|
2536
|
+
function registerSequencerConfig(config) {
|
|
2537
|
+
registeredServerConfig2 = config;
|
|
2538
|
+
cachedRuntimeSequencers = config.sequencers ?? null;
|
|
2539
|
+
}
|
|
2540
|
+
function clearRegisteredSequencerConfig() {
|
|
2541
|
+
registeredServerConfig2 = null;
|
|
2542
|
+
cachedRuntimeSequencers = null;
|
|
2543
|
+
}
|
|
2544
|
+
function getSequencerDefinitions() {
|
|
2545
|
+
if (cachedRuntimeSequencers) {
|
|
2546
|
+
return cachedRuntimeSequencers;
|
|
2547
|
+
}
|
|
2548
|
+
if (registeredServerConfig2?.sequencers) {
|
|
2549
|
+
cachedRuntimeSequencers = registeredServerConfig2.sequencers;
|
|
2550
|
+
return cachedRuntimeSequencers;
|
|
2551
|
+
}
|
|
2552
|
+
const fileConfig = loadRuntimeConfigFile2();
|
|
2553
|
+
if (fileConfig?.sequencers) {
|
|
2554
|
+
cachedRuntimeSequencers = fileConfig.sequencers;
|
|
2555
|
+
return cachedRuntimeSequencers;
|
|
2556
|
+
}
|
|
2557
|
+
return {};
|
|
2558
|
+
}
|
|
2559
|
+
function getSequencerConfig(sequencerName) {
|
|
2560
|
+
return getSequencerDefinitions()[sequencerName];
|
|
2561
|
+
}
|
|
2562
|
+
|
|
2450
2563
|
// src/server/utils/schema.ts
|
|
2451
2564
|
var z9 = __toESM(require("zod"));
|
|
2452
2565
|
function normalizeBilling(billing) {
|
|
@@ -2853,25 +2966,28 @@ function createInstanceClient(config) {
|
|
|
2853
2966
|
pagination: pagination ?? { page: 1, total: 0, hasMore: false, limit: args?.limit ?? 50 }
|
|
2854
2967
|
};
|
|
2855
2968
|
},
|
|
2856
|
-
async get(modelHandle, id) {
|
|
2969
|
+
async get(modelHandle, id, options) {
|
|
2857
2970
|
const { data } = await callCoreWithConfig("instance.get", {
|
|
2858
2971
|
modelHandle,
|
|
2859
|
-
id
|
|
2972
|
+
id,
|
|
2973
|
+
...options?.includeEnv ? { includeEnv: true } : {}
|
|
2860
2974
|
});
|
|
2861
2975
|
return data;
|
|
2862
2976
|
},
|
|
2863
|
-
async create(modelHandle, data) {
|
|
2977
|
+
async create(modelHandle, data, options) {
|
|
2864
2978
|
const { data: inst } = await callCoreWithConfig("instance.create", {
|
|
2865
2979
|
modelHandle,
|
|
2866
|
-
data
|
|
2980
|
+
data,
|
|
2981
|
+
...options?.env ? { env: options.env } : {}
|
|
2867
2982
|
});
|
|
2868
2983
|
return inst;
|
|
2869
2984
|
},
|
|
2870
|
-
async update(modelHandle, id, data) {
|
|
2985
|
+
async update(modelHandle, id, data, options) {
|
|
2871
2986
|
const { data: inst } = await callCoreWithConfig("instance.update", {
|
|
2872
2987
|
modelHandle,
|
|
2873
2988
|
id,
|
|
2874
|
-
data
|
|
2989
|
+
data,
|
|
2990
|
+
...options?.env ? { env: options.env } : {}
|
|
2875
2991
|
});
|
|
2876
2992
|
return inst;
|
|
2877
2993
|
},
|
|
@@ -2970,10 +3086,11 @@ var instance = {
|
|
|
2970
3086
|
* const record = await instance.get('phone_number', 'ins_abc123')
|
|
2971
3087
|
* ```
|
|
2972
3088
|
*/
|
|
2973
|
-
async get(modelHandle, id) {
|
|
3089
|
+
async get(modelHandle, id, options) {
|
|
2974
3090
|
const { data } = await callCore("instance.get", {
|
|
2975
3091
|
modelHandle,
|
|
2976
|
-
id
|
|
3092
|
+
id,
|
|
3093
|
+
...options?.includeEnv ? { includeEnv: true } : {}
|
|
2977
3094
|
});
|
|
2978
3095
|
return data;
|
|
2979
3096
|
},
|
|
@@ -2990,10 +3107,11 @@ var instance = {
|
|
|
2990
3107
|
* })
|
|
2991
3108
|
* ```
|
|
2992
3109
|
*/
|
|
2993
|
-
async create(modelHandle, data) {
|
|
3110
|
+
async create(modelHandle, data, options) {
|
|
2994
3111
|
const { data: instance2 } = await callCore("instance.create", {
|
|
2995
3112
|
modelHandle,
|
|
2996
|
-
data
|
|
3113
|
+
data,
|
|
3114
|
+
...options?.env ? { env: options.env } : {}
|
|
2997
3115
|
});
|
|
2998
3116
|
return instance2;
|
|
2999
3117
|
},
|
|
@@ -3010,11 +3128,12 @@ var instance = {
|
|
|
3010
3128
|
* })
|
|
3011
3129
|
* ```
|
|
3012
3130
|
*/
|
|
3013
|
-
async update(modelHandle, id, data) {
|
|
3131
|
+
async update(modelHandle, id, data, options) {
|
|
3014
3132
|
const { data: instance2 } = await callCore("instance.update", {
|
|
3015
3133
|
modelHandle,
|
|
3016
3134
|
id,
|
|
3017
|
-
data
|
|
3135
|
+
data,
|
|
3136
|
+
...options?.env ? { env: options.env } : {}
|
|
3018
3137
|
});
|
|
3019
3138
|
return instance2;
|
|
3020
3139
|
},
|
|
@@ -4381,7 +4500,7 @@ function printStartupLog(config, tools, port) {
|
|
|
4381
4500
|
|
|
4382
4501
|
// src/server/route-handlers/adapters.ts
|
|
4383
4502
|
function fromLambdaEvent(event2) {
|
|
4384
|
-
const
|
|
4503
|
+
const path6 = event2.path || event2.rawPath || "/";
|
|
4385
4504
|
const method = event2.httpMethod || event2.requestContext?.http?.method || "POST";
|
|
4386
4505
|
const forwardedProto = event2.headers?.["x-forwarded-proto"] ?? event2.headers?.["X-Forwarded-Proto"];
|
|
4387
4506
|
const protocol = forwardedProto ?? "https";
|
|
@@ -4389,9 +4508,9 @@ function fromLambdaEvent(event2) {
|
|
|
4389
4508
|
const queryString = event2.queryStringParameters ? "?" + new URLSearchParams(
|
|
4390
4509
|
event2.queryStringParameters
|
|
4391
4510
|
).toString() : "";
|
|
4392
|
-
const url = `${protocol}://${host}${
|
|
4511
|
+
const url = `${protocol}://${host}${path6}${queryString}`;
|
|
4393
4512
|
return {
|
|
4394
|
-
path:
|
|
4513
|
+
path: path6,
|
|
4395
4514
|
method,
|
|
4396
4515
|
headers: event2.headers,
|
|
4397
4516
|
query: event2.queryStringParameters ?? {},
|
|
@@ -4473,8 +4592,8 @@ function parseBodyByContentType(req) {
|
|
|
4473
4592
|
}
|
|
4474
4593
|
|
|
4475
4594
|
// src/server/route-handlers/handlers.ts
|
|
4476
|
-
var
|
|
4477
|
-
var
|
|
4595
|
+
var fs3 = __toESM(require("fs"));
|
|
4596
|
+
var path3 = __toESM(require("path"));
|
|
4478
4597
|
|
|
4479
4598
|
// src/server/core-api-handler.ts
|
|
4480
4599
|
async function handleCoreMethod(method, params) {
|
|
@@ -4942,7 +5061,7 @@ async function handleOAuthCallback(parsedBody, hooks) {
|
|
|
4942
5061
|
}
|
|
4943
5062
|
|
|
4944
5063
|
// src/server/handlers/webhook-handler.ts
|
|
4945
|
-
function parseWebhookRequest(parsedBody, method, url,
|
|
5064
|
+
function parseWebhookRequest(parsedBody, method, url, path6, headers, query, rawBody, appIdHeader, appVersionIdHeader) {
|
|
4946
5065
|
const isEnvelope = typeof parsedBody === "object" && parsedBody !== null && "env" in parsedBody && "request" in parsedBody && "context" in parsedBody;
|
|
4947
5066
|
if (isEnvelope) {
|
|
4948
5067
|
const envelope = parsedBody;
|
|
@@ -4996,7 +5115,7 @@ function parseWebhookRequest(parsedBody, method, url, path5, headers, query, raw
|
|
|
4996
5115
|
const webhookRequest = {
|
|
4997
5116
|
method,
|
|
4998
5117
|
url,
|
|
4999
|
-
path:
|
|
5118
|
+
path: path6,
|
|
5000
5119
|
headers,
|
|
5001
5120
|
query,
|
|
5002
5121
|
body: parsedBody,
|
|
@@ -5025,9 +5144,17 @@ async function executeWebhookHandler(handle, webhookRegistry, data) {
|
|
|
5025
5144
|
};
|
|
5026
5145
|
let webhookResponse;
|
|
5027
5146
|
try {
|
|
5147
|
+
const rateLimitContext = {
|
|
5148
|
+
app: data.webhookContext.app,
|
|
5149
|
+
appInstallationId: isRuntimeWebhookContext(data.webhookContext) ? data.webhookContext.appInstallationId : void 0,
|
|
5150
|
+
invocation: data.invocation,
|
|
5151
|
+
isProvisionContext: !isRuntimeWebhookContext(data.webhookContext)
|
|
5152
|
+
};
|
|
5028
5153
|
webhookResponse = await runWithLogContext({ invocation: data.invocation }, async () => {
|
|
5029
5154
|
return await runWithConfig(requestConfig, async () => {
|
|
5030
|
-
return await
|
|
5155
|
+
return await runWithRateLimitExecutionContext(rateLimitContext, async () => {
|
|
5156
|
+
return await webhookDef.handler(data.webhookRequest, data.webhookContext);
|
|
5157
|
+
});
|
|
5031
5158
|
});
|
|
5032
5159
|
});
|
|
5033
5160
|
} catch (err) {
|
|
@@ -5054,7 +5181,7 @@ function isMethodAllowed(webhookRegistry, handle, method) {
|
|
|
5054
5181
|
|
|
5055
5182
|
// src/server/route-handlers/handlers.ts
|
|
5056
5183
|
function getConfigFilePath() {
|
|
5057
|
-
return process.env.LAMBDA_TASK_ROOT ?
|
|
5184
|
+
return process.env.LAMBDA_TASK_ROOT ? path3.join(process.env.LAMBDA_TASK_ROOT, ".skedyul", "config.json") : ".skedyul/config.json";
|
|
5058
5185
|
}
|
|
5059
5186
|
function findToolInRegistry(registry, toolName) {
|
|
5060
5187
|
for (const [key, t] of Object.entries(registry)) {
|
|
@@ -5093,8 +5220,8 @@ function handleHealthRoute(ctx) {
|
|
|
5093
5220
|
function handleConfigRoute(ctx) {
|
|
5094
5221
|
const configFilePath = getConfigFilePath();
|
|
5095
5222
|
try {
|
|
5096
|
-
if (
|
|
5097
|
-
const fileConfig = JSON.parse(
|
|
5223
|
+
if (fs3.existsSync(configFilePath)) {
|
|
5224
|
+
const fileConfig = JSON.parse(fs3.readFileSync(configFilePath, "utf-8"));
|
|
5098
5225
|
return { status: 200, body: fileConfig };
|
|
5099
5226
|
}
|
|
5100
5227
|
} catch (err) {
|
|
@@ -5782,6 +5909,7 @@ installContextLogger();
|
|
|
5782
5909
|
function createSkedyulServer(config) {
|
|
5783
5910
|
mergeRuntimeEnv();
|
|
5784
5911
|
registerQueueConfig(config);
|
|
5912
|
+
registerSequencerConfig(config);
|
|
5785
5913
|
const registry = config.tools;
|
|
5786
5914
|
const webhookRegistry = config.webhooks;
|
|
5787
5915
|
if (config.coreApi?.service) {
|
|
@@ -6030,6 +6158,9 @@ function defineConfig(config) {
|
|
|
6030
6158
|
function defineModel(model) {
|
|
6031
6159
|
return model;
|
|
6032
6160
|
}
|
|
6161
|
+
function defineEntity(entity) {
|
|
6162
|
+
return entity;
|
|
6163
|
+
}
|
|
6033
6164
|
function defineChannel(channel) {
|
|
6034
6165
|
return channel;
|
|
6035
6166
|
}
|
|
@@ -6050,13 +6181,13 @@ function defineNavigation(navigation) {
|
|
|
6050
6181
|
}
|
|
6051
6182
|
|
|
6052
6183
|
// src/config/schema-loader.ts
|
|
6053
|
-
var
|
|
6054
|
-
var
|
|
6184
|
+
var fs4 = __toESM(require("fs"));
|
|
6185
|
+
var path4 = __toESM(require("path"));
|
|
6055
6186
|
var os = __toESM(require("os"));
|
|
6056
6187
|
|
|
6057
6188
|
// src/config/resolver.ts
|
|
6058
|
-
var
|
|
6059
|
-
var
|
|
6189
|
+
var fs5 = __toESM(require("fs"));
|
|
6190
|
+
var path5 = __toESM(require("path"));
|
|
6060
6191
|
|
|
6061
6192
|
// src/config/utils.ts
|
|
6062
6193
|
function getAllEnvKeys(config) {
|
|
@@ -6159,7 +6290,7 @@ function getApiToken() {
|
|
|
6159
6290
|
const config = getConfig();
|
|
6160
6291
|
return config.apiToken || process.env.SKEDYUL_API_TOKEN || "";
|
|
6161
6292
|
}
|
|
6162
|
-
async function callRateLimitApi(
|
|
6293
|
+
async function callRateLimitApi(path6, body) {
|
|
6163
6294
|
const baseUrl = getApiBaseUrl();
|
|
6164
6295
|
const token2 = getApiToken();
|
|
6165
6296
|
if (!baseUrl || !token2) {
|
|
@@ -6167,7 +6298,7 @@ async function callRateLimitApi(path5, body) {
|
|
|
6167
6298
|
"SKEDYUL_API_URL and SKEDYUL_API_TOKEN are required for platform queue coordination"
|
|
6168
6299
|
);
|
|
6169
6300
|
}
|
|
6170
|
-
const response = await fetch(`${baseUrl}/api/internal/ratelimit/${
|
|
6301
|
+
const response = await fetch(`${baseUrl}/api/internal/ratelimit/${path6}`, {
|
|
6171
6302
|
method: "POST",
|
|
6172
6303
|
headers: {
|
|
6173
6304
|
Authorization: `Bearer ${token2}`,
|
|
@@ -6177,11 +6308,11 @@ async function callRateLimitApi(path5, body) {
|
|
|
6177
6308
|
});
|
|
6178
6309
|
const payload = await response.json().catch(() => null);
|
|
6179
6310
|
if (!response.ok || payload?.success === false) {
|
|
6180
|
-
const message = payload?.errors?.[0]?.message ?? `Queue coordination API ${
|
|
6311
|
+
const message = payload?.errors?.[0]?.message ?? `Queue coordination API ${path6} failed with status ${response.status}`;
|
|
6181
6312
|
throw new RateLimitBackendError(message, response.status);
|
|
6182
6313
|
}
|
|
6183
6314
|
if (!payload?.data) {
|
|
6184
|
-
throw new RateLimitBackendError(`Queue coordination API ${
|
|
6315
|
+
throw new RateLimitBackendError(`Queue coordination API ${path6} returned empty data`);
|
|
6185
6316
|
}
|
|
6186
6317
|
return payload.data;
|
|
6187
6318
|
}
|
|
@@ -6636,6 +6767,406 @@ async function queuedFetchResponse(queueInput, url, init) {
|
|
|
6636
6767
|
return queuedFetch(queueInput, () => fetch(url, init));
|
|
6637
6768
|
}
|
|
6638
6769
|
|
|
6770
|
+
// src/sequencer/errors.ts
|
|
6771
|
+
var SequencerContextError = class extends Error {
|
|
6772
|
+
constructor(message) {
|
|
6773
|
+
super(message);
|
|
6774
|
+
this.code = "SEQUENCER_CONTEXT_ERROR";
|
|
6775
|
+
this.name = "SequencerContextError";
|
|
6776
|
+
}
|
|
6777
|
+
};
|
|
6778
|
+
var SequencerNotFoundError = class extends Error {
|
|
6779
|
+
constructor(name) {
|
|
6780
|
+
super(`Sequencer "${name}" is not defined in skedyul.config`);
|
|
6781
|
+
this.code = "SEQUENCER_NOT_FOUND";
|
|
6782
|
+
this.name = "SequencerNotFoundError";
|
|
6783
|
+
}
|
|
6784
|
+
};
|
|
6785
|
+
var SequencerBackendError = class extends Error {
|
|
6786
|
+
constructor(message, statusCode) {
|
|
6787
|
+
super(message);
|
|
6788
|
+
this.code = "SEQUENCER_BACKEND_ERROR";
|
|
6789
|
+
this.name = "SequencerBackendError";
|
|
6790
|
+
this.statusCode = statusCode;
|
|
6791
|
+
}
|
|
6792
|
+
};
|
|
6793
|
+
var SequencerLockError = class extends Error {
|
|
6794
|
+
constructor(message) {
|
|
6795
|
+
super(message);
|
|
6796
|
+
this.code = "SEQUENCER_LOCK_ERROR";
|
|
6797
|
+
this.name = "SequencerLockError";
|
|
6798
|
+
}
|
|
6799
|
+
};
|
|
6800
|
+
|
|
6801
|
+
// src/sequencer/resolve-sequencer-key.ts
|
|
6802
|
+
function resolveEndpointHandle2(config, invocation) {
|
|
6803
|
+
if (config.endpoint) {
|
|
6804
|
+
return config.endpoint;
|
|
6805
|
+
}
|
|
6806
|
+
if (invocation?.toolHandle) {
|
|
6807
|
+
return invocation.toolHandle;
|
|
6808
|
+
}
|
|
6809
|
+
if (invocation?.serverHookHandle) {
|
|
6810
|
+
return invocation.serverHookHandle;
|
|
6811
|
+
}
|
|
6812
|
+
throw new SequencerContextError(
|
|
6813
|
+
`Cannot resolve endpoint handle for sequencer scope "${config.scope}". Set endpoint in sequencer config or ensure invocation.toolHandle/serverHookHandle is available.`
|
|
6814
|
+
);
|
|
6815
|
+
}
|
|
6816
|
+
function appendSubKey2(base, subKey) {
|
|
6817
|
+
return subKey ? `${base}:${subKey}` : base;
|
|
6818
|
+
}
|
|
6819
|
+
function resolveSequencerKey(sequencerName, config, ctx, subKey) {
|
|
6820
|
+
const { app, appInstallationId, invocation, isProvisionContext: isProvisionContext2 } = ctx;
|
|
6821
|
+
switch (config.scope) {
|
|
6822
|
+
case "provision": {
|
|
6823
|
+
const base = `seq:pv:${app.versionId}:${sequencerName}`;
|
|
6824
|
+
return appendSubKey2(base, subKey);
|
|
6825
|
+
}
|
|
6826
|
+
case "install": {
|
|
6827
|
+
if (!appInstallationId) {
|
|
6828
|
+
throw new SequencerContextError(
|
|
6829
|
+
`Sequencer "${sequencerName}" with scope "install" requires appInstallationId in context`
|
|
6830
|
+
);
|
|
6831
|
+
}
|
|
6832
|
+
const base = `seq:in:${appInstallationId}:${sequencerName}`;
|
|
6833
|
+
return appendSubKey2(base, subKey);
|
|
6834
|
+
}
|
|
6835
|
+
case "provision_endpoint": {
|
|
6836
|
+
if (!isProvisionContext2 && appInstallationId) {
|
|
6837
|
+
throw new SequencerContextError(
|
|
6838
|
+
`Sequencer "${sequencerName}" with scope "provision_endpoint" requires provision context (no install)`
|
|
6839
|
+
);
|
|
6840
|
+
}
|
|
6841
|
+
const endpointHandle = resolveEndpointHandle2(config, invocation);
|
|
6842
|
+
const base = `seq:pep:${app.versionId}:${endpointHandle}:${sequencerName}`;
|
|
6843
|
+
return appendSubKey2(base, subKey);
|
|
6844
|
+
}
|
|
6845
|
+
case "install_endpoint": {
|
|
6846
|
+
if (!appInstallationId) {
|
|
6847
|
+
throw new SequencerContextError(
|
|
6848
|
+
`Sequencer "${sequencerName}" with scope "install_endpoint" requires appInstallationId in context`
|
|
6849
|
+
);
|
|
6850
|
+
}
|
|
6851
|
+
const endpointHandle = resolveEndpointHandle2(config, invocation);
|
|
6852
|
+
const base = `seq:iep:${appInstallationId}:${endpointHandle}:${sequencerName}`;
|
|
6853
|
+
return appendSubKey2(base, subKey);
|
|
6854
|
+
}
|
|
6855
|
+
case "global": {
|
|
6856
|
+
const base = `seq:gl:${app.versionId}:${sequencerName}`;
|
|
6857
|
+
return appendSubKey2(base, subKey);
|
|
6858
|
+
}
|
|
6859
|
+
default: {
|
|
6860
|
+
const _exhaustive = config.scope;
|
|
6861
|
+
throw new SequencerContextError(`Unknown sequencer scope: ${String(_exhaustive)}`);
|
|
6862
|
+
}
|
|
6863
|
+
}
|
|
6864
|
+
}
|
|
6865
|
+
|
|
6866
|
+
// src/sequencer/backends/platform.ts
|
|
6867
|
+
function getApiBaseUrl2() {
|
|
6868
|
+
const config = getConfig();
|
|
6869
|
+
if (config.baseUrl) {
|
|
6870
|
+
return config.baseUrl.replace(/\/+$/, "");
|
|
6871
|
+
}
|
|
6872
|
+
return (process.env.SKEDYUL_API_URL ?? process.env.SKEDYUL_NODE_URL ?? "").replace(/\/+$/, "");
|
|
6873
|
+
}
|
|
6874
|
+
function getApiToken2() {
|
|
6875
|
+
const config = getConfig();
|
|
6876
|
+
return config.apiToken || process.env.SKEDYUL_API_TOKEN || "";
|
|
6877
|
+
}
|
|
6878
|
+
async function callSequencerApi(path6, body) {
|
|
6879
|
+
const baseUrl = getApiBaseUrl2();
|
|
6880
|
+
const token2 = getApiToken2();
|
|
6881
|
+
if (!baseUrl || !token2) {
|
|
6882
|
+
throw new SequencerBackendError(
|
|
6883
|
+
"SKEDYUL_API_URL and SKEDYUL_API_TOKEN are required for platform sequencer coordination"
|
|
6884
|
+
);
|
|
6885
|
+
}
|
|
6886
|
+
const response = await fetch(`${baseUrl}/api/internal/sequencer/${path6}`, {
|
|
6887
|
+
method: "POST",
|
|
6888
|
+
headers: {
|
|
6889
|
+
Authorization: `Bearer ${token2}`,
|
|
6890
|
+
"Content-Type": "application/json"
|
|
6891
|
+
},
|
|
6892
|
+
body: JSON.stringify(body)
|
|
6893
|
+
});
|
|
6894
|
+
const payload = await response.json().catch(() => null);
|
|
6895
|
+
if (!response.ok || payload?.success === false) {
|
|
6896
|
+
const message = payload?.errors?.[0]?.message ?? `Sequencer coordination API ${path6} failed with status ${response.status}`;
|
|
6897
|
+
throw new SequencerBackendError(message, response.status);
|
|
6898
|
+
}
|
|
6899
|
+
if (!payload?.data) {
|
|
6900
|
+
throw new SequencerBackendError(`Sequencer coordination API ${path6} returned empty data`);
|
|
6901
|
+
}
|
|
6902
|
+
return payload.data;
|
|
6903
|
+
}
|
|
6904
|
+
var PlatformSequencerBackend = class {
|
|
6905
|
+
async allow(sequencerKey, input) {
|
|
6906
|
+
return callSequencerApi("allow", {
|
|
6907
|
+
sequencerKey,
|
|
6908
|
+
timestamp: input.timestamp,
|
|
6909
|
+
leaseId: input.leaseId,
|
|
6910
|
+
watermarkTtlMs: input.watermarkTtlMs
|
|
6911
|
+
});
|
|
6912
|
+
}
|
|
6913
|
+
async acquire(sequencerKey, input) {
|
|
6914
|
+
return callSequencerApi("acquire", {
|
|
6915
|
+
sequencerKey,
|
|
6916
|
+
leaseId: input.leaseId,
|
|
6917
|
+
timestamp: input.timestamp,
|
|
6918
|
+
lockTtlMs: input.lockTtlMs,
|
|
6919
|
+
watermarkTtlMs: input.watermarkTtlMs
|
|
6920
|
+
});
|
|
6921
|
+
}
|
|
6922
|
+
async release(sequencerKey, leaseId) {
|
|
6923
|
+
await callSequencerApi("release", {
|
|
6924
|
+
sequencerKey,
|
|
6925
|
+
leaseId
|
|
6926
|
+
});
|
|
6927
|
+
}
|
|
6928
|
+
};
|
|
6929
|
+
var platformSequencerBackend = new PlatformSequencerBackend();
|
|
6930
|
+
|
|
6931
|
+
// src/sequencer/backends/memory.ts
|
|
6932
|
+
function generateLeaseId2() {
|
|
6933
|
+
return `mem_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
6934
|
+
}
|
|
6935
|
+
var MemorySequencerBackend = class {
|
|
6936
|
+
constructor() {
|
|
6937
|
+
this.state = /* @__PURE__ */ new Map();
|
|
6938
|
+
}
|
|
6939
|
+
getState(sequencerKey) {
|
|
6940
|
+
let state = this.state.get(sequencerKey);
|
|
6941
|
+
if (!state) {
|
|
6942
|
+
state = { watermark: 0, lockLeaseId: null, lockExpiresAt: 0 };
|
|
6943
|
+
this.state.set(sequencerKey, state);
|
|
6944
|
+
}
|
|
6945
|
+
if (state.lockLeaseId && state.lockExpiresAt <= Date.now()) {
|
|
6946
|
+
state.lockLeaseId = null;
|
|
6947
|
+
state.lockExpiresAt = 0;
|
|
6948
|
+
}
|
|
6949
|
+
return state;
|
|
6950
|
+
}
|
|
6951
|
+
async allow(sequencerKey, input) {
|
|
6952
|
+
void input.watermarkTtlMs;
|
|
6953
|
+
const state = this.getState(sequencerKey);
|
|
6954
|
+
if (input.timestamp < state.watermark) {
|
|
6955
|
+
return { allowed: false, reason: "stale", watermark: state.watermark };
|
|
6956
|
+
}
|
|
6957
|
+
if (state.lockLeaseId && input.leaseId && state.lockLeaseId !== input.leaseId) {
|
|
6958
|
+
return { allowed: false, reason: "locked", watermark: state.watermark };
|
|
6959
|
+
}
|
|
6960
|
+
state.watermark = Math.max(state.watermark, input.timestamp);
|
|
6961
|
+
return { allowed: true, reason: "ok", watermark: state.watermark };
|
|
6962
|
+
}
|
|
6963
|
+
async acquire(sequencerKey, input) {
|
|
6964
|
+
void input.watermarkTtlMs;
|
|
6965
|
+
const state = this.getState(sequencerKey);
|
|
6966
|
+
const leaseId = input.leaseId || generateLeaseId2();
|
|
6967
|
+
if (state.lockLeaseId && state.lockLeaseId !== leaseId) {
|
|
6968
|
+
return { acquired: false, reason: "locked" };
|
|
6969
|
+
}
|
|
6970
|
+
state.lockLeaseId = leaseId;
|
|
6971
|
+
state.lockExpiresAt = Date.now() + (input.lockTtlMs ?? 6e4);
|
|
6972
|
+
if (input.timestamp !== void 0) {
|
|
6973
|
+
state.watermark = Math.max(state.watermark, input.timestamp);
|
|
6974
|
+
}
|
|
6975
|
+
return { acquired: true, reason: "ok" };
|
|
6976
|
+
}
|
|
6977
|
+
async release(sequencerKey, leaseId) {
|
|
6978
|
+
const state = this.state.get(sequencerKey);
|
|
6979
|
+
if (!state || state.lockLeaseId !== leaseId) {
|
|
6980
|
+
return;
|
|
6981
|
+
}
|
|
6982
|
+
state.lockLeaseId = null;
|
|
6983
|
+
state.lockExpiresAt = 0;
|
|
6984
|
+
}
|
|
6985
|
+
resetForTests() {
|
|
6986
|
+
this.state.clear();
|
|
6987
|
+
}
|
|
6988
|
+
};
|
|
6989
|
+
var memorySequencerBackend = new MemorySequencerBackend();
|
|
6990
|
+
|
|
6991
|
+
// src/sequencer/backends/index.ts
|
|
6992
|
+
var cachedBackend2 = null;
|
|
6993
|
+
function shouldForceMemoryBackend2() {
|
|
6994
|
+
const flag = process.env.SKEDYUL_SEQUENCER_MEMORY;
|
|
6995
|
+
return flag === "1" || flag === "true";
|
|
6996
|
+
}
|
|
6997
|
+
function getSequencerBackend() {
|
|
6998
|
+
if (cachedBackend2) {
|
|
6999
|
+
return cachedBackend2;
|
|
7000
|
+
}
|
|
7001
|
+
if (shouldForceMemoryBackend2()) {
|
|
7002
|
+
cachedBackend2 = memorySequencerBackend;
|
|
7003
|
+
return cachedBackend2;
|
|
7004
|
+
}
|
|
7005
|
+
cachedBackend2 = createResilientBackend2();
|
|
7006
|
+
return cachedBackend2;
|
|
7007
|
+
}
|
|
7008
|
+
function createResilientBackend2() {
|
|
7009
|
+
return {
|
|
7010
|
+
async allow(sequencerKey, input) {
|
|
7011
|
+
try {
|
|
7012
|
+
return await platformSequencerBackend.allow(sequencerKey, input);
|
|
7013
|
+
} catch (error) {
|
|
7014
|
+
if (shouldFallbackToMemory2(error)) {
|
|
7015
|
+
return memorySequencerBackend.allow(sequencerKey, input);
|
|
7016
|
+
}
|
|
7017
|
+
throw error;
|
|
7018
|
+
}
|
|
7019
|
+
},
|
|
7020
|
+
async acquire(sequencerKey, input) {
|
|
7021
|
+
try {
|
|
7022
|
+
return await platformSequencerBackend.acquire(sequencerKey, input);
|
|
7023
|
+
} catch (error) {
|
|
7024
|
+
if (shouldFallbackToMemory2(error)) {
|
|
7025
|
+
return memorySequencerBackend.acquire(sequencerKey, input);
|
|
7026
|
+
}
|
|
7027
|
+
throw error;
|
|
7028
|
+
}
|
|
7029
|
+
},
|
|
7030
|
+
async release(sequencerKey, leaseId) {
|
|
7031
|
+
if (leaseId.startsWith("mem_")) {
|
|
7032
|
+
return memorySequencerBackend.release(sequencerKey, leaseId);
|
|
7033
|
+
}
|
|
7034
|
+
try {
|
|
7035
|
+
await platformSequencerBackend.release(sequencerKey, leaseId);
|
|
7036
|
+
} catch (error) {
|
|
7037
|
+
if (shouldFallbackToMemory2(error)) {
|
|
7038
|
+
return memorySequencerBackend.release(sequencerKey, leaseId);
|
|
7039
|
+
}
|
|
7040
|
+
throw error;
|
|
7041
|
+
}
|
|
7042
|
+
}
|
|
7043
|
+
};
|
|
7044
|
+
}
|
|
7045
|
+
function shouldFallbackToMemory2(error) {
|
|
7046
|
+
if (shouldForceMemoryBackend2()) {
|
|
7047
|
+
return true;
|
|
7048
|
+
}
|
|
7049
|
+
if (error instanceof SequencerBackendError) {
|
|
7050
|
+
if (error.statusCode === 404 || error.statusCode === 503) {
|
|
7051
|
+
return true;
|
|
7052
|
+
}
|
|
7053
|
+
}
|
|
7054
|
+
if (error instanceof TypeError) {
|
|
7055
|
+
return true;
|
|
7056
|
+
}
|
|
7057
|
+
const nodeEnv = process.env.NODE_ENV;
|
|
7058
|
+
return nodeEnv === "development" || nodeEnv === "test";
|
|
7059
|
+
}
|
|
7060
|
+
function resetSequencerBackendForTests() {
|
|
7061
|
+
cachedBackend2 = null;
|
|
7062
|
+
}
|
|
7063
|
+
|
|
7064
|
+
// src/sequencer/index.ts
|
|
7065
|
+
function normalizeSequencerInput(input) {
|
|
7066
|
+
if (typeof input === "string") {
|
|
7067
|
+
return { name: input };
|
|
7068
|
+
}
|
|
7069
|
+
return { name: input.sequencer, subKey: input.key };
|
|
7070
|
+
}
|
|
7071
|
+
function mergeContext(ctxOverride) {
|
|
7072
|
+
const ctx = getRateLimitExecutionContext();
|
|
7073
|
+
if (!ctx?.app?.versionId) {
|
|
7074
|
+
throw new SequencerContextError(
|
|
7075
|
+
"Cannot resolve sequencer without app context. Ensure sequencer runs inside a tool/hook/webhook handler."
|
|
7076
|
+
);
|
|
7077
|
+
}
|
|
7078
|
+
return { ...ctx, ...ctxOverride };
|
|
7079
|
+
}
|
|
7080
|
+
function resolveSequencer(sequencerInput, ctxOverride) {
|
|
7081
|
+
const ctx = mergeContext(ctxOverride);
|
|
7082
|
+
const { name, subKey } = normalizeSequencerInput(sequencerInput);
|
|
7083
|
+
const config = getSequencerConfig(name);
|
|
7084
|
+
if (!config) {
|
|
7085
|
+
throw new SequencerNotFoundError(name);
|
|
7086
|
+
}
|
|
7087
|
+
const sequencerKey = resolveSequencerKey(name, config, ctx, subKey);
|
|
7088
|
+
return { name, sequencerKey, config };
|
|
7089
|
+
}
|
|
7090
|
+
function createSequencerHandle(sequencerInput, ctxOverride) {
|
|
7091
|
+
return {
|
|
7092
|
+
allow(input) {
|
|
7093
|
+
return allow(sequencerInput, input, ctxOverride);
|
|
7094
|
+
},
|
|
7095
|
+
acquire(input) {
|
|
7096
|
+
return acquire(sequencerInput, input, ctxOverride);
|
|
7097
|
+
},
|
|
7098
|
+
release(input) {
|
|
7099
|
+
return release(sequencerInput, input, ctxOverride);
|
|
7100
|
+
}
|
|
7101
|
+
};
|
|
7102
|
+
}
|
|
7103
|
+
function disabledAllowResult() {
|
|
7104
|
+
return { allowed: true, reason: "disabled" };
|
|
7105
|
+
}
|
|
7106
|
+
async function allow(sequencerInput, input, ctxOverride) {
|
|
7107
|
+
const { name, subKey } = normalizeSequencerInput(sequencerInput);
|
|
7108
|
+
const config = getSequencerConfig(name);
|
|
7109
|
+
if (!config || config.enabled !== true) {
|
|
7110
|
+
return disabledAllowResult();
|
|
7111
|
+
}
|
|
7112
|
+
const resolvedSubKey = input.key ?? subKey;
|
|
7113
|
+
const resolved = resolveSequencer(
|
|
7114
|
+
{ sequencer: name, key: resolvedSubKey },
|
|
7115
|
+
ctxOverride
|
|
7116
|
+
);
|
|
7117
|
+
const backend = getSequencerBackend();
|
|
7118
|
+
return backend.allow(resolved.sequencerKey, {
|
|
7119
|
+
timestamp: input.timestamp,
|
|
7120
|
+
leaseId: input.leaseId,
|
|
7121
|
+
watermarkTtlMs: resolved.config.watermarkTtlMs
|
|
7122
|
+
});
|
|
7123
|
+
}
|
|
7124
|
+
async function acquire(sequencerInput, input, ctxOverride) {
|
|
7125
|
+
const { name, subKey } = normalizeSequencerInput(sequencerInput);
|
|
7126
|
+
const config = getSequencerConfig(name);
|
|
7127
|
+
if (!config || config.enabled !== true) {
|
|
7128
|
+
return;
|
|
7129
|
+
}
|
|
7130
|
+
const resolvedSubKey = input.key ?? subKey;
|
|
7131
|
+
const resolved = resolveSequencer(
|
|
7132
|
+
{ sequencer: name, key: resolvedSubKey },
|
|
7133
|
+
ctxOverride
|
|
7134
|
+
);
|
|
7135
|
+
const backend = getSequencerBackend();
|
|
7136
|
+
const result = await backend.acquire(resolved.sequencerKey, {
|
|
7137
|
+
leaseId: input.leaseId,
|
|
7138
|
+
timestamp: input.timestamp,
|
|
7139
|
+
lockTtlMs: input.lockTtlMs ?? resolved.config.lockTtlMs,
|
|
7140
|
+
watermarkTtlMs: resolved.config.watermarkTtlMs
|
|
7141
|
+
});
|
|
7142
|
+
if (!result.acquired) {
|
|
7143
|
+
throw new SequencerLockError(
|
|
7144
|
+
`Sequencer "${name}" lock held by another lease (${result.reason})`
|
|
7145
|
+
);
|
|
7146
|
+
}
|
|
7147
|
+
}
|
|
7148
|
+
async function release(sequencerInput, input, ctxOverride) {
|
|
7149
|
+
const { name, subKey } = normalizeSequencerInput(sequencerInput);
|
|
7150
|
+
const config = getSequencerConfig(name);
|
|
7151
|
+
if (!config || config.enabled !== true) {
|
|
7152
|
+
return;
|
|
7153
|
+
}
|
|
7154
|
+
const resolvedSubKey = input.key ?? subKey;
|
|
7155
|
+
const resolved = resolveSequencer(
|
|
7156
|
+
{ sequencer: name, key: resolvedSubKey },
|
|
7157
|
+
ctxOverride
|
|
7158
|
+
);
|
|
7159
|
+
const backend = getSequencerBackend();
|
|
7160
|
+
await backend.release(resolved.sequencerKey, input.leaseId);
|
|
7161
|
+
}
|
|
7162
|
+
var sequencer = {
|
|
7163
|
+
allow,
|
|
7164
|
+
acquire,
|
|
7165
|
+
release,
|
|
7166
|
+
resolve: resolveSequencer,
|
|
7167
|
+
createHandle: createSequencerHandle
|
|
7168
|
+
};
|
|
7169
|
+
|
|
6639
7170
|
// src/triggers/types.ts
|
|
6640
7171
|
var import_v410 = require("zod/v4");
|
|
6641
7172
|
var CRMDataSchema = import_v410.z.object({
|
|
@@ -6740,16 +7271,16 @@ function evaluateTemplate(template, context) {
|
|
|
6740
7271
|
const templateRegex = /\{\{\s*([^}]+)\s*\}\}/g;
|
|
6741
7272
|
const singleMatch = template.match(/^\{\{\s*([^}]+)\s*\}\}$/);
|
|
6742
7273
|
if (singleMatch) {
|
|
6743
|
-
const
|
|
6744
|
-
return resolvePath(context,
|
|
7274
|
+
const path6 = singleMatch[1].trim();
|
|
7275
|
+
return resolvePath(context, path6);
|
|
6745
7276
|
}
|
|
6746
|
-
return template.replace(templateRegex, (_,
|
|
6747
|
-
const value = resolvePath(context,
|
|
7277
|
+
return template.replace(templateRegex, (_, path6) => {
|
|
7278
|
+
const value = resolvePath(context, path6.trim());
|
|
6748
7279
|
return value === void 0 || value === null ? "" : String(value);
|
|
6749
7280
|
});
|
|
6750
7281
|
}
|
|
6751
|
-
function resolvePath(obj,
|
|
6752
|
-
const parts =
|
|
7282
|
+
function resolvePath(obj, path6) {
|
|
7283
|
+
const parts = path6.split(".");
|
|
6753
7284
|
let current = obj;
|
|
6754
7285
|
for (const part of parts) {
|
|
6755
7286
|
if (current === null || current === void 0) {
|
|
@@ -6770,14 +7301,14 @@ function evaluateCondition(condition, context) {
|
|
|
6770
7301
|
const expression = match[1].trim();
|
|
6771
7302
|
const eqMatch = expression.match(/^(.+?)\s*==\s*['"](.+)['"]$/);
|
|
6772
7303
|
if (eqMatch) {
|
|
6773
|
-
const [,
|
|
6774
|
-
const actualValue = resolvePath(context,
|
|
7304
|
+
const [, path6, expectedValue] = eqMatch;
|
|
7305
|
+
const actualValue = resolvePath(context, path6.trim());
|
|
6775
7306
|
return actualValue === expectedValue;
|
|
6776
7307
|
}
|
|
6777
7308
|
const neqMatch = expression.match(/^(.+?)\s*!=\s*['"](.+)['"]$/);
|
|
6778
7309
|
if (neqMatch) {
|
|
6779
|
-
const [,
|
|
6780
|
-
const actualValue = resolvePath(context,
|
|
7310
|
+
const [, path6, expectedValue] = neqMatch;
|
|
7311
|
+
const actualValue = resolvePath(context, path6.trim());
|
|
6781
7312
|
return actualValue !== expectedValue;
|
|
6782
7313
|
}
|
|
6783
7314
|
const value = resolvePath(context, expression);
|
|
@@ -8113,6 +8644,9 @@ var index_default = { z: import_v414.z };
|
|
|
8113
8644
|
DatePickerComponentDefinitionSchema,
|
|
8114
8645
|
DayOfWeekSchema,
|
|
8115
8646
|
EmptyFormComponentDefinitionSchema,
|
|
8647
|
+
EntityDefinitionSchema,
|
|
8648
|
+
EntityFieldDefinitionSchema,
|
|
8649
|
+
EntityRelationshipDefinitionSchema,
|
|
8116
8650
|
EnvSchemaSchema,
|
|
8117
8651
|
EnvVariableDefinitionSchema,
|
|
8118
8652
|
EnvVisibilitySchema,
|
|
@@ -8230,6 +8764,10 @@ var index_default = { z: import_v414.z };
|
|
|
8230
8764
|
SelectComponentDefinitionSchema,
|
|
8231
8765
|
SemanticMemoryConfigSchema,
|
|
8232
8766
|
SenderContextSchema,
|
|
8767
|
+
SequencerBackendError,
|
|
8768
|
+
SequencerContextError,
|
|
8769
|
+
SequencerLockError,
|
|
8770
|
+
SequencerNotFoundError,
|
|
8233
8771
|
SkedyulConfigSchema,
|
|
8234
8772
|
SkillExampleSchema,
|
|
8235
8773
|
SkillMetadataSchema,
|
|
@@ -8285,6 +8823,7 @@ var index_default = { z: import_v414.z };
|
|
|
8285
8823
|
buildAgentContext,
|
|
8286
8824
|
calculateWaitTime,
|
|
8287
8825
|
call,
|
|
8826
|
+
clearRegisteredSequencerConfig,
|
|
8288
8827
|
communicationChannel,
|
|
8289
8828
|
compileAgent,
|
|
8290
8829
|
compileWorkflow,
|
|
@@ -8304,6 +8843,7 @@ var index_default = { z: import_v414.z };
|
|
|
8304
8843
|
createPermissionError,
|
|
8305
8844
|
createQueueHandle,
|
|
8306
8845
|
createRateLimitError,
|
|
8846
|
+
createSequencerHandle,
|
|
8307
8847
|
createServerHookContext,
|
|
8308
8848
|
createSuccessResponse,
|
|
8309
8849
|
createTimeoutError,
|
|
@@ -8316,6 +8856,7 @@ var index_default = { z: import_v414.z };
|
|
|
8316
8856
|
defineAgent,
|
|
8317
8857
|
defineChannel,
|
|
8318
8858
|
defineConfig,
|
|
8859
|
+
defineEntity,
|
|
8319
8860
|
defineEnv,
|
|
8320
8861
|
defineModel,
|
|
8321
8862
|
defineNavigation,
|
|
@@ -8341,6 +8882,8 @@ var index_default = { z: import_v414.z };
|
|
|
8341
8882
|
getRateLimitExecutionContext,
|
|
8342
8883
|
getRequiredInstallEnvKeys,
|
|
8343
8884
|
getRetryDelay,
|
|
8885
|
+
getSequencerConfig,
|
|
8886
|
+
getSequencerDefinitions,
|
|
8344
8887
|
instance,
|
|
8345
8888
|
isChannelDependency,
|
|
8346
8889
|
isCronContext,
|
|
@@ -8356,20 +8899,29 @@ var index_default = { z: import_v414.z };
|
|
|
8356
8899
|
isTimeInWindowSlot,
|
|
8357
8900
|
isWorkflowDependency,
|
|
8358
8901
|
matchesTrigger,
|
|
8902
|
+
memorySequencerBackend,
|
|
8359
8903
|
parseCRMSchema,
|
|
8360
8904
|
parseEstimationFromBilling,
|
|
8905
|
+
platformSequencerBackend,
|
|
8361
8906
|
queuedFetch,
|
|
8362
8907
|
queuedFetchResponse,
|
|
8363
8908
|
registerQueueConfig,
|
|
8909
|
+
registerSequencerConfig,
|
|
8364
8910
|
report,
|
|
8365
8911
|
requeue,
|
|
8912
|
+
resetSequencerBackendForTests,
|
|
8366
8913
|
resolveInputMappings,
|
|
8367
8914
|
resolveQueue,
|
|
8915
|
+
resolveSequencer,
|
|
8368
8916
|
resource,
|
|
8369
8917
|
runWithConfig,
|
|
8370
8918
|
runWithRateLimitExecutionContext,
|
|
8371
8919
|
safeParseCRMSchema,
|
|
8372
8920
|
safeParseConfig,
|
|
8921
|
+
sequencer,
|
|
8922
|
+
sequencerAcquire,
|
|
8923
|
+
sequencerAllow,
|
|
8924
|
+
sequencerRelease,
|
|
8373
8925
|
server,
|
|
8374
8926
|
toGsm7,
|
|
8375
8927
|
token,
|