@okrlinkhub/agent-factory 2.0.0 → 2.0.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/dist/client/index.d.ts +38 -4
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +174 -36
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/component.d.ts +138 -8
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/identity.d.ts +5 -5
- package/dist/component/pushing.d.ts +30 -30
- package/dist/component/queue.d.ts +125 -51
- package/dist/component/queue.d.ts.map +1 -1
- package/dist/component/queue.js +128 -14
- package/dist/component/queue.js.map +1 -1
- package/dist/component/scheduler.d.ts +13 -13
- package/dist/component/scheduler.js +4 -0
- package/dist/component/scheduler.js.map +1 -1
- package/dist/component/schema.d.ts +164 -80
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +29 -0
- package/dist/component/schema.js.map +1 -1
- package/package.json +1 -1
- package/src/client/index.ts +302 -42
- package/src/component/_generated/component.ts +164 -14
- package/src/component/lib.test.ts +132 -0
- package/src/component/queue.ts +185 -20
- package/src/component/scheduler.ts +4 -0
- package/src/component/schema.ts +46 -0
|
@@ -40,6 +40,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
40
40
|
agentKey: string;
|
|
41
41
|
boundAt: number;
|
|
42
42
|
consumerUserId: string;
|
|
43
|
+
conversationId: string;
|
|
43
44
|
metadata: null | Record<string, string>;
|
|
44
45
|
revokedAt: null | number;
|
|
45
46
|
source: "manual" | "telegram_pairing" | "api";
|
|
@@ -247,6 +248,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
247
248
|
agentKey: string;
|
|
248
249
|
boundAt: number;
|
|
249
250
|
consumerUserId: string;
|
|
251
|
+
conversationId: string;
|
|
250
252
|
metadata: null | Record<string, string>;
|
|
251
253
|
revokedAt: null | number;
|
|
252
254
|
source: "manual" | "telegram_pairing" | "api";
|
|
@@ -372,7 +374,11 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
372
374
|
"query",
|
|
373
375
|
"internal",
|
|
374
376
|
{ telegramChatId?: string; telegramUserId?: string },
|
|
375
|
-
{
|
|
377
|
+
{
|
|
378
|
+
agentKey: null | string;
|
|
379
|
+
consumerUserId: null | string;
|
|
380
|
+
conversationId: null | string;
|
|
381
|
+
},
|
|
376
382
|
Name
|
|
377
383
|
>;
|
|
378
384
|
resolveAgentForUser: FunctionReference<
|
|
@@ -430,6 +436,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
430
436
|
agentKey: string;
|
|
431
437
|
boundAt: number;
|
|
432
438
|
consumerUserId: string;
|
|
439
|
+
conversationId: string;
|
|
433
440
|
metadata: null | Record<string, string>;
|
|
434
441
|
revokedAt: null | number;
|
|
435
442
|
source: "manual" | "telegram_pairing" | "api";
|
|
@@ -475,6 +482,16 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
475
482
|
leaseId: string;
|
|
476
483
|
messageId: string;
|
|
477
484
|
payload: {
|
|
485
|
+
attachments?: Array<{
|
|
486
|
+
expiresAt: number;
|
|
487
|
+
fileName?: string;
|
|
488
|
+
kind: "photo" | "video" | "audio" | "voice" | "document";
|
|
489
|
+
mimeType?: string;
|
|
490
|
+
sizeBytes?: number;
|
|
491
|
+
status: "ready" | "expired";
|
|
492
|
+
storageId: string;
|
|
493
|
+
telegramFileId: string;
|
|
494
|
+
}>;
|
|
478
495
|
externalMessageId?: string;
|
|
479
496
|
messageText: string;
|
|
480
497
|
metadata?: Record<string, string>;
|
|
@@ -765,6 +782,16 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
765
782
|
maxAttempts?: number;
|
|
766
783
|
nowMs?: number;
|
|
767
784
|
payload: {
|
|
785
|
+
attachments?: Array<{
|
|
786
|
+
expiresAt: number;
|
|
787
|
+
fileName?: string;
|
|
788
|
+
kind: "photo" | "video" | "audio" | "voice" | "document";
|
|
789
|
+
mimeType?: string;
|
|
790
|
+
sizeBytes?: number;
|
|
791
|
+
status: "ready" | "expired";
|
|
792
|
+
storageId: string;
|
|
793
|
+
telegramFileId: string;
|
|
794
|
+
}>;
|
|
768
795
|
externalMessageId?: string;
|
|
769
796
|
messageText: string;
|
|
770
797
|
metadata?: Record<string, string>;
|
|
@@ -886,6 +913,16 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
886
913
|
lastError: null | string;
|
|
887
914
|
maxAttempts: number;
|
|
888
915
|
payload: {
|
|
916
|
+
attachments?: Array<{
|
|
917
|
+
expiresAt: number;
|
|
918
|
+
fileName?: string;
|
|
919
|
+
kind: "photo" | "video" | "audio" | "voice" | "document";
|
|
920
|
+
mimeType?: string;
|
|
921
|
+
sizeBytes?: number;
|
|
922
|
+
status: "ready" | "expired";
|
|
923
|
+
storageId: string;
|
|
924
|
+
telegramFileId: string;
|
|
925
|
+
}>;
|
|
889
926
|
externalMessageId?: string;
|
|
890
927
|
messageText: string;
|
|
891
928
|
metadata?: Record<string, string>;
|
|
@@ -929,6 +966,16 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
929
966
|
};
|
|
930
967
|
messageId: string;
|
|
931
968
|
payload: {
|
|
969
|
+
attachments?: Array<{
|
|
970
|
+
expiresAt: number;
|
|
971
|
+
fileName?: string;
|
|
972
|
+
kind: "photo" | "video" | "audio" | "voice" | "document";
|
|
973
|
+
mimeType?: string;
|
|
974
|
+
sizeBytes?: number;
|
|
975
|
+
status: "ready" | "expired";
|
|
976
|
+
storageId: string;
|
|
977
|
+
telegramFileId: string;
|
|
978
|
+
}>;
|
|
932
979
|
externalMessageId?: string;
|
|
933
980
|
messageText: string;
|
|
934
981
|
metadata?: Record<string, string>;
|
|
@@ -945,7 +992,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
945
992
|
"internal",
|
|
946
993
|
{ agentKey: string; consumerUserId: string; nowMs?: number },
|
|
947
994
|
null | {
|
|
948
|
-
conversationId:
|
|
995
|
+
conversationId: string;
|
|
949
996
|
createdAt: number;
|
|
950
997
|
downloadUrl: null | string;
|
|
951
998
|
sha256: null | string;
|
|
@@ -1040,6 +1087,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1040
1087
|
agentKey: string;
|
|
1041
1088
|
boundAt: number;
|
|
1042
1089
|
consumerUserId: string;
|
|
1090
|
+
conversationId: string;
|
|
1043
1091
|
metadata: null | Record<string, string>;
|
|
1044
1092
|
revokedAt: null | number;
|
|
1045
1093
|
source: "manual" | "telegram_pairing" | "api";
|
|
@@ -1323,6 +1371,16 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1323
1371
|
lastError: null | string;
|
|
1324
1372
|
maxAttempts: number;
|
|
1325
1373
|
payload: {
|
|
1374
|
+
attachments?: Array<{
|
|
1375
|
+
expiresAt: number;
|
|
1376
|
+
fileName?: string;
|
|
1377
|
+
kind: "photo" | "video" | "audio" | "voice" | "document";
|
|
1378
|
+
mimeType?: string;
|
|
1379
|
+
sizeBytes?: number;
|
|
1380
|
+
status: "ready" | "expired";
|
|
1381
|
+
storageId: string;
|
|
1382
|
+
telegramFileId: string;
|
|
1383
|
+
}>;
|
|
1326
1384
|
externalMessageId?: string;
|
|
1327
1385
|
messageText: string;
|
|
1328
1386
|
metadata?: Record<string, string>;
|
|
@@ -1356,6 +1414,16 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1356
1414
|
lastError: null | string;
|
|
1357
1415
|
maxAttempts: number;
|
|
1358
1416
|
payload: {
|
|
1417
|
+
attachments?: Array<{
|
|
1418
|
+
expiresAt: number;
|
|
1419
|
+
fileName?: string;
|
|
1420
|
+
kind: "photo" | "video" | "audio" | "voice" | "document";
|
|
1421
|
+
mimeType?: string;
|
|
1422
|
+
sizeBytes?: number;
|
|
1423
|
+
status: "ready" | "expired";
|
|
1424
|
+
storageId: string;
|
|
1425
|
+
telegramFileId: string;
|
|
1426
|
+
}>;
|
|
1359
1427
|
externalMessageId?: string;
|
|
1360
1428
|
messageText: string;
|
|
1361
1429
|
metadata?: Record<string, string>;
|
|
@@ -1374,7 +1442,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1374
1442
|
"internal",
|
|
1375
1443
|
{ conversationId: string; limit?: number; nowMs?: number },
|
|
1376
1444
|
Array<{
|
|
1377
|
-
conversationId:
|
|
1445
|
+
conversationId: string;
|
|
1378
1446
|
createdAt: number;
|
|
1379
1447
|
downloadUrl: null | string;
|
|
1380
1448
|
sha256: null | string;
|
|
@@ -1394,7 +1462,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1394
1462
|
nowMs?: number;
|
|
1395
1463
|
},
|
|
1396
1464
|
Array<{
|
|
1397
|
-
conversationId:
|
|
1465
|
+
conversationId: string;
|
|
1398
1466
|
createdAt: number;
|
|
1399
1467
|
downloadUrl: null | string;
|
|
1400
1468
|
sha256: null | string;
|
|
@@ -1429,7 +1497,10 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1429
1497
|
"query",
|
|
1430
1498
|
"internal",
|
|
1431
1499
|
{},
|
|
1432
|
-
null | {
|
|
1500
|
+
null | {
|
|
1501
|
+
systemPrompt?: string;
|
|
1502
|
+
telegramAttachmentRetentionMs?: number;
|
|
1503
|
+
},
|
|
1433
1504
|
Name
|
|
1434
1505
|
>;
|
|
1435
1506
|
providerRuntimeConfig: FunctionReference<
|
|
@@ -1495,7 +1566,11 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1495
1566
|
"query",
|
|
1496
1567
|
"internal",
|
|
1497
1568
|
{ telegramChatId?: string; telegramUserId?: string },
|
|
1498
|
-
{
|
|
1569
|
+
{
|
|
1570
|
+
agentKey: null | string;
|
|
1571
|
+
consumerUserId: null | string;
|
|
1572
|
+
conversationId: null | string;
|
|
1573
|
+
},
|
|
1499
1574
|
Name
|
|
1500
1575
|
>;
|
|
1501
1576
|
resolveAgentForUser: FunctionReference<
|
|
@@ -1577,7 +1652,13 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1577
1652
|
setMessageRuntimeConfig: FunctionReference<
|
|
1578
1653
|
"mutation",
|
|
1579
1654
|
"internal",
|
|
1580
|
-
{
|
|
1655
|
+
{
|
|
1656
|
+
messageConfig: {
|
|
1657
|
+
systemPrompt?: string;
|
|
1658
|
+
telegramAttachmentRetentionMs?: number;
|
|
1659
|
+
};
|
|
1660
|
+
nowMs?: number;
|
|
1661
|
+
},
|
|
1581
1662
|
null,
|
|
1582
1663
|
Name
|
|
1583
1664
|
>;
|
|
@@ -2201,6 +2282,16 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2201
2282
|
leaseId: string;
|
|
2202
2283
|
messageId: string;
|
|
2203
2284
|
payload: {
|
|
2285
|
+
attachments?: Array<{
|
|
2286
|
+
expiresAt: number;
|
|
2287
|
+
fileName?: string;
|
|
2288
|
+
kind: "photo" | "video" | "audio" | "voice" | "document";
|
|
2289
|
+
mimeType?: string;
|
|
2290
|
+
sizeBytes?: number;
|
|
2291
|
+
status: "ready" | "expired";
|
|
2292
|
+
storageId: string;
|
|
2293
|
+
telegramFileId: string;
|
|
2294
|
+
}>;
|
|
2204
2295
|
externalMessageId?: string;
|
|
2205
2296
|
messageText: string;
|
|
2206
2297
|
metadata?: Record<string, string>;
|
|
@@ -2280,6 +2371,16 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2280
2371
|
maxAttempts?: number;
|
|
2281
2372
|
nowMs?: number;
|
|
2282
2373
|
payload: {
|
|
2374
|
+
attachments?: Array<{
|
|
2375
|
+
expiresAt: number;
|
|
2376
|
+
fileName?: string;
|
|
2377
|
+
kind: "photo" | "video" | "audio" | "voice" | "document";
|
|
2378
|
+
mimeType?: string;
|
|
2379
|
+
sizeBytes?: number;
|
|
2380
|
+
status: "ready" | "expired";
|
|
2381
|
+
storageId: string;
|
|
2382
|
+
telegramFileId: string;
|
|
2383
|
+
}>;
|
|
2283
2384
|
externalMessageId?: string;
|
|
2284
2385
|
messageText: string;
|
|
2285
2386
|
metadata?: Record<string, string>;
|
|
@@ -2387,6 +2488,16 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2387
2488
|
lastError: null | string;
|
|
2388
2489
|
maxAttempts: number;
|
|
2389
2490
|
payload: {
|
|
2491
|
+
attachments?: Array<{
|
|
2492
|
+
expiresAt: number;
|
|
2493
|
+
fileName?: string;
|
|
2494
|
+
kind: "photo" | "video" | "audio" | "voice" | "document";
|
|
2495
|
+
mimeType?: string;
|
|
2496
|
+
sizeBytes?: number;
|
|
2497
|
+
status: "ready" | "expired";
|
|
2498
|
+
storageId: string;
|
|
2499
|
+
telegramFileId: string;
|
|
2500
|
+
}>;
|
|
2390
2501
|
externalMessageId?: string;
|
|
2391
2502
|
messageText: string;
|
|
2392
2503
|
metadata?: Record<string, string>;
|
|
@@ -2430,6 +2541,16 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2430
2541
|
};
|
|
2431
2542
|
messageId: string;
|
|
2432
2543
|
payload: {
|
|
2544
|
+
attachments?: Array<{
|
|
2545
|
+
expiresAt: number;
|
|
2546
|
+
fileName?: string;
|
|
2547
|
+
kind: "photo" | "video" | "audio" | "voice" | "document";
|
|
2548
|
+
mimeType?: string;
|
|
2549
|
+
sizeBytes?: number;
|
|
2550
|
+
status: "ready" | "expired";
|
|
2551
|
+
storageId: string;
|
|
2552
|
+
telegramFileId: string;
|
|
2553
|
+
}>;
|
|
2433
2554
|
externalMessageId?: string;
|
|
2434
2555
|
messageText: string;
|
|
2435
2556
|
metadata?: Record<string, string>;
|
|
@@ -2446,7 +2567,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2446
2567
|
"internal",
|
|
2447
2568
|
{
|
|
2448
2569
|
agentKey: string;
|
|
2449
|
-
conversationId
|
|
2570
|
+
conversationId: string;
|
|
2450
2571
|
nowMs?: number;
|
|
2451
2572
|
workspaceId: string;
|
|
2452
2573
|
},
|
|
@@ -2464,7 +2585,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2464
2585
|
"internal",
|
|
2465
2586
|
{ agentKey: string; consumerUserId: string; nowMs?: number },
|
|
2466
2587
|
null | {
|
|
2467
|
-
conversationId:
|
|
2588
|
+
conversationId: string;
|
|
2468
2589
|
createdAt: number;
|
|
2469
2590
|
downloadUrl: null | string;
|
|
2470
2591
|
sha256: null | string;
|
|
@@ -2643,6 +2764,16 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2643
2764
|
lastError: null | string;
|
|
2644
2765
|
maxAttempts: number;
|
|
2645
2766
|
payload: {
|
|
2767
|
+
attachments?: Array<{
|
|
2768
|
+
expiresAt: number;
|
|
2769
|
+
fileName?: string;
|
|
2770
|
+
kind: "photo" | "video" | "audio" | "voice" | "document";
|
|
2771
|
+
mimeType?: string;
|
|
2772
|
+
sizeBytes?: number;
|
|
2773
|
+
status: "ready" | "expired";
|
|
2774
|
+
storageId: string;
|
|
2775
|
+
telegramFileId: string;
|
|
2776
|
+
}>;
|
|
2646
2777
|
externalMessageId?: string;
|
|
2647
2778
|
messageText: string;
|
|
2648
2779
|
metadata?: Record<string, string>;
|
|
@@ -2676,6 +2807,16 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2676
2807
|
lastError: null | string;
|
|
2677
2808
|
maxAttempts: number;
|
|
2678
2809
|
payload: {
|
|
2810
|
+
attachments?: Array<{
|
|
2811
|
+
expiresAt: number;
|
|
2812
|
+
fileName?: string;
|
|
2813
|
+
kind: "photo" | "video" | "audio" | "voice" | "document";
|
|
2814
|
+
mimeType?: string;
|
|
2815
|
+
sizeBytes?: number;
|
|
2816
|
+
status: "ready" | "expired";
|
|
2817
|
+
storageId: string;
|
|
2818
|
+
telegramFileId: string;
|
|
2819
|
+
}>;
|
|
2679
2820
|
externalMessageId?: string;
|
|
2680
2821
|
messageText: string;
|
|
2681
2822
|
metadata?: Record<string, string>;
|
|
@@ -2694,7 +2835,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2694
2835
|
"internal",
|
|
2695
2836
|
{ conversationId: string; limit?: number; nowMs?: number },
|
|
2696
2837
|
Array<{
|
|
2697
|
-
conversationId:
|
|
2838
|
+
conversationId: string;
|
|
2698
2839
|
createdAt: number;
|
|
2699
2840
|
downloadUrl: null | string;
|
|
2700
2841
|
sha256: null | string;
|
|
@@ -2714,7 +2855,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2714
2855
|
nowMs?: number;
|
|
2715
2856
|
},
|
|
2716
2857
|
Array<{
|
|
2717
|
-
conversationId:
|
|
2858
|
+
conversationId: string;
|
|
2718
2859
|
createdAt: number;
|
|
2719
2860
|
downloadUrl: null | string;
|
|
2720
2861
|
sha256: null | string;
|
|
@@ -2728,7 +2869,10 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2728
2869
|
"query",
|
|
2729
2870
|
"internal",
|
|
2730
2871
|
{},
|
|
2731
|
-
null | {
|
|
2872
|
+
null | {
|
|
2873
|
+
systemPrompt?: string;
|
|
2874
|
+
telegramAttachmentRetentionMs?: number;
|
|
2875
|
+
},
|
|
2732
2876
|
Name
|
|
2733
2877
|
>;
|
|
2734
2878
|
prepareDataSnapshotUpload: FunctionReference<
|
|
@@ -2736,7 +2880,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2736
2880
|
"internal",
|
|
2737
2881
|
{
|
|
2738
2882
|
agentKey: string;
|
|
2739
|
-
conversationId
|
|
2883
|
+
conversationId: string;
|
|
2740
2884
|
nowMs?: number;
|
|
2741
2885
|
reason: "drain" | "signal" | "manual";
|
|
2742
2886
|
workerId: string;
|
|
@@ -2806,7 +2950,13 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2806
2950
|
setMessageRuntimeConfig: FunctionReference<
|
|
2807
2951
|
"mutation",
|
|
2808
2952
|
"internal",
|
|
2809
|
-
{
|
|
2953
|
+
{
|
|
2954
|
+
messageConfig: {
|
|
2955
|
+
systemPrompt?: string;
|
|
2956
|
+
telegramAttachmentRetentionMs?: number;
|
|
2957
|
+
};
|
|
2958
|
+
nowMs?: number;
|
|
2959
|
+
},
|
|
2810
2960
|
null,
|
|
2811
2961
|
Name
|
|
2812
2962
|
>;
|
|
@@ -201,6 +201,138 @@ describe("component lib", () => {
|
|
|
201
201
|
expect(claim?.payload.messageText).toBe("hello");
|
|
202
202
|
});
|
|
203
203
|
|
|
204
|
+
test("message runtime config should store telegram attachment retention", async () => {
|
|
205
|
+
const t = initConvexTest();
|
|
206
|
+
await t.mutation(api.lib.setMessageRuntimeConfig, {
|
|
207
|
+
messageConfig: {
|
|
208
|
+
telegramAttachmentRetentionMs: 60_000,
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const storedMessageConfig = await t.query(api.lib.messageRuntimeConfig, {});
|
|
213
|
+
expect(storedMessageConfig).toEqual({
|
|
214
|
+
telegramAttachmentRetentionMs: 60_000,
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
test("enqueue should persist telegram attachments for claimed jobs", async () => {
|
|
219
|
+
const t = initConvexTest();
|
|
220
|
+
const nowMs = Date.UTC(2026, 0, 1, 9, 0, 0);
|
|
221
|
+
vi.setSystemTime(nowMs);
|
|
222
|
+
await t.mutation(api.queue.upsertAgentProfile, {
|
|
223
|
+
agentKey: "attachment-agent",
|
|
224
|
+
version: "1.0.0",
|
|
225
|
+
secretsRef: [],
|
|
226
|
+
enabled: true,
|
|
227
|
+
});
|
|
228
|
+
const storageId = await t.run(async (ctx) => {
|
|
229
|
+
return await ctx.storage.store(new Blob(["photo-binary"], { type: "image/jpeg" }));
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
const messageId = await t.mutation(api.lib.enqueue, {
|
|
233
|
+
conversationId: "telegram:chat:attachment",
|
|
234
|
+
agentKey: "attachment-agent",
|
|
235
|
+
payload: {
|
|
236
|
+
provider: "telegram",
|
|
237
|
+
providerUserId: "u-attachment-1",
|
|
238
|
+
messageText: "[telegram media] photo message",
|
|
239
|
+
attachments: [
|
|
240
|
+
{
|
|
241
|
+
kind: "photo",
|
|
242
|
+
status: "ready",
|
|
243
|
+
storageId,
|
|
244
|
+
telegramFileId: "telegram-photo-1",
|
|
245
|
+
mimeType: "image/jpeg",
|
|
246
|
+
sizeBytes: 12,
|
|
247
|
+
expiresAt: nowMs + 60_000,
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
},
|
|
251
|
+
nowMs,
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
const claim = await t.mutation(api.lib.claim, {
|
|
255
|
+
workerId: "worker-attachment-1",
|
|
256
|
+
nowMs,
|
|
257
|
+
});
|
|
258
|
+
expect(claim?.messageId).toBe(messageId);
|
|
259
|
+
expect(claim?.payload.attachments).toHaveLength(1);
|
|
260
|
+
expect(claim?.payload.attachments?.[0]?.telegramFileId).toBe("telegram-photo-1");
|
|
261
|
+
|
|
262
|
+
const bundle = await t.query(api.lib.getHydrationBundle, {
|
|
263
|
+
messageId,
|
|
264
|
+
workspaceId: "default",
|
|
265
|
+
});
|
|
266
|
+
expect(bundle?.payload.attachments).toHaveLength(1);
|
|
267
|
+
expect(bundle?.payload.attachments?.[0]?.storageId).toBe(storageId);
|
|
268
|
+
|
|
269
|
+
const attachmentRows = await t.run(async (ctx) => {
|
|
270
|
+
return await ctx.db
|
|
271
|
+
.query("messageAttachments")
|
|
272
|
+
.withIndex("by_messageId", (q) => q.eq("messageId", messageId))
|
|
273
|
+
.collect();
|
|
274
|
+
});
|
|
275
|
+
expect(attachmentRows).toHaveLength(1);
|
|
276
|
+
expect(attachmentRows[0]?.status).toBe("ready");
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
test("expireOldTelegramAttachments should expire stored attachments and queued payloads", async () => {
|
|
280
|
+
const t = initConvexTest();
|
|
281
|
+
const nowMs = Date.UTC(2026, 0, 1, 10, 0, 0);
|
|
282
|
+
vi.setSystemTime(nowMs);
|
|
283
|
+
await t.mutation(api.queue.upsertAgentProfile, {
|
|
284
|
+
agentKey: "attachment-expiry-agent",
|
|
285
|
+
version: "1.0.0",
|
|
286
|
+
secretsRef: [],
|
|
287
|
+
enabled: true,
|
|
288
|
+
});
|
|
289
|
+
const storageId = await t.run(async (ctx) => {
|
|
290
|
+
return await ctx.storage.store(new Blob(["document-binary"], { type: "application/pdf" }));
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
const messageId = await t.mutation(api.queue.enqueueMessage, {
|
|
294
|
+
conversationId: "telegram:chat:attachment-expiry",
|
|
295
|
+
agentKey: "attachment-expiry-agent",
|
|
296
|
+
payload: {
|
|
297
|
+
provider: "telegram",
|
|
298
|
+
providerUserId: "u-attachment-expiry-1",
|
|
299
|
+
messageText: "[telegram media] document message",
|
|
300
|
+
attachments: [
|
|
301
|
+
{
|
|
302
|
+
kind: "document",
|
|
303
|
+
status: "ready",
|
|
304
|
+
storageId,
|
|
305
|
+
telegramFileId: "telegram-document-1",
|
|
306
|
+
fileName: "brief.pdf",
|
|
307
|
+
mimeType: "application/pdf",
|
|
308
|
+
sizeBytes: 15,
|
|
309
|
+
expiresAt: nowMs + 10,
|
|
310
|
+
},
|
|
311
|
+
],
|
|
312
|
+
},
|
|
313
|
+
nowMs,
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const expired = await t.mutation((internal.queue as any).expireOldTelegramAttachments, {
|
|
317
|
+
nowMs: nowMs + 11,
|
|
318
|
+
limit: 10,
|
|
319
|
+
});
|
|
320
|
+
expect(expired).toBe(1);
|
|
321
|
+
|
|
322
|
+
const attachmentRows = await t.run(async (ctx) => {
|
|
323
|
+
return await ctx.db
|
|
324
|
+
.query("messageAttachments")
|
|
325
|
+
.withIndex("by_messageId", (q) => q.eq("messageId", messageId))
|
|
326
|
+
.collect();
|
|
327
|
+
});
|
|
328
|
+
expect(attachmentRows[0]?.status).toBe("expired");
|
|
329
|
+
|
|
330
|
+
const messageRow = await t.run(async (ctx) => {
|
|
331
|
+
return await ctx.db.get(messageId);
|
|
332
|
+
});
|
|
333
|
+
expect(messageRow?.payload.attachments?.[0]?.status).toBe("expired");
|
|
334
|
+
});
|
|
335
|
+
|
|
204
336
|
test("enqueue should fail when providerUserId is blank in payload", async () => {
|
|
205
337
|
const t = initConvexTest();
|
|
206
338
|
await t.mutation(api.queue.upsertAgentProfile, {
|