@codemation/host 0.9.0 → 0.9.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/CHANGELOG.md +22 -0
- package/dist/{AppContainerFactory-jpYXGZGe.js → AppContainerFactory-CHCXP2rn.js} +17 -6
- package/dist/{AppContainerFactory-jpYXGZGe.js.map → AppContainerFactory-CHCXP2rn.js.map} +1 -1
- package/dist/index.js +2 -2
- package/dist/nextServer.js +1 -1
- package/dist/{server-BlG9qV5S.js → server-CNj_y0QO.js} +2 -2
- package/dist/{server-BlG9qV5S.js.map → server-CNj_y0QO.js.map} +1 -1
- package/dist/server.js +2 -2
- package/package.json +3 -3
- package/src/hitl/HitlTimeoutJobScheduler.ts +19 -7
- package/src/hitl/HitlTimeoutWorker.ts +8 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @codemation/host
|
|
2
2
|
|
|
3
|
+
## 0.9.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#179](https://github.com/MadeRelevant/codemation/pull/179) [`6efde7a`](https://github.com/MadeRelevant/codemation/commit/6efde7aa045050cd2fbd22015f7608c513a6f79f) Thanks [@cblokland90](https://github.com/cblokland90)! - fix(hitl): gate the HITL timeout scheduler/worker on the scheduler abstraction instead of hardcoding Redis
|
|
8
|
+
|
|
9
|
+
`HitlTimeoutJobScheduler` and `HitlTimeoutWorker` previously fell back to
|
|
10
|
+
`redis://127.0.0.1:6379` unconditionally and always constructed a BullMQ
|
|
11
|
+
`Queue`/`Worker`. In inline/local mode (no Redis — e.g. managed workspace pods),
|
|
12
|
+
this caused two failures: the host crash-spammed `ECONNREFUSED 127.0.0.1:6379`,
|
|
13
|
+
and a HITL decision hung in `cancelTimeoutJob` (against the dead Redis) before the
|
|
14
|
+
run could resume, so the CP relay timed out (500) and the run never completed.
|
|
15
|
+
|
|
16
|
+
Both now gate on `appConfig.scheduler.kind` — the same abstraction the rest of the
|
|
17
|
+
host uses (`bullmq` only when a Redis URL is present, otherwise `local`). In local
|
|
18
|
+
mode they never touch Redis: `enqueueTimeoutJob`/`cancelTimeoutJob` are inert
|
|
19
|
+
no-ops and `start()` constructs no worker. Behavior is unchanged for Redis-backed
|
|
20
|
+
(`bullmq`) deployments.
|
|
21
|
+
|
|
22
|
+
Trade-off: in local mode, HITL expiry timeouts (auto-accept/halt on expiry) do not
|
|
23
|
+
fire, since there is no background queue. Manual decisions resume the run normally.
|
|
24
|
+
|
|
3
25
|
## 0.9.0
|
|
4
26
|
|
|
5
27
|
### Minor Changes
|
|
@@ -25932,14 +25932,15 @@ const HITL_TIMEOUT_QUEUE_NAME_SUFFIX = "hitl.timeout";
|
|
|
25932
25932
|
let HitlTimeoutJobScheduler = class HitlTimeoutJobScheduler$1 {
|
|
25933
25933
|
queue = null;
|
|
25934
25934
|
queueName;
|
|
25935
|
+
/** Redis URL when running in BullMQ mode; null in local/inline mode (no Redis). */
|
|
25935
25936
|
redisUrl;
|
|
25936
25937
|
constructor(appConfig) {
|
|
25937
|
-
|
|
25938
|
-
this.redisUrl = rawRedisUrl && rawRedisUrl !== "" ? rawRedisUrl : "redis://127.0.0.1:6379";
|
|
25938
|
+
this.redisUrl = appConfig.scheduler.kind === "bullmq" ? appConfig.scheduler.redisUrl ?? null : null;
|
|
25939
25939
|
this.queueName = `${appConfig.env.CODEMATION_BULLMQ_PREFIX ?? "codemation"}.${HITL_TIMEOUT_QUEUE_NAME_SUFFIX}`;
|
|
25940
25940
|
}
|
|
25941
25941
|
async enqueueTimeoutJob(args) {
|
|
25942
25942
|
const queue = this.getOrCreateQueue();
|
|
25943
|
+
if (!queue) return;
|
|
25943
25944
|
const delay = Math.max(0, args.expiresAt.getTime() - Date.now());
|
|
25944
25945
|
await queue.add("hitl.timeout", {
|
|
25945
25946
|
kind: "hitl.timeout",
|
|
@@ -25952,7 +25953,9 @@ let HitlTimeoutJobScheduler = class HitlTimeoutJobScheduler$1 {
|
|
|
25952
25953
|
});
|
|
25953
25954
|
}
|
|
25954
25955
|
async cancelTimeoutJob(taskId) {
|
|
25955
|
-
|
|
25956
|
+
const queue = this.getOrCreateQueue();
|
|
25957
|
+
if (!queue) return;
|
|
25958
|
+
await (await queue.getJob(this.makeJobId(taskId)))?.remove();
|
|
25956
25959
|
}
|
|
25957
25960
|
async close() {
|
|
25958
25961
|
if (this.queue) {
|
|
@@ -25963,7 +25966,13 @@ let HitlTimeoutJobScheduler = class HitlTimeoutJobScheduler$1 {
|
|
|
25963
25966
|
getQueueName() {
|
|
25964
25967
|
return this.queueName;
|
|
25965
25968
|
}
|
|
25969
|
+
/**
|
|
25970
|
+
* Returns the BullMQ queue in Redis-backed mode, or null in local/inline mode.
|
|
25971
|
+
* Construction is deferred to the first enqueue/cancel so DI consumers that
|
|
25972
|
+
* never enqueue can resolve this scheduler without building a connection.
|
|
25973
|
+
*/
|
|
25966
25974
|
getOrCreateQueue() {
|
|
25975
|
+
if (this.redisUrl === null) return null;
|
|
25967
25976
|
if (!this.queue) {
|
|
25968
25977
|
const connectionOptions = RedisConnectionOptionsFactory.fromConfig({ url: this.redisUrl });
|
|
25969
25978
|
this.queue = new Queue(this.queueName, { connection: connectionOptions });
|
|
@@ -26018,6 +26027,7 @@ var _ref$8, _ref2$4, _ref3$1;
|
|
|
26018
26027
|
let HitlTimeoutWorker = class HitlTimeoutWorker$1 {
|
|
26019
26028
|
taskStore;
|
|
26020
26029
|
worker = null;
|
|
26030
|
+
/** Redis connection options in BullMQ mode; null in local/inline mode (no Redis). */
|
|
26021
26031
|
connectionOptions;
|
|
26022
26032
|
constructor(taskStore, engine, scheduler, appConfig, resumeTelemetry) {
|
|
26023
26033
|
this.engine = engine;
|
|
@@ -26025,10 +26035,11 @@ let HitlTimeoutWorker = class HitlTimeoutWorker$1 {
|
|
|
26025
26035
|
this.resumeTelemetry = resumeTelemetry;
|
|
26026
26036
|
if (!taskStore) throw new Error("HitlTimeoutWorker: HumanTaskStore is not registered.");
|
|
26027
26037
|
this.taskStore = taskStore;
|
|
26028
|
-
const redisUrl = appConfig.
|
|
26029
|
-
this.connectionOptions = RedisConnectionOptionsFactory.fromConfig({ url: redisUrl });
|
|
26038
|
+
const redisUrl = appConfig.scheduler.kind === "bullmq" ? appConfig.scheduler.redisUrl ?? null : null;
|
|
26039
|
+
this.connectionOptions = redisUrl === null ? null : RedisConnectionOptionsFactory.fromConfig({ url: redisUrl });
|
|
26030
26040
|
}
|
|
26031
26041
|
start() {
|
|
26042
|
+
if (!this.connectionOptions) return;
|
|
26032
26043
|
this.worker = new Worker(this.scheduler.getQueueName(), async (job) => {
|
|
26033
26044
|
await this.processJob(job);
|
|
26034
26045
|
}, { connection: this.connectionOptions });
|
|
@@ -27180,4 +27191,4 @@ var AppContainerFactory = class AppContainerFactory {
|
|
|
27180
27191
|
|
|
27181
27192
|
//#endregion
|
|
27182
27193
|
export { WorkflowDefinitionMapper as A, CodemationHonoApiApp as C, FrontendAppConfigFactory as D, InternalAuthBootstrapFactory as E, StartWorkflowRunCommand as F, UpsertLocalBootstrapUserCommand as I, ListUserAccountsQuery as L, GetWorkflowDetailQuery as M, GetRunStateQuery as N, CodemationFrontendAuthSnapshotFactory as O, RunBinaryAttachmentLookupService as P, CredentialHttpRouteHandler as S, PublicFrontendBootstrapFactory as T, WorkflowHttpRouteHandler as _, GetCollectionQuery as a, RunHttpRouteHandler as b, InsertCollectionRowCommand as c, FrontendRuntime as d, CollectionSchemaSyncerHolder as f, ExecaProcessRunner as g, WorkflowRunRetentionPruneScheduler as h, GetCollectionRowQuery as i, GetWorkflowSummariesQuery as j, WorkflowWebsocketServer as k, DeleteCollectionRowCommand as l, AppContainerLifecycle as m, ListCollectionsQuery as n, UpdateCollectionRowCommand as o, DatabaseMigrations as p, ListCollectionRowsQuery as r, SyncCollectionsCommand as s, AppContainerFactory as t, WorkerRuntime as u, WebhookHttpRouteHandler as v, BinaryHttpRouteHandler as w, OAuth2HttpRouteHandler as x, RequestToWebhookItemMapper as y };
|
|
27183
|
-
//# sourceMappingURL=AppContainerFactory-
|
|
27194
|
+
//# sourceMappingURL=AppContainerFactory-CHCXP2rn.js.map
|