@exulu/backend 1.31.1 → 1.32.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/CHANGELOG.md +3 -3
- package/dist/index.cjs +94 -5
- package/dist/index.d.cts +20 -2
- package/dist/index.d.ts +20 -2
- package/dist/index.js +94 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
# [1.32.0](https://github.com/Qventu/exulu-backend/compare/v1.31.2...v1.32.0) (2025-11-11)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
###
|
|
4
|
+
### Features
|
|
5
5
|
|
|
6
|
-
*
|
|
6
|
+
* implement scheduled data sources for contexts ([d936754](https://github.com/Qventu/exulu-backend/commit/d9367545fc3dc35b9c2d2ad0820fc7d2fddd4666))
|
package/dist/index.cjs
CHANGED
|
@@ -67,6 +67,7 @@ var redisServer = {
|
|
|
67
67
|
// src/redis/client.ts
|
|
68
68
|
var client = {};
|
|
69
69
|
async function redisClient() {
|
|
70
|
+
console.log("[EXULU] redisServer:", redisServer);
|
|
70
71
|
if (!redisServer.host || !redisServer.port) {
|
|
71
72
|
return { client: null };
|
|
72
73
|
}
|
|
@@ -2333,7 +2334,7 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
2333
2334
|
if (!item) {
|
|
2334
2335
|
throw new Error("Item not found, or your user does not have access to it.");
|
|
2335
2336
|
}
|
|
2336
|
-
const { job, result } = await exists.
|
|
2337
|
+
const { job, result } = await exists.processField(
|
|
2337
2338
|
"api",
|
|
2338
2339
|
context.user.id,
|
|
2339
2340
|
context.user.role?.id,
|
|
@@ -5379,10 +5380,12 @@ var ExuluContext = class {
|
|
|
5379
5380
|
resultReranker;
|
|
5380
5381
|
// todo typings
|
|
5381
5382
|
configuration;
|
|
5382
|
-
|
|
5383
|
+
sources = [];
|
|
5384
|
+
constructor({ id, name, description, embedder, active, rateLimit, fields, queryRewriter, resultReranker, configuration, sources }) {
|
|
5383
5385
|
this.id = id;
|
|
5384
5386
|
this.name = name;
|
|
5385
5387
|
this.fields = fields || [];
|
|
5388
|
+
this.sources = sources || [];
|
|
5386
5389
|
this.configuration = configuration || {
|
|
5387
5390
|
calculateVectors: "manual",
|
|
5388
5391
|
language: "english",
|
|
@@ -5395,7 +5398,7 @@ var ExuluContext = class {
|
|
|
5395
5398
|
this.queryRewriter = queryRewriter;
|
|
5396
5399
|
this.resultReranker = resultReranker;
|
|
5397
5400
|
}
|
|
5398
|
-
|
|
5401
|
+
processField = async (trigger, user, role, item, config) => {
|
|
5399
5402
|
console.log("[EXULU] processing field", item.field, " in context", this.id);
|
|
5400
5403
|
console.log("[EXULU] fields", this.fields.map((field2) => field2.name));
|
|
5401
5404
|
const field = this.fields.find((field2) => field2.name === item.field?.replace("_s3key", ""));
|
|
@@ -5457,6 +5460,9 @@ var ExuluContext = class {
|
|
|
5457
5460
|
results: []
|
|
5458
5461
|
};
|
|
5459
5462
|
};
|
|
5463
|
+
executeSource = async (source, inputs) => {
|
|
5464
|
+
return await source.execute(inputs);
|
|
5465
|
+
};
|
|
5460
5466
|
tableExists = async () => {
|
|
5461
5467
|
const { db: db3 } = await postgresClient();
|
|
5462
5468
|
const tableName = getTableName(this.id);
|
|
@@ -6650,8 +6656,13 @@ var createWorkers = async (agents, queues2, config, contexts, evals, tools, trac
|
|
|
6650
6656
|
throw new Error("No redis server configured in the environment, so cannot start worker.");
|
|
6651
6657
|
}
|
|
6652
6658
|
if (!redisConnection) {
|
|
6653
|
-
|
|
6654
|
-
|
|
6659
|
+
let url = "";
|
|
6660
|
+
if (redisServer.username) {
|
|
6661
|
+
url = `redis://${redisServer.username}:${redisServer.password}@${redisServer.host}:${redisServer.port}`;
|
|
6662
|
+
} else {
|
|
6663
|
+
url = `redis://${redisServer.host}:${redisServer.port}`;
|
|
6664
|
+
}
|
|
6665
|
+
redisConnection = new import_ioredis.default(url, {
|
|
6655
6666
|
enableOfflineQueue: true,
|
|
6656
6667
|
retryStrategy: function(times) {
|
|
6657
6668
|
return Math.max(Math.min(Math.exp(times), 2e4), 1e3);
|
|
@@ -6966,6 +6977,49 @@ var createWorkers = async (agents, queues2, config, contexts, evals, tools, trac
|
|
|
6966
6977
|
metadata: {}
|
|
6967
6978
|
};
|
|
6968
6979
|
}
|
|
6980
|
+
if (data.type === "source") {
|
|
6981
|
+
console.log("[EXULU] running a source job.", logMetadata(bullmqJob.name));
|
|
6982
|
+
if (!data.source) {
|
|
6983
|
+
throw new Error(`No source id set for source job.`);
|
|
6984
|
+
}
|
|
6985
|
+
if (!data.context) {
|
|
6986
|
+
throw new Error(`No context id set for source job.`);
|
|
6987
|
+
}
|
|
6988
|
+
const context = contexts.find((c) => c.id === data.context);
|
|
6989
|
+
if (!context) {
|
|
6990
|
+
throw new Error(`Context ${data.context} not found in the registry.`);
|
|
6991
|
+
}
|
|
6992
|
+
const source = context.sources.find((s) => s.id === data.source);
|
|
6993
|
+
if (!source) {
|
|
6994
|
+
throw new Error(`Source ${data.source} not found in the context ${context.id}.`);
|
|
6995
|
+
}
|
|
6996
|
+
const result = await source.execute(data.inputs);
|
|
6997
|
+
let jobs = [];
|
|
6998
|
+
let items = [];
|
|
6999
|
+
for (const item of result) {
|
|
7000
|
+
const { item: createdItem, job } = await context.createItem(item, config, data.user, data.role);
|
|
7001
|
+
if (job) {
|
|
7002
|
+
jobs.push(job);
|
|
7003
|
+
console.log(`[EXULU] Scheduled job through source update job for item ${createdItem.id} (Job ID: ${job})`, logMetadata(bullmqJob.name, {
|
|
7004
|
+
item: createdItem,
|
|
7005
|
+
job
|
|
7006
|
+
}));
|
|
7007
|
+
}
|
|
7008
|
+
if (createdItem.id) {
|
|
7009
|
+
items.push(createdItem.id);
|
|
7010
|
+
console.log(`[EXULU] created item through source update job ${createdItem.id}`, logMetadata(bullmqJob.name, {
|
|
7011
|
+
item: createdItem
|
|
7012
|
+
}));
|
|
7013
|
+
}
|
|
7014
|
+
}
|
|
7015
|
+
return {
|
|
7016
|
+
result,
|
|
7017
|
+
metadata: {
|
|
7018
|
+
jobs,
|
|
7019
|
+
items
|
|
7020
|
+
}
|
|
7021
|
+
};
|
|
7022
|
+
}
|
|
6969
7023
|
throw new Error(`Invalid job type: ${data.type} for job ${bullmqJob.name}.`);
|
|
6970
7024
|
} catch (error) {
|
|
6971
7025
|
console.error(`[EXULU] job failed.`, error instanceof Error ? error.message : String(error));
|
|
@@ -8872,6 +8926,41 @@ var ExuluApp = class {
|
|
|
8872
8926
|
if (queues2) {
|
|
8873
8927
|
filteredQueues = filteredQueues.filter((q) => queues2.includes(q.queue.name));
|
|
8874
8928
|
}
|
|
8929
|
+
const sources = Object.values(this._contexts ?? {}).flatMap((context) => ({
|
|
8930
|
+
...context.sources,
|
|
8931
|
+
context: context.id
|
|
8932
|
+
}));
|
|
8933
|
+
if (sources.length > 0) {
|
|
8934
|
+
console.log("[EXULU] Creating ContextSource schedulers for", sources.length, "sources.");
|
|
8935
|
+
for (const source of sources) {
|
|
8936
|
+
const queue = await source.config?.queue;
|
|
8937
|
+
if (queue) {
|
|
8938
|
+
if (!source.config.schedule) {
|
|
8939
|
+
throw new Error("Schedule is required for source when configuring a queue: " + source.name);
|
|
8940
|
+
}
|
|
8941
|
+
console.log("[EXULU] Creating ContextSource scheduler for", source.name, "in queue", queue.queue?.name);
|
|
8942
|
+
await queue.queue?.upsertJobScheduler(source.id, {
|
|
8943
|
+
pattern: source.config?.schedule
|
|
8944
|
+
}, {
|
|
8945
|
+
// default job data
|
|
8946
|
+
name: `${source.id}-job`,
|
|
8947
|
+
data: {
|
|
8948
|
+
source: source.id,
|
|
8949
|
+
context: source.context,
|
|
8950
|
+
type: "source"
|
|
8951
|
+
},
|
|
8952
|
+
opts: {
|
|
8953
|
+
backoff: {
|
|
8954
|
+
type: source.config.backoff?.type || "exponential",
|
|
8955
|
+
delay: source.config.backoff?.delay || 2e3
|
|
8956
|
+
},
|
|
8957
|
+
attempts: source.config.retries || 3,
|
|
8958
|
+
removeOnFail: 200
|
|
8959
|
+
}
|
|
8960
|
+
});
|
|
8961
|
+
}
|
|
8962
|
+
}
|
|
8963
|
+
}
|
|
8875
8964
|
return await createWorkers(
|
|
8876
8965
|
this._agents,
|
|
8877
8966
|
filteredQueues,
|
package/dist/index.d.cts
CHANGED
|
@@ -544,6 +544,21 @@ declare class ExuluStorage {
|
|
|
544
544
|
getPresignedUrl: (key: string) => Promise<string>;
|
|
545
545
|
uploadFile: (user: number, file: Buffer | Uint8Array, key: string, type: string, metadata?: Record<string, string>) => Promise<string>;
|
|
546
546
|
}
|
|
547
|
+
type ExuluContextSource = {
|
|
548
|
+
id: string;
|
|
549
|
+
name: string;
|
|
550
|
+
description: string;
|
|
551
|
+
config: {
|
|
552
|
+
schedule: string;
|
|
553
|
+
queue: Promise<ExuluQueueConfig>;
|
|
554
|
+
retries?: number;
|
|
555
|
+
backoff?: {
|
|
556
|
+
type: 'exponential' | 'linear';
|
|
557
|
+
delay: number;
|
|
558
|
+
};
|
|
559
|
+
};
|
|
560
|
+
execute: (inputs: any) => Promise<Item[]>;
|
|
561
|
+
};
|
|
547
562
|
declare class ExuluContext {
|
|
548
563
|
id: string;
|
|
549
564
|
name: string;
|
|
@@ -559,12 +574,14 @@ declare class ExuluContext {
|
|
|
559
574
|
defaultRightsMode?: ExuluRightsMode;
|
|
560
575
|
language?: "german" | "english";
|
|
561
576
|
};
|
|
562
|
-
|
|
577
|
+
sources: ExuluContextSource[];
|
|
578
|
+
constructor({ id, name, description, embedder, active, rateLimit, fields, queryRewriter, resultReranker, configuration, sources }: {
|
|
563
579
|
id: string;
|
|
564
580
|
name: string;
|
|
565
581
|
fields: ExuluContextFieldDefinition[];
|
|
566
582
|
description: string;
|
|
567
583
|
embedder?: ExuluEmbedder;
|
|
584
|
+
sources: ExuluContextSource[];
|
|
568
585
|
category?: string;
|
|
569
586
|
active: boolean;
|
|
570
587
|
rateLimit?: RateLimiterRule;
|
|
@@ -576,13 +593,14 @@ declare class ExuluContext {
|
|
|
576
593
|
language?: "german" | "english";
|
|
577
594
|
};
|
|
578
595
|
});
|
|
579
|
-
|
|
596
|
+
processField: (trigger: STATISTICS_LABELS, user: number, role: string, item: Item & {
|
|
580
597
|
field: string;
|
|
581
598
|
}, config: ExuluConfig) => Promise<{
|
|
582
599
|
result: string;
|
|
583
600
|
job?: string;
|
|
584
601
|
}>;
|
|
585
602
|
deleteAll: () => Promise<VectorOperationResponse>;
|
|
603
|
+
executeSource: (source: ExuluContextSource, inputs: any) => Promise<Item[]>;
|
|
586
604
|
tableExists: () => Promise<boolean>;
|
|
587
605
|
chunksTableExists: () => Promise<boolean>;
|
|
588
606
|
createAndUpsertEmbeddings: (item: Item, config: ExuluConfig, user?: number, statistics?: ExuluStatisticParams, role?: string, job?: string) => Promise<{
|
package/dist/index.d.ts
CHANGED
|
@@ -544,6 +544,21 @@ declare class ExuluStorage {
|
|
|
544
544
|
getPresignedUrl: (key: string) => Promise<string>;
|
|
545
545
|
uploadFile: (user: number, file: Buffer | Uint8Array, key: string, type: string, metadata?: Record<string, string>) => Promise<string>;
|
|
546
546
|
}
|
|
547
|
+
type ExuluContextSource = {
|
|
548
|
+
id: string;
|
|
549
|
+
name: string;
|
|
550
|
+
description: string;
|
|
551
|
+
config: {
|
|
552
|
+
schedule: string;
|
|
553
|
+
queue: Promise<ExuluQueueConfig>;
|
|
554
|
+
retries?: number;
|
|
555
|
+
backoff?: {
|
|
556
|
+
type: 'exponential' | 'linear';
|
|
557
|
+
delay: number;
|
|
558
|
+
};
|
|
559
|
+
};
|
|
560
|
+
execute: (inputs: any) => Promise<Item[]>;
|
|
561
|
+
};
|
|
547
562
|
declare class ExuluContext {
|
|
548
563
|
id: string;
|
|
549
564
|
name: string;
|
|
@@ -559,12 +574,14 @@ declare class ExuluContext {
|
|
|
559
574
|
defaultRightsMode?: ExuluRightsMode;
|
|
560
575
|
language?: "german" | "english";
|
|
561
576
|
};
|
|
562
|
-
|
|
577
|
+
sources: ExuluContextSource[];
|
|
578
|
+
constructor({ id, name, description, embedder, active, rateLimit, fields, queryRewriter, resultReranker, configuration, sources }: {
|
|
563
579
|
id: string;
|
|
564
580
|
name: string;
|
|
565
581
|
fields: ExuluContextFieldDefinition[];
|
|
566
582
|
description: string;
|
|
567
583
|
embedder?: ExuluEmbedder;
|
|
584
|
+
sources: ExuluContextSource[];
|
|
568
585
|
category?: string;
|
|
569
586
|
active: boolean;
|
|
570
587
|
rateLimit?: RateLimiterRule;
|
|
@@ -576,13 +593,14 @@ declare class ExuluContext {
|
|
|
576
593
|
language?: "german" | "english";
|
|
577
594
|
};
|
|
578
595
|
});
|
|
579
|
-
|
|
596
|
+
processField: (trigger: STATISTICS_LABELS, user: number, role: string, item: Item & {
|
|
580
597
|
field: string;
|
|
581
598
|
}, config: ExuluConfig) => Promise<{
|
|
582
599
|
result: string;
|
|
583
600
|
job?: string;
|
|
584
601
|
}>;
|
|
585
602
|
deleteAll: () => Promise<VectorOperationResponse>;
|
|
603
|
+
executeSource: (source: ExuluContextSource, inputs: any) => Promise<Item[]>;
|
|
586
604
|
tableExists: () => Promise<boolean>;
|
|
587
605
|
chunksTableExists: () => Promise<boolean>;
|
|
588
606
|
createAndUpsertEmbeddings: (item: Item, config: ExuluConfig, user?: number, statistics?: ExuluStatisticParams, role?: string, job?: string) => Promise<{
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var redisServer = {
|
|
|
15
15
|
// src/redis/client.ts
|
|
16
16
|
var client = {};
|
|
17
17
|
async function redisClient() {
|
|
18
|
+
console.log("[EXULU] redisServer:", redisServer);
|
|
18
19
|
if (!redisServer.host || !redisServer.port) {
|
|
19
20
|
return { client: null };
|
|
20
21
|
}
|
|
@@ -2281,7 +2282,7 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
2281
2282
|
if (!item) {
|
|
2282
2283
|
throw new Error("Item not found, or your user does not have access to it.");
|
|
2283
2284
|
}
|
|
2284
|
-
const { job, result } = await exists.
|
|
2285
|
+
const { job, result } = await exists.processField(
|
|
2285
2286
|
"api",
|
|
2286
2287
|
context.user.id,
|
|
2287
2288
|
context.user.role?.id,
|
|
@@ -5346,10 +5347,12 @@ var ExuluContext = class {
|
|
|
5346
5347
|
resultReranker;
|
|
5347
5348
|
// todo typings
|
|
5348
5349
|
configuration;
|
|
5349
|
-
|
|
5350
|
+
sources = [];
|
|
5351
|
+
constructor({ id, name, description, embedder, active, rateLimit, fields, queryRewriter, resultReranker, configuration, sources }) {
|
|
5350
5352
|
this.id = id;
|
|
5351
5353
|
this.name = name;
|
|
5352
5354
|
this.fields = fields || [];
|
|
5355
|
+
this.sources = sources || [];
|
|
5353
5356
|
this.configuration = configuration || {
|
|
5354
5357
|
calculateVectors: "manual",
|
|
5355
5358
|
language: "english",
|
|
@@ -5362,7 +5365,7 @@ var ExuluContext = class {
|
|
|
5362
5365
|
this.queryRewriter = queryRewriter;
|
|
5363
5366
|
this.resultReranker = resultReranker;
|
|
5364
5367
|
}
|
|
5365
|
-
|
|
5368
|
+
processField = async (trigger, user, role, item, config) => {
|
|
5366
5369
|
console.log("[EXULU] processing field", item.field, " in context", this.id);
|
|
5367
5370
|
console.log("[EXULU] fields", this.fields.map((field2) => field2.name));
|
|
5368
5371
|
const field = this.fields.find((field2) => field2.name === item.field?.replace("_s3key", ""));
|
|
@@ -5424,6 +5427,9 @@ var ExuluContext = class {
|
|
|
5424
5427
|
results: []
|
|
5425
5428
|
};
|
|
5426
5429
|
};
|
|
5430
|
+
executeSource = async (source, inputs) => {
|
|
5431
|
+
return await source.execute(inputs);
|
|
5432
|
+
};
|
|
5427
5433
|
tableExists = async () => {
|
|
5428
5434
|
const { db: db3 } = await postgresClient();
|
|
5429
5435
|
const tableName = getTableName(this.id);
|
|
@@ -6617,8 +6623,13 @@ var createWorkers = async (agents, queues2, config, contexts, evals, tools, trac
|
|
|
6617
6623
|
throw new Error("No redis server configured in the environment, so cannot start worker.");
|
|
6618
6624
|
}
|
|
6619
6625
|
if (!redisConnection) {
|
|
6620
|
-
|
|
6621
|
-
|
|
6626
|
+
let url = "";
|
|
6627
|
+
if (redisServer.username) {
|
|
6628
|
+
url = `redis://${redisServer.username}:${redisServer.password}@${redisServer.host}:${redisServer.port}`;
|
|
6629
|
+
} else {
|
|
6630
|
+
url = `redis://${redisServer.host}:${redisServer.port}`;
|
|
6631
|
+
}
|
|
6632
|
+
redisConnection = new IORedis(url, {
|
|
6622
6633
|
enableOfflineQueue: true,
|
|
6623
6634
|
retryStrategy: function(times) {
|
|
6624
6635
|
return Math.max(Math.min(Math.exp(times), 2e4), 1e3);
|
|
@@ -6933,6 +6944,49 @@ var createWorkers = async (agents, queues2, config, contexts, evals, tools, trac
|
|
|
6933
6944
|
metadata: {}
|
|
6934
6945
|
};
|
|
6935
6946
|
}
|
|
6947
|
+
if (data.type === "source") {
|
|
6948
|
+
console.log("[EXULU] running a source job.", logMetadata(bullmqJob.name));
|
|
6949
|
+
if (!data.source) {
|
|
6950
|
+
throw new Error(`No source id set for source job.`);
|
|
6951
|
+
}
|
|
6952
|
+
if (!data.context) {
|
|
6953
|
+
throw new Error(`No context id set for source job.`);
|
|
6954
|
+
}
|
|
6955
|
+
const context = contexts.find((c) => c.id === data.context);
|
|
6956
|
+
if (!context) {
|
|
6957
|
+
throw new Error(`Context ${data.context} not found in the registry.`);
|
|
6958
|
+
}
|
|
6959
|
+
const source = context.sources.find((s) => s.id === data.source);
|
|
6960
|
+
if (!source) {
|
|
6961
|
+
throw new Error(`Source ${data.source} not found in the context ${context.id}.`);
|
|
6962
|
+
}
|
|
6963
|
+
const result = await source.execute(data.inputs);
|
|
6964
|
+
let jobs = [];
|
|
6965
|
+
let items = [];
|
|
6966
|
+
for (const item of result) {
|
|
6967
|
+
const { item: createdItem, job } = await context.createItem(item, config, data.user, data.role);
|
|
6968
|
+
if (job) {
|
|
6969
|
+
jobs.push(job);
|
|
6970
|
+
console.log(`[EXULU] Scheduled job through source update job for item ${createdItem.id} (Job ID: ${job})`, logMetadata(bullmqJob.name, {
|
|
6971
|
+
item: createdItem,
|
|
6972
|
+
job
|
|
6973
|
+
}));
|
|
6974
|
+
}
|
|
6975
|
+
if (createdItem.id) {
|
|
6976
|
+
items.push(createdItem.id);
|
|
6977
|
+
console.log(`[EXULU] created item through source update job ${createdItem.id}`, logMetadata(bullmqJob.name, {
|
|
6978
|
+
item: createdItem
|
|
6979
|
+
}));
|
|
6980
|
+
}
|
|
6981
|
+
}
|
|
6982
|
+
return {
|
|
6983
|
+
result,
|
|
6984
|
+
metadata: {
|
|
6985
|
+
jobs,
|
|
6986
|
+
items
|
|
6987
|
+
}
|
|
6988
|
+
};
|
|
6989
|
+
}
|
|
6936
6990
|
throw new Error(`Invalid job type: ${data.type} for job ${bullmqJob.name}.`);
|
|
6937
6991
|
} catch (error) {
|
|
6938
6992
|
console.error(`[EXULU] job failed.`, error instanceof Error ? error.message : String(error));
|
|
@@ -8839,6 +8893,41 @@ var ExuluApp = class {
|
|
|
8839
8893
|
if (queues2) {
|
|
8840
8894
|
filteredQueues = filteredQueues.filter((q) => queues2.includes(q.queue.name));
|
|
8841
8895
|
}
|
|
8896
|
+
const sources = Object.values(this._contexts ?? {}).flatMap((context) => ({
|
|
8897
|
+
...context.sources,
|
|
8898
|
+
context: context.id
|
|
8899
|
+
}));
|
|
8900
|
+
if (sources.length > 0) {
|
|
8901
|
+
console.log("[EXULU] Creating ContextSource schedulers for", sources.length, "sources.");
|
|
8902
|
+
for (const source of sources) {
|
|
8903
|
+
const queue = await source.config?.queue;
|
|
8904
|
+
if (queue) {
|
|
8905
|
+
if (!source.config.schedule) {
|
|
8906
|
+
throw new Error("Schedule is required for source when configuring a queue: " + source.name);
|
|
8907
|
+
}
|
|
8908
|
+
console.log("[EXULU] Creating ContextSource scheduler for", source.name, "in queue", queue.queue?.name);
|
|
8909
|
+
await queue.queue?.upsertJobScheduler(source.id, {
|
|
8910
|
+
pattern: source.config?.schedule
|
|
8911
|
+
}, {
|
|
8912
|
+
// default job data
|
|
8913
|
+
name: `${source.id}-job`,
|
|
8914
|
+
data: {
|
|
8915
|
+
source: source.id,
|
|
8916
|
+
context: source.context,
|
|
8917
|
+
type: "source"
|
|
8918
|
+
},
|
|
8919
|
+
opts: {
|
|
8920
|
+
backoff: {
|
|
8921
|
+
type: source.config.backoff?.type || "exponential",
|
|
8922
|
+
delay: source.config.backoff?.delay || 2e3
|
|
8923
|
+
},
|
|
8924
|
+
attempts: source.config.retries || 3,
|
|
8925
|
+
removeOnFail: 200
|
|
8926
|
+
}
|
|
8927
|
+
});
|
|
8928
|
+
}
|
|
8929
|
+
}
|
|
8930
|
+
}
|
|
8842
8931
|
return await createWorkers(
|
|
8843
8932
|
this._agents,
|
|
8844
8933
|
filteredQueues,
|