skedyul 1.2.50 → 1.3.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 +171 -142
- 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 +43 -15
- package/dist/esm/index.mjs +701 -39
- package/dist/index.d.ts +2 -0
- package/dist/index.js +715 -39
- 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/server.js +43 -15
- package/dist/serverless/server.mjs +43 -15
- 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);
|
|
@@ -637,7 +663,7 @@ function printStartupLog(config, tools, port) {
|
|
|
637
663
|
|
|
638
664
|
// src/server/route-handlers/adapters.ts
|
|
639
665
|
function fromLambdaEvent(event) {
|
|
640
|
-
const
|
|
666
|
+
const path3 = event.path || event.rawPath || "/";
|
|
641
667
|
const method = event.httpMethod || event.requestContext?.http?.method || "POST";
|
|
642
668
|
const forwardedProto = event.headers?.["x-forwarded-proto"] ?? event.headers?.["X-Forwarded-Proto"];
|
|
643
669
|
const protocol = forwardedProto ?? "https";
|
|
@@ -645,9 +671,9 @@ function fromLambdaEvent(event) {
|
|
|
645
671
|
const queryString = event.queryStringParameters ? "?" + new URLSearchParams(
|
|
646
672
|
event.queryStringParameters
|
|
647
673
|
).toString() : "";
|
|
648
|
-
const url = `${protocol}://${host}${
|
|
674
|
+
const url = `${protocol}://${host}${path3}${queryString}`;
|
|
649
675
|
return {
|
|
650
|
-
path:
|
|
676
|
+
path: path3,
|
|
651
677
|
method,
|
|
652
678
|
headers: event.headers,
|
|
653
679
|
query: event.queryStringParameters ?? {},
|
|
@@ -729,8 +755,8 @@ function parseBodyByContentType(req) {
|
|
|
729
755
|
}
|
|
730
756
|
|
|
731
757
|
// src/server/route-handlers/handlers.ts
|
|
732
|
-
var
|
|
733
|
-
var
|
|
758
|
+
var fs2 = __toESM(require("fs"));
|
|
759
|
+
var path2 = __toESM(require("path"));
|
|
734
760
|
|
|
735
761
|
// src/server/core-api-handler.ts
|
|
736
762
|
async function handleCoreMethod(method, params) {
|
|
@@ -898,7 +924,8 @@ function serializeConfig(config) {
|
|
|
898
924
|
type: w.type ?? "WEBHOOK"
|
|
899
925
|
})) : [],
|
|
900
926
|
provision: isProvisionConfig(config.provision) ? config.provision : void 0,
|
|
901
|
-
agents: config.agents
|
|
927
|
+
agents: config.agents,
|
|
928
|
+
queues: config.queues
|
|
902
929
|
};
|
|
903
930
|
}
|
|
904
931
|
function isProvisionConfig(value) {
|
|
@@ -1194,7 +1221,7 @@ async function handleOAuthCallback(parsedBody, hooks) {
|
|
|
1194
1221
|
}
|
|
1195
1222
|
|
|
1196
1223
|
// src/server/handlers/webhook-handler.ts
|
|
1197
|
-
function parseWebhookRequest(parsedBody, method, url,
|
|
1224
|
+
function parseWebhookRequest(parsedBody, method, url, path3, headers, query, rawBody, appIdHeader, appVersionIdHeader) {
|
|
1198
1225
|
const isEnvelope = typeof parsedBody === "object" && parsedBody !== null && "env" in parsedBody && "request" in parsedBody && "context" in parsedBody;
|
|
1199
1226
|
if (isEnvelope) {
|
|
1200
1227
|
const envelope = parsedBody;
|
|
@@ -1248,7 +1275,7 @@ function parseWebhookRequest(parsedBody, method, url, path2, headers, query, raw
|
|
|
1248
1275
|
const webhookRequest = {
|
|
1249
1276
|
method,
|
|
1250
1277
|
url,
|
|
1251
|
-
path:
|
|
1278
|
+
path: path3,
|
|
1252
1279
|
headers,
|
|
1253
1280
|
query,
|
|
1254
1281
|
body: parsedBody,
|
|
@@ -1306,7 +1333,7 @@ function isMethodAllowed(webhookRegistry, handle, method) {
|
|
|
1306
1333
|
|
|
1307
1334
|
// src/server/route-handlers/handlers.ts
|
|
1308
1335
|
function getConfigFilePath() {
|
|
1309
|
-
return process.env.LAMBDA_TASK_ROOT ?
|
|
1336
|
+
return process.env.LAMBDA_TASK_ROOT ? path2.join(process.env.LAMBDA_TASK_ROOT, ".skedyul", "config.json") : ".skedyul/config.json";
|
|
1310
1337
|
}
|
|
1311
1338
|
function findToolInRegistry(registry, toolName) {
|
|
1312
1339
|
for (const [key, t] of Object.entries(registry)) {
|
|
@@ -1345,8 +1372,8 @@ function handleHealthRoute(ctx) {
|
|
|
1345
1372
|
function handleConfigRoute(ctx) {
|
|
1346
1373
|
const configFilePath = getConfigFilePath();
|
|
1347
1374
|
try {
|
|
1348
|
-
if (
|
|
1349
|
-
const fileConfig = JSON.parse(
|
|
1375
|
+
if (fs2.existsSync(configFilePath)) {
|
|
1376
|
+
const fileConfig = JSON.parse(fs2.readFileSync(configFilePath, "utf-8"));
|
|
1350
1377
|
return { status: 200, body: fileConfig };
|
|
1351
1378
|
}
|
|
1352
1379
|
} catch (err) {
|
|
@@ -2031,6 +2058,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
|
|
|
2031
2058
|
installContextLogger();
|
|
2032
2059
|
function createSkedyulServer(config) {
|
|
2033
2060
|
mergeRuntimeEnv();
|
|
2061
|
+
registerQueueConfig(config);
|
|
2034
2062
|
const registry = config.tools;
|
|
2035
2063
|
const webhookRegistry = config.webhooks;
|
|
2036
2064
|
if (config.coreApi?.service) {
|