@bpinhosilva/agent-orchestrator 1.1.1 → 1.1.3
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 +15 -0
- package/dist/cli/commands/run.command.js +13 -0
- package/dist/common/postman/postman-conversion.js +57 -0
- package/dist/migrations/1776400000000-ProductionHardening.js +94 -42
- package/dist/migrations/1776401000000-FixRecurrentTaskExecsForeignKey.js +54 -0
- package/dist/tasks/recurrent-task-scheduler.service.js +3 -4
- package/package.json +9 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## [1.1.3](https://github.com/bpinhosilva/agent-orchestrator/compare/v1.1.2...v1.1.3) (2026-05-02)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* add UUID support and Postman collection generation ([a4bfd77](https://github.com/bpinhosilva/agent-orchestrator/commit/a4bfd7733d7a28ba3bc06748a6dce1ca27c5c466))
|
|
7
|
+
* update cron job handling to replace inactive jobs for active tasks ([3d01155](https://github.com/bpinhosilva/agent-orchestrator/commit/3d01155f3f8f5be127e2bace79ede889502e4ec8))
|
|
8
|
+
|
|
9
|
+
## [1.1.2](https://github.com/bpinhosilva/agent-orchestrator/compare/v1.1.1...v1.1.2) (2026-04-21)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* add migration checks for pending database migrations and correct FK in recurrent_task_execs ([9978f4e](https://github.com/bpinhosilva/agent-orchestrator/commit/9978f4eef9af69449326f97422cc857aa3d7a0e3))
|
|
15
|
+
|
|
1
16
|
## [1.1.1](https://github.com/bpinhosilva/agent-orchestrator/compare/v1.1.0...v1.1.1) (2026-04-19)
|
|
2
17
|
|
|
3
18
|
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.registerRunCommand = registerRunCommand;
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
5
|
const process_manager_1 = require("../process-manager");
|
|
6
|
+
const migration_state_1 = require("../../database/migration-state");
|
|
6
7
|
const constants_1 = require("../constants");
|
|
7
8
|
const VALID_LOG_LEVELS = [
|
|
8
9
|
'fatal',
|
|
@@ -25,6 +26,18 @@ function registerRunCommand(program) {
|
|
|
25
26
|
throw new Error(`Invalid log level "${options.logLevel}". Valid values: ${VALID_LOG_LEVELS.join(', ')}`);
|
|
26
27
|
}
|
|
27
28
|
}
|
|
29
|
+
// Check for pending migrations before starting
|
|
30
|
+
const { hasPending } = await (0, migration_state_1.checkPendingMigrations)({
|
|
31
|
+
assumePendingOnError: true,
|
|
32
|
+
});
|
|
33
|
+
if (hasPending) {
|
|
34
|
+
console.error('Pending database migrations detected.\n' +
|
|
35
|
+
'Run the following command before starting the server:\n\n' +
|
|
36
|
+
' agent-orchestrator migrate --yes\n\n' +
|
|
37
|
+
'Then run:\n\n' +
|
|
38
|
+
' agent-orchestrator run');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
28
41
|
const existingProcess = (0, process_manager_1.findManagedProcess)();
|
|
29
42
|
if (existingProcess) {
|
|
30
43
|
console.log(`Orchestrator is already running.\n${(0, process_manager_1.formatProcessSummary)(existingProcess)}`);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.convertOpenApiToPostman = convertOpenApiToPostman;
|
|
37
|
+
exports.writePostmanCollection = writePostmanCollection;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
function convertOpenApiToPostman(openApiJson, convert) {
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
convert({ type: 'string', data: openApiJson }, { schemaFaker: true }, (error, result) => {
|
|
42
|
+
if (error) {
|
|
43
|
+
reject(error instanceof Error ? error : new Error('Converter failed'));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (!result?.result) {
|
|
47
|
+
reject(new Error(result?.reason ??
|
|
48
|
+
'Could not convert OpenAPI document to Postman collection'));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
resolve(result.output?.[0]?.data ?? {});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function writePostmanCollection(outputPath, collection) {
|
|
56
|
+
fs.writeFileSync(outputPath, JSON.stringify(collection, null, 2));
|
|
57
|
+
}
|
|
@@ -32,6 +32,27 @@ class ProductionHardening1776400000000 {
|
|
|
32
32
|
await queryRunner.query(`CREATE INDEX "IDX_a03520bcf60ada1a46bf548e22" ON "recurrent_tasks" ("status")`);
|
|
33
33
|
await queryRunner.query(`CREATE INDEX "IDX_0f9f543bd40419122e69aeff00" ON "recurrent_tasks" ("projectId")`);
|
|
34
34
|
await queryRunner.query(`CREATE INDEX "IDX_6755ac981ae6d51a135f2ead5d" ON "recurrent_tasks" ("projectId", "updatedAt")`);
|
|
35
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_f5bb7be33ddb87ac0f04807b4a"`);
|
|
36
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_f076c050d237e20ec9335cdeff"`);
|
|
37
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_96d8e0300e884502e0382f67bb"`);
|
|
38
|
+
await queryRunner.query(`ALTER TABLE "recurrent_task_execs" RENAME TO "recurrent_task_execs_old"`);
|
|
39
|
+
await queryRunner.query(`CREATE TABLE "recurrent_task_execs" (` +
|
|
40
|
+
`"id" varchar PRIMARY KEY NOT NULL, ` +
|
|
41
|
+
`"status" varchar CHECK("status" IN ('running','success','failure','canceled')) NOT NULL DEFAULT ('running'), ` +
|
|
42
|
+
`"result" text, ` +
|
|
43
|
+
`"latencyMs" integer, ` +
|
|
44
|
+
`"artifacts" text, ` +
|
|
45
|
+
`"createdAt" datetime NOT NULL DEFAULT (datetime('now')), ` +
|
|
46
|
+
`"updatedAt" datetime NOT NULL DEFAULT (datetime('now')), ` +
|
|
47
|
+
`"recurrentTaskId" varchar NOT NULL, ` +
|
|
48
|
+
`CONSTRAINT "FK_f5bb7be33ddb87ac0f04807b4ab" FOREIGN KEY ("recurrentTaskId") REFERENCES "recurrent_tasks" ("id") ON DELETE CASCADE ON UPDATE NO ACTION` +
|
|
49
|
+
`)`);
|
|
50
|
+
await queryRunner.query(`INSERT INTO "recurrent_task_execs" ("id", "status", "result", "latencyMs", "artifacts", "createdAt", "updatedAt", "recurrentTaskId") ` +
|
|
51
|
+
`SELECT "id", "status", "result", "latencyMs", "artifacts", "createdAt", "updatedAt", "recurrentTaskId" FROM "recurrent_task_execs_old"`);
|
|
52
|
+
await queryRunner.query(`DROP TABLE "recurrent_task_execs_old"`);
|
|
53
|
+
await queryRunner.query(`CREATE INDEX "IDX_f5bb7be33ddb87ac0f04807b4a" ON "recurrent_task_execs" ("recurrentTaskId")`);
|
|
54
|
+
await queryRunner.query(`CREATE INDEX "IDX_f076c050d237e20ec9335cdeff" ON "recurrent_task_execs" ("recurrentTaskId", "createdAt")`);
|
|
55
|
+
await queryRunner.query(`CREATE INDEX "IDX_96d8e0300e884502e0382f67bb" ON "recurrent_task_execs" ("recurrentTaskId", "updatedAt")`);
|
|
35
56
|
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_d19892d8f03928e5bfc7313780"`);
|
|
36
57
|
await queryRunner.query(`ALTER TABLE "project_members" RENAME TO "project_members_old"`);
|
|
37
58
|
await queryRunner.query(`CREATE TABLE "project_members" (` +
|
|
@@ -63,48 +84,79 @@ class ProductionHardening1776400000000 {
|
|
|
63
84
|
const isSqlite = queryRunner.connection.options.type === 'sqlite' ||
|
|
64
85
|
queryRunner.connection.options.type === 'better-sqlite3';
|
|
65
86
|
if (isSqlite) {
|
|
66
|
-
await queryRunner.query(`
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
`
|
|
76
|
-
`
|
|
77
|
-
`
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
`
|
|
81
|
-
`"
|
|
82
|
-
`"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
`"
|
|
97
|
-
`"
|
|
98
|
-
`"
|
|
99
|
-
`"
|
|
100
|
-
`"
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
87
|
+
await queryRunner.query(`PRAGMA foreign_keys = OFF`);
|
|
88
|
+
try {
|
|
89
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_refresh_tokens_absoluteExpiry"`);
|
|
90
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_project_members_userId"`);
|
|
91
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_d19892d8f03928e5bfc7313780"`);
|
|
92
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_9ec101b70a5f9612b0757d87c8"`);
|
|
93
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_a03520bcf60ada1a46bf548e22"`);
|
|
94
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_0f9f543bd40419122e69aeff00"`);
|
|
95
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_6755ac981ae6d51a135f2ead5d"`);
|
|
96
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_96d8e0300e884502e0382f67bb"`);
|
|
97
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_f076c050d237e20ec9335cdeff"`);
|
|
98
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_f5bb7be33ddb87ac0f04807b4a"`);
|
|
99
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_2b3c4d5e6f7a8b9c0d1e2f3a4b"`);
|
|
100
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_1a2b3c4d5e6f7a8b9c0d1e2f3a"`);
|
|
101
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_4a1b8f1e0c2d3e4f5a6b7c8d9e"`);
|
|
102
|
+
await queryRunner.query(`ALTER TABLE "recurrent_task_execs" RENAME TO "recurrent_task_execs_new"`);
|
|
103
|
+
await queryRunner.query(`CREATE TABLE "recurrent_task_execs" (` +
|
|
104
|
+
`"id" varchar PRIMARY KEY NOT NULL, ` +
|
|
105
|
+
`"status" varchar CHECK("status" IN ('running','success','failure','canceled')) NOT NULL DEFAULT ('running'), ` +
|
|
106
|
+
`"result" text, ` +
|
|
107
|
+
`"latencyMs" integer, ` +
|
|
108
|
+
`"artifacts" text, ` +
|
|
109
|
+
`"createdAt" datetime NOT NULL DEFAULT (datetime('now')), ` +
|
|
110
|
+
`"updatedAt" datetime NOT NULL DEFAULT (datetime('now')), ` +
|
|
111
|
+
`"recurrentTaskId" varchar NOT NULL, ` +
|
|
112
|
+
`CONSTRAINT "FK_f5bb7be33ddb87ac0f04807b4ab" FOREIGN KEY ("recurrentTaskId") REFERENCES "recurrent_tasks" ("id") ON DELETE CASCADE ON UPDATE NO ACTION` +
|
|
113
|
+
`)`);
|
|
114
|
+
await queryRunner.query(`INSERT INTO "recurrent_task_execs" ("id", "status", "result", "latencyMs", "artifacts", "createdAt", "updatedAt", "recurrentTaskId") ` +
|
|
115
|
+
`SELECT "id", "status", "result", "latencyMs", "artifacts", "createdAt", "updatedAt", "recurrentTaskId" FROM "recurrent_task_execs_new"`);
|
|
116
|
+
await queryRunner.query(`DROP TABLE "recurrent_task_execs_new"`);
|
|
117
|
+
await queryRunner.query(`CREATE INDEX "IDX_f5bb7be33ddb87ac0f04807b4a" ON "recurrent_task_execs" ("recurrentTaskId")`);
|
|
118
|
+
await queryRunner.query(`CREATE INDEX "IDX_f076c050d237e20ec9335cdeff" ON "recurrent_task_execs" ("recurrentTaskId", "createdAt")`);
|
|
119
|
+
await queryRunner.query(`CREATE INDEX "IDX_96d8e0300e884502e0382f67bb" ON "recurrent_task_execs" ("recurrentTaskId", "updatedAt")`);
|
|
120
|
+
await queryRunner.query(`ALTER TABLE "recurrent_tasks" RENAME TO "recurrent_tasks_new"`);
|
|
121
|
+
await queryRunner.query(`CREATE TABLE "recurrent_tasks" (` +
|
|
122
|
+
`"id" varchar PRIMARY KEY NOT NULL, ` +
|
|
123
|
+
`"title" varchar NOT NULL, ` +
|
|
124
|
+
`"description" text NOT NULL, ` +
|
|
125
|
+
`"status" varchar CHECK("status" IN ('active','paused','error')) NOT NULL DEFAULT ('active'), ` +
|
|
126
|
+
`"priority" varchar CHECK("priority" IN ('0','1','2','3')) NOT NULL DEFAULT (2), ` +
|
|
127
|
+
`"cronExpression" varchar NOT NULL, ` +
|
|
128
|
+
`"createdAt" datetime NOT NULL DEFAULT (datetime('now')), ` +
|
|
129
|
+
`"updatedAt" datetime NOT NULL DEFAULT (datetime('now')), ` +
|
|
130
|
+
`"assigneeId" varchar NOT NULL, ` +
|
|
131
|
+
`"projectId" varchar, ` +
|
|
132
|
+
`CONSTRAINT "FK_0f9f543bd40419122e69aeff006" FOREIGN KEY ("projectId") REFERENCES "projects" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, ` +
|
|
133
|
+
`CONSTRAINT "FK_9ec101b70a5f9612b0757d87c83" FOREIGN KEY ("assigneeId") REFERENCES "agents" ("id") ON DELETE CASCADE ON UPDATE NO ACTION` +
|
|
134
|
+
`)`);
|
|
135
|
+
await queryRunner.query(`INSERT INTO "recurrent_tasks" SELECT * FROM "recurrent_tasks_new" WHERE "assigneeId" IS NOT NULL`);
|
|
136
|
+
await queryRunner.query(`DROP TABLE "recurrent_tasks_new"`);
|
|
137
|
+
await queryRunner.query(`CREATE INDEX "IDX_9ec101b70a5f9612b0757d87c8" ON "recurrent_tasks" ("assigneeId")`);
|
|
138
|
+
await queryRunner.query(`CREATE INDEX "IDX_a03520bcf60ada1a46bf548e22" ON "recurrent_tasks" ("status")`);
|
|
139
|
+
await queryRunner.query(`CREATE INDEX "IDX_0f9f543bd40419122e69aeff00" ON "recurrent_tasks" ("projectId")`);
|
|
140
|
+
await queryRunner.query(`CREATE INDEX "IDX_6755ac981ae6d51a135f2ead5d" ON "recurrent_tasks" ("projectId", "updatedAt")`);
|
|
141
|
+
await queryRunner.query(`ALTER TABLE "project_members" RENAME TO "project_members_new"`);
|
|
142
|
+
await queryRunner.query(`CREATE TABLE "project_members" (` +
|
|
143
|
+
`"id" varchar PRIMARY KEY NOT NULL, ` +
|
|
144
|
+
`"role" varchar NOT NULL DEFAULT ('member'), ` +
|
|
145
|
+
`"createdAt" datetime NOT NULL DEFAULT (datetime('now')), ` +
|
|
146
|
+
`"projectId" varchar, ` +
|
|
147
|
+
`"userId" varchar, ` +
|
|
148
|
+
`CONSTRAINT "UQ_project_members_project_user" UNIQUE ("projectId", "userId"), ` +
|
|
149
|
+
`CONSTRAINT "FK_project_members_project" FOREIGN KEY ("projectId") REFERENCES "projects" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, ` +
|
|
150
|
+
`CONSTRAINT "FK_project_members_user" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION` +
|
|
151
|
+
`)`);
|
|
152
|
+
await queryRunner.query(`INSERT INTO "project_members" SELECT * FROM "project_members_new"`);
|
|
153
|
+
await queryRunner.query(`DROP TABLE "project_members_new"`);
|
|
154
|
+
await queryRunner.query(`CREATE INDEX "IDX_d19892d8f03928e5bfc7313780" ON "project_members" ("projectId")`);
|
|
155
|
+
await queryRunner.query(`CREATE INDEX "IDX_project_members_userId" ON "project_members" ("userId")`);
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
await queryRunner.query(`PRAGMA foreign_keys = ON`);
|
|
159
|
+
}
|
|
108
160
|
}
|
|
109
161
|
else {
|
|
110
162
|
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_refresh_tokens_absoluteExpiry"`);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FixRecurrentTaskExecsForeignKey1776401000000 = void 0;
|
|
4
|
+
class FixRecurrentTaskExecsForeignKey1776401000000 {
|
|
5
|
+
name = 'FixRecurrentTaskExecsForeignKey1776401000000';
|
|
6
|
+
async up(queryRunner) {
|
|
7
|
+
const isSqlite = queryRunner.connection.options.type === 'sqlite' ||
|
|
8
|
+
queryRunner.connection.options.type === 'better-sqlite3';
|
|
9
|
+
if (!isSqlite) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const fks = (await queryRunner.query(`PRAGMA foreign_key_list("recurrent_task_execs")`));
|
|
13
|
+
const hasBrokenFk = fks.some((fk) => fk.table === 'recurrent_tasks_old');
|
|
14
|
+
if (!hasBrokenFk) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
await queryRunner.query(`PRAGMA foreign_keys = OFF`);
|
|
18
|
+
try {
|
|
19
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_f5bb7be33ddb87ac0f04807b4a"`);
|
|
20
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_f076c050d237e20ec9335cdeff"`);
|
|
21
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_96d8e0300e884502e0382f67bb"`);
|
|
22
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_4a1b8f1e0c2d3e4f5a6b7c8d9e"`);
|
|
23
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_1a2b3c4d5e6f7a8b9c0d1e2f3a"`);
|
|
24
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_2b3c4d5e6f7a8b9c0d1e2f3a4b"`);
|
|
25
|
+
await queryRunner.query(`ALTER TABLE "recurrent_task_execs" RENAME TO "recurrent_task_execs_broken"`);
|
|
26
|
+
await queryRunner.query(`CREATE TABLE "recurrent_task_execs" (` +
|
|
27
|
+
`"id" varchar PRIMARY KEY NOT NULL, ` +
|
|
28
|
+
`"status" varchar CHECK("status" IN ('running','success','failure','canceled')) NOT NULL DEFAULT ('running'), ` +
|
|
29
|
+
`"result" text, ` +
|
|
30
|
+
`"latencyMs" integer, ` +
|
|
31
|
+
`"artifacts" text, ` +
|
|
32
|
+
`"createdAt" datetime NOT NULL DEFAULT (datetime('now')), ` +
|
|
33
|
+
`"updatedAt" datetime NOT NULL DEFAULT (datetime('now')), ` +
|
|
34
|
+
`"recurrentTaskId" varchar NOT NULL, ` +
|
|
35
|
+
`CONSTRAINT "FK_f5bb7be33ddb87ac0f04807b4ab" FOREIGN KEY ("recurrentTaskId") REFERENCES "recurrent_tasks" ("id") ON DELETE CASCADE ON UPDATE NO ACTION` +
|
|
36
|
+
`)`);
|
|
37
|
+
await queryRunner.query(`INSERT INTO "recurrent_task_execs" ("id", "status", "result", "latencyMs", "artifacts", "createdAt", "updatedAt", "recurrentTaskId") ` +
|
|
38
|
+
`SELECT b."id", b."status", b."result", b."latencyMs", b."artifacts", b."createdAt", b."updatedAt", b."recurrentTaskId" ` +
|
|
39
|
+
`FROM "recurrent_task_execs_broken" b ` +
|
|
40
|
+
`WHERE b."recurrentTaskId" IS NOT NULL ` +
|
|
41
|
+
`AND EXISTS (SELECT 1 FROM "recurrent_tasks" r WHERE r."id" = b."recurrentTaskId")`);
|
|
42
|
+
await queryRunner.query(`DROP TABLE "recurrent_task_execs_broken"`);
|
|
43
|
+
await queryRunner.query(`CREATE INDEX "IDX_f5bb7be33ddb87ac0f04807b4a" ON "recurrent_task_execs" ("recurrentTaskId")`);
|
|
44
|
+
await queryRunner.query(`CREATE INDEX "IDX_f076c050d237e20ec9335cdeff" ON "recurrent_task_execs" ("recurrentTaskId", "createdAt")`);
|
|
45
|
+
await queryRunner.query(`CREATE INDEX "IDX_96d8e0300e884502e0382f67bb" ON "recurrent_task_execs" ("recurrentTaskId", "updatedAt")`);
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
await queryRunner.query(`PRAGMA foreign_keys = ON`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async down() {
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.FixRecurrentTaskExecsForeignKey1776401000000 = FixRecurrentTaskExecsForeignKey1776401000000;
|
|
@@ -103,11 +103,10 @@ let RecurrentTaskSchedulerService = RecurrentTaskSchedulerService_1 = class Recu
|
|
|
103
103
|
if (name.startsWith('recurrent-task-')) {
|
|
104
104
|
const taskId = name.replace('recurrent-task-', '');
|
|
105
105
|
const task = activeTasks.find((t) => t.id === taskId);
|
|
106
|
-
const
|
|
106
|
+
const jobIsInactive = !job.isActive;
|
|
107
107
|
if (!activeTaskIds.has(taskId) ||
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
jobWithCron.cronTime.source !== task.cronExpression)) {
|
|
108
|
+
jobIsInactive ||
|
|
109
|
+
(task && job.cronTime && job.cronTime.source !== task.cronExpression)) {
|
|
111
110
|
void job.stop();
|
|
112
111
|
this.schedulerRegistry.deleteCronJob(name);
|
|
113
112
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bpinhosilva/agent-orchestrator",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "An open-source AI agent orchestrator platform built with NestJS.",
|
|
5
5
|
"author": "bpinhosilva",
|
|
6
6
|
"license": "MIT",
|
|
@@ -155,8 +155,10 @@
|
|
|
155
155
|
"@angular-devkit/core": "^21.2.5",
|
|
156
156
|
"@angular-devkit/schematics": "^21.2.5",
|
|
157
157
|
"typeorm": {
|
|
158
|
-
"glob": "^13.0.0"
|
|
159
|
-
|
|
158
|
+
"glob": "^13.0.0",
|
|
159
|
+
"uuid": "^14.0.0"
|
|
160
|
+
},
|
|
161
|
+
"uuid": "^14.0.0"
|
|
160
162
|
},
|
|
161
163
|
"jest": {
|
|
162
164
|
"moduleFileExtensions": [
|
|
@@ -183,6 +185,9 @@
|
|
|
183
185
|
],
|
|
184
186
|
"coverageDirectory": "../coverage",
|
|
185
187
|
"testEnvironment": "node",
|
|
186
|
-
"maxWorkers": 1
|
|
188
|
+
"maxWorkers": 1,
|
|
189
|
+
"moduleNameMapper": {
|
|
190
|
+
"^uuid$": "<rootDir>/../test/mocks/uuid.js"
|
|
191
|
+
}
|
|
187
192
|
}
|
|
188
193
|
}
|