@okrlinkhub/agent-factory 0.2.14 → 0.2.15

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.
Files changed (35) hide show
  1. package/README.md +1 -4
  2. package/dist/client/index.d.ts +1 -1
  3. package/dist/client/index.d.ts.map +1 -1
  4. package/dist/client/index.js +0 -3
  5. package/dist/client/index.js.map +1 -1
  6. package/dist/component/_generated/component.d.ts +0 -34
  7. package/dist/component/_generated/component.d.ts.map +1 -1
  8. package/dist/component/lib.d.ts +1 -1
  9. package/dist/component/lib.d.ts.map +1 -1
  10. package/dist/component/lib.js +1 -1
  11. package/dist/component/lib.js.map +1 -1
  12. package/dist/component/providers/fly.d.ts +14 -0
  13. package/dist/component/providers/fly.d.ts.map +1 -1
  14. package/dist/component/providers/fly.js +35 -5
  15. package/dist/component/providers/fly.js.map +1 -1
  16. package/dist/component/queue.d.ts +5 -20
  17. package/dist/component/queue.d.ts.map +1 -1
  18. package/dist/component/queue.js +41 -107
  19. package/dist/component/queue.js.map +1 -1
  20. package/dist/component/scheduler.d.ts.map +1 -1
  21. package/dist/component/scheduler.js +127 -81
  22. package/dist/component/scheduler.js.map +1 -1
  23. package/dist/component/schema.d.ts +5 -13
  24. package/dist/component/schema.d.ts.map +1 -1
  25. package/dist/component/schema.js +0 -4
  26. package/dist/component/schema.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/client/index.ts +0 -3
  29. package/src/component/_generated/component.ts +0 -42
  30. package/src/component/lib.test.ts +348 -88
  31. package/src/component/lib.ts +0 -1
  32. package/src/component/providers/fly.ts +50 -5
  33. package/src/component/queue.ts +52 -135
  34. package/src/component/scheduler.ts +211 -96
  35. package/src/component/schema.ts +0 -4
@@ -120,20 +120,15 @@ export const enqueueMessage = mutation({
120
120
  if (!profile || !profile.enabled) {
121
121
  throw new Error(`Agent profile '${args.agentKey}' not found or disabled`);
122
122
  }
123
- const resolvedProviderUserId =
124
- profile.providerUserId && profile.providerUserId.trim().length > 0
125
- ? profile.providerUserId.trim()
126
- : args.payload.providerUserId;
127
-
128
123
  const providerUserIdStr =
129
- typeof resolvedProviderUserId === "string" &&
130
- resolvedProviderUserId.trim().length > 0
131
- ? resolvedProviderUserId.trim()
124
+ typeof args.payload.providerUserId === "string" &&
125
+ args.payload.providerUserId.trim().length > 0
126
+ ? args.payload.providerUserId.trim()
132
127
  : null;
133
128
 
134
129
  if (providerUserIdStr === null) {
135
130
  throw new Error(
136
- `providerUserId is required but missing: profile.providerUserId=${JSON.stringify(profile.providerUserId)}, payload.providerUserId=${JSON.stringify(args.payload.providerUserId)}`,
131
+ `providerUserId is required but missing in payload.providerUserId=${JSON.stringify(args.payload.providerUserId)}`,
137
132
  );
138
133
  }
139
134
 
@@ -267,11 +262,7 @@ export const appendConversationMessages = mutation({
267
262
  export const upsertAgentProfile = mutation({
268
263
  args: {
269
264
  agentKey: v.string(),
270
- providerUserId: v.optional(v.string()),
271
265
  version: v.string(),
272
- soulMd: v.optional(v.string()),
273
- clientMd: v.optional(v.string()),
274
- skills: v.optional(v.array(v.string())),
275
266
  secretsRef: v.array(v.string()),
276
267
  bridgeConfig: v.optional(bridgeProfileConfigValidator),
277
268
  enabled: v.boolean(),
@@ -295,85 +286,6 @@ export const upsertAgentProfile = mutation({
295
286
  },
296
287
  });
297
288
 
298
- export const clearDeprecatedAgentProfileFields = mutation({
299
- args: {
300
- dryRun: v.optional(v.boolean()),
301
- },
302
- returns: v.object({
303
- dryRun: v.boolean(),
304
- scanned: v.number(),
305
- updated: v.number(),
306
- unchanged: v.number(),
307
- clearedProviderUserId: v.number(),
308
- clearedSoulMd: v.number(),
309
- clearedClientMd: v.number(),
310
- clearedSkills: v.number(),
311
- updatedAgentKeys: v.array(v.string()),
312
- }),
313
- handler: async (ctx, args) => {
314
- const profiles = await ctx.db.query("agentProfiles").collect();
315
- const dryRun = args.dryRun ?? false;
316
-
317
- let updated = 0;
318
- let clearedProviderUserId = 0;
319
- let clearedSoulMd = 0;
320
- let clearedClientMd = 0;
321
- let clearedSkills = 0;
322
- const updatedAgentKeys: Array<string> = [];
323
-
324
- for (const profile of profiles) {
325
- const patch: {
326
- providerUserId?: undefined;
327
- soulMd?: undefined;
328
- clientMd?: undefined;
329
- skills?: undefined;
330
- } = {};
331
- let shouldPatch = false;
332
-
333
- if (profile.providerUserId !== undefined) {
334
- patch.providerUserId = undefined;
335
- clearedProviderUserId += 1;
336
- shouldPatch = true;
337
- }
338
- if (profile.soulMd !== undefined) {
339
- patch.soulMd = undefined;
340
- clearedSoulMd += 1;
341
- shouldPatch = true;
342
- }
343
- if (profile.clientMd !== undefined) {
344
- patch.clientMd = undefined;
345
- clearedClientMd += 1;
346
- shouldPatch = true;
347
- }
348
- if (profile.skills !== undefined) {
349
- patch.skills = undefined;
350
- clearedSkills += 1;
351
- shouldPatch = true;
352
- }
353
-
354
- if (!shouldPatch) continue;
355
-
356
- updated += 1;
357
- updatedAgentKeys.push(profile.agentKey);
358
- if (!dryRun) {
359
- await ctx.db.patch(profile._id, patch);
360
- }
361
- }
362
-
363
- return {
364
- dryRun,
365
- scanned: profiles.length,
366
- updated,
367
- unchanged: profiles.length - updated,
368
- clearedProviderUserId,
369
- clearedSoulMd,
370
- clearedClientMd,
371
- clearedSkills,
372
- updatedAgentKeys,
373
- };
374
- },
375
- });
376
-
377
289
  export const importPlaintextSecret = mutation({
378
290
  args: {
379
291
  secretRef: v.string(),
@@ -1110,6 +1022,13 @@ export const claimNextJob = mutation({
1110
1022
  returns: v.union(v.null(), claimedJobValidator),
1111
1023
  handler: async (ctx, args) => {
1112
1024
  const nowMs = args.nowMs ?? Date.now();
1025
+ const worker = await ctx.db
1026
+ .query("workers")
1027
+ .withIndex("by_workerId", (q) => q.eq("workerId", args.workerId))
1028
+ .unique();
1029
+ if (worker?.status === "stopped") {
1030
+ return null;
1031
+ }
1113
1032
  const candidates = await ctx.db
1114
1033
  .query("messageQueue")
1115
1034
  .withIndex("by_status_and_scheduledFor", (q) =>
@@ -1155,11 +1074,6 @@ export const claimNextJob = mutation({
1155
1074
  },
1156
1075
  });
1157
1076
 
1158
- const worker = await ctx.db
1159
- .query("workers")
1160
- .withIndex("by_workerId", (q) => q.eq("workerId", args.workerId))
1161
- .unique();
1162
-
1163
1077
  if (!worker) {
1164
1078
  await ctx.db.insert("workers", {
1165
1079
  workerId: args.workerId,
@@ -1179,7 +1093,6 @@ export const claimNextJob = mutation({
1179
1093
  heartbeatAt: nowMs,
1180
1094
  lastClaimAt: nowMs,
1181
1095
  scheduledShutdownAt: undefined,
1182
- stoppedAt: undefined,
1183
1096
  });
1184
1097
  }
1185
1098
 
@@ -1310,25 +1223,9 @@ export const completeJob = mutation({
1310
1223
  load: nextLoad,
1311
1224
  heartbeatAt: nowMs,
1312
1225
  scheduledShutdownAt: nextScheduledShutdownAt,
1313
- stoppedAt: undefined,
1314
1226
  });
1315
1227
  if (nextScheduledShutdownAt !== undefined) {
1316
- const delayMs = Math.max(0, nextScheduledShutdownAt - nowMs) + 1_000;
1317
- try {
1318
- await ctx.scheduler.runAfter(
1319
- delayMs,
1320
- (internal.scheduler as any).enforceIdleShutdowns,
1321
- {
1322
- providerConfig: args.providerConfig,
1323
- },
1324
- );
1325
- } catch (error) {
1326
- console.warn(
1327
- `[queue] failed to schedule idle-shutdown watchdog: ${
1328
- error instanceof Error ? error.message : String(error)
1329
- }`,
1330
- );
1331
- }
1228
+ await scheduleIdleShutdownWatchdog(ctx, nextScheduledShutdownAt, nowMs, args.providerConfig);
1332
1229
  }
1333
1230
  }
1334
1231
  return true;
@@ -1418,25 +1315,9 @@ export const failJob = mutation({
1418
1315
  load: nextLoad,
1419
1316
  heartbeatAt: nowMs,
1420
1317
  scheduledShutdownAt: nextScheduledShutdownAt,
1421
- stoppedAt: undefined,
1422
1318
  });
1423
1319
  if (nextScheduledShutdownAt !== undefined) {
1424
- const delayMs = Math.max(0, nextScheduledShutdownAt - nowMs) + 1_000;
1425
- try {
1426
- await ctx.scheduler.runAfter(
1427
- delayMs,
1428
- (internal.scheduler as any).enforceIdleShutdowns,
1429
- {
1430
- providerConfig: args.providerConfig,
1431
- },
1432
- );
1433
- } catch (error) {
1434
- console.warn(
1435
- `[queue] failed to schedule idle-shutdown watchdog: ${
1436
- error instanceof Error ? error.message : String(error)
1437
- }`,
1438
- );
1439
- }
1320
+ await scheduleIdleShutdownWatchdog(ctx, nextScheduledShutdownAt, nowMs, args.providerConfig);
1440
1321
  }
1441
1322
  }
1442
1323
 
@@ -1509,8 +1390,10 @@ export const releaseExpiredLeases = internalMutation({
1509
1390
  load: nextLoad,
1510
1391
  heartbeatAt: nowMs,
1511
1392
  scheduledShutdownAt: nextScheduledShutdownAt,
1512
- stoppedAt: undefined,
1513
1393
  });
1394
+ if (nextScheduledShutdownAt !== undefined) {
1395
+ await scheduleIdleShutdownWatchdog(ctx, nextScheduledShutdownAt, nowMs);
1396
+ }
1514
1397
  }
1515
1398
  }
1516
1399
  }
@@ -1580,8 +1463,10 @@ export const releaseStuckJobs = mutation({
1580
1463
  load: nextLoad,
1581
1464
  heartbeatAt: nowMs,
1582
1465
  scheduledShutdownAt: nextScheduledShutdownAt,
1583
- stoppedAt: undefined,
1584
1466
  });
1467
+ if (nextScheduledShutdownAt !== undefined) {
1468
+ await scheduleIdleShutdownWatchdog(ctx, nextScheduledShutdownAt, nowMs);
1469
+ }
1585
1470
  }
1586
1471
  }
1587
1472
  }
@@ -1862,6 +1747,7 @@ export const upsertWorkerState = internalMutation({
1862
1747
  machineId: v.optional(v.string()),
1863
1748
  appName: v.optional(v.string()),
1864
1749
  region: v.optional(v.string()),
1750
+ clearLastSnapshotId: v.optional(v.boolean()),
1865
1751
  },
1866
1752
  returns: v.null(),
1867
1753
  handler: async (ctx, args) => {
@@ -1892,6 +1778,10 @@ export const upsertWorkerState = internalMutation({
1892
1778
  return null;
1893
1779
  }
1894
1780
 
1781
+ if (worker.status === "stopped" && args.status === "active") {
1782
+ throw new Error(`Worker '${args.workerId}' is stopped and cannot be reactivated.`);
1783
+ }
1784
+
1895
1785
  await ctx.db.patch(worker._id, {
1896
1786
  status: args.status,
1897
1787
  load: args.load,
@@ -1901,6 +1791,7 @@ export const upsertWorkerState = internalMutation({
1901
1791
  args.status === "active"
1902
1792
  ? undefined
1903
1793
  : (args.stoppedAt ?? worker.stoppedAt ?? nowMs),
1794
+ lastSnapshotId: args.clearLastSnapshotId ? undefined : worker.lastSnapshotId,
1904
1795
  machineRef:
1905
1796
  args.machineId && args.appName
1906
1797
  ? {
@@ -1926,8 +1817,12 @@ export const getWorkerControlState = query({
1926
1817
  .query("workers")
1927
1818
  .withIndex("by_workerId", (q) => q.eq("workerId", args.workerId))
1928
1819
  .unique();
1820
+ const nowMs = Date.now();
1929
1821
  return {
1930
- shouldStop: !worker || worker.status === "stopped",
1822
+ shouldStop:
1823
+ !worker ||
1824
+ worker.status === "stopped" ||
1825
+ (worker.scheduledShutdownAt !== undefined && worker.scheduledShutdownAt <= nowMs),
1931
1826
  };
1932
1827
  },
1933
1828
  });
@@ -2083,6 +1978,7 @@ export const listWorkersForScheduler = internalQuery({
2083
1978
  lastClaimAt: v.union(v.null(), v.number()),
2084
1979
  scheduledShutdownAt: v.union(v.null(), v.number()),
2085
1980
  stoppedAt: v.union(v.null(), v.number()),
1981
+ lastSnapshotId: v.union(v.null(), v.id("dataSnapshots")),
2086
1982
  machineId: v.union(v.null(), v.string()),
2087
1983
  appName: v.union(v.null(), v.string()),
2088
1984
  region: v.union(v.null(), v.string()),
@@ -2098,6 +1994,7 @@ export const listWorkersForScheduler = internalQuery({
2098
1994
  lastClaimAt: worker.lastClaimAt ?? null,
2099
1995
  scheduledShutdownAt: worker.scheduledShutdownAt ?? null,
2100
1996
  stoppedAt: worker.stoppedAt ?? null,
1997
+ lastSnapshotId: worker.lastSnapshotId ?? null,
2101
1998
  machineId: worker.machineRef?.machineId ?? null,
2102
1999
  appName: worker.machineRef?.appName ?? null,
2103
2000
  region: worker.machineRef?.region ?? null,
@@ -2249,6 +2146,26 @@ function appendSystemPromptToMessage(messageText: string, systemPrompt?: string)
2249
2146
  return `${normalizedMessageText}\n\n${normalizedSystemPrompt}`;
2250
2147
  }
2251
2148
 
2149
+ async function scheduleIdleShutdownWatchdog(
2150
+ ctx: any,
2151
+ scheduledShutdownAt: number,
2152
+ nowMs: number,
2153
+ providerConfig?: typeof DEFAULT_CONFIG.provider,
2154
+ ) {
2155
+ const delayMs = Math.max(0, scheduledShutdownAt - nowMs) + 1_000;
2156
+ try {
2157
+ await ctx.scheduler.runAfter(delayMs, (internal.scheduler as any).enforceIdleShutdowns, {
2158
+ providerConfig,
2159
+ });
2160
+ } catch (error) {
2161
+ console.warn(
2162
+ `[queue] failed to schedule idle-shutdown watchdog: ${
2163
+ error instanceof Error ? error.message : String(error)
2164
+ }`,
2165
+ );
2166
+ }
2167
+ }
2168
+
2252
2169
  function normalizeMessageRuntimeConfig(
2253
2170
  messageConfig: { systemPrompt?: string } | null | undefined,
2254
2171
  ): { systemPrompt?: string } | null {