@sentry/junior-scheduler 0.74.1 → 0.76.0
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/db/schema.d.ts +223 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +624 -455
- package/dist/plugin.d.ts +2 -2
- package/dist/schedule-tools.d.ts +10 -9
- package/dist/store.d.ts +21 -3
- package/dist/types.d.ts +2 -5
- package/migrations/0001_scheduler.sql +35 -0
- package/package.json +6 -2
- package/src/db/schema.ts +53 -0
- package/src/index.ts +6 -2
- package/src/plugin.ts +89 -30
- package/src/schedule-tools.ts +68 -36
- package/src/store.ts +842 -47
- package/src/types.ts +2 -5
- package/dist/prompt.d.ts +0 -7
- package/src/prompt.ts +0 -90
package/dist/plugin.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/** Create Junior's built-in trusted scheduler plugin. */
|
|
2
|
-
export declare function createSchedulerPlugin(): import("@sentry/junior-plugin-api").
|
|
3
|
-
/** Register
|
|
2
|
+
export declare function createSchedulerPlugin(): import("@sentry/junior-plugin-api").PluginRegistration;
|
|
3
|
+
/** Register scheduler runtime hooks for scheduled Junior tasks. */
|
|
4
4
|
export declare const schedulerPlugin: typeof createSchedulerPlugin;
|
package/dist/schedule-tools.d.ts
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type PluginCredentialSubject, type PluginToolDefinition, type SlackRequester, type SlackSource } from "@sentry/junior-plugin-api";
|
|
2
|
+
import { type SchedulerStore } from "./store";
|
|
2
3
|
export interface SchedulerToolContext {
|
|
3
|
-
credentialSubject?:
|
|
4
|
+
credentialSubject?: PluginCredentialSubject;
|
|
4
5
|
requester?: SlackRequester;
|
|
5
|
-
source?:
|
|
6
|
-
|
|
6
|
+
source?: SlackSource;
|
|
7
|
+
store: SchedulerStore;
|
|
7
8
|
userText?: string;
|
|
8
9
|
}
|
|
9
10
|
/** Create a tool that stores a scheduled task for the active Slack context. */
|
|
10
|
-
export declare function createSlackScheduleCreateTaskTool(context: SchedulerToolContext):
|
|
11
|
+
export declare function createSlackScheduleCreateTaskTool(context: SchedulerToolContext): PluginToolDefinition<any>;
|
|
11
12
|
/** Create a tool that lists scheduled tasks for the active Slack conversation. */
|
|
12
|
-
export declare function createSlackScheduleListTasksTool(context: SchedulerToolContext):
|
|
13
|
+
export declare function createSlackScheduleListTasksTool(context: SchedulerToolContext): PluginToolDefinition<any>;
|
|
13
14
|
/** Create a tool that edits a scheduled task in the active Slack conversation. */
|
|
14
|
-
export declare function createSlackScheduleUpdateTaskTool(context: SchedulerToolContext):
|
|
15
|
+
export declare function createSlackScheduleUpdateTaskTool(context: SchedulerToolContext): PluginToolDefinition<any>;
|
|
15
16
|
/** Create a tool that removes a scheduled task from the active Slack conversation. */
|
|
16
|
-
export declare function createSlackScheduleDeleteTaskTool(context: SchedulerToolContext):
|
|
17
|
+
export declare function createSlackScheduleDeleteTaskTool(context: SchedulerToolContext): PluginToolDefinition<any>;
|
|
17
18
|
/** Create a tool that marks an existing scheduled task due immediately. */
|
|
18
|
-
export declare function createSlackScheduleRunTaskNowTool(context: SchedulerToolContext):
|
|
19
|
+
export declare function createSlackScheduleRunTaskNowTool(context: SchedulerToolContext): PluginToolDefinition<any>;
|
package/dist/store.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type PluginReadState, type PluginState } from "@sentry/junior-plugin-api";
|
|
2
|
+
import type { PgDatabase } from "drizzle-orm/pg-core";
|
|
3
|
+
import type { PgQueryResultHKT } from "drizzle-orm/pg-core/session";
|
|
4
|
+
import * as schedulerSqlSchema from "./db/schema";
|
|
2
5
|
import type { ScheduledRun, ScheduledTask } from "./types";
|
|
6
|
+
export type SchedulerDb = PgDatabase<PgQueryResultHKT, typeof schedulerSqlSchema>;
|
|
3
7
|
export interface SchedulerStore {
|
|
4
8
|
claimDueRun(args: {
|
|
5
9
|
nowMs: number;
|
|
@@ -51,6 +55,20 @@ export interface SchedulerOperationalStore {
|
|
|
51
55
|
listTasks(): Promise<ScheduledTask[]>;
|
|
52
56
|
}
|
|
53
57
|
/** Create a scheduler store backed by this plugin's durable state namespace. */
|
|
54
|
-
export declare function createSchedulerStore(state:
|
|
58
|
+
export declare function createSchedulerStore(state: PluginState): SchedulerStore;
|
|
55
59
|
/** Create a read-only scheduler store for operational reporting. */
|
|
56
|
-
export declare function createSchedulerOperationalStore(state:
|
|
60
|
+
export declare function createSchedulerOperationalStore(state: PluginReadState): SchedulerOperationalStore;
|
|
61
|
+
/** Create a scheduler store backed by the plugin SQL database. */
|
|
62
|
+
export declare function createSchedulerSqlStore(db: SchedulerDb): SchedulerStore;
|
|
63
|
+
/** Create a read-only scheduler operational store backed by SQL. */
|
|
64
|
+
export declare function createSchedulerOperationalSqlStore(db: SchedulerDb): SchedulerOperationalStore;
|
|
65
|
+
/** Copy retained scheduler plugin-state records into the scheduler SQL tables. */
|
|
66
|
+
export declare function migrateSchedulerStateToSql(args: {
|
|
67
|
+
db: SchedulerDb;
|
|
68
|
+
state: PluginState;
|
|
69
|
+
}): Promise<{
|
|
70
|
+
existing: number;
|
|
71
|
+
migrated: number;
|
|
72
|
+
missing: number;
|
|
73
|
+
scanned: number;
|
|
74
|
+
}>;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PluginCredentialSubject, SlackDestination } from "@sentry/junior-plugin-api";
|
|
2
2
|
export type ScheduledTaskStatus = "active" | "paused" | "blocked" | "deleted";
|
|
3
3
|
export type ScheduledRunStatus = "pending" | "running" | "completed" | "failed" | "blocked" | "skipped";
|
|
4
4
|
export interface ScheduledTaskPrincipal {
|
|
@@ -46,7 +46,7 @@ export interface ScheduledTask {
|
|
|
46
46
|
createdAtMs: number;
|
|
47
47
|
createdBy: ScheduledTaskPrincipal;
|
|
48
48
|
conversationAccess?: ScheduledTaskConversationAccess;
|
|
49
|
-
credentialSubject?:
|
|
49
|
+
credentialSubject?: PluginCredentialSubject;
|
|
50
50
|
destination: SlackDestination;
|
|
51
51
|
executionActor?: ScheduledTaskExecutionActor;
|
|
52
52
|
lastRunAtMs?: number;
|
|
@@ -58,7 +58,6 @@ export interface ScheduledTask {
|
|
|
58
58
|
statusReason?: string;
|
|
59
59
|
task: ScheduledTaskSpec;
|
|
60
60
|
updatedAtMs: number;
|
|
61
|
-
version: number;
|
|
62
61
|
}
|
|
63
62
|
export interface ScheduledRun {
|
|
64
63
|
id: string;
|
|
@@ -67,11 +66,9 @@ export interface ScheduledRun {
|
|
|
67
66
|
completedAtMs?: number;
|
|
68
67
|
dispatchId?: string;
|
|
69
68
|
errorMessage?: string;
|
|
70
|
-
idempotencyKey: string;
|
|
71
69
|
resultMessageTs?: string;
|
|
72
70
|
scheduledForMs: number;
|
|
73
71
|
startedAtMs?: number;
|
|
74
72
|
status: ScheduledRunStatus;
|
|
75
73
|
taskId: string;
|
|
76
|
-
taskVersion: number;
|
|
77
74
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS junior_scheduler_tasks (
|
|
2
|
+
id TEXT PRIMARY KEY,
|
|
3
|
+
team_id TEXT NOT NULL,
|
|
4
|
+
status TEXT NOT NULL,
|
|
5
|
+
next_run_at_ms BIGINT,
|
|
6
|
+
run_now_at_ms BIGINT,
|
|
7
|
+
created_at_ms BIGINT NOT NULL,
|
|
8
|
+
record JSONB NOT NULL
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
CREATE INDEX IF NOT EXISTS junior_scheduler_tasks_team_status_idx
|
|
12
|
+
ON junior_scheduler_tasks (team_id, created_at_ms, id)
|
|
13
|
+
WHERE status <> 'deleted';
|
|
14
|
+
|
|
15
|
+
CREATE INDEX IF NOT EXISTS junior_scheduler_tasks_run_now_due_idx
|
|
16
|
+
ON junior_scheduler_tasks (run_now_at_ms, created_at_ms, id)
|
|
17
|
+
WHERE status = 'active' AND run_now_at_ms IS NOT NULL;
|
|
18
|
+
|
|
19
|
+
CREATE INDEX IF NOT EXISTS junior_scheduler_tasks_next_run_due_idx
|
|
20
|
+
ON junior_scheduler_tasks (next_run_at_ms, created_at_ms, id)
|
|
21
|
+
WHERE status = 'active' AND next_run_at_ms IS NOT NULL;
|
|
22
|
+
|
|
23
|
+
CREATE TABLE IF NOT EXISTS junior_scheduler_runs (
|
|
24
|
+
id TEXT PRIMARY KEY,
|
|
25
|
+
task_id TEXT NOT NULL,
|
|
26
|
+
status TEXT NOT NULL,
|
|
27
|
+
scheduled_for_ms BIGINT NOT NULL,
|
|
28
|
+
record JSONB NOT NULL
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
CREATE INDEX IF NOT EXISTS junior_scheduler_runs_task_status_idx
|
|
32
|
+
ON junior_scheduler_runs (task_id, status, scheduled_for_ms);
|
|
33
|
+
|
|
34
|
+
CREATE INDEX IF NOT EXISTS junior_scheduler_runs_status_idx
|
|
35
|
+
ON junior_scheduler_runs (status, scheduled_for_ms);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior-scheduler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.76.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -19,11 +19,14 @@
|
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
21
|
"dist",
|
|
22
|
+
"migrations",
|
|
22
23
|
"src"
|
|
23
24
|
],
|
|
24
25
|
"dependencies": {
|
|
25
26
|
"@sinclair/typebox": "^0.34.49",
|
|
26
|
-
"
|
|
27
|
+
"drizzle-orm": "^0.45.2",
|
|
28
|
+
"zod": "^4.4.3",
|
|
29
|
+
"@sentry/junior-plugin-api": "0.76.0"
|
|
27
30
|
},
|
|
28
31
|
"devDependencies": {
|
|
29
32
|
"@types/node": "^25.9.1",
|
|
@@ -32,6 +35,7 @@
|
|
|
32
35
|
},
|
|
33
36
|
"scripts": {
|
|
34
37
|
"build": "tsup && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
38
|
+
"db:generate": "pnpm dlx drizzle-kit@0.31.10 generate --config drizzle.config.ts",
|
|
35
39
|
"typecheck": "tsc --noEmit"
|
|
36
40
|
}
|
|
37
41
|
}
|
package/src/db/schema.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { bigint, index, jsonb, pgTable, text } from "drizzle-orm/pg-core";
|
|
3
|
+
import type { ScheduledRun, ScheduledTask } from "../types";
|
|
4
|
+
|
|
5
|
+
export const juniorSchedulerTasks = pgTable(
|
|
6
|
+
"junior_scheduler_tasks",
|
|
7
|
+
{
|
|
8
|
+
id: text("id").primaryKey(),
|
|
9
|
+
teamId: text("team_id").notNull(),
|
|
10
|
+
status: text("status").notNull(),
|
|
11
|
+
nextRunAtMs: bigint("next_run_at_ms", { mode: "number" }),
|
|
12
|
+
runNowAtMs: bigint("run_now_at_ms", { mode: "number" }),
|
|
13
|
+
createdAtMs: bigint("created_at_ms", { mode: "number" }).notNull(),
|
|
14
|
+
record: jsonb("record").$type<ScheduledTask>().notNull(),
|
|
15
|
+
},
|
|
16
|
+
(table) => [
|
|
17
|
+
index("junior_scheduler_tasks_team_status_idx")
|
|
18
|
+
.on(table.teamId, table.createdAtMs, table.id)
|
|
19
|
+
.where(sql`${table.status} <> 'deleted'`),
|
|
20
|
+
index("junior_scheduler_tasks_run_now_due_idx")
|
|
21
|
+
.on(table.runNowAtMs, table.createdAtMs, table.id)
|
|
22
|
+
.where(
|
|
23
|
+
sql`${table.status} = 'active' AND ${table.runNowAtMs} IS NOT NULL`,
|
|
24
|
+
),
|
|
25
|
+
index("junior_scheduler_tasks_next_run_due_idx")
|
|
26
|
+
.on(table.nextRunAtMs, table.createdAtMs, table.id)
|
|
27
|
+
.where(
|
|
28
|
+
sql`${table.status} = 'active' AND ${table.nextRunAtMs} IS NOT NULL`,
|
|
29
|
+
),
|
|
30
|
+
],
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export const juniorSchedulerRuns = pgTable(
|
|
34
|
+
"junior_scheduler_runs",
|
|
35
|
+
{
|
|
36
|
+
id: text("id").primaryKey(),
|
|
37
|
+
taskId: text("task_id").notNull(),
|
|
38
|
+
status: text("status").notNull(),
|
|
39
|
+
scheduledForMs: bigint("scheduled_for_ms", { mode: "number" }).notNull(),
|
|
40
|
+
record: jsonb("record").$type<ScheduledRun>().notNull(),
|
|
41
|
+
},
|
|
42
|
+
(table) => [
|
|
43
|
+
index("junior_scheduler_runs_task_status_idx").on(
|
|
44
|
+
table.taskId,
|
|
45
|
+
table.status,
|
|
46
|
+
table.scheduledForMs,
|
|
47
|
+
),
|
|
48
|
+
index("junior_scheduler_runs_status_idx").on(
|
|
49
|
+
table.status,
|
|
50
|
+
table.scheduledForMs,
|
|
51
|
+
),
|
|
52
|
+
],
|
|
53
|
+
);
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export { createSchedulerPlugin, schedulerPlugin } from "./plugin";
|
|
2
|
-
export { buildScheduledTaskRunPrompt } from "./prompt";
|
|
3
2
|
export {
|
|
4
3
|
createSlackScheduleCreateTaskTool,
|
|
5
4
|
createSlackScheduleDeleteTaskTool,
|
|
@@ -8,7 +7,12 @@ export {
|
|
|
8
7
|
createSlackScheduleUpdateTaskTool,
|
|
9
8
|
type SchedulerToolContext,
|
|
10
9
|
} from "./schedule-tools";
|
|
11
|
-
export {
|
|
10
|
+
export {
|
|
11
|
+
createSchedulerOperationalSqlStore,
|
|
12
|
+
createSchedulerSqlStore,
|
|
13
|
+
migrateSchedulerStateToSql,
|
|
14
|
+
type SchedulerDb,
|
|
15
|
+
} from "./store";
|
|
12
16
|
export type {
|
|
13
17
|
ScheduledCalendarFrequency,
|
|
14
18
|
ScheduledLocalTime,
|
package/src/plugin.ts
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
|
+
createSlackSource,
|
|
2
3
|
defineJuniorPlugin,
|
|
3
4
|
type Dispatch,
|
|
4
|
-
type
|
|
5
|
+
type PluginToolDefinition,
|
|
5
6
|
type PluginOperationalReportContent,
|
|
7
|
+
type PluginReadState,
|
|
8
|
+
type PluginState,
|
|
6
9
|
type SlackDestination,
|
|
10
|
+
type Source,
|
|
7
11
|
type ToolRegistrationHookContext,
|
|
8
12
|
} from "@sentry/junior-plugin-api";
|
|
9
|
-
import { buildScheduledTaskRunPrompt } from "./prompt";
|
|
10
13
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
createSchedulerOperationalSqlStore,
|
|
15
|
+
createSchedulerSqlStore,
|
|
16
|
+
migrateSchedulerStateToSql,
|
|
17
|
+
type SchedulerDb,
|
|
13
18
|
type SchedulerOperationalStore,
|
|
14
19
|
type SchedulerStore,
|
|
15
20
|
} from "./store";
|
|
16
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
sanitizeScheduledTaskPrincipal,
|
|
23
|
+
scheduledTaskPrincipalLabel,
|
|
24
|
+
} from "./identity";
|
|
17
25
|
import type {
|
|
18
26
|
ScheduledRun,
|
|
19
27
|
ScheduledTask,
|
|
@@ -31,6 +39,60 @@ import {
|
|
|
31
39
|
const SCHEDULER_HEARTBEAT_LIMIT = 10;
|
|
32
40
|
const DASHBOARD_TABLE_LIMIT = 5;
|
|
33
41
|
|
|
42
|
+
function singleLineMetadataValue(value: string): string {
|
|
43
|
+
return value
|
|
44
|
+
.replace(/[\r\n]+/g, " ")
|
|
45
|
+
.replace(/\s+/g, " ")
|
|
46
|
+
.trim();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function buildScheduledTaskDispatchMetadata(args: {
|
|
50
|
+
nowMs: number;
|
|
51
|
+
run: ScheduledRun;
|
|
52
|
+
task: ScheduledTask;
|
|
53
|
+
}): Record<string, string> {
|
|
54
|
+
const { run, task } = args;
|
|
55
|
+
const creator = sanitizeScheduledTaskPrincipal(task.createdBy);
|
|
56
|
+
if (!task.task.text?.trim()) {
|
|
57
|
+
throw new Error("Scheduled task text is required");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
creatorSlackUserId: creator.slackUserId,
|
|
62
|
+
runId: run.id,
|
|
63
|
+
schedule: singleLineMetadataValue(task.schedule.description),
|
|
64
|
+
scheduleKind: task.schedule.kind,
|
|
65
|
+
scheduledFor: new Date(run.scheduledForMs).toISOString(),
|
|
66
|
+
runningAt: new Date(args.nowMs).toISOString(),
|
|
67
|
+
taskId: task.id,
|
|
68
|
+
timezone: task.schedule.timezone,
|
|
69
|
+
...(task.schedule.recurrence
|
|
70
|
+
? {
|
|
71
|
+
recurrenceFrequency: task.schedule.recurrence.frequency,
|
|
72
|
+
recurrenceInterval: String(task.schedule.recurrence.interval),
|
|
73
|
+
recurrenceStartDate: task.schedule.recurrence.startDate,
|
|
74
|
+
}
|
|
75
|
+
: {}),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function scheduledTaskDispatchSource(task: ScheduledTask): Source {
|
|
80
|
+
return createSlackSource({
|
|
81
|
+
teamId: task.destination.teamId,
|
|
82
|
+
channelId: task.destination.channelId,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function schedulerStore(ctx: { db: unknown }): SchedulerStore {
|
|
87
|
+
return createSchedulerSqlStore(ctx.db as SchedulerDb);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function schedulerOperationalStore(ctx: {
|
|
91
|
+
db: unknown;
|
|
92
|
+
}): SchedulerOperationalStore {
|
|
93
|
+
return createSchedulerOperationalSqlStore(ctx.db as SchedulerDb);
|
|
94
|
+
}
|
|
95
|
+
|
|
34
96
|
function shouldSkipRun(
|
|
35
97
|
task: ScheduledTask,
|
|
36
98
|
run: ScheduledRun,
|
|
@@ -55,16 +117,9 @@ function createSchedulerToolContext(
|
|
|
55
117
|
): SchedulerToolContext {
|
|
56
118
|
return {
|
|
57
119
|
credentialSubject: ctx.slack?.credentialSubject,
|
|
58
|
-
source:
|
|
59
|
-
ctx.source.platform === "slack"
|
|
60
|
-
? {
|
|
61
|
-
platform: "slack",
|
|
62
|
-
teamId: ctx.source.teamId,
|
|
63
|
-
channelId: ctx.source.channelId,
|
|
64
|
-
}
|
|
65
|
-
: undefined,
|
|
120
|
+
source: ctx.source.platform === "slack" ? ctx.source : undefined,
|
|
66
121
|
requester: ctx.requester?.platform === "slack" ? ctx.requester : undefined,
|
|
67
|
-
|
|
122
|
+
store: schedulerStore(ctx),
|
|
68
123
|
userText: ctx.userText,
|
|
69
124
|
};
|
|
70
125
|
}
|
|
@@ -73,7 +128,7 @@ async function applyDispatchResult(args: {
|
|
|
73
128
|
dispatch: Dispatch;
|
|
74
129
|
nowMs: number;
|
|
75
130
|
run: ScheduledRun;
|
|
76
|
-
store:
|
|
131
|
+
store: SchedulerStore;
|
|
77
132
|
}): Promise<boolean> {
|
|
78
133
|
if (args.dispatch.status === "completed") {
|
|
79
134
|
const completed = await args.store.markRunCompleted({
|
|
@@ -367,14 +422,14 @@ export function createSchedulerPlugin() {
|
|
|
367
422
|
displayName: "Scheduler",
|
|
368
423
|
description: "Scheduled Junior task management and heartbeat dispatch",
|
|
369
424
|
},
|
|
370
|
-
|
|
425
|
+
packageName: "@sentry/junior-scheduler",
|
|
371
426
|
hooks: {
|
|
372
427
|
tools(ctx) {
|
|
373
428
|
if (
|
|
374
429
|
ctx.source.platform !== "slack" ||
|
|
375
430
|
ctx.requester?.platform !== "slack"
|
|
376
431
|
) {
|
|
377
|
-
return {} as Record<string,
|
|
432
|
+
return {} as Record<string, PluginToolDefinition<any>>;
|
|
378
433
|
}
|
|
379
434
|
const context = createSchedulerToolContext(ctx);
|
|
380
435
|
return {
|
|
@@ -383,10 +438,10 @@ export function createSchedulerPlugin() {
|
|
|
383
438
|
slackScheduleUpdateTask: createSlackScheduleUpdateTaskTool(context),
|
|
384
439
|
slackScheduleDeleteTask: createSlackScheduleDeleteTaskTool(context),
|
|
385
440
|
slackScheduleRunTaskNow: createSlackScheduleRunTaskNowTool(context),
|
|
386
|
-
} satisfies Record<string,
|
|
441
|
+
} satisfies Record<string, PluginToolDefinition<any>>;
|
|
387
442
|
},
|
|
388
443
|
async heartbeat(ctx) {
|
|
389
|
-
const store =
|
|
444
|
+
const store = schedulerStore(ctx);
|
|
390
445
|
let processedCount = 0;
|
|
391
446
|
let dispatchCount = 0;
|
|
392
447
|
for (const run of await store.listIncompleteRuns()) {
|
|
@@ -443,9 +498,9 @@ export function createSchedulerPlugin() {
|
|
|
443
498
|
continue;
|
|
444
499
|
}
|
|
445
500
|
|
|
446
|
-
let
|
|
501
|
+
let dispatchMetadata: Record<string, string>;
|
|
447
502
|
try {
|
|
448
|
-
|
|
503
|
+
dispatchMetadata = buildScheduledTaskDispatchMetadata({
|
|
449
504
|
nowMs: ctx.nowMs,
|
|
450
505
|
run,
|
|
451
506
|
task,
|
|
@@ -453,8 +508,8 @@ export function createSchedulerPlugin() {
|
|
|
453
508
|
} catch (error) {
|
|
454
509
|
const errorMessage =
|
|
455
510
|
error instanceof Error
|
|
456
|
-
? `Scheduled task
|
|
457
|
-
: "Scheduled task
|
|
511
|
+
? `Scheduled task dispatch metadata could not be built: ${error.message}`
|
|
512
|
+
: "Scheduled task dispatch metadata could not be built.";
|
|
458
513
|
await blockClaimedRun({
|
|
459
514
|
errorMessage,
|
|
460
515
|
nowMs: ctx.nowMs,
|
|
@@ -471,11 +526,9 @@ export function createSchedulerPlugin() {
|
|
|
471
526
|
? { credentialSubject: task.credentialSubject }
|
|
472
527
|
: {}),
|
|
473
528
|
destination: task.destination,
|
|
474
|
-
input:
|
|
475
|
-
metadata:
|
|
476
|
-
|
|
477
|
-
taskId: task.id,
|
|
478
|
-
},
|
|
529
|
+
input: task.task.text,
|
|
530
|
+
metadata: dispatchMetadata,
|
|
531
|
+
source: scheduledTaskDispatchSource(task),
|
|
479
532
|
});
|
|
480
533
|
} catch (error) {
|
|
481
534
|
const errorMessage =
|
|
@@ -504,12 +557,18 @@ export function createSchedulerPlugin() {
|
|
|
504
557
|
async operationalReport(ctx) {
|
|
505
558
|
return buildSchedulerOperationalReport({
|
|
506
559
|
nowMs: ctx.nowMs,
|
|
507
|
-
store:
|
|
560
|
+
store: schedulerOperationalStore(ctx),
|
|
561
|
+
});
|
|
562
|
+
},
|
|
563
|
+
async migrateStorage(ctx) {
|
|
564
|
+
return await migrateSchedulerStateToSql({
|
|
565
|
+
db: ctx.db as SchedulerDb,
|
|
566
|
+
state: ctx.state,
|
|
508
567
|
});
|
|
509
568
|
},
|
|
510
569
|
},
|
|
511
570
|
});
|
|
512
571
|
}
|
|
513
572
|
|
|
514
|
-
/** Register
|
|
573
|
+
/** Register scheduler runtime hooks for scheduled Junior tasks. */
|
|
515
574
|
export const schedulerPlugin = createSchedulerPlugin;
|