@polpo-ai/server 0.15.45 → 0.15.47

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 (34) hide show
  1. package/dist/deps.d.ts +5 -3
  2. package/dist/deps.d.ts.map +1 -1
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +2 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/routes/schedules.d.ts +2 -5
  8. package/dist/routes/schedules.d.ts.map +1 -1
  9. package/dist/routes/schedules.js +625 -121
  10. package/dist/routes/schedules.js.map +1 -1
  11. package/dist/routes/schedules.test.d.ts +2 -0
  12. package/dist/routes/schedules.test.d.ts.map +1 -0
  13. package/dist/routes/schedules.test.js +328 -0
  14. package/dist/routes/schedules.test.js.map +1 -0
  15. package/dist/schemas.d.ts +10 -10
  16. package/dist/schemas.js +4 -4
  17. package/dist/schemas.js.map +1 -1
  18. package/dist/services/schedules-migration.d.ts +44 -0
  19. package/dist/services/schedules-migration.d.ts.map +1 -0
  20. package/dist/services/schedules-migration.js +308 -0
  21. package/dist/services/schedules-migration.js.map +1 -0
  22. package/dist/services/schedules-migration.test.d.ts +2 -0
  23. package/dist/services/schedules-migration.test.d.ts.map +1 -0
  24. package/dist/services/schedules-migration.test.js +471 -0
  25. package/dist/services/schedules-migration.test.js.map +1 -0
  26. package/dist/services/schedules.d.ts +42 -0
  27. package/dist/services/schedules.d.ts.map +1 -0
  28. package/dist/services/schedules.js +183 -0
  29. package/dist/services/schedules.js.map +1 -0
  30. package/dist/services/schedules.test.d.ts +2 -0
  31. package/dist/services/schedules.test.d.ts.map +1 -0
  32. package/dist/services/schedules.test.js +319 -0
  33. package/dist/services/schedules.test.js.map +1 -0
  34. package/package.json +6 -6
@@ -0,0 +1,183 @@
1
+ import { SCHEDULE_LIMITS, ScheduleNotFoundError, nextScheduleOccurrence, normalizeCreateScheduleInput, normalizeUpdateScheduleInput, } from "@polpo-ai/core/scheduling";
2
+ export class ScheduleServiceError extends Error {
3
+ code;
4
+ retryable;
5
+ constructor(code, message, retryable, options) {
6
+ super(message, options);
7
+ this.code = code;
8
+ this.retryable = retryable;
9
+ this.name = "ScheduleServiceError";
10
+ }
11
+ }
12
+ /**
13
+ * Host-neutral application service for schedule lifecycle and durable runs.
14
+ *
15
+ * Provider registration failures are persisted on the Schedule instead of
16
+ * rolling back local truth. Reconciliation can then repair external state.
17
+ */
18
+ export class ScheduleService {
19
+ store;
20
+ driver;
21
+ nowProvider;
22
+ onRunCreated;
23
+ constructor(options) {
24
+ if (!options?.store)
25
+ throw new Error("Schedule service requires a store");
26
+ if (!options.driver)
27
+ throw new Error("Schedule service requires a driver");
28
+ this.store = options.store;
29
+ this.driver = options.driver;
30
+ this.nowProvider = options.now ?? (() => new Date());
31
+ this.onRunCreated = options.onRunCreated;
32
+ }
33
+ list(filter) {
34
+ return this.store.list(filter);
35
+ }
36
+ async get(id) {
37
+ const normalizedId = identifier(id, "Schedule id");
38
+ const schedule = await this.store.get(normalizedId);
39
+ if (!schedule)
40
+ throw new ScheduleNotFoundError("Schedule", normalizedId);
41
+ return schedule;
42
+ }
43
+ async create(input) {
44
+ const now = this.now();
45
+ const normalized = normalizeRequest(() => normalizeCreateScheduleInput(input, { now }));
46
+ let schedule = await this.store.create(normalized);
47
+ const next = nextScheduleOccurrence(schedule, now);
48
+ schedule = await this.store.updateOperationalState(schedule.id, { nextOccurrenceAt: next?.occurrenceAt ?? null }, { expectedRevision: schedule.revision });
49
+ const registration = await this.registerDriver("register", schedule);
50
+ return this.store.updateOperationalState(schedule.id, { driver: registration }, { expectedRevision: schedule.revision });
51
+ }
52
+ async update(id, patch, options = {}) {
53
+ const normalizedId = identifier(id, "Schedule id");
54
+ const previous = await this.get(normalizedId);
55
+ const now = this.now();
56
+ const normalizedPatch = normalizeRequest(() => normalizeUpdateScheduleInput(patch, { now }));
57
+ let schedule = await this.store.update(normalizedId, normalizedPatch, options);
58
+ if (normalizedPatch.timing !== undefined) {
59
+ const next = nextScheduleOccurrence(schedule, now);
60
+ schedule = await this.store.updateOperationalState(schedule.id, { nextOccurrenceAt: next?.occurrenceAt ?? null }, { expectedRevision: schedule.revision });
61
+ }
62
+ if (normalizedPatch.status !== undefined
63
+ && normalizedPatch.status !== previous.status) {
64
+ return this.applyDriverLifecycle(normalizedPatch.status === "active" ? "resume" : "pause", schedule);
65
+ }
66
+ const registration = await this.registerDriver("update", schedule);
67
+ return this.store.updateOperationalState(schedule.id, { driver: registration }, { expectedRevision: schedule.revision });
68
+ }
69
+ async pause(id, options = {}) {
70
+ const schedule = await this.store.update(identifier(id, "Schedule id"), { status: "paused" }, options);
71
+ return this.applyDriverLifecycle("pause", schedule);
72
+ }
73
+ async resume(id, options = {}) {
74
+ const schedule = await this.store.update(identifier(id, "Schedule id"), { status: "active" }, options);
75
+ return this.applyDriverLifecycle("resume", schedule);
76
+ }
77
+ async delete(id, options = {}) {
78
+ const normalizedId = identifier(id, "Schedule id");
79
+ await this.get(normalizedId);
80
+ await this.store.markDeleted(normalizedId, options);
81
+ const deleted = await this.get(normalizedId);
82
+ return this.applyDriverLifecycle("delete", deleted);
83
+ }
84
+ async listRuns(scheduleId, filter = {}) {
85
+ const schedule = await this.get(scheduleId);
86
+ return this.store.listRuns({ ...filter, scheduleId: schedule.id });
87
+ }
88
+ async trigger(scheduleId, input) {
89
+ const schedule = await this.get(scheduleId);
90
+ if (schedule.status !== "active") {
91
+ throw new ScheduleServiceError("INVALID_STATE", `Schedule "${schedule.id}" must be active to trigger a run`, false);
92
+ }
93
+ const callerKey = identifier(input?.idempotencyKey, "Manual schedule idempotency key");
94
+ const now = this.now().toISOString();
95
+ const identity = `manual:${schedule.id}:${callerKey}`;
96
+ const run = await this.store.createRun({
97
+ scheduleId: schedule.id,
98
+ occurrenceAt: now,
99
+ triggerId: identity,
100
+ idempotencyKey: identity,
101
+ });
102
+ try {
103
+ await this.onRunCreated?.(run);
104
+ }
105
+ catch {
106
+ // The durable pending run remains discoverable by polling/reconciliation.
107
+ }
108
+ return run;
109
+ }
110
+ async registerDriver(operation, schedule) {
111
+ try {
112
+ return await this.driver[operation](schedule);
113
+ }
114
+ catch (error) {
115
+ return failedRegistration(operation, schedule, this.now(), error);
116
+ }
117
+ }
118
+ async applyDriverLifecycle(operation, schedule) {
119
+ let registration;
120
+ try {
121
+ const lifecycleRegistration = await this.driver[operation](schedule);
122
+ registration = lifecycleRegistration ?? {
123
+ kind: schedule.driver?.kind ?? "unknown",
124
+ status: schedule.driver?.status === "not_required"
125
+ ? "not_required"
126
+ : "registered",
127
+ ...(schedule.driver?.providerId === undefined
128
+ ? {}
129
+ : { providerId: schedule.driver.providerId }),
130
+ ...(schedule.driver?.metadata === undefined
131
+ ? {}
132
+ : { metadata: schedule.driver.metadata }),
133
+ updatedAt: this.now().toISOString(),
134
+ };
135
+ }
136
+ catch (error) {
137
+ registration = failedRegistration(operation, schedule, this.now(), error);
138
+ }
139
+ return this.store.updateOperationalState(schedule.id, { driver: registration }, { expectedRevision: schedule.revision });
140
+ }
141
+ now() {
142
+ const now = new Date(this.nowProvider());
143
+ if (!Number.isFinite(now.getTime())) {
144
+ throw new ScheduleServiceError("INVALID_STATE", "Schedule service clock returned an invalid date", false);
145
+ }
146
+ return now;
147
+ }
148
+ }
149
+ function failedRegistration(operation, schedule, now, error) {
150
+ void error;
151
+ return {
152
+ kind: schedule.driver?.kind ?? "unknown",
153
+ status: "failed",
154
+ ...(schedule.driver?.providerId === undefined
155
+ ? {}
156
+ : { providerId: schedule.driver.providerId }),
157
+ error: {
158
+ code: `DRIVER_${operation.toUpperCase()}_FAILED`,
159
+ message: `Schedule driver ${operation} operation failed`,
160
+ retryable: true,
161
+ },
162
+ updatedAt: now.toISOString(),
163
+ };
164
+ }
165
+ function normalizeRequest(operation) {
166
+ try {
167
+ return operation();
168
+ }
169
+ catch (cause) {
170
+ throw new ScheduleServiceError("INVALID_REQUEST", cause instanceof Error ? cause.message : "Invalid schedule request", false, { cause });
171
+ }
172
+ }
173
+ function identifier(value, label) {
174
+ if (typeof value !== "string" || value.trim().length === 0) {
175
+ throw new ScheduleServiceError("INVALID_REQUEST", `${label} must be a non-empty string`, false);
176
+ }
177
+ const normalized = value.trim();
178
+ if (normalized.length > SCHEDULE_LIMITS.idLength) {
179
+ throw new ScheduleServiceError("INVALID_REQUEST", `${label} exceeds ${SCHEDULE_LIMITS.idLength} characters`, false);
180
+ }
181
+ return normalized;
182
+ }
183
+ //# sourceMappingURL=schedules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedules.js","sourceRoot":"","sources":["../../src/services/schedules.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,4BAA4B,EAC5B,4BAA4B,GAW7B,MAAM,2BAA2B,CAAC;AAOnC,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAElC;IAEA;IAHX,YACW,IAA8B,EACvC,OAAe,EACN,SAAkB,EAC3B,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QALf,SAAI,GAAJ,IAAI,CAA0B;QAE9B,cAAS,GAAT,SAAS,CAAS;QAI3B,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAaD;;;;;GAKG;AACH,MAAM,OAAO,eAAe;IACT,KAAK,CAAgB;IACrB,MAAM,CAAiB;IACvB,WAAW,CAAsB;IACjC,YAAY,CAA0C;IAEvE,YAAY,OAA+B;QACzC,IAAI,CAAC,OAAO,EAAE,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC1E,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAC3E,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAC3C,CAAC;IAED,IAAI,CAAC,MAAuB;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,MAAM,YAAY,GAAG,UAAU,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACpD,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,qBAAqB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QACzE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAA0B;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,gBAAgB,CACjC,GAAG,EAAE,CAAC,4BAA4B,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,CACnD,CAAC;QACF,IAAI,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,sBAAsB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACnD,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAChD,QAAQ,CAAC,EAAE,EACX,EAAE,gBAAgB,EAAE,IAAI,EAAE,YAAY,IAAI,IAAI,EAAE,EAChD,EAAE,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,EAAE,CACxC,CAAC;QACF,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC,KAAK,CAAC,sBAAsB,CACtC,QAAQ,CAAC,EAAE,EACX,EAAE,MAAM,EAAE,YAAY,EAAE,EACxB,EAAE,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,EAAE,CACxC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CACV,EAAU,EACV,KAA0B,EAC1B,UAAmC,EAAE;QAErC,MAAM,YAAY,GAAG,UAAU,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,eAAe,GAAG,gBAAgB,CACtC,GAAG,EAAE,CAAC,4BAA4B,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,CACnD,CAAC;QACF,IAAI,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CACpC,YAAY,EACZ,eAAe,EACf,OAAO,CACR,CAAC;QACF,IAAI,eAAe,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,sBAAsB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YACnD,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAChD,QAAQ,CAAC,EAAE,EACX,EAAE,gBAAgB,EAAE,IAAI,EAAE,YAAY,IAAI,IAAI,EAAE,EAChD,EAAE,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,EAAE,CACxC,CAAC;QACJ,CAAC;QACD,IACE,eAAe,CAAC,MAAM,KAAK,SAAS;eACjC,eAAe,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAC7C,CAAC;YACD,OAAO,IAAI,CAAC,oBAAoB,CAC9B,eAAe,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EACxD,QAAQ,CACT,CAAC;QACJ,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACnE,OAAO,IAAI,CAAC,KAAK,CAAC,sBAAsB,CACtC,QAAQ,CAAC,EAAE,EACX,EAAE,MAAM,EAAE,YAAY,EAAE,EACxB,EAAE,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,EAAE,CACxC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,KAAK,CACT,EAAU,EACV,UAAmC,EAAE;QAErC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CACtC,UAAU,CAAC,EAAE,EAAE,aAAa,CAAC,EAC7B,EAAE,MAAM,EAAE,QAAQ,EAAE,EACpB,OAAO,CACR,CAAC;QACF,OAAO,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,MAAM,CACV,EAAU,EACV,UAAmC,EAAE;QAErC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CACtC,UAAU,CAAC,EAAE,EAAE,aAAa,CAAC,EAC7B,EAAE,MAAM,EAAE,QAAQ,EAAE,EACpB,OAAO,CACR,CAAC;QACF,OAAO,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,MAAM,CACV,EAAU,EACV,UAAmC,EAAE;QAErC,MAAM,YAAY,GAAG,UAAU,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QACnD,MAAM,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC7B,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,QAAQ,CACZ,UAAkB,EAClB,SAAgD,EAAE;QAElD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,OAAO,CACX,UAAkB,EAClB,KAAiC;QAEjC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5C,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,IAAI,oBAAoB,CAC5B,eAAe,EACf,aAAa,QAAQ,CAAC,EAAE,mCAAmC,EAC3D,KAAK,CACN,CAAC;QACJ,CAAC;QACD,MAAM,SAAS,GAAG,UAAU,CAC1B,KAAK,EAAE,cAAc,EACrB,iCAAiC,CAClC,CAAC;QACF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,UAAU,QAAQ,CAAC,EAAE,IAAI,SAAS,EAAE,CAAC;QACtD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;YACrC,UAAU,EAAE,QAAQ,CAAC,EAAE;YACvB,YAAY,EAAE,GAAG;YACjB,SAAS,EAAE,QAAQ;YACnB,cAAc,EAAE,QAAQ;SACzB,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,0EAA0E;QAC5E,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,KAAK,CAAC,cAAc,CAC1B,SAAgC,EAChC,QAAkB;QAElB,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,kBAAkB,CACvB,SAAS,EACT,QAAQ,EACR,IAAI,CAAC,GAAG,EAAE,EACV,KAAK,CACN,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAChC,SAAwC,EACxC,QAAkB;QAElB,IAAI,YAAwC,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,qBAAqB,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC;YACrE,YAAY,GAAG,qBAAqB,IAAI;gBACtC,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,IAAI,SAAS;gBACxC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,KAAK,cAAc;oBAChD,CAAC,CAAC,cAAc;oBAChB,CAAC,CAAC,YAAY;gBAChB,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,KAAK,SAAS;oBAC3C,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;gBAC/C,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,KAAK,SAAS;oBACzC,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAC3C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,YAAY,GAAG,kBAAkB,CAC/B,SAAS,EACT,QAAQ,EACR,IAAI,CAAC,GAAG,EAAE,EACV,KAAK,CACN,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,sBAAsB,CACtC,QAAQ,CAAC,EAAE,EACX,EAAE,MAAM,EAAE,YAAY,EAAE,EACxB,EAAE,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,EAAE,CACxC,CAAC;IACJ,CAAC;IAEO,GAAG;QACT,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,oBAAoB,CAC5B,eAAe,EACf,iDAAiD,EACjD,KAAK,CACN,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AAED,SAAS,kBAAkB,CACzB,SAAgE,EAChE,QAAkB,EAClB,GAAS,EACT,KAAc;IAEd,KAAK,KAAK,CAAC;IACX,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,IAAI,SAAS;QACxC,MAAM,EAAE,QAAQ;QAChB,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,KAAK,SAAS;YAC3C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/C,KAAK,EAAE;YACL,IAAI,EAAE,UAAU,SAAS,CAAC,WAAW,EAAE,SAAS;YAChD,OAAO,EAAE,mBAAmB,SAAS,mBAAmB;YACxD,SAAS,EAAE,IAAI;SAChB;QACD,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE;KAC7B,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAI,SAAkB;IAC7C,IAAI,CAAC;QACH,OAAO,SAAS,EAAE,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,oBAAoB,CAC5B,iBAAiB,EACjB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B,EACnE,KAAK,EACL,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAc,EAAE,KAAa;IAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,oBAAoB,CAC5B,iBAAiB,EACjB,GAAG,KAAK,6BAA6B,EACrC,KAAK,CACN,CAAC;IACJ,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,UAAU,CAAC,MAAM,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAC;QACjD,MAAM,IAAI,oBAAoB,CAC5B,iBAAiB,EACjB,GAAG,KAAK,YAAY,eAAe,CAAC,QAAQ,aAAa,EACzD,KAAK,CACN,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=schedules.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedules.test.d.ts","sourceRoot":"","sources":["../../src/services/schedules.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,319 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { InMemoryScheduleStore, ScheduleConflictError, } from "@polpo-ai/core/scheduling";
3
+ import { ScheduleService, ScheduleServiceError, } from "./schedules.js";
4
+ function input(overrides = {}) {
5
+ return {
6
+ id: "schedule-1",
7
+ name: "Daily report",
8
+ timing: {
9
+ kind: "cron",
10
+ expression: "0 9 * * *",
11
+ timezone: "UTC",
12
+ },
13
+ invocation: {
14
+ surface: "agent",
15
+ agentName: "reporter",
16
+ input: { prompt: "Prepare the daily report" },
17
+ },
18
+ ...overrides,
19
+ };
20
+ }
21
+ function harness(driverOverrides = {}) {
22
+ let clock = new Date("2026-07-28T08:00:00.000Z");
23
+ let runSequence = 0;
24
+ const store = new InMemoryScheduleStore({
25
+ now: () => clock,
26
+ createId: (kind) => kind === "schedule" ? "generated-schedule" : `run-${++runSequence}`,
27
+ });
28
+ const driver = {
29
+ register: vi.fn(async (schedule) => ({
30
+ kind: "test",
31
+ status: "registered",
32
+ providerId: `provider:${schedule.id}`,
33
+ updatedAt: clock.toISOString(),
34
+ })),
35
+ update: vi.fn(async (schedule) => ({
36
+ kind: "test",
37
+ status: "registered",
38
+ providerId: `provider:${schedule.id}`,
39
+ updatedAt: clock.toISOString(),
40
+ })),
41
+ pause: vi.fn(async () => { }),
42
+ resume: vi.fn(async () => { }),
43
+ delete: vi.fn(async () => { }),
44
+ ...driverOverrides,
45
+ };
46
+ const onRunCreated = vi.fn(async () => { });
47
+ const service = new ScheduleService({
48
+ store,
49
+ driver,
50
+ now: () => clock,
51
+ onRunCreated,
52
+ });
53
+ return {
54
+ store,
55
+ driver,
56
+ service,
57
+ onRunCreated,
58
+ setNow(value) {
59
+ clock = new Date(value);
60
+ },
61
+ };
62
+ }
63
+ describe("ScheduleService", () => {
64
+ it("creates a normalized schedule with next occurrence and driver state", async () => {
65
+ const state = harness();
66
+ await expect(state.service.create(input())).resolves.toMatchObject({
67
+ id: "schedule-1",
68
+ status: "active",
69
+ nextOccurrenceAt: "2026-07-28T09:00:00.000Z",
70
+ driver: {
71
+ kind: "test",
72
+ status: "registered",
73
+ providerId: "provider:schedule-1",
74
+ },
75
+ });
76
+ expect(state.driver.register).toHaveBeenCalledTimes(1);
77
+ expect(state.driver.register).toHaveBeenCalledWith(expect.objectContaining({
78
+ id: "schedule-1",
79
+ nextOccurrenceAt: "2026-07-28T09:00:00.000Z",
80
+ }));
81
+ });
82
+ it("persists a failed driver registration instead of losing the schedule", async () => {
83
+ const state = harness({
84
+ register: vi.fn(async () => {
85
+ throw new Error("provider unavailable");
86
+ }),
87
+ });
88
+ const created = await state.service.create(input());
89
+ expect(created).toMatchObject({
90
+ id: "schedule-1",
91
+ status: "active",
92
+ driver: {
93
+ kind: "unknown",
94
+ status: "failed",
95
+ error: {
96
+ code: "DRIVER_REGISTER_FAILED",
97
+ retryable: true,
98
+ },
99
+ },
100
+ });
101
+ expect(created.driver?.error?.message).toBe("Schedule driver register operation failed");
102
+ expect(await state.store.get("schedule-1")).toEqual(created);
103
+ });
104
+ it("recomputes occurrence on timing update and uses optimistic revision", async () => {
105
+ const state = harness();
106
+ const created = await state.service.create(input());
107
+ const updated = await state.service.update(created.id, {
108
+ timing: {
109
+ kind: "cron",
110
+ expression: "30 10 * * *",
111
+ timezone: "UTC",
112
+ },
113
+ }, { expectedRevision: created.revision });
114
+ expect(updated).toMatchObject({
115
+ nextOccurrenceAt: "2026-07-28T10:30:00.000Z",
116
+ driver: { status: "registered" },
117
+ });
118
+ expect(state.driver.update).toHaveBeenCalledTimes(1);
119
+ await expect(state.service.update(created.id, { name: "stale" }, { expectedRevision: created.revision })).rejects.toBeInstanceOf(ScheduleConflictError);
120
+ });
121
+ it("uses lifecycle methods for status transitions made through update", async () => {
122
+ const state = harness();
123
+ const created = await state.service.create(input());
124
+ vi.mocked(state.driver.update).mockClear();
125
+ const paused = await state.service.update(created.id, {
126
+ status: "paused",
127
+ });
128
+ expect(paused.status).toBe("paused");
129
+ expect(state.driver.pause).toHaveBeenCalledTimes(1);
130
+ expect(state.driver.update).not.toHaveBeenCalled();
131
+ const resumed = await state.service.update(created.id, {
132
+ status: "active",
133
+ });
134
+ expect(resumed.status).toBe("active");
135
+ expect(state.driver.resume).toHaveBeenCalledTimes(1);
136
+ });
137
+ it("persists provider registrations returned by lifecycle operations", async () => {
138
+ const state = harness({
139
+ register: vi.fn(async () => ({
140
+ kind: "test",
141
+ status: "not_required",
142
+ metadata: { mode: "once", paused: true },
143
+ updatedAt: "2026-07-28T08:00:00.000Z",
144
+ })),
145
+ resume: vi.fn(async () => ({
146
+ kind: "test",
147
+ status: "registered",
148
+ providerId: "message:resumed",
149
+ metadata: { mode: "once", paused: false },
150
+ updatedAt: "2026-07-28T08:00:00.000Z",
151
+ })),
152
+ pause: vi.fn(async () => ({
153
+ kind: "test",
154
+ status: "not_required",
155
+ metadata: { mode: "once", paused: true },
156
+ updatedAt: "2026-07-28T08:00:00.000Z",
157
+ })),
158
+ delete: vi.fn(async () => ({
159
+ kind: "test",
160
+ status: "not_required",
161
+ metadata: { mode: "once", deleted: true },
162
+ updatedAt: "2026-07-28T08:00:00.000Z",
163
+ })),
164
+ });
165
+ const created = await state.service.create(input({
166
+ status: "paused",
167
+ timing: {
168
+ kind: "once",
169
+ at: "2026-07-28T10:00:00.000Z",
170
+ timezone: "UTC",
171
+ },
172
+ }));
173
+ expect(created.driver).toMatchObject({
174
+ status: "not_required",
175
+ metadata: { mode: "once", paused: true },
176
+ });
177
+ const resumed = await state.service.resume(created.id);
178
+ expect(resumed.driver).toMatchObject({
179
+ status: "registered",
180
+ providerId: "message:resumed",
181
+ metadata: { mode: "once", paused: false },
182
+ });
183
+ const paused = await state.service.pause(created.id);
184
+ expect(paused.driver).toMatchObject({
185
+ status: "not_required",
186
+ metadata: { mode: "once", paused: true },
187
+ });
188
+ expect(paused.driver).not.toHaveProperty("providerId");
189
+ const deleted = await state.service.delete(created.id);
190
+ expect(deleted.driver).toMatchObject({
191
+ status: "not_required",
192
+ metadata: { mode: "once", deleted: true },
193
+ });
194
+ });
195
+ it("classifies deep core validation failures as invalid requests", async () => {
196
+ const state = harness();
197
+ await expect(state.service.create(input({
198
+ invocation: {
199
+ surface: "agent",
200
+ agentName: "",
201
+ input: { prompt: "" },
202
+ },
203
+ }))).rejects.toMatchObject({
204
+ name: "ScheduleServiceError",
205
+ code: "INVALID_REQUEST",
206
+ retryable: false,
207
+ });
208
+ });
209
+ it("pauses, resumes, and deletes local truth even if driver lifecycle fails", async () => {
210
+ const state = harness({
211
+ pause: vi.fn(async () => {
212
+ throw new Error("pause failed");
213
+ }),
214
+ resume: vi.fn(async () => {
215
+ throw new Error("resume failed");
216
+ }),
217
+ delete: vi.fn(async () => {
218
+ throw new Error("delete failed");
219
+ }),
220
+ });
221
+ const created = await state.service.create(input());
222
+ const paused = await state.service.pause(created.id);
223
+ expect(paused).toMatchObject({
224
+ status: "paused",
225
+ driver: {
226
+ status: "failed",
227
+ error: { code: "DRIVER_PAUSE_FAILED" },
228
+ },
229
+ });
230
+ const resumed = await state.service.resume(created.id);
231
+ expect(resumed).toMatchObject({
232
+ status: "active",
233
+ driver: {
234
+ status: "failed",
235
+ error: { code: "DRIVER_RESUME_FAILED" },
236
+ },
237
+ });
238
+ const deleted = await state.service.delete(created.id);
239
+ expect(deleted).toMatchObject({
240
+ status: "deleted",
241
+ driver: {
242
+ status: "failed",
243
+ error: { code: "DRIVER_DELETE_FAILED" },
244
+ },
245
+ });
246
+ expect(await state.service.list()).toEqual([]);
247
+ expect(await state.service.list({ includeDeleted: true }))
248
+ .toEqual([deleted]);
249
+ });
250
+ it("creates one durable manual run per caller idempotency key", async () => {
251
+ const state = harness();
252
+ const created = await state.service.create(input());
253
+ state.setNow("2026-07-28T08:10:00.000Z");
254
+ const first = await state.service.trigger(created.id, {
255
+ idempotencyKey: " manual-test-1 ",
256
+ });
257
+ const duplicate = await state.service.trigger(created.id, {
258
+ idempotencyKey: "manual-test-1",
259
+ });
260
+ expect(first).toEqual(duplicate);
261
+ expect(first).toMatchObject({
262
+ scheduleId: "schedule-1",
263
+ occurrenceAt: "2026-07-28T08:10:00.000Z",
264
+ triggerId: "manual:schedule-1:manual-test-1",
265
+ idempotencyKey: "manual:schedule-1:manual-test-1",
266
+ status: "pending",
267
+ });
268
+ expect(await state.service.listRuns(created.id)).toHaveLength(1);
269
+ expect(state.onRunCreated).toHaveBeenCalledTimes(2);
270
+ });
271
+ it("rejects manual runs for inactive schedules and malformed keys", async () => {
272
+ const state = harness();
273
+ const created = await state.service.create(input());
274
+ await state.service.pause(created.id);
275
+ await expect(state.service.trigger(created.id, {
276
+ idempotencyKey: "manual-1",
277
+ })).rejects.toMatchObject({
278
+ code: "INVALID_STATE",
279
+ retryable: false,
280
+ });
281
+ const activeState = harness();
282
+ const active = await activeState.service.create(input());
283
+ await expect(activeState.service.trigger(active.id, {
284
+ idempotencyKey: " ",
285
+ })).rejects.toMatchObject({
286
+ code: "INVALID_REQUEST",
287
+ retryable: false,
288
+ });
289
+ });
290
+ it("requires schedule existence for reads, updates, and run history", async () => {
291
+ const state = harness();
292
+ await expect(state.service.get("missing")).rejects.toMatchObject({
293
+ code: "NOT_FOUND",
294
+ });
295
+ await expect(state.service.update("missing", { name: "x" }))
296
+ .rejects.toMatchObject({ code: "NOT_FOUND" });
297
+ await expect(state.service.listRuns("missing")).rejects.toMatchObject({
298
+ code: "NOT_FOUND",
299
+ });
300
+ });
301
+ it("reports callback failures without rolling back a durable manual run", async () => {
302
+ const state = harness();
303
+ const created = await state.service.create(input());
304
+ state.onRunCreated.mockRejectedValueOnce(new Error("wake failed"));
305
+ await expect(state.service.trigger(created.id, {
306
+ idempotencyKey: "manual-1",
307
+ })).resolves.toMatchObject({ status: "pending" });
308
+ expect(await state.service.listRuns(created.id)).toHaveLength(1);
309
+ });
310
+ it("exposes stable service errors", () => {
311
+ const error = new ScheduleServiceError("INVALID_REQUEST", "Invalid request", false);
312
+ expect(error).toMatchObject({
313
+ name: "ScheduleServiceError",
314
+ code: "INVALID_REQUEST",
315
+ retryable: false,
316
+ });
317
+ });
318
+ });
319
+ //# sourceMappingURL=schedules.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedules.test.js","sourceRoot":"","sources":["../../src/services/schedules.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polpo-ai/server",
3
- "version": "0.15.45",
3
+ "version": "0.15.47",
4
4
  "description": "Polpo API route factories — edge-compatible Hono routes for tasks, agents, missions, vault, and more",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,11 +20,11 @@
20
20
  "hono": ">=4.0.0",
21
21
  "nanoid": ">=5.0.0",
22
22
  "typescript": "^5.7.3",
23
- "@polpo-ai/connect": "0.15.45",
24
- "@polpo-ai/connect-server": "0.15.45",
25
- "@polpo-ai/core": "0.15.45",
26
- "@polpo-ai/llm": "0.15.45",
27
- "@polpo-ai/tools": "0.15.45"
23
+ "@polpo-ai/connect": "0.15.47",
24
+ "@polpo-ai/connect-server": "0.15.47",
25
+ "@polpo-ai/core": "0.15.47",
26
+ "@polpo-ai/llm": "0.15.47",
27
+ "@polpo-ai/tools": "0.15.47"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "ai": ">=6.0.0",