@axiom-lattice/pg-stores 1.0.1 → 1.0.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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +17 -0
- package/dist/index.d.mts +126 -3
- package/dist/index.d.ts +126 -3
- package/dist/index.js +545 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +545 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +7 -0
- package/src/migrations/schedule_migrations.ts +116 -0
- package/src/stores/PostgreSQLScheduleStorage.ts +591 -0
package/dist/index.mjs
CHANGED
|
@@ -573,11 +573,556 @@ var PostgreSQLAssistantStore = class {
|
|
|
573
573
|
};
|
|
574
574
|
}
|
|
575
575
|
};
|
|
576
|
+
|
|
577
|
+
// src/stores/PostgreSQLScheduleStorage.ts
|
|
578
|
+
import { Pool as Pool3 } from "pg";
|
|
579
|
+
import {
|
|
580
|
+
ScheduledTaskStatus
|
|
581
|
+
} from "@axiom-lattice/protocols";
|
|
582
|
+
|
|
583
|
+
// src/migrations/schedule_migrations.ts
|
|
584
|
+
var createScheduledTasksTable = {
|
|
585
|
+
name: "create_scheduled_tasks_table",
|
|
586
|
+
version: 2,
|
|
587
|
+
up: async (client) => {
|
|
588
|
+
await client.query(`
|
|
589
|
+
CREATE TABLE IF NOT EXISTS lattice_scheduled_tasks (
|
|
590
|
+
-- Primary key
|
|
591
|
+
task_id VARCHAR(255) PRIMARY KEY,
|
|
592
|
+
|
|
593
|
+
-- Task type (maps to handler)
|
|
594
|
+
task_type VARCHAR(255) NOT NULL,
|
|
595
|
+
|
|
596
|
+
-- Payload (JSON-serializable data)
|
|
597
|
+
payload JSONB NOT NULL DEFAULT '{}',
|
|
598
|
+
|
|
599
|
+
-- Context fields for querying
|
|
600
|
+
assistant_id VARCHAR(255),
|
|
601
|
+
thread_id VARCHAR(255),
|
|
602
|
+
|
|
603
|
+
-- Execution type: 'once' or 'cron'
|
|
604
|
+
execution_type VARCHAR(50) NOT NULL,
|
|
605
|
+
|
|
606
|
+
-- For ONCE type
|
|
607
|
+
execute_at TIMESTAMPTZ,
|
|
608
|
+
delay_ms BIGINT,
|
|
609
|
+
|
|
610
|
+
-- For CRON type
|
|
611
|
+
cron_expression VARCHAR(255),
|
|
612
|
+
timezone VARCHAR(100),
|
|
613
|
+
next_run_at TIMESTAMPTZ,
|
|
614
|
+
last_run_at TIMESTAMPTZ,
|
|
615
|
+
|
|
616
|
+
-- Status
|
|
617
|
+
status VARCHAR(50) NOT NULL DEFAULT 'pending',
|
|
618
|
+
|
|
619
|
+
-- Execution tracking
|
|
620
|
+
run_count INTEGER NOT NULL DEFAULT 0,
|
|
621
|
+
max_runs INTEGER,
|
|
622
|
+
|
|
623
|
+
-- Error handling
|
|
624
|
+
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
625
|
+
max_retries INTEGER NOT NULL DEFAULT 0,
|
|
626
|
+
last_error TEXT,
|
|
627
|
+
|
|
628
|
+
-- Timestamps
|
|
629
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
630
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
631
|
+
expires_at TIMESTAMPTZ,
|
|
632
|
+
|
|
633
|
+
-- Metadata
|
|
634
|
+
metadata JSONB
|
|
635
|
+
);
|
|
636
|
+
|
|
637
|
+
-- Index for querying active tasks
|
|
638
|
+
CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_status
|
|
639
|
+
ON lattice_scheduled_tasks (status);
|
|
640
|
+
|
|
641
|
+
-- Index for querying by task type
|
|
642
|
+
CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_task_type
|
|
643
|
+
ON lattice_scheduled_tasks (task_type);
|
|
644
|
+
|
|
645
|
+
-- Index for querying by execution type
|
|
646
|
+
CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_execution_type
|
|
647
|
+
ON lattice_scheduled_tasks (execution_type);
|
|
648
|
+
|
|
649
|
+
-- Index for querying by assistant ID
|
|
650
|
+
CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_assistant_id
|
|
651
|
+
ON lattice_scheduled_tasks (assistant_id)
|
|
652
|
+
WHERE assistant_id IS NOT NULL;
|
|
653
|
+
|
|
654
|
+
-- Index for querying by thread ID
|
|
655
|
+
CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_thread_id
|
|
656
|
+
ON lattice_scheduled_tasks (thread_id)
|
|
657
|
+
WHERE thread_id IS NOT NULL;
|
|
658
|
+
|
|
659
|
+
-- Index for querying pending tasks by next run time
|
|
660
|
+
CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_next_run
|
|
661
|
+
ON lattice_scheduled_tasks (next_run_at)
|
|
662
|
+
WHERE status = 'pending';
|
|
663
|
+
|
|
664
|
+
-- Index for querying pending one-time tasks by execute time
|
|
665
|
+
CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_execute_at
|
|
666
|
+
ON lattice_scheduled_tasks (execute_at)
|
|
667
|
+
WHERE status = 'pending' AND execution_type = 'once';
|
|
668
|
+
|
|
669
|
+
-- Index for cleanup queries (old completed/cancelled tasks)
|
|
670
|
+
CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_cleanup
|
|
671
|
+
ON lattice_scheduled_tasks (updated_at)
|
|
672
|
+
WHERE status IN ('completed', 'cancelled', 'failed');
|
|
673
|
+
`);
|
|
674
|
+
},
|
|
675
|
+
down: async (client) => {
|
|
676
|
+
await client.query(`
|
|
677
|
+
DROP INDEX IF EXISTS idx_scheduled_tasks_cleanup;
|
|
678
|
+
DROP INDEX IF EXISTS idx_scheduled_tasks_execute_at;
|
|
679
|
+
DROP INDEX IF EXISTS idx_scheduled_tasks_next_run;
|
|
680
|
+
DROP INDEX IF EXISTS idx_scheduled_tasks_thread_id;
|
|
681
|
+
DROP INDEX IF EXISTS idx_scheduled_tasks_assistant_id;
|
|
682
|
+
DROP INDEX IF EXISTS idx_scheduled_tasks_execution_type;
|
|
683
|
+
DROP INDEX IF EXISTS idx_scheduled_tasks_task_type;
|
|
684
|
+
DROP INDEX IF EXISTS idx_scheduled_tasks_status;
|
|
685
|
+
DROP TABLE IF EXISTS lattice_scheduled_tasks;
|
|
686
|
+
`);
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
// src/stores/PostgreSQLScheduleStorage.ts
|
|
691
|
+
var PostgreSQLScheduleStorage = class {
|
|
692
|
+
constructor(options) {
|
|
693
|
+
this.initialized = false;
|
|
694
|
+
if (typeof options.poolConfig === "string") {
|
|
695
|
+
this.pool = new Pool3({ connectionString: options.poolConfig });
|
|
696
|
+
} else {
|
|
697
|
+
this.pool = new Pool3(options.poolConfig);
|
|
698
|
+
}
|
|
699
|
+
this.migrationManager = new MigrationManager(this.pool);
|
|
700
|
+
this.migrationManager.register(createScheduledTasksTable);
|
|
701
|
+
if (options.autoMigrate !== false) {
|
|
702
|
+
this.initialize().catch((error) => {
|
|
703
|
+
console.error("Failed to initialize PostgreSQLScheduleStorage:", error);
|
|
704
|
+
throw error;
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Dispose resources and close the connection pool
|
|
710
|
+
*/
|
|
711
|
+
async dispose() {
|
|
712
|
+
if (this.pool) {
|
|
713
|
+
await this.pool.end();
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Initialize the store and run migrations
|
|
718
|
+
*/
|
|
719
|
+
async initialize() {
|
|
720
|
+
if (this.initialized) {
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
await this.migrationManager.migrate();
|
|
724
|
+
this.initialized = true;
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Ensure store is initialized
|
|
728
|
+
*/
|
|
729
|
+
async ensureInitialized() {
|
|
730
|
+
if (!this.initialized) {
|
|
731
|
+
await this.initialize();
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Save a new task
|
|
736
|
+
*/
|
|
737
|
+
async save(task) {
|
|
738
|
+
await this.ensureInitialized();
|
|
739
|
+
await this.pool.query(
|
|
740
|
+
`
|
|
741
|
+
INSERT INTO lattice_scheduled_tasks (
|
|
742
|
+
task_id, task_type, payload, assistant_id, thread_id, execution_type,
|
|
743
|
+
execute_at, delay_ms, cron_expression, timezone,
|
|
744
|
+
next_run_at, last_run_at, status, run_count, max_runs,
|
|
745
|
+
retry_count, max_retries, last_error,
|
|
746
|
+
created_at, updated_at, expires_at, metadata
|
|
747
|
+
) VALUES (
|
|
748
|
+
$1, $2, $3, $4, $5, $6,
|
|
749
|
+
$7, $8, $9, $10,
|
|
750
|
+
$11, $12, $13, $14, $15,
|
|
751
|
+
$16, $17, $18,
|
|
752
|
+
$19, $20, $21, $22
|
|
753
|
+
)
|
|
754
|
+
ON CONFLICT (task_id) DO UPDATE SET
|
|
755
|
+
task_type = EXCLUDED.task_type,
|
|
756
|
+
payload = EXCLUDED.payload,
|
|
757
|
+
assistant_id = EXCLUDED.assistant_id,
|
|
758
|
+
thread_id = EXCLUDED.thread_id,
|
|
759
|
+
execution_type = EXCLUDED.execution_type,
|
|
760
|
+
execute_at = EXCLUDED.execute_at,
|
|
761
|
+
delay_ms = EXCLUDED.delay_ms,
|
|
762
|
+
cron_expression = EXCLUDED.cron_expression,
|
|
763
|
+
timezone = EXCLUDED.timezone,
|
|
764
|
+
next_run_at = EXCLUDED.next_run_at,
|
|
765
|
+
last_run_at = EXCLUDED.last_run_at,
|
|
766
|
+
status = EXCLUDED.status,
|
|
767
|
+
run_count = EXCLUDED.run_count,
|
|
768
|
+
max_runs = EXCLUDED.max_runs,
|
|
769
|
+
retry_count = EXCLUDED.retry_count,
|
|
770
|
+
max_retries = EXCLUDED.max_retries,
|
|
771
|
+
last_error = EXCLUDED.last_error,
|
|
772
|
+
updated_at = EXCLUDED.updated_at,
|
|
773
|
+
expires_at = EXCLUDED.expires_at,
|
|
774
|
+
metadata = EXCLUDED.metadata
|
|
775
|
+
`,
|
|
776
|
+
[
|
|
777
|
+
task.taskId,
|
|
778
|
+
task.taskType,
|
|
779
|
+
JSON.stringify(task.payload),
|
|
780
|
+
task.assistantId ?? null,
|
|
781
|
+
task.threadId ?? null,
|
|
782
|
+
task.executionType,
|
|
783
|
+
task.executeAt ? new Date(task.executeAt) : null,
|
|
784
|
+
task.delayMs ?? null,
|
|
785
|
+
task.cronExpression ?? null,
|
|
786
|
+
task.timezone ?? null,
|
|
787
|
+
task.nextRunAt ? new Date(task.nextRunAt) : null,
|
|
788
|
+
task.lastRunAt ? new Date(task.lastRunAt) : null,
|
|
789
|
+
task.status,
|
|
790
|
+
task.runCount,
|
|
791
|
+
task.maxRuns ?? null,
|
|
792
|
+
task.retryCount,
|
|
793
|
+
task.maxRetries,
|
|
794
|
+
task.lastError ?? null,
|
|
795
|
+
new Date(task.createdAt),
|
|
796
|
+
new Date(task.updatedAt),
|
|
797
|
+
task.expiresAt ? new Date(task.expiresAt) : null,
|
|
798
|
+
task.metadata ? JSON.stringify(task.metadata) : null
|
|
799
|
+
]
|
|
800
|
+
);
|
|
801
|
+
}
|
|
802
|
+
/**
|
|
803
|
+
* Get task by ID
|
|
804
|
+
*/
|
|
805
|
+
async get(taskId) {
|
|
806
|
+
await this.ensureInitialized();
|
|
807
|
+
const result = await this.pool.query(
|
|
808
|
+
`SELECT * FROM lattice_scheduled_tasks WHERE task_id = $1`,
|
|
809
|
+
[taskId]
|
|
810
|
+
);
|
|
811
|
+
if (result.rows.length === 0) {
|
|
812
|
+
return null;
|
|
813
|
+
}
|
|
814
|
+
return this.mapRowToTask(result.rows[0]);
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Update task
|
|
818
|
+
*/
|
|
819
|
+
async update(taskId, updates) {
|
|
820
|
+
await this.ensureInitialized();
|
|
821
|
+
const setClauses = [];
|
|
822
|
+
const values = [];
|
|
823
|
+
let paramIndex = 1;
|
|
824
|
+
if (updates.taskType !== void 0) {
|
|
825
|
+
setClauses.push(`task_type = $${paramIndex++}`);
|
|
826
|
+
values.push(updates.taskType);
|
|
827
|
+
}
|
|
828
|
+
if (updates.payload !== void 0) {
|
|
829
|
+
setClauses.push(`payload = $${paramIndex++}`);
|
|
830
|
+
values.push(JSON.stringify(updates.payload));
|
|
831
|
+
}
|
|
832
|
+
if (updates.assistantId !== void 0) {
|
|
833
|
+
setClauses.push(`assistant_id = $${paramIndex++}`);
|
|
834
|
+
values.push(updates.assistantId);
|
|
835
|
+
}
|
|
836
|
+
if (updates.threadId !== void 0) {
|
|
837
|
+
setClauses.push(`thread_id = $${paramIndex++}`);
|
|
838
|
+
values.push(updates.threadId);
|
|
839
|
+
}
|
|
840
|
+
if (updates.executionType !== void 0) {
|
|
841
|
+
setClauses.push(`execution_type = $${paramIndex++}`);
|
|
842
|
+
values.push(updates.executionType);
|
|
843
|
+
}
|
|
844
|
+
if (updates.executeAt !== void 0) {
|
|
845
|
+
setClauses.push(`execute_at = $${paramIndex++}`);
|
|
846
|
+
values.push(updates.executeAt ? new Date(updates.executeAt) : null);
|
|
847
|
+
}
|
|
848
|
+
if (updates.delayMs !== void 0) {
|
|
849
|
+
setClauses.push(`delay_ms = $${paramIndex++}`);
|
|
850
|
+
values.push(updates.delayMs);
|
|
851
|
+
}
|
|
852
|
+
if (updates.cronExpression !== void 0) {
|
|
853
|
+
setClauses.push(`cron_expression = $${paramIndex++}`);
|
|
854
|
+
values.push(updates.cronExpression);
|
|
855
|
+
}
|
|
856
|
+
if (updates.timezone !== void 0) {
|
|
857
|
+
setClauses.push(`timezone = $${paramIndex++}`);
|
|
858
|
+
values.push(updates.timezone);
|
|
859
|
+
}
|
|
860
|
+
if (updates.nextRunAt !== void 0) {
|
|
861
|
+
setClauses.push(`next_run_at = $${paramIndex++}`);
|
|
862
|
+
values.push(updates.nextRunAt ? new Date(updates.nextRunAt) : null);
|
|
863
|
+
}
|
|
864
|
+
if (updates.lastRunAt !== void 0) {
|
|
865
|
+
setClauses.push(`last_run_at = $${paramIndex++}`);
|
|
866
|
+
values.push(updates.lastRunAt ? new Date(updates.lastRunAt) : null);
|
|
867
|
+
}
|
|
868
|
+
if (updates.status !== void 0) {
|
|
869
|
+
setClauses.push(`status = $${paramIndex++}`);
|
|
870
|
+
values.push(updates.status);
|
|
871
|
+
}
|
|
872
|
+
if (updates.runCount !== void 0) {
|
|
873
|
+
setClauses.push(`run_count = $${paramIndex++}`);
|
|
874
|
+
values.push(updates.runCount);
|
|
875
|
+
}
|
|
876
|
+
if (updates.maxRuns !== void 0) {
|
|
877
|
+
setClauses.push(`max_runs = $${paramIndex++}`);
|
|
878
|
+
values.push(updates.maxRuns);
|
|
879
|
+
}
|
|
880
|
+
if (updates.retryCount !== void 0) {
|
|
881
|
+
setClauses.push(`retry_count = $${paramIndex++}`);
|
|
882
|
+
values.push(updates.retryCount);
|
|
883
|
+
}
|
|
884
|
+
if (updates.maxRetries !== void 0) {
|
|
885
|
+
setClauses.push(`max_retries = $${paramIndex++}`);
|
|
886
|
+
values.push(updates.maxRetries);
|
|
887
|
+
}
|
|
888
|
+
if (updates.lastError !== void 0) {
|
|
889
|
+
setClauses.push(`last_error = $${paramIndex++}`);
|
|
890
|
+
values.push(updates.lastError);
|
|
891
|
+
}
|
|
892
|
+
if (updates.expiresAt !== void 0) {
|
|
893
|
+
setClauses.push(`expires_at = $${paramIndex++}`);
|
|
894
|
+
values.push(updates.expiresAt ? new Date(updates.expiresAt) : null);
|
|
895
|
+
}
|
|
896
|
+
if (updates.metadata !== void 0) {
|
|
897
|
+
setClauses.push(`metadata = $${paramIndex++}`);
|
|
898
|
+
values.push(updates.metadata ? JSON.stringify(updates.metadata) : null);
|
|
899
|
+
}
|
|
900
|
+
setClauses.push(`updated_at = $${paramIndex++}`);
|
|
901
|
+
values.push(/* @__PURE__ */ new Date());
|
|
902
|
+
values.push(taskId);
|
|
903
|
+
if (setClauses.length === 0) {
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
await this.pool.query(
|
|
907
|
+
`UPDATE lattice_scheduled_tasks SET ${setClauses.join(
|
|
908
|
+
", "
|
|
909
|
+
)} WHERE task_id = $${paramIndex}`,
|
|
910
|
+
values
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
/**
|
|
914
|
+
* Delete task
|
|
915
|
+
*/
|
|
916
|
+
async delete(taskId) {
|
|
917
|
+
await this.ensureInitialized();
|
|
918
|
+
await this.pool.query(
|
|
919
|
+
`DELETE FROM lattice_scheduled_tasks WHERE task_id = $1`,
|
|
920
|
+
[taskId]
|
|
921
|
+
);
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Get all active tasks (pending or paused)
|
|
925
|
+
*/
|
|
926
|
+
async getActiveTasks() {
|
|
927
|
+
await this.ensureInitialized();
|
|
928
|
+
const result = await this.pool.query(
|
|
929
|
+
`SELECT * FROM lattice_scheduled_tasks WHERE status IN ($1, $2) ORDER BY created_at ASC`,
|
|
930
|
+
[ScheduledTaskStatus.PENDING, ScheduledTaskStatus.PAUSED]
|
|
931
|
+
);
|
|
932
|
+
return result.rows.map((row) => this.mapRowToTask(row));
|
|
933
|
+
}
|
|
934
|
+
/**
|
|
935
|
+
* Get tasks by type
|
|
936
|
+
*/
|
|
937
|
+
async getTasksByType(taskType) {
|
|
938
|
+
await this.ensureInitialized();
|
|
939
|
+
const result = await this.pool.query(
|
|
940
|
+
`SELECT * FROM lattice_scheduled_tasks WHERE task_type = $1 ORDER BY created_at DESC`,
|
|
941
|
+
[taskType]
|
|
942
|
+
);
|
|
943
|
+
return result.rows.map((row) => this.mapRowToTask(row));
|
|
944
|
+
}
|
|
945
|
+
/**
|
|
946
|
+
* Get tasks by status
|
|
947
|
+
*/
|
|
948
|
+
async getTasksByStatus(status) {
|
|
949
|
+
await this.ensureInitialized();
|
|
950
|
+
const result = await this.pool.query(
|
|
951
|
+
`SELECT * FROM lattice_scheduled_tasks WHERE status = $1 ORDER BY created_at DESC`,
|
|
952
|
+
[status]
|
|
953
|
+
);
|
|
954
|
+
return result.rows.map((row) => this.mapRowToTask(row));
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* Get tasks by execution type
|
|
958
|
+
*/
|
|
959
|
+
async getTasksByExecutionType(executionType) {
|
|
960
|
+
await this.ensureInitialized();
|
|
961
|
+
const result = await this.pool.query(
|
|
962
|
+
`SELECT * FROM lattice_scheduled_tasks WHERE execution_type = $1 ORDER BY created_at DESC`,
|
|
963
|
+
[executionType]
|
|
964
|
+
);
|
|
965
|
+
return result.rows.map((row) => this.mapRowToTask(row));
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* Get tasks by assistant ID
|
|
969
|
+
*/
|
|
970
|
+
async getTasksByAssistantId(assistantId) {
|
|
971
|
+
await this.ensureInitialized();
|
|
972
|
+
const result = await this.pool.query(
|
|
973
|
+
`SELECT * FROM lattice_scheduled_tasks WHERE assistant_id = $1 ORDER BY created_at DESC`,
|
|
974
|
+
[assistantId]
|
|
975
|
+
);
|
|
976
|
+
return result.rows.map((row) => this.mapRowToTask(row));
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Get tasks by thread ID
|
|
980
|
+
*/
|
|
981
|
+
async getTasksByThreadId(threadId) {
|
|
982
|
+
await this.ensureInitialized();
|
|
983
|
+
const result = await this.pool.query(
|
|
984
|
+
`SELECT * FROM lattice_scheduled_tasks WHERE thread_id = $1 ORDER BY created_at DESC`,
|
|
985
|
+
[threadId]
|
|
986
|
+
);
|
|
987
|
+
return result.rows.map((row) => this.mapRowToTask(row));
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* Get all tasks with optional filters
|
|
991
|
+
*/
|
|
992
|
+
async getAllTasks(filters) {
|
|
993
|
+
await this.ensureInitialized();
|
|
994
|
+
const whereClauses = [];
|
|
995
|
+
const values = [];
|
|
996
|
+
let paramIndex = 1;
|
|
997
|
+
if (filters?.status !== void 0) {
|
|
998
|
+
whereClauses.push(`status = $${paramIndex++}`);
|
|
999
|
+
values.push(filters.status);
|
|
1000
|
+
}
|
|
1001
|
+
if (filters?.executionType !== void 0) {
|
|
1002
|
+
whereClauses.push(`execution_type = $${paramIndex++}`);
|
|
1003
|
+
values.push(filters.executionType);
|
|
1004
|
+
}
|
|
1005
|
+
if (filters?.taskType !== void 0) {
|
|
1006
|
+
whereClauses.push(`task_type = $${paramIndex++}`);
|
|
1007
|
+
values.push(filters.taskType);
|
|
1008
|
+
}
|
|
1009
|
+
if (filters?.assistantId !== void 0) {
|
|
1010
|
+
whereClauses.push(`assistant_id = $${paramIndex++}`);
|
|
1011
|
+
values.push(filters.assistantId);
|
|
1012
|
+
}
|
|
1013
|
+
if (filters?.threadId !== void 0) {
|
|
1014
|
+
whereClauses.push(`thread_id = $${paramIndex++}`);
|
|
1015
|
+
values.push(filters.threadId);
|
|
1016
|
+
}
|
|
1017
|
+
let query = `SELECT * FROM lattice_scheduled_tasks`;
|
|
1018
|
+
if (whereClauses.length > 0) {
|
|
1019
|
+
query += ` WHERE ${whereClauses.join(" AND ")}`;
|
|
1020
|
+
}
|
|
1021
|
+
query += ` ORDER BY created_at DESC`;
|
|
1022
|
+
if (filters?.limit !== void 0) {
|
|
1023
|
+
query += ` LIMIT $${paramIndex++}`;
|
|
1024
|
+
values.push(filters.limit);
|
|
1025
|
+
}
|
|
1026
|
+
if (filters?.offset !== void 0) {
|
|
1027
|
+
query += ` OFFSET $${paramIndex++}`;
|
|
1028
|
+
values.push(filters.offset);
|
|
1029
|
+
}
|
|
1030
|
+
const result = await this.pool.query(query, values);
|
|
1031
|
+
return result.rows.map((row) => this.mapRowToTask(row));
|
|
1032
|
+
}
|
|
1033
|
+
/**
|
|
1034
|
+
* Count tasks with optional filters
|
|
1035
|
+
*/
|
|
1036
|
+
async countTasks(filters) {
|
|
1037
|
+
await this.ensureInitialized();
|
|
1038
|
+
const whereClauses = [];
|
|
1039
|
+
const values = [];
|
|
1040
|
+
let paramIndex = 1;
|
|
1041
|
+
if (filters?.status !== void 0) {
|
|
1042
|
+
whereClauses.push(`status = $${paramIndex++}`);
|
|
1043
|
+
values.push(filters.status);
|
|
1044
|
+
}
|
|
1045
|
+
if (filters?.executionType !== void 0) {
|
|
1046
|
+
whereClauses.push(`execution_type = $${paramIndex++}`);
|
|
1047
|
+
values.push(filters.executionType);
|
|
1048
|
+
}
|
|
1049
|
+
if (filters?.taskType !== void 0) {
|
|
1050
|
+
whereClauses.push(`task_type = $${paramIndex++}`);
|
|
1051
|
+
values.push(filters.taskType);
|
|
1052
|
+
}
|
|
1053
|
+
if (filters?.assistantId !== void 0) {
|
|
1054
|
+
whereClauses.push(`assistant_id = $${paramIndex++}`);
|
|
1055
|
+
values.push(filters.assistantId);
|
|
1056
|
+
}
|
|
1057
|
+
if (filters?.threadId !== void 0) {
|
|
1058
|
+
whereClauses.push(`thread_id = $${paramIndex++}`);
|
|
1059
|
+
values.push(filters.threadId);
|
|
1060
|
+
}
|
|
1061
|
+
let query = `SELECT COUNT(*) as count FROM lattice_scheduled_tasks`;
|
|
1062
|
+
if (whereClauses.length > 0) {
|
|
1063
|
+
query += ` WHERE ${whereClauses.join(" AND ")}`;
|
|
1064
|
+
}
|
|
1065
|
+
const result = await this.pool.query(query, values);
|
|
1066
|
+
return parseInt(result.rows[0].count, 10);
|
|
1067
|
+
}
|
|
1068
|
+
/**
|
|
1069
|
+
* Delete completed/cancelled/failed tasks older than specified time
|
|
1070
|
+
*/
|
|
1071
|
+
async deleteOldTasks(olderThanMs) {
|
|
1072
|
+
await this.ensureInitialized();
|
|
1073
|
+
const cutoff = new Date(Date.now() - olderThanMs);
|
|
1074
|
+
const result = await this.pool.query(
|
|
1075
|
+
`
|
|
1076
|
+
DELETE FROM lattice_scheduled_tasks
|
|
1077
|
+
WHERE status IN ($1, $2, $3)
|
|
1078
|
+
AND updated_at < $4
|
|
1079
|
+
`,
|
|
1080
|
+
[
|
|
1081
|
+
ScheduledTaskStatus.COMPLETED,
|
|
1082
|
+
ScheduledTaskStatus.CANCELLED,
|
|
1083
|
+
ScheduledTaskStatus.FAILED,
|
|
1084
|
+
cutoff
|
|
1085
|
+
]
|
|
1086
|
+
);
|
|
1087
|
+
return result.rowCount ?? 0;
|
|
1088
|
+
}
|
|
1089
|
+
/**
|
|
1090
|
+
* Map database row to ScheduledTaskDefinition
|
|
1091
|
+
*/
|
|
1092
|
+
mapRowToTask(row) {
|
|
1093
|
+
return {
|
|
1094
|
+
taskId: row.task_id,
|
|
1095
|
+
taskType: row.task_type,
|
|
1096
|
+
payload: typeof row.payload === "string" ? JSON.parse(row.payload) : row.payload || {},
|
|
1097
|
+
assistantId: row.assistant_id ?? void 0,
|
|
1098
|
+
threadId: row.thread_id ?? void 0,
|
|
1099
|
+
executionType: row.execution_type,
|
|
1100
|
+
executeAt: row.execute_at ? row.execute_at.getTime() : void 0,
|
|
1101
|
+
delayMs: row.delay_ms ?? void 0,
|
|
1102
|
+
cronExpression: row.cron_expression ?? void 0,
|
|
1103
|
+
timezone: row.timezone ?? void 0,
|
|
1104
|
+
nextRunAt: row.next_run_at ? row.next_run_at.getTime() : void 0,
|
|
1105
|
+
lastRunAt: row.last_run_at ? row.last_run_at.getTime() : void 0,
|
|
1106
|
+
status: row.status,
|
|
1107
|
+
runCount: row.run_count,
|
|
1108
|
+
maxRuns: row.max_runs ?? void 0,
|
|
1109
|
+
retryCount: row.retry_count,
|
|
1110
|
+
maxRetries: row.max_retries,
|
|
1111
|
+
lastError: row.last_error ?? void 0,
|
|
1112
|
+
createdAt: row.created_at.getTime(),
|
|
1113
|
+
updatedAt: row.updated_at.getTime(),
|
|
1114
|
+
expiresAt: row.expires_at ? row.expires_at.getTime() : void 0,
|
|
1115
|
+
metadata: row.metadata === null ? void 0 : typeof row.metadata === "string" ? JSON.parse(row.metadata) : row.metadata
|
|
1116
|
+
};
|
|
1117
|
+
}
|
|
1118
|
+
};
|
|
576
1119
|
export {
|
|
577
1120
|
MigrationManager,
|
|
578
1121
|
PostgreSQLAssistantStore,
|
|
1122
|
+
PostgreSQLScheduleStorage,
|
|
579
1123
|
PostgreSQLThreadStore,
|
|
580
1124
|
createAssistantsTable,
|
|
1125
|
+
createScheduledTasksTable,
|
|
581
1126
|
createThreadsTable
|
|
582
1127
|
};
|
|
583
1128
|
//# sourceMappingURL=index.mjs.map
|