@rubytech/create-maxy-code 0.1.550 → 0.1.552
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/package.json +1 -1
- package/payload/platform/lib/agent-dispatch-rule/dist/index.d.ts +22 -8
- package/payload/platform/lib/agent-dispatch-rule/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/agent-dispatch-rule/dist/index.js +47 -13
- package/payload/platform/lib/agent-dispatch-rule/dist/index.js.map +1 -1
- package/payload/platform/lib/agent-dispatch-rule/src/__tests__/rule.test.ts +68 -9
- package/payload/platform/lib/agent-dispatch-rule/src/index.ts +60 -16
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +3 -3
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +9 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +2 -2
- package/payload/platform/plugins/scheduling/PLUGIN.md +4 -0
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +62 -0
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch.test.js +2 -2
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/connector-sync-provision.test.js +2 -2
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/connector-sync-provision.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js +128 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js +135 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-sync-provision.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-sync-provision.js +21 -8
- package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-sync-provision.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts +92 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js +185 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts +8 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts +49 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js +165 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js +146 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +27 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +18 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +106 -64
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js +218 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js +291 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts +31 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +44 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.d.ts +3 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js +57 -3
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts +148 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js +410 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/package.json +1 -0
- package/payload/platform/plugins/telegram/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/telegram/PLUGIN.md +6 -4
- package/payload/platform/plugins/telegram/mcp/dist/index.js +62 -38
- package/payload/platform/plugins/telegram/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-token.d.ts +18 -5
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-token.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-token.js +34 -6
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-token.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.d.ts +25 -8
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.js +28 -16
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/agent-active.d.ts +12 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/agent-active.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/agent-active.js +26 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/agent-active.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/secret-path.d.ts +16 -13
- package/payload/platform/plugins/telegram/mcp/dist/lib/secret-path.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/secret-path.js +19 -23
- package/payload/platform/plugins/telegram/mcp/dist/lib/secret-path.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/webhook-url.d.ts +9 -7
- package/payload/platform/plugins/telegram/mcp/dist/lib/webhook-url.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/webhook-url.js +11 -8
- package/payload/platform/plugins/telegram/mcp/dist/lib/webhook-url.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/tools/message.d.ts +4 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/message.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/tools/message.js +13 -3
- package/payload/platform/plugins/telegram/mcp/dist/tools/message.js.map +1 -1
- package/payload/platform/plugins/telegram/references/setup-guide.md +16 -8
- package/payload/platform/plugins/telegram/skills/configure/SKILL.md +30 -32
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-census.d.ts +51 -4
- package/payload/platform/services/claude-session-manager/dist/pty-census.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-census.js +60 -10
- package/payload/platform/services/claude-session-manager/dist/pty-census.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.d.ts +64 -1
- package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.js +189 -6
- package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.js.map +1 -1
- package/payload/server/server.js +510 -240
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
// @vitest-environment node
|
|
2
|
+
// Task 2378 — the gate tool.
|
|
3
|
+
//
|
|
4
|
+
// Every check is asserted ONE AT A TIME. `hasWork` is a disjunction, so a suite
|
|
5
|
+
// that only ever ran all four together could not tell a working check from an
|
|
6
|
+
// always-true one riding on a sibling.
|
|
7
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
8
|
+
import { mkdtempSync, mkdirSync, readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
vi.mock("../../lib/neo4j.js", () => ({
|
|
12
|
+
getSession: () => ({ run: vi.fn(async () => ({ records: [] })), close: vi.fn(async () => { }) }),
|
|
13
|
+
}));
|
|
14
|
+
import { runSchedulingGate, watermarkPath, parseD1Count, digestBusy, } from "../scheduling-gate.js";
|
|
15
|
+
const ACCOUNT = "20028fb5-0000-4000-8000-000000000000";
|
|
16
|
+
const EVENT = "65ef758c-0000-4000-8000-000000000000";
|
|
17
|
+
let platformRoot;
|
|
18
|
+
/** Sources that all answer "quiet". Each test overrides only what it is about. */
|
|
19
|
+
function quietSources(over = {}) {
|
|
20
|
+
return {
|
|
21
|
+
mail: async (_c, sinceUid) => ({ matched: false, highestUid: sinceUid, uidValidity: 1 }),
|
|
22
|
+
d1: async () => 0,
|
|
23
|
+
whatsappStatus: async () => ({ connected: true }),
|
|
24
|
+
whatsappInbound: async (_a, since) => ({ latest: since, newer: false }),
|
|
25
|
+
calendarDigest: async () => "DIGEST-A",
|
|
26
|
+
...over,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function seedWatermarks(marks) {
|
|
30
|
+
const path = watermarkPath(EVENT, platformRoot);
|
|
31
|
+
mkdirSync(join(path, ".."), { recursive: true });
|
|
32
|
+
writeFileSync(path, JSON.stringify(marks, null, 2));
|
|
33
|
+
}
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
const root = mkdtempSync(join(tmpdir(), "sched-gate-"));
|
|
36
|
+
platformRoot = join(root, "platform");
|
|
37
|
+
mkdirSync(platformRoot, { recursive: true });
|
|
38
|
+
vi.spyOn(console, "error").mockImplementation(() => { });
|
|
39
|
+
});
|
|
40
|
+
afterEach(() => vi.restoreAllMocks());
|
|
41
|
+
const run = (checks, sources, commit = false) => runSchedulingGate({ eventId: EVENT, checks, commit }, ACCOUNT, platformRoot, sources);
|
|
42
|
+
describe("d1 check", () => {
|
|
43
|
+
const CHECK = { type: "d1", database: "bookings", sql: "SELECT count(*) FROM b" };
|
|
44
|
+
it("is false on a zero count", async () => {
|
|
45
|
+
expect(await run([CHECK], quietSources())).toEqual({ hasWork: false, reasons: [] });
|
|
46
|
+
});
|
|
47
|
+
it("is true on one row", async () => {
|
|
48
|
+
expect(await run([CHECK], quietSources({ d1: async () => 1 }))).toEqual({
|
|
49
|
+
hasWork: true,
|
|
50
|
+
reasons: ["d1"],
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
it("reports work rather than an error when the source is unreachable", async () => {
|
|
54
|
+
const sources = quietSources({
|
|
55
|
+
d1: async () => {
|
|
56
|
+
throw new Error("no cloudflare credentials");
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
expect(await run([CHECK], sources)).toEqual({ hasWork: true, reasons: ["d1"] });
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe("mail check", () => {
|
|
63
|
+
const CHECK = { type: "mail", mailbox: "ops@example.com" };
|
|
64
|
+
it("is false when nothing sits above the watermark", async () => {
|
|
65
|
+
seedWatermarks({ mail: { "ops@example.com|INBOX": { uid: 100, uidValidity: 1 } } });
|
|
66
|
+
expect(await run([CHECK], quietSources())).toEqual({ hasWork: false, reasons: [] });
|
|
67
|
+
});
|
|
68
|
+
it("is true when a UID above the watermark matches", async () => {
|
|
69
|
+
seedWatermarks({ mail: { "ops@example.com|INBOX": { uid: 100, uidValidity: 1 } } });
|
|
70
|
+
const sources = quietSources({
|
|
71
|
+
mail: async () => ({ matched: true, highestUid: 104, uidValidity: 1 }),
|
|
72
|
+
});
|
|
73
|
+
expect(await run([CHECK], sources)).toEqual({ hasWork: true, reasons: ["mail"] });
|
|
74
|
+
});
|
|
75
|
+
it("probes from UID 0 on a first run, so nothing already there is missed", async () => {
|
|
76
|
+
const seen = [];
|
|
77
|
+
const sources = quietSources({
|
|
78
|
+
mail: async (_c, since) => {
|
|
79
|
+
seen.push(since);
|
|
80
|
+
return { matched: false, highestUid: since, uidValidity: 1 };
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
await run([CHECK], sources);
|
|
84
|
+
expect(seen).toEqual([0]);
|
|
85
|
+
});
|
|
86
|
+
it("treats a UIDVALIDITY change as work — the stored UID names a different message", async () => {
|
|
87
|
+
seedWatermarks({ mail: { "ops@example.com|INBOX": { uid: 100, uidValidity: 1 } } });
|
|
88
|
+
const sources = quietSources({
|
|
89
|
+
mail: async () => ({ matched: false, highestUid: 100, uidValidity: 7 }),
|
|
90
|
+
});
|
|
91
|
+
expect(await run([CHECK], sources)).toEqual({ hasWork: true, reasons: ["mail"] });
|
|
92
|
+
});
|
|
93
|
+
it("keys the watermark by folder, so two folders of one mailbox never collide", async () => {
|
|
94
|
+
seedWatermarks({ mail: { "ops@example.com|Archive": { uid: 100, uidValidity: 1 } } });
|
|
95
|
+
const seen = [];
|
|
96
|
+
const sources = quietSources({
|
|
97
|
+
mail: async (_c, since) => {
|
|
98
|
+
seen.push(since);
|
|
99
|
+
return { matched: false, highestUid: since, uidValidity: 1 };
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
await run([CHECK], sources);
|
|
103
|
+
expect(seen).toEqual([0]);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe("whatsapp check", () => {
|
|
107
|
+
it("status is false while connected", async () => {
|
|
108
|
+
const check = { type: "whatsapp", scope: "status" };
|
|
109
|
+
expect(await run([check], quietSources())).toEqual({ hasWork: false, reasons: [] });
|
|
110
|
+
});
|
|
111
|
+
it("status is true while disconnected", async () => {
|
|
112
|
+
const check = { type: "whatsapp", scope: "status" };
|
|
113
|
+
const sources = quietSources({ whatsappStatus: async () => ({ connected: false }) });
|
|
114
|
+
expect(await run([check], sources)).toEqual({ hasWork: true, reasons: ["whatsapp"] });
|
|
115
|
+
});
|
|
116
|
+
it("inbound is true only on a message received since the watermark", async () => {
|
|
117
|
+
const check = { type: "whatsapp", scope: "inbound" };
|
|
118
|
+
seedWatermarks({ whatsapp: { inbound: 1_754_000_000 } });
|
|
119
|
+
const sources = quietSources({
|
|
120
|
+
whatsappInbound: async () => ({ latest: 1_754_000_900, newer: true }),
|
|
121
|
+
});
|
|
122
|
+
expect(await run([check], sources)).toEqual({ hasWork: true, reasons: ["whatsapp"] });
|
|
123
|
+
});
|
|
124
|
+
it("inbound passes the stored watermark to the source", async () => {
|
|
125
|
+
const check = { type: "whatsapp", scope: "inbound" };
|
|
126
|
+
seedWatermarks({ whatsapp: { inbound: 1_754_000_000 } });
|
|
127
|
+
const seen = [];
|
|
128
|
+
const sources = quietSources({
|
|
129
|
+
whatsappInbound: async (_a, since) => {
|
|
130
|
+
seen.push(since);
|
|
131
|
+
return { latest: since, newer: false };
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
await run([check], sources);
|
|
135
|
+
expect(seen).toEqual([1_754_000_000]);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
describe("calendar check", () => {
|
|
139
|
+
const CHECK = { type: "calendar", connector: "google" };
|
|
140
|
+
it("is false on an unchanged digest", async () => {
|
|
141
|
+
seedWatermarks({ calendar: { digest: "DIGEST-A" } });
|
|
142
|
+
expect(await run([CHECK], quietSources())).toEqual({ hasWork: false, reasons: [] });
|
|
143
|
+
});
|
|
144
|
+
it("is true on a changed digest", async () => {
|
|
145
|
+
seedWatermarks({ calendar: { digest: "DIGEST-A" } });
|
|
146
|
+
const sources = quietSources({ calendarDigest: async () => "DIGEST-B" });
|
|
147
|
+
expect(await run([CHECK], sources)).toEqual({ hasWork: true, reasons: ["calendar"] });
|
|
148
|
+
});
|
|
149
|
+
it("is true on a first run, when nothing has been committed yet", async () => {
|
|
150
|
+
expect(await run([CHECK], quietSources())).toEqual({ hasWork: true, reasons: ["calendar"] });
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
describe("digestBusy", () => {
|
|
154
|
+
it("is order-independent, so a re-sync that returns the same set reads unchanged", () => {
|
|
155
|
+
const a = digestBusy("google", [
|
|
156
|
+
{ start: "2026-08-03T09:00:00Z", end: "2026-08-03T10:00:00Z" },
|
|
157
|
+
{ start: "2026-08-04T09:00:00Z", end: "2026-08-04T10:00:00Z" },
|
|
158
|
+
]);
|
|
159
|
+
const b = digestBusy("google", [
|
|
160
|
+
{ start: "2026-08-04T09:00:00Z", end: "2026-08-04T10:00:00Z" },
|
|
161
|
+
{ start: "2026-08-03T09:00:00Z", end: "2026-08-03T10:00:00Z" },
|
|
162
|
+
]);
|
|
163
|
+
expect(a).toBe(b);
|
|
164
|
+
});
|
|
165
|
+
it("changes when an interval changes", () => {
|
|
166
|
+
const a = digestBusy("google", [{ start: "2026-08-03T09:00:00Z", end: "2026-08-03T10:00:00Z" }]);
|
|
167
|
+
const b = digestBusy("google", [{ start: "2026-08-03T09:00:00Z", end: "2026-08-03T11:00:00Z" }]);
|
|
168
|
+
expect(a).not.toBe(b);
|
|
169
|
+
});
|
|
170
|
+
it("changes when the connector changes, even on an identical busy set", () => {
|
|
171
|
+
const iv = [{ start: "2026-08-03T09:00:00Z", end: "2026-08-03T10:00:00Z" }];
|
|
172
|
+
expect(digestBusy("google", iv)).not.toBe(digestBusy("m365", iv));
|
|
173
|
+
});
|
|
174
|
+
it("an empty set has a stable digest, so a cleared calendar is not permanently 'changed'", () => {
|
|
175
|
+
expect(digestBusy("none", [])).toBe(digestBusy("none", []));
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
describe("parseD1Count", () => {
|
|
179
|
+
it("reads the first column of the first row", () => {
|
|
180
|
+
expect(parseD1Count({ result: [{ results: [{ "count(*)": 3 }] }] })).toBe(3);
|
|
181
|
+
});
|
|
182
|
+
it("is zero on an empty result set", () => {
|
|
183
|
+
expect(parseD1Count({ result: [{ results: [] }] })).toBe(0);
|
|
184
|
+
});
|
|
185
|
+
it("throws on an envelope it cannot understand, rather than reporting zero", () => {
|
|
186
|
+
// Reporting zero here would make an unreadable payload indistinguishable
|
|
187
|
+
// from an empty queue, and the routine would skip for ever.
|
|
188
|
+
expect(() => parseD1Count({ result: [{}] })).toThrow(/no results array/);
|
|
189
|
+
expect(() => parseD1Count({})).toThrow(/no results array/);
|
|
190
|
+
});
|
|
191
|
+
it("throws when the first column is not a number", () => {
|
|
192
|
+
expect(() => parseD1Count({ result: [{ results: [{ name: "alice" }] }] })).toThrow(/not a number/);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
describe("all four together", () => {
|
|
196
|
+
const ALL = [
|
|
197
|
+
{ type: "mail", mailbox: "ops@example.com" },
|
|
198
|
+
{ type: "d1", database: "bookings", sql: "SELECT count(*) FROM b" },
|
|
199
|
+
{ type: "whatsapp", scope: "status" },
|
|
200
|
+
{ type: "calendar", connector: "google" },
|
|
201
|
+
];
|
|
202
|
+
it("every source quiet returns hasWork:false with no reasons", async () => {
|
|
203
|
+
seedWatermarks({
|
|
204
|
+
mail: { "ops@example.com|INBOX": { uid: 100, uidValidity: 1 } },
|
|
205
|
+
calendar: { digest: "DIGEST-A" },
|
|
206
|
+
});
|
|
207
|
+
expect(await run(ALL, quietSources())).toEqual({ hasWork: false, reasons: [] });
|
|
208
|
+
});
|
|
209
|
+
it("one noisy source is enough, and names only itself", async () => {
|
|
210
|
+
seedWatermarks({
|
|
211
|
+
mail: { "ops@example.com|INBOX": { uid: 100, uidValidity: 1 } },
|
|
212
|
+
calendar: { digest: "DIGEST-A" },
|
|
213
|
+
});
|
|
214
|
+
expect(await run(ALL, quietSources({ d1: async () => 2 }))).toEqual({
|
|
215
|
+
hasWork: true,
|
|
216
|
+
reasons: ["d1"],
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
describe("commit", () => {
|
|
221
|
+
const ALL = [
|
|
222
|
+
{ type: "mail", mailbox: "ops@example.com" },
|
|
223
|
+
{ type: "d1", database: "bookings", sql: "SELECT count(*) FROM b" },
|
|
224
|
+
{ type: "whatsapp", scope: "inbound" },
|
|
225
|
+
{ type: "calendar", connector: "google" },
|
|
226
|
+
];
|
|
227
|
+
it("a plain call leaves the file bytes unchanged", async () => {
|
|
228
|
+
seedWatermarks({ calendar: { digest: "DIGEST-A" } });
|
|
229
|
+
const path = watermarkPath(EVENT, platformRoot);
|
|
230
|
+
const before = readFileSync(path);
|
|
231
|
+
await run(ALL, quietSources({ calendarDigest: async () => "DIGEST-B" }));
|
|
232
|
+
expect(readFileSync(path).equals(before)).toBe(true);
|
|
233
|
+
});
|
|
234
|
+
it("a plain call on a first run writes no file at all", async () => {
|
|
235
|
+
await run(ALL, quietSources());
|
|
236
|
+
expect(existsSync(watermarkPath(EVENT, platformRoot))).toBe(false);
|
|
237
|
+
});
|
|
238
|
+
it("advances every watermark named in checks", async () => {
|
|
239
|
+
const sources = quietSources({
|
|
240
|
+
mail: async () => ({ matched: true, highestUid: 250, uidValidity: 9 }),
|
|
241
|
+
whatsappInbound: async () => ({ latest: 1_754_009_999, newer: true }),
|
|
242
|
+
calendarDigest: async () => "DIGEST-Z",
|
|
243
|
+
});
|
|
244
|
+
const result = await run(ALL, sources, true);
|
|
245
|
+
const marks = JSON.parse(readFileSync(watermarkPath(EVENT, platformRoot), "utf-8"));
|
|
246
|
+
expect(marks.mail["ops@example.com|INBOX"]).toEqual({ uid: 250, uidValidity: 9 });
|
|
247
|
+
expect(marks.whatsapp.inbound).toBe(1_754_009_999);
|
|
248
|
+
expect(marks.calendar.digest).toBe("DIGEST-Z");
|
|
249
|
+
expect(marks.lastCommitAt).toMatch(/^\d{4}-\d{2}-\d{2}T/);
|
|
250
|
+
// d1 has no watermark: its answer is a property of the present, not a
|
|
251
|
+
// position in a stream.
|
|
252
|
+
expect(result.advanced).toEqual(["ops@example.com|INBOX", "whatsapp", "calendar"]);
|
|
253
|
+
});
|
|
254
|
+
it("a commit whose sources are quiet still stamps lastCommitAt", async () => {
|
|
255
|
+
// Otherwise a routine that ran and found nothing would look, to the
|
|
256
|
+
// watermark-age audit, exactly like one whose commits had stopped.
|
|
257
|
+
await run(ALL, quietSources(), true);
|
|
258
|
+
const marks = JSON.parse(readFileSync(watermarkPath(EVENT, platformRoot), "utf-8"));
|
|
259
|
+
expect(marks.lastCommitAt).toMatch(/^\d{4}-\d{2}-\d{2}T/);
|
|
260
|
+
});
|
|
261
|
+
it("a committed watermark makes the next plain call quiet", async () => {
|
|
262
|
+
const sources = quietSources({ calendarDigest: async () => "DIGEST-Z" });
|
|
263
|
+
const checks = [{ type: "calendar", connector: "google" }];
|
|
264
|
+
expect(await run(checks, sources)).toEqual({ hasWork: true, reasons: ["calendar"] });
|
|
265
|
+
await run(checks, sources, true);
|
|
266
|
+
expect(await run(checks, sources)).toEqual({ hasWork: false, reasons: [] });
|
|
267
|
+
});
|
|
268
|
+
it("a check that errors is not committed, so its work is not marked consumed", async () => {
|
|
269
|
+
const checks = [{ type: "calendar", connector: "google" }];
|
|
270
|
+
const sources = quietSources({
|
|
271
|
+
calendarDigest: async () => {
|
|
272
|
+
throw new Error("neo4j down");
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
const result = await run(checks, sources, true);
|
|
276
|
+
expect(result).toMatchObject({ hasWork: true, reasons: ["calendar"], advanced: [] });
|
|
277
|
+
const marks = JSON.parse(readFileSync(watermarkPath(EVENT, platformRoot), "utf-8"));
|
|
278
|
+
expect(marks.calendar).toBeUndefined();
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
describe("watermark location", () => {
|
|
282
|
+
it("is install-rooted and named by eventId, with no account segment", () => {
|
|
283
|
+
// An account segment would let the dispatcher's ACCOUNT_ID and the agent
|
|
284
|
+
// turn's resolved account disagree, so the commit would write one file and
|
|
285
|
+
// the next gate read another.
|
|
286
|
+
const path = watermarkPath(EVENT, "/opt/brand/platform");
|
|
287
|
+
expect(path).toBe(`/opt/brand/state/scheduling-gate/${EVENT}.json`);
|
|
288
|
+
expect(path).not.toContain(ACCOUNT);
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
//# sourceMappingURL=scheduling-gate.test.js.map
|
package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduling-gate.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/scheduling-gate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,36 @@ export interface AgentDispatch {
|
|
|
11
11
|
destination: string;
|
|
12
12
|
prompt: string;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Task 2378 — the precondition evaluated before the model is invoked.
|
|
16
|
+
*
|
|
17
|
+
* Same shape and handling as `EventAction`: a plugin, a tool, and args stored as
|
|
18
|
+
* a JSON string and passed to the tool verbatim. The dispatcher reads only
|
|
19
|
+
* `structuredContent.hasWork` from the result.
|
|
20
|
+
*/
|
|
21
|
+
export interface EventGate {
|
|
22
|
+
plugin: string;
|
|
23
|
+
tool: string;
|
|
24
|
+
args?: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Task 2378 — the two write-time refusals a gate carries, shared by
|
|
28
|
+
* `schedule-event` and `schedule-update` so the create path and the edit path
|
|
29
|
+
* cannot disagree about what a valid gate is.
|
|
30
|
+
*
|
|
31
|
+
* A gate on an action-mode event is refused because the action rail already runs
|
|
32
|
+
* headlessly with no model: there is nothing there for a precondition to save,
|
|
33
|
+
* and accepting one would store three properties the dispatcher never reads.
|
|
34
|
+
*
|
|
35
|
+
* A gate with no complete agent dispatch is refused because the gate is only
|
|
36
|
+
* ever consulted on the agent path. Stored on a row that cannot dispatch an
|
|
37
|
+
* agent turn it would read as configured and do nothing, which is precisely the
|
|
38
|
+
* silent-misconfiguration class Task 2130 exists to remove.
|
|
39
|
+
*/
|
|
40
|
+
export declare function validateGate(gate: EventGate, ctx: {
|
|
41
|
+
hasAction: boolean;
|
|
42
|
+
hasCompleteAgentDispatch: boolean;
|
|
43
|
+
}): void;
|
|
14
44
|
export interface ScheduleEventParams {
|
|
15
45
|
accountId: string;
|
|
16
46
|
name: string;
|
|
@@ -32,6 +62,7 @@ export interface ScheduleEventParams {
|
|
|
32
62
|
sessionKey?: string;
|
|
33
63
|
action?: EventAction;
|
|
34
64
|
agentDispatch?: AgentDispatch;
|
|
65
|
+
gate?: EventGate;
|
|
35
66
|
attendees?: ScheduleAttendee[];
|
|
36
67
|
createdBy: CreatedBy;
|
|
37
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule-event.d.ts","sourceRoot":"","sources":["../../src/tools/schedule-event.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,8CAA8C,CAAC;AAGtD,OAAO,EAAyB,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE/G,OAAO,EAAyB,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEpF,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,aAAa,CAAC;IACrB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,
|
|
1
|
+
{"version":3,"file":"schedule-event.d.ts","sourceRoot":"","sources":["../../src/tools/schedule-event.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,8CAA8C,CAAC;AAGtD,OAAO,EAAyB,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE/G,OAAO,EAAyB,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEpF,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,EACf,GAAG,EAAE;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,wBAAwB,EAAE,OAAO,CAAA;CAAE,GAC7D,IAAI,CAcN;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,aAAa,CAAC;IACrB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAqO7F"}
|
|
@@ -10,8 +10,33 @@ const { parseExpression } = cronParser;
|
|
|
10
10
|
import { classifyScheduleWrite } from "../lib/schedule-classify.js";
|
|
11
11
|
import { writeMeeting } from "../lib/meeting-write.js";
|
|
12
12
|
import { validateAgentDispatch } from "../lib/agent-dispatch.js";
|
|
13
|
+
/**
|
|
14
|
+
* Task 2378 — the two write-time refusals a gate carries, shared by
|
|
15
|
+
* `schedule-event` and `schedule-update` so the create path and the edit path
|
|
16
|
+
* cannot disagree about what a valid gate is.
|
|
17
|
+
*
|
|
18
|
+
* A gate on an action-mode event is refused because the action rail already runs
|
|
19
|
+
* headlessly with no model: there is nothing there for a precondition to save,
|
|
20
|
+
* and accepting one would store three properties the dispatcher never reads.
|
|
21
|
+
*
|
|
22
|
+
* A gate with no complete agent dispatch is refused because the gate is only
|
|
23
|
+
* ever consulted on the agent path. Stored on a row that cannot dispatch an
|
|
24
|
+
* agent turn it would read as configured and do nothing, which is precisely the
|
|
25
|
+
* silent-misconfiguration class Task 2130 exists to remove.
|
|
26
|
+
*/
|
|
27
|
+
export function validateGate(gate, ctx) {
|
|
28
|
+
if (!gate.plugin || !gate.tool) {
|
|
29
|
+
throw new Error("Gate requires both 'plugin' and 'tool' fields");
|
|
30
|
+
}
|
|
31
|
+
if (ctx.hasAction) {
|
|
32
|
+
throw new Error("A gate cannot be set on an action-mode event — an action already runs headlessly with no model, so it has nothing to gate. Gates apply to agentDispatch events only.");
|
|
33
|
+
}
|
|
34
|
+
if (!ctx.hasCompleteAgentDispatch) {
|
|
35
|
+
throw new Error("A gate requires a complete agentDispatch (channel, destination and prompt) — the gate is only evaluated on the agent dispatch path.");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
13
38
|
export async function scheduleEvent(params) {
|
|
14
|
-
const { accountId, name, description, startDate, endDate, location, recurrence, timezone, accountTimezone, sessionKey, action, agentDispatch, attendees, createdBy, } = params;
|
|
39
|
+
const { accountId, name, description, startDate, endDate, location, recurrence, timezone, accountTimezone, sessionKey, action, agentDispatch, gate, attendees, createdBy, } = params;
|
|
15
40
|
// Decide the bucket up front. A genuine meeting (a resolvable counterparty, or
|
|
16
41
|
// a bounded start+end with no trigger) lands as a :Meeting; a recurrence/action/
|
|
17
42
|
// agentDispatch or a bare one-time reminder lands as an :Event.
|
|
@@ -51,6 +76,15 @@ export async function scheduleEvent(params) {
|
|
|
51
76
|
if (agentDispatch) {
|
|
52
77
|
validateAgentDispatch(accountId, agentDispatch);
|
|
53
78
|
}
|
|
79
|
+
// Task 2378 — refused before the action block below, so a call setting both a
|
|
80
|
+
// gate and an action is told about the gate rather than about an incidental
|
|
81
|
+
// plugin-directory miss.
|
|
82
|
+
if (gate) {
|
|
83
|
+
validateGate(gate, {
|
|
84
|
+
hasAction: Boolean(action),
|
|
85
|
+
hasCompleteAgentDispatch: Boolean(agentDispatch?.channel && agentDispatch?.destination && agentDispatch?.prompt),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
54
88
|
if (action) {
|
|
55
89
|
if (!action.plugin || !action.tool) {
|
|
56
90
|
throw new Error("Action requires both 'plugin' and 'tool' fields");
|
|
@@ -143,6 +177,13 @@ export async function scheduleEvent(params) {
|
|
|
143
177
|
props.agentDestination = agentDispatch.destination;
|
|
144
178
|
props.agentPrompt = agentDispatch.prompt;
|
|
145
179
|
}
|
|
180
|
+
if (gate) {
|
|
181
|
+
props.gatePlugin = gate.plugin;
|
|
182
|
+
props.gateTool = gate.tool;
|
|
183
|
+
if (gate.args && Object.keys(gate.args).length > 0) {
|
|
184
|
+
props.gateArgs = JSON.stringify(gate.args);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
146
187
|
const parts = [`Event: ${name}`];
|
|
147
188
|
if (description)
|
|
148
189
|
parts.push(description);
|
|
@@ -155,6 +196,8 @@ export async function scheduleEvent(params) {
|
|
|
155
196
|
parts.push(`action: ${action.plugin}/${action.tool}`);
|
|
156
197
|
if (agentDispatch)
|
|
157
198
|
parts.push(`agent dispatch: ${agentDispatch.channel} → ${agentDispatch.destination}`);
|
|
199
|
+
if (gate)
|
|
200
|
+
parts.push(`gate: ${gate.plugin}/${gate.tool}`);
|
|
158
201
|
const embedding = await computeEmbedding(parts.join(" — "));
|
|
159
202
|
if (embedding.length > 0)
|
|
160
203
|
props.embedding = embedding;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule-event.js","sourceRoot":"","sources":["../../src/tools/schedule-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,kBAAkB,GAGnB,MAAM,8CAA8C,CAAC;AACtD,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,MAAM,EAAE,eAAe,EAAE,GAAG,UAAU,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAA6C,MAAM,6BAA6B,CAAC;AAC/G,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAqB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"schedule-event.js","sourceRoot":"","sources":["../../src/tools/schedule-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,kBAAkB,GAGnB,MAAM,8CAA8C,CAAC;AACtD,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,MAAM,EAAE,eAAe,EAAE,GAAG,UAAU,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAA6C,MAAM,6BAA6B,CAAC;AAC/G,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAqB,MAAM,0BAA0B,CAAC;AA2BpF;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAe,EACf,GAA8D;IAE9D,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,sKAAsK,CACvK,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,qIAAqI,CACtI,CAAC;IACJ,CAAC;AACH,CAAC;AAyCD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAA2B;IAC7D,MAAM,EACJ,SAAS,EACT,IAAI,EACJ,WAAW,EACX,SAAS,EACT,OAAO,EACP,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,eAAe,EACf,UAAU,EACV,MAAM,EACN,aAAa,EACb,IAAI,EACJ,SAAS,EACT,SAAS,GACV,GAAG,MAAM,CAAC;IAEX,+EAA+E;IAC/E,iFAAiF;IACjF,gEAAgE;IAChE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,qBAAqB,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IAC3G,OAAO,CAAC,KAAK,CAAC,mCAAmC,KAAK,WAAW,MAAM,EAAE,CAAC,CAAC;IAE3E,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,cAAc,GAAG,UAAU,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE;gBAC3C,SAAS;gBACT,IAAI;gBACJ,SAAS;gBACT,OAAO;gBACP,QAAQ;gBACR,WAAW;gBACX,QAAQ;gBACR,SAAS;gBACT,UAAU;gBACV,SAAS,EAAE;oBACT,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,EAAE;oBAC5B,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,EAAE;oBAChC,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,gBAAgB;iBACzC;aACF,CAAC,CAAC;YACH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,eAAe,EAAE,CAAC,CAAC,eAAe,EAAE,CAAC;QAC3F,CAAC;gBAAS,CAAC;YACT,MAAM,cAAc,CAAC,KAAK,EAAE,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,2EAA2E;IAC3E,sDAAsD;IACtD,IAAI,MAAM,IAAI,aAAa,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,kFAAkF,CAAC,CAAC;IACtG,CAAC;IAED,IAAI,aAAa,EAAE,CAAC;QAClB,qBAAqB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IAClD,CAAC;IAED,8EAA8E;IAC9E,4EAA4E;IAC5E,yBAAyB;IACzB,IAAI,IAAI,EAAE,CAAC;QACT,YAAY,CAAC,IAAI,EAAE;YACjB,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC;YAC1B,wBAAwB,EAAE,OAAO,CAC/B,aAAa,EAAE,OAAO,IAAI,aAAa,EAAE,WAAW,IAAI,aAAa,EAAE,MAAM,CAC9E;SACF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QAC/C,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;QAC9F,CAAC;QACD,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QACrD,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,WAAW,GAAG,GAAG,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,sCAAsC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACjD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,2DAA2D;IAC3D,8EAA8E;IAC9E,2EAA2E;IAC3E,6CAA6C;IAC7C,MAAM,YAAY,GAAG,QAAQ,IAAI,eAAe,IAAI,IAAI,CAAC;IACzD,MAAM,cAAc,GAAG,kBAAkB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACnE,OAAO,CAAC,KAAK,CACX,+CAA+C,SAAS,QAAQ,cAAc,GAAG;QAC/E,MAAM,YAAY,IAAI,GAAG,WAAW,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,EAAE,CAClG,CAAC;IAEF,IAAI,OAA2B,CAAC;IAChC,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC;YACH,+DAA+D;YAC/D,oEAAoE;YACpE,sEAAsE;YACtE,uEAAuE;YACvE,uEAAuE;YACvE,gEAAgE;YAChE,yEAAyE;YACzE,wEAAwE;YACxE,EAAE;YACF,mEAAmE;YACnE,sEAAsE;YACtE,sEAAsE;YACtE,yEAAyE;YACzE,wCAAwC;YACxC,MAAM,QAAQ,GAAG,eAAe,CAAC,UAAU,EAAE;gBAC3C,WAAW,EAAE,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBAC7D,EAAE,EAAE,QAAQ;aACb,CAAC,CAAC;YACH,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,mCAAmC,UAAU,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACvG,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,MAAM,KAAK,GAA4B;QACrC,OAAO;QACP,SAAS;QACT,IAAI;QACJ,SAAS,EAAE,cAAc;QACzB,WAAW,EAAE,WAAW;QACxB,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG;KACf,CAAC;IAEF,IAAI,WAAW;QAAE,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;IACjD,IAAI,OAAO;QAAE,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;IACrC,IAAI,QAAQ;QAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxC,IAAI,UAAU;QAAE,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;IAC9C,IAAI,QAAQ;QAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxC,IAAI,OAAO;QAAE,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;IACrC,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;QACnC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC;QAC/B,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvD,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,CAAC,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC;QAC3C,KAAK,CAAC,gBAAgB,GAAG,aAAa,CAAC,WAAW,CAAC;QACnD,KAAK,CAAC,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC;IAC3C,CAAC;IACD,IAAI,IAAI,EAAE,CAAC;QACT,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;QAC/B,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;QAC3B,IAAI,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnD,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IACjC,IAAI,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzC,KAAK,CAAC,IAAI,CAAC,WAAW,SAAS,EAAE,CAAC,CAAC;IACnC,IAAI,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,UAAU,EAAE,CAAC,CAAC;IACpD,IAAI,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,QAAQ,EAAE,CAAC,CAAC;IAC5C,IAAI,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAClE,IAAI,aAAa;QAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,aAAa,CAAC,OAAO,MAAM,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC;IACzG,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAE1D,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;IAEtD,gEAAgE;IAChE,0EAA0E;IAC1E,4EAA4E;IAC5E,oCAAoC;IACpC,MAAM,aAAa,GAAwB,EAAE,CAAC;IAC9C,MAAM,YAAY,GAAG,UAAU,EAAE,CAAC;IAClC,IAAI,CAAC;QACH,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,CAAC,GAAG,MAAM,YAAY,CAAC,GAAG,CAC9B,mFAAmF,EACnF,EAAE,UAAU,EAAE,CACf,CAAC;YACF,OAAO,CAAC,KAAK,CACX,kDAAkD,UAAU,YAAY,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAC/F,CAAC;YACF,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,aAAa,CAAC,IAAI,CAAC;oBACjB,IAAI,EAAE,SAAS;oBACf,SAAS,EAAE,UAAU;oBACrB,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAW;iBAC/C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACb,oFAAoF,UAAU,IAAI,QAAQ,wJAAwJ,CACnQ,CAAC;QACJ,CAAC;QAED,MAAM,kBAAkB,CAAC;YACvB,OAAO,EAAE,YAAY;YACrB,MAAM,EAAE,CAAC,OAAO,CAAC;YACjB,KAAK;YACL,aAAa;YACb,SAAS;SACV,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AACrC,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ScheduleUpdateResult } from "../lib/update-summary.js";
|
|
2
|
-
import type { EventAction, AgentDispatch } from "./schedule-event.js";
|
|
2
|
+
import type { EventAction, AgentDispatch, EventGate } from "./schedule-event.js";
|
|
3
3
|
/**
|
|
4
4
|
* Task 2134 — the status vocabulary, in one place.
|
|
5
5
|
*
|
|
@@ -33,6 +33,8 @@ export interface ScheduleUpdateParams {
|
|
|
33
33
|
note?: string;
|
|
34
34
|
action?: EventAction | null;
|
|
35
35
|
agentDispatch?: AgentDispatch | null;
|
|
36
|
+
/** Task 2378 — set/replace the precondition, or null to clear it. */
|
|
37
|
+
gate?: EventGate | null;
|
|
36
38
|
}
|
|
37
39
|
/**
|
|
38
40
|
* Task 2134 — the resume decision, separated from the write so it is testable
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule-update.d.ts","sourceRoot":"","sources":["../../src/tools/schedule-update.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAMpF,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"schedule-update.d.ts","sourceRoot":"","sources":["../../src/tools/schedule-update.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAMpF,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAIjF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,sEAAuE,CAAC;AAEnG,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,qEAAqE;IACrE,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,GAAG,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7E,wBAAgB,UAAU,CACxB,GAAG,EAAE;IAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EACrF,GAAG,EAAE,IAAI,GACR,UAAU,CAmCZ;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA+hBhG"}
|
|
@@ -7,6 +7,7 @@ import { computeEmbedding } from "../lib/embedding.js";
|
|
|
7
7
|
import { normaliseStartDate } from "../lib/time-format.js";
|
|
8
8
|
import cronParser from "cron-parser";
|
|
9
9
|
const { parseExpression } = cronParser;
|
|
10
|
+
import { validateGate } from "./schedule-event.js";
|
|
10
11
|
import { validateAgentDispatch } from "../lib/agent-dispatch.js";
|
|
11
12
|
/**
|
|
12
13
|
* Task 2134 — the status vocabulary, in one place.
|
|
@@ -63,7 +64,7 @@ export function planResume(row, now) {
|
|
|
63
64
|
return { ok: true, nextRun: null };
|
|
64
65
|
}
|
|
65
66
|
export async function scheduleUpdate(params) {
|
|
66
|
-
const { accountId, eventId, note, skipNext, action, agentDispatch, ...updates } = params;
|
|
67
|
+
const { accountId, eventId, note, skipNext, action, agentDispatch, gate, ...updates } = params;
|
|
67
68
|
// Task 1378 — an event carries EITHER an action OR an agent dispatch. Reject a
|
|
68
69
|
// single call that would set both; the individual set branches below also clear
|
|
69
70
|
// the opposite mode so the "at most one" invariant holds across updates.
|
|
@@ -135,13 +136,19 @@ export async function scheduleUpdate(params) {
|
|
|
135
136
|
if (updates.eventStatus !== undefined ||
|
|
136
137
|
updates.recurrence !== undefined ||
|
|
137
138
|
updates.startDate !== undefined ||
|
|
138
|
-
embedNeedsStored
|
|
139
|
+
embedNeedsStored ||
|
|
140
|
+
// Task 2378 — a gate being SET needs the row's dispatch mode to validate
|
|
141
|
+
// against. Clearing one (`gate === null`) needs nothing read: three property
|
|
142
|
+
// writes to null are valid on any row.
|
|
143
|
+
gate != null) {
|
|
139
144
|
const readSession = getSession();
|
|
140
145
|
try {
|
|
141
146
|
const read = await readSession.run(`MATCH (e:Event {eventId: $eventId, accountId: $accountId})
|
|
142
147
|
RETURN e.eventStatus AS eventStatus, e.recurrence AS recurrence,
|
|
143
148
|
e.timezone AS timezone, e.startDate AS startDate,
|
|
144
|
-
e.name AS name, e.description AS description
|
|
149
|
+
e.name AS name, e.description AS description,
|
|
150
|
+
e.agentChannel AS agentChannel, e.agentDestination AS agentDestination,
|
|
151
|
+
e.agentPrompt AS agentPrompt, e.actionPlugin AS actionPlugin`, { eventId, accountId });
|
|
145
152
|
if (read.records.length > 0) {
|
|
146
153
|
const r = read.records[0];
|
|
147
154
|
stored = {
|
|
@@ -151,6 +158,10 @@ export async function scheduleUpdate(params) {
|
|
|
151
158
|
startDate: (r.get("startDate") ?? null),
|
|
152
159
|
name: (r.get("name") ?? null),
|
|
153
160
|
description: (r.get("description") ?? null),
|
|
161
|
+
agentChannel: (r.get("agentChannel") ?? null),
|
|
162
|
+
agentDestination: (r.get("agentDestination") ?? null),
|
|
163
|
+
agentPrompt: (r.get("agentPrompt") ?? null),
|
|
164
|
+
actionPlugin: (r.get("actionPlugin") ?? null),
|
|
154
165
|
};
|
|
155
166
|
}
|
|
156
167
|
}
|
|
@@ -320,6 +331,13 @@ export async function scheduleUpdate(params) {
|
|
|
320
331
|
setClauses.push("e.agentChannel = null");
|
|
321
332
|
setClauses.push("e.agentDestination = null");
|
|
322
333
|
setClauses.push("e.agentPrompt = null");
|
|
334
|
+
// Task 2378 — and with the agent dispatch goes its gate. A gate left behind
|
|
335
|
+
// on a row that is now action-mode is three properties the dispatcher never
|
|
336
|
+
// reads, and the next `gate` edit would be refused against a state the row
|
|
337
|
+
// no longer visibly holds.
|
|
338
|
+
setClauses.push("e.gatePlugin = null");
|
|
339
|
+
setClauses.push("e.gateTool = null");
|
|
340
|
+
setClauses.push("e.gateArgs = null");
|
|
323
341
|
}
|
|
324
342
|
// Agent dispatch: set, replace, or clear (Task 1378) — mirrors the action block.
|
|
325
343
|
if (agentDispatch === null) {
|
|
@@ -349,6 +367,42 @@ export async function scheduleUpdate(params) {
|
|
|
349
367
|
setClauses.push("e.actionTool = null");
|
|
350
368
|
setClauses.push("e.actionArgs = null");
|
|
351
369
|
}
|
|
370
|
+
// Task 2378 — gate: set, replace, or clear. Mirrors the action and
|
|
371
|
+
// agentDispatch blocks. Validated against the state the row will hold after
|
|
372
|
+
// this update: whichever of action/agentDispatch this call supplies wins over
|
|
373
|
+
// the stored value, so a single call that sets both an agentDispatch and its
|
|
374
|
+
// gate is accepted, and one that sets a gate onto a row that is action-mode is
|
|
375
|
+
// refused with the reason named.
|
|
376
|
+
if (gate === null) {
|
|
377
|
+
setClauses.push("e.gatePlugin = null");
|
|
378
|
+
setClauses.push("e.gateTool = null");
|
|
379
|
+
setClauses.push("e.gateArgs = null");
|
|
380
|
+
}
|
|
381
|
+
else if (gate !== undefined) {
|
|
382
|
+
const effectiveAction = action === null ? false : action !== undefined || Boolean(stored?.actionPlugin);
|
|
383
|
+
const effectiveDispatch = agentDispatch === null
|
|
384
|
+
? false
|
|
385
|
+
: agentDispatch !== undefined
|
|
386
|
+
? Boolean(agentDispatch.channel && agentDispatch.destination && agentDispatch.prompt)
|
|
387
|
+
: Boolean(stored?.agentChannel && stored?.agentDestination && stored?.agentPrompt);
|
|
388
|
+
validateGate(gate, {
|
|
389
|
+
hasAction: effectiveAction,
|
|
390
|
+
hasCompleteAgentDispatch: effectiveDispatch,
|
|
391
|
+
});
|
|
392
|
+
setClauses.push("e.gatePlugin = $gatePlugin");
|
|
393
|
+
setClauses.push("e.gateTool = $gateTool");
|
|
394
|
+
queryParams.gatePlugin = gate.plugin;
|
|
395
|
+
queryParams.gateTool = gate.tool;
|
|
396
|
+
if (gate.args && Object.keys(gate.args).length > 0) {
|
|
397
|
+
setClauses.push("e.gateArgs = $gateArgs");
|
|
398
|
+
queryParams.gateArgs = JSON.stringify(gate.args);
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
// Same handling as actionArgs: replacing a gate with an argument-less one
|
|
402
|
+
// must not leave the previous gate's arguments behind for the new tool.
|
|
403
|
+
setClauses.push("e.gateArgs = null");
|
|
404
|
+
}
|
|
405
|
+
}
|
|
352
406
|
// One append, however many lines it carries. Two appendNotesCapped clauses in
|
|
353
407
|
// the same SET both write e.notes, and the later would drop the earlier.
|
|
354
408
|
const noteLines = [];
|