@hotmeshio/long-tail 0.2.2 → 0.2.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/build/services/cron/index.js +33 -23
- package/package.json +2 -2
|
@@ -148,7 +148,8 @@ class LTCronRegistry {
|
|
|
148
148
|
callback: async () => {
|
|
149
149
|
try {
|
|
150
150
|
const client = new hotmesh_1.Durable.Client({ connection });
|
|
151
|
-
const
|
|
151
|
+
const { guid } = hotmesh_1.Virtual.getContext();
|
|
152
|
+
const workflowId = `${workflowType}-cron-${guid}`;
|
|
152
153
|
logger_1.loggerRegistry.info(`[lt-cron] invoking ${workflowType} (${workflowId})`);
|
|
153
154
|
await client.workflow.start({
|
|
154
155
|
args: [defaultEnvelope],
|
|
@@ -302,27 +303,8 @@ class LTCronRegistry {
|
|
|
302
303
|
const topic = `lt.cron.agent.${agent.id}.${idx}`;
|
|
303
304
|
const cronId = `lt-cron-agent-${agent.id}-${idx}`;
|
|
304
305
|
const executeAs = schedule.execute_as || agent.user_id || undefined;
|
|
305
|
-
let principal;
|
|
306
|
-
if (executeAs) {
|
|
307
|
-
try {
|
|
308
|
-
principal = await (0, principal_1.resolvePrincipal)(executeAs);
|
|
309
|
-
}
|
|
310
|
-
catch { /* use system */ }
|
|
311
|
-
}
|
|
312
|
-
if (!principal) {
|
|
313
|
-
principal = this.systemPrincipal ?? undefined;
|
|
314
|
-
}
|
|
315
|
-
const envelope = {
|
|
316
|
-
data: schedule.envelope ?? {},
|
|
317
|
-
metadata: { source: 'agent-cron', agentId: agent.id, agentName: agent.name, certified: true },
|
|
318
|
-
lt: {
|
|
319
|
-
userId: principal?.id ?? 'lt-system',
|
|
320
|
-
principal,
|
|
321
|
-
scopes: ['workflow:invoke'],
|
|
322
|
-
},
|
|
323
|
-
};
|
|
324
306
|
const isPipeline = schedule.reaction_type === 'pipeline' && schedule.pipeline_id;
|
|
325
|
-
// Resolve
|
|
307
|
+
// Resolve task queue at arm time (static — doesn't change between ticks)
|
|
326
308
|
let taskQueue;
|
|
327
309
|
if (!isPipeline) {
|
|
328
310
|
const wfConfig = await configService.getWorkflowConfig(schedule.workflow_type);
|
|
@@ -334,6 +316,27 @@ class LTCronRegistry {
|
|
|
334
316
|
connection,
|
|
335
317
|
callback: async () => {
|
|
336
318
|
try {
|
|
319
|
+
// Resolve principal at fire time so users seeded after startup are found
|
|
320
|
+
let principal;
|
|
321
|
+
if (executeAs) {
|
|
322
|
+
try {
|
|
323
|
+
principal = await (0, principal_1.resolvePrincipal)(executeAs);
|
|
324
|
+
}
|
|
325
|
+
catch { /* use system */ }
|
|
326
|
+
}
|
|
327
|
+
if (!principal) {
|
|
328
|
+
principal = this.systemPrincipal ?? undefined;
|
|
329
|
+
}
|
|
330
|
+
logger_1.loggerRegistry.info(`[lt-cron] agent ${agent.name} principal: ${principal?.id ?? 'NONE'} (executeAs=${executeAs ?? 'unset'})`);
|
|
331
|
+
const envelope = {
|
|
332
|
+
data: schedule.envelope ?? {},
|
|
333
|
+
metadata: { source: 'agent-cron', agentId: agent.id, agentName: agent.name, certified: true },
|
|
334
|
+
lt: {
|
|
335
|
+
userId: principal?.id ?? 'lt-system',
|
|
336
|
+
principal,
|
|
337
|
+
scopes: ['workflow:invoke'],
|
|
338
|
+
},
|
|
339
|
+
};
|
|
337
340
|
if (isPipeline) {
|
|
338
341
|
const { invokeYamlWorkflow } = await Promise.resolve().then(() => __importStar(require('../yaml-workflow/invoke')));
|
|
339
342
|
const { getYamlWorkflow } = await Promise.resolve().then(() => __importStar(require('../yaml-workflow/db')));
|
|
@@ -348,7 +351,8 @@ class LTCronRegistry {
|
|
|
348
351
|
}
|
|
349
352
|
else {
|
|
350
353
|
const client = new hotmesh_1.Durable.Client({ connection });
|
|
351
|
-
const
|
|
354
|
+
const { guid } = hotmesh_1.Virtual.getContext();
|
|
355
|
+
const workflowId = `agent-cron-${agent.id}-${idx}-${guid}`;
|
|
352
356
|
logger_1.loggerRegistry.info(`[lt-cron] agent invoking ${schedule.workflow_type} on ${taskQueue} (${workflowId})`);
|
|
353
357
|
await client.workflow.start({
|
|
354
358
|
args: [envelope],
|
|
@@ -362,7 +366,13 @@ class LTCronRegistry {
|
|
|
362
366
|
}
|
|
363
367
|
}
|
|
364
368
|
catch (err) {
|
|
365
|
-
|
|
369
|
+
const msg = err?.message ?? '';
|
|
370
|
+
if (msg.includes('Duplicate job')) {
|
|
371
|
+
// Expected — deterministic ID dedup when cron fires multiple consumers
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
logger_1.loggerRegistry.error(`[lt-cron] agent ${agent.name}/${targetLabel} failed: ${msg}`);
|
|
375
|
+
}
|
|
366
376
|
}
|
|
367
377
|
},
|
|
368
378
|
args: [],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hotmeshio/long-tail",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Long Tail Workflows — Durable AI workflows with human-in-the-loop escalation. Powered by PostgreSQL.",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "./build/index.d.ts",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"@anthropic-ai/sdk": "^0.92.0",
|
|
71
71
|
"@aws-sdk/client-s3": "^3.1017.0",
|
|
72
72
|
"@aws-sdk/s3-request-presigner": "^3.1045.0",
|
|
73
|
-
"@hotmeshio/hotmesh": "^0.16.
|
|
73
|
+
"@hotmeshio/hotmesh": "^0.16.1",
|
|
74
74
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
75
75
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.215.0",
|
|
76
76
|
"@opentelemetry/resources": "^2.5.1",
|