skedyul 1.2.51 → 1.3.1
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 +173 -143
- package/dist/config/app-config.d.ts +6 -0
- package/dist/config/index.d.ts +1 -1
- package/dist/config/queue-config.d.ts +33 -0
- package/dist/dedicated/server.js +45 -16
- package/dist/esm/index.mjs +717 -50
- package/dist/index.d.ts +2 -0
- package/dist/index.js +731 -50
- package/dist/ratelimit/backends/index.d.ts +10 -0
- package/dist/ratelimit/backends/memory.d.ts +14 -0
- package/dist/ratelimit/backends/platform.d.ts +9 -0
- package/dist/ratelimit/config-loader.d.ts +10 -0
- package/dist/ratelimit/context.d.ts +7 -0
- package/dist/ratelimit/errors.d.ts +27 -0
- package/dist/ratelimit/index.d.ts +9 -0
- package/dist/ratelimit/queued-fetch.d.ts +11 -0
- package/dist/ratelimit/resolve-queue-key.d.ts +14 -0
- package/dist/ratelimit/should-retry.d.ts +5 -0
- package/dist/ratelimit/types.d.ts +43 -0
- package/dist/scheduling/index.js +14 -10
- package/dist/scheduling/index.mjs +14 -10
- package/dist/server.js +45 -16
- package/dist/serverless/server.mjs +45 -16
- package/package.json +3 -3
|
@@ -7,6 +7,8 @@ import type { ToolRegistry, WebhookRegistry, ToolMetadata, WebhookMetadata } fro
|
|
|
7
7
|
import type { ServerHooks } from '../types/handlers';
|
|
8
8
|
import type { CoreApiConfig } from '../core/types';
|
|
9
9
|
import type { EnvSchema, ComputeLayer, ModelDefinition, RelationshipDefinition, ChannelDefinition, WorkflowDefinition, PageDefinition, NavigationConfig, AgentDefinition, SignalDefinition } from './types';
|
|
10
|
+
import type { QueueRegistry, SerializableQueueConfig } from './queue-config';
|
|
11
|
+
export type { QueueScope, QueueConfig, SerializableQueueConfig, QueueRegistry, } from './queue-config';
|
|
10
12
|
/**
|
|
11
13
|
* Install configuration - defines per-install env vars and SHARED models.
|
|
12
14
|
* This is configured by users during app installation.
|
|
@@ -102,6 +104,8 @@ export interface SkedyulConfig {
|
|
|
102
104
|
agents?: AgentDefinition[];
|
|
103
105
|
/** Build configuration for the integration */
|
|
104
106
|
build?: BuildConfig;
|
|
107
|
+
/** Rate-limit queue definitions for queuedFetch */
|
|
108
|
+
queues?: QueueRegistry;
|
|
105
109
|
}
|
|
106
110
|
/**
|
|
107
111
|
* Serializable config (for database storage).
|
|
@@ -120,6 +124,8 @@ export interface SerializableSkedyulConfig {
|
|
|
120
124
|
provision?: ProvisionConfig;
|
|
121
125
|
/** Agent definitions (stored as-is) */
|
|
122
126
|
agents?: AgentDefinition[];
|
|
127
|
+
/** Rate-limit queue definitions */
|
|
128
|
+
queues?: Record<string, SerializableQueueConfig>;
|
|
123
129
|
}
|
|
124
130
|
/**
|
|
125
131
|
* Define a Skedyul app configuration with full type safety.
|
package/dist/config/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* - All definition types extend BaseDefinition
|
|
10
10
|
*/
|
|
11
11
|
export * from './types';
|
|
12
|
-
export type { InstallConfig, ProvisionConfig, BuildConfig, CorsOptions, SkedyulConfig, SerializableSkedyulConfig, } from './app-config';
|
|
12
|
+
export type { InstallConfig, ProvisionConfig, BuildConfig, CorsOptions, SkedyulConfig, SerializableSkedyulConfig, QueueScope, QueueConfig, SerializableQueueConfig, QueueRegistry, } from './app-config';
|
|
13
13
|
export { defineConfig } from './app-config';
|
|
14
14
|
export { defineModel, defineChannel, definePage, defineWorkflow, defineAgent, defineEnv, defineNavigation, } from './define';
|
|
15
15
|
export { CONFIG_FILE_NAMES, loadConfig, validateConfig } from './loader';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate-limit queue configuration for skedyul.config queues.
|
|
3
|
+
*/
|
|
4
|
+
export type QueueScope = 'provision' | 'install' | 'provision_endpoint' | 'install_endpoint' | 'global';
|
|
5
|
+
/**
|
|
6
|
+
* Serializable queue config (stored in DB / .skedyul/config.json).
|
|
7
|
+
*/
|
|
8
|
+
export interface SerializableQueueConfig {
|
|
9
|
+
scope: QueueScope;
|
|
10
|
+
/** Override endpoint handle for provision_endpoint / install_endpoint scopes */
|
|
11
|
+
endpoint?: string;
|
|
12
|
+
/** Max in-flight operations (concurrency cap) */
|
|
13
|
+
maxConcurrent?: number;
|
|
14
|
+
/** Minimum ms between operation starts */
|
|
15
|
+
minTime?: number;
|
|
16
|
+
/** Token bucket: max operations per refresh window */
|
|
17
|
+
reservoir?: number;
|
|
18
|
+
reservoirRefreshAmount?: number;
|
|
19
|
+
reservoirRefreshInterval?: number;
|
|
20
|
+
/** SDK-level retries inside queuedFetch */
|
|
21
|
+
maxRetries?: number;
|
|
22
|
+
retryDelayMs?: number;
|
|
23
|
+
/** Hard timeout for acquire wait + fn execution (ms) */
|
|
24
|
+
timeout?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Full queue config including non-serializable retry predicate.
|
|
28
|
+
*/
|
|
29
|
+
export interface QueueConfig extends SerializableQueueConfig {
|
|
30
|
+
/** Predicate for whether a thrown error should trigger requeue */
|
|
31
|
+
shouldRetry?: (error: unknown, attempt: number) => boolean;
|
|
32
|
+
}
|
|
33
|
+
export type QueueRegistry = Record<string, QueueConfig>;
|
package/dist/dedicated/server.js
CHANGED
|
@@ -87,6 +87,16 @@ var CoreApiService = class {
|
|
|
87
87
|
};
|
|
88
88
|
var coreApiService = new CoreApiService();
|
|
89
89
|
|
|
90
|
+
// src/ratelimit/config-loader.ts
|
|
91
|
+
var fs = __toESM(require("fs"));
|
|
92
|
+
var path = __toESM(require("path"));
|
|
93
|
+
var cachedRuntimeQueues = null;
|
|
94
|
+
var registeredServerConfig = null;
|
|
95
|
+
function registerQueueConfig(config) {
|
|
96
|
+
registeredServerConfig = config;
|
|
97
|
+
cachedRuntimeQueues = config.queues ?? null;
|
|
98
|
+
}
|
|
99
|
+
|
|
90
100
|
// src/server/utils/schema.ts
|
|
91
101
|
var z = __toESM(require("zod"));
|
|
92
102
|
function normalizeBilling(billing) {
|
|
@@ -265,6 +275,14 @@ function runWithConfig(config, fn) {
|
|
|
265
275
|
return requestConfigStorage.run(config, fn);
|
|
266
276
|
}
|
|
267
277
|
|
|
278
|
+
// src/ratelimit/context.ts
|
|
279
|
+
var import_async_hooks2 = require("async_hooks");
|
|
280
|
+
var executionContextStorage = new import_async_hooks2.AsyncLocalStorage();
|
|
281
|
+
var activeOperationStorage = new import_async_hooks2.AsyncLocalStorage();
|
|
282
|
+
function runWithRateLimitExecutionContext(ctx, fn) {
|
|
283
|
+
return executionContextStorage.run(ctx, fn);
|
|
284
|
+
}
|
|
285
|
+
|
|
268
286
|
// src/errors.ts
|
|
269
287
|
var InstallError = class extends Error {
|
|
270
288
|
// Optional: which field caused the error
|
|
@@ -284,8 +302,8 @@ var AppAuthInvalidError = class extends Error {
|
|
|
284
302
|
};
|
|
285
303
|
|
|
286
304
|
// src/server/context-logger.ts
|
|
287
|
-
var
|
|
288
|
-
var logContextStorage = new
|
|
305
|
+
var import_async_hooks3 = require("async_hooks");
|
|
306
|
+
var logContextStorage = new import_async_hooks3.AsyncLocalStorage();
|
|
289
307
|
function runWithLogContext(context, fn) {
|
|
290
308
|
return logContextStorage.run(context, fn);
|
|
291
309
|
}
|
|
@@ -498,9 +516,17 @@ function createCallToolHandler(registry, state, onMaxRequests) {
|
|
|
498
516
|
baseUrl: toolEnv.SKEDYUL_API_URL ?? "",
|
|
499
517
|
apiToken: toolEnv.SKEDYUL_API_TOKEN ?? ""
|
|
500
518
|
};
|
|
519
|
+
const rateLimitContext = {
|
|
520
|
+
app,
|
|
521
|
+
appInstallationId: trigger === "provision" ? void 0 : rawContext.appInstallationId,
|
|
522
|
+
invocation,
|
|
523
|
+
isProvisionContext: trigger === "provision"
|
|
524
|
+
};
|
|
501
525
|
const functionResult = await runWithConfig(requestConfig, async () => {
|
|
502
|
-
return await
|
|
503
|
-
return await
|
|
526
|
+
return await runWithRateLimitExecutionContext(rateLimitContext, async () => {
|
|
527
|
+
return await runWithLogContext({ invocation }, async () => {
|
|
528
|
+
return await fn(inputs, executionContext);
|
|
529
|
+
});
|
|
504
530
|
});
|
|
505
531
|
});
|
|
506
532
|
const billing = normalizeBilling(functionResult.billing);
|
|
@@ -544,6 +570,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
|
|
|
544
570
|
};
|
|
545
571
|
}
|
|
546
572
|
const errorMessage = error instanceof Error ? error.message : String(error ?? "");
|
|
573
|
+
const errorCode = error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : "TOOL_EXECUTION_ERROR";
|
|
547
574
|
return {
|
|
548
575
|
output: null,
|
|
549
576
|
billing: { credits: 0 },
|
|
@@ -553,7 +580,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
|
|
|
553
580
|
toolName
|
|
554
581
|
},
|
|
555
582
|
error: {
|
|
556
|
-
code:
|
|
583
|
+
code: errorCode,
|
|
557
584
|
message: errorMessage
|
|
558
585
|
}
|
|
559
586
|
};
|
|
@@ -637,7 +664,7 @@ function printStartupLog(config, tools, port) {
|
|
|
637
664
|
|
|
638
665
|
// src/server/route-handlers/adapters.ts
|
|
639
666
|
function fromLambdaEvent(event) {
|
|
640
|
-
const
|
|
667
|
+
const path3 = event.path || event.rawPath || "/";
|
|
641
668
|
const method = event.httpMethod || event.requestContext?.http?.method || "POST";
|
|
642
669
|
const forwardedProto = event.headers?.["x-forwarded-proto"] ?? event.headers?.["X-Forwarded-Proto"];
|
|
643
670
|
const protocol = forwardedProto ?? "https";
|
|
@@ -645,9 +672,9 @@ function fromLambdaEvent(event) {
|
|
|
645
672
|
const queryString = event.queryStringParameters ? "?" + new URLSearchParams(
|
|
646
673
|
event.queryStringParameters
|
|
647
674
|
).toString() : "";
|
|
648
|
-
const url = `${protocol}://${host}${
|
|
675
|
+
const url = `${protocol}://${host}${path3}${queryString}`;
|
|
649
676
|
return {
|
|
650
|
-
path:
|
|
677
|
+
path: path3,
|
|
651
678
|
method,
|
|
652
679
|
headers: event.headers,
|
|
653
680
|
query: event.queryStringParameters ?? {},
|
|
@@ -729,8 +756,8 @@ function parseBodyByContentType(req) {
|
|
|
729
756
|
}
|
|
730
757
|
|
|
731
758
|
// src/server/route-handlers/handlers.ts
|
|
732
|
-
var
|
|
733
|
-
var
|
|
759
|
+
var fs2 = __toESM(require("fs"));
|
|
760
|
+
var path2 = __toESM(require("path"));
|
|
734
761
|
|
|
735
762
|
// src/server/core-api-handler.ts
|
|
736
763
|
async function handleCoreMethod(method, params) {
|
|
@@ -898,7 +925,8 @@ function serializeConfig(config) {
|
|
|
898
925
|
type: w.type ?? "WEBHOOK"
|
|
899
926
|
})) : [],
|
|
900
927
|
provision: isProvisionConfig(config.provision) ? config.provision : void 0,
|
|
901
|
-
agents: config.agents
|
|
928
|
+
agents: config.agents,
|
|
929
|
+
queues: config.queues
|
|
902
930
|
};
|
|
903
931
|
}
|
|
904
932
|
function isProvisionConfig(value) {
|
|
@@ -1194,7 +1222,7 @@ async function handleOAuthCallback(parsedBody, hooks) {
|
|
|
1194
1222
|
}
|
|
1195
1223
|
|
|
1196
1224
|
// src/server/handlers/webhook-handler.ts
|
|
1197
|
-
function parseWebhookRequest(parsedBody, method, url,
|
|
1225
|
+
function parseWebhookRequest(parsedBody, method, url, path3, headers, query, rawBody, appIdHeader, appVersionIdHeader) {
|
|
1198
1226
|
const isEnvelope = typeof parsedBody === "object" && parsedBody !== null && "env" in parsedBody && "request" in parsedBody && "context" in parsedBody;
|
|
1199
1227
|
if (isEnvelope) {
|
|
1200
1228
|
const envelope = parsedBody;
|
|
@@ -1248,7 +1276,7 @@ function parseWebhookRequest(parsedBody, method, url, path2, headers, query, raw
|
|
|
1248
1276
|
const webhookRequest = {
|
|
1249
1277
|
method,
|
|
1250
1278
|
url,
|
|
1251
|
-
path:
|
|
1279
|
+
path: path3,
|
|
1252
1280
|
headers,
|
|
1253
1281
|
query,
|
|
1254
1282
|
body: parsedBody,
|
|
@@ -1306,7 +1334,7 @@ function isMethodAllowed(webhookRegistry, handle, method) {
|
|
|
1306
1334
|
|
|
1307
1335
|
// src/server/route-handlers/handlers.ts
|
|
1308
1336
|
function getConfigFilePath() {
|
|
1309
|
-
return process.env.LAMBDA_TASK_ROOT ?
|
|
1337
|
+
return process.env.LAMBDA_TASK_ROOT ? path2.join(process.env.LAMBDA_TASK_ROOT, ".skedyul", "config.json") : ".skedyul/config.json";
|
|
1310
1338
|
}
|
|
1311
1339
|
function findToolInRegistry(registry, toolName) {
|
|
1312
1340
|
for (const [key, t] of Object.entries(registry)) {
|
|
@@ -1345,8 +1373,8 @@ function handleHealthRoute(ctx) {
|
|
|
1345
1373
|
function handleConfigRoute(ctx) {
|
|
1346
1374
|
const configFilePath = getConfigFilePath();
|
|
1347
1375
|
try {
|
|
1348
|
-
if (
|
|
1349
|
-
const fileConfig = JSON.parse(
|
|
1376
|
+
if (fs2.existsSync(configFilePath)) {
|
|
1377
|
+
const fileConfig = JSON.parse(fs2.readFileSync(configFilePath, "utf-8"));
|
|
1350
1378
|
return { status: 200, body: fileConfig };
|
|
1351
1379
|
}
|
|
1352
1380
|
} catch (err) {
|
|
@@ -2031,6 +2059,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
|
|
|
2031
2059
|
installContextLogger();
|
|
2032
2060
|
function createSkedyulServer(config) {
|
|
2033
2061
|
mergeRuntimeEnv();
|
|
2062
|
+
registerQueueConfig(config);
|
|
2034
2063
|
const registry = config.tools;
|
|
2035
2064
|
const webhookRegistry = config.webhooks;
|
|
2036
2065
|
if (config.coreApi?.service) {
|