@easyoref/agent 1.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/__tests__/clarify.test.ts +827 -0
  2. package/__tests__/config.test.ts +304 -0
  3. package/__tests__/enrichment.integration.test.ts +871 -0
  4. package/__tests__/graph.test.ts +661 -0
  5. package/dist/auth.d.ts +11 -0
  6. package/dist/auth.d.ts.map +1 -0
  7. package/dist/auth.js +54 -0
  8. package/dist/auth.js.map +1 -0
  9. package/dist/dry-run.d.ts +12 -0
  10. package/dist/dry-run.d.ts.map +1 -0
  11. package/dist/dry-run.js +236 -0
  12. package/dist/dry-run.js.map +1 -0
  13. package/dist/extract.d.ts +180 -0
  14. package/dist/extract.d.ts.map +1 -0
  15. package/dist/extract.js +210 -0
  16. package/dist/extract.js.map +1 -0
  17. package/dist/graph.d.ts +4083 -0
  18. package/dist/graph.d.ts.map +1 -0
  19. package/dist/graph.js +162 -0
  20. package/dist/graph.js.map +1 -0
  21. package/dist/index.d.ts +23 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +23 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/models.d.ts +7 -0
  26. package/dist/models.d.ts.map +1 -0
  27. package/dist/models.js +18 -0
  28. package/dist/models.js.map +1 -0
  29. package/dist/nodes/clarify-node.d.ts +132 -0
  30. package/dist/nodes/clarify-node.d.ts.map +1 -0
  31. package/dist/nodes/clarify-node.js +118 -0
  32. package/dist/nodes/clarify-node.js.map +1 -0
  33. package/dist/nodes/clarify.d.ts +6 -0
  34. package/dist/nodes/clarify.d.ts.map +1 -0
  35. package/dist/nodes/clarify.js +124 -0
  36. package/dist/nodes/clarify.js.map +1 -0
  37. package/dist/nodes/edit-node.d.ts +71 -0
  38. package/dist/nodes/edit-node.d.ts.map +1 -0
  39. package/dist/nodes/edit-node.js +496 -0
  40. package/dist/nodes/edit-node.js.map +1 -0
  41. package/dist/nodes/edit.d.ts +6 -0
  42. package/dist/nodes/edit.d.ts.map +1 -0
  43. package/dist/nodes/edit.js +22 -0
  44. package/dist/nodes/edit.js.map +1 -0
  45. package/dist/nodes/extract-node.d.ts +174 -0
  46. package/dist/nodes/extract-node.d.ts.map +1 -0
  47. package/dist/nodes/extract-node.js +233 -0
  48. package/dist/nodes/extract-node.js.map +1 -0
  49. package/dist/nodes/extract.d.ts +6 -0
  50. package/dist/nodes/extract.d.ts.map +1 -0
  51. package/dist/nodes/extract.js +49 -0
  52. package/dist/nodes/extract.js.map +1 -0
  53. package/dist/nodes/filter-agent.d.ts +11 -0
  54. package/dist/nodes/filter-agent.d.ts.map +1 -0
  55. package/dist/nodes/filter-agent.js +60 -0
  56. package/dist/nodes/filter-agent.js.map +1 -0
  57. package/dist/nodes/filter-node.d.ts +9 -0
  58. package/dist/nodes/filter-node.d.ts.map +1 -0
  59. package/dist/nodes/filter-node.js +111 -0
  60. package/dist/nodes/filter-node.js.map +1 -0
  61. package/dist/nodes/filters.d.ts +13 -0
  62. package/dist/nodes/filters.d.ts.map +1 -0
  63. package/dist/nodes/filters.js +111 -0
  64. package/dist/nodes/filters.js.map +1 -0
  65. package/dist/nodes/message-node.d.ts +71 -0
  66. package/dist/nodes/message-node.d.ts.map +1 -0
  67. package/dist/nodes/message-node.js +491 -0
  68. package/dist/nodes/message-node.js.map +1 -0
  69. package/dist/nodes/message.d.ts +71 -0
  70. package/dist/nodes/message.d.ts.map +1 -0
  71. package/dist/nodes/message.js +496 -0
  72. package/dist/nodes/message.js.map +1 -0
  73. package/dist/nodes/vote-node.d.ts +13 -0
  74. package/dist/nodes/vote-node.d.ts.map +1 -0
  75. package/dist/nodes/vote-node.js +232 -0
  76. package/dist/nodes/vote-node.js.map +1 -0
  77. package/dist/nodes/vote.d.ts +13 -0
  78. package/dist/nodes/vote.d.ts.map +1 -0
  79. package/dist/nodes/vote.js +232 -0
  80. package/dist/nodes/vote.js.map +1 -0
  81. package/dist/queue.d.ts +15 -0
  82. package/dist/queue.d.ts.map +1 -0
  83. package/dist/queue.js +41 -0
  84. package/dist/queue.js.map +1 -0
  85. package/dist/redis.d.ts +8 -0
  86. package/dist/redis.d.ts.map +1 -0
  87. package/dist/redis.js +33 -0
  88. package/dist/redis.js.map +1 -0
  89. package/dist/runtime/auth.d.ts +11 -0
  90. package/dist/runtime/auth.d.ts.map +1 -0
  91. package/dist/runtime/auth.js +54 -0
  92. package/dist/runtime/auth.js.map +1 -0
  93. package/dist/runtime/dry-run.d.ts +12 -0
  94. package/dist/runtime/dry-run.d.ts.map +1 -0
  95. package/dist/runtime/dry-run.js +236 -0
  96. package/dist/runtime/dry-run.js.map +1 -0
  97. package/dist/runtime/queue.d.ts +15 -0
  98. package/dist/runtime/queue.d.ts.map +1 -0
  99. package/dist/runtime/queue.js +41 -0
  100. package/dist/runtime/queue.js.map +1 -0
  101. package/dist/runtime/redis.d.ts +8 -0
  102. package/dist/runtime/redis.d.ts.map +1 -0
  103. package/dist/runtime/redis.js +33 -0
  104. package/dist/runtime/redis.js.map +1 -0
  105. package/dist/runtime/worker.d.ts +14 -0
  106. package/dist/runtime/worker.d.ts.map +1 -0
  107. package/dist/runtime/worker.js +135 -0
  108. package/dist/runtime/worker.js.map +1 -0
  109. package/dist/tools/alert-history.d.ts +18 -0
  110. package/dist/tools/alert-history.d.ts.map +1 -0
  111. package/dist/tools/alert-history.js +98 -0
  112. package/dist/tools/alert-history.js.map +1 -0
  113. package/dist/tools/betterstack-log.d.ts +15 -0
  114. package/dist/tools/betterstack-log.d.ts.map +1 -0
  115. package/dist/tools/betterstack-log.js +80 -0
  116. package/dist/tools/betterstack-log.js.map +1 -0
  117. package/dist/tools/index.d.ts +44 -0
  118. package/dist/tools/index.d.ts.map +1 -0
  119. package/dist/tools/index.js +20 -0
  120. package/dist/tools/index.js.map +1 -0
  121. package/dist/tools/read-sources.d.ts +15 -0
  122. package/dist/tools/read-sources.d.ts.map +1 -0
  123. package/dist/tools/read-sources.js +67 -0
  124. package/dist/tools/read-sources.js.map +1 -0
  125. package/dist/tools/resolve-area.d.ts +19 -0
  126. package/dist/tools/resolve-area.d.ts.map +1 -0
  127. package/dist/tools/resolve-area.js +147 -0
  128. package/dist/tools/resolve-area.js.map +1 -0
  129. package/dist/tools.d.ts +115 -0
  130. package/dist/tools.d.ts.map +1 -0
  131. package/dist/tools.js +439 -0
  132. package/dist/tools.js.map +1 -0
  133. package/dist/worker.d.ts +14 -0
  134. package/dist/worker.d.ts.map +1 -0
  135. package/dist/worker.js +135 -0
  136. package/dist/worker.js.map +1 -0
  137. package/package.json +26 -0
  138. package/src/graph.ts +200 -0
  139. package/src/index.ts +27 -0
  140. package/src/models.ts +20 -0
  141. package/src/nodes/clarify-node.ts +172 -0
  142. package/src/nodes/edit-node.ts +695 -0
  143. package/src/nodes/extract-node.ts +299 -0
  144. package/src/nodes/filter-node.ts +139 -0
  145. package/src/nodes/message.ts +695 -0
  146. package/src/nodes/vote-node.ts +354 -0
  147. package/src/nodes/vote.ts +354 -0
  148. package/src/runtime/auth.ts +63 -0
  149. package/src/runtime/dry-run.ts +303 -0
  150. package/src/runtime/queue.ts +53 -0
  151. package/src/runtime/redis.ts +38 -0
  152. package/src/runtime/worker.ts +167 -0
  153. package/src/tools/alert-history.ts +120 -0
  154. package/src/tools/betterstack-log.ts +102 -0
  155. package/src/tools/index.ts +23 -0
  156. package/src/tools/read-sources.ts +86 -0
  157. package/src/tools/resolve-area.ts +202 -0
  158. package/tsconfig.json +14 -0
@@ -0,0 +1,115 @@
1
+ /**
2
+ * LangChain tool definitions for agentic clarification.
3
+ *
4
+ * 4 tools the LLM can choose to call (or not):
5
+ *
6
+ * 1. read_telegram_sources
7
+ * → Fetch last 1-4 posts from a Telegram news channel via MTProto.
8
+ * Returns actual message texts — the LLM extracts data from them.
9
+ * Rate-limited: max 4 posts/call, anti-flood jitter.
10
+ *
11
+ * 2. alert_history
12
+ * → Get recent alert history from Pikud HaOref.
13
+ * Answers: "was there really an alert in area X recently?"
14
+ * More useful than active alerts (bot already has those).
15
+ *
16
+ * 3. resolve_area
17
+ * → Determine if a mentioned location is relevant to user's
18
+ * monitored areas. "попадание в Петах Тикве" → relevant for
19
+ * Герцлия? (same defense zone / Gush Dan).
20
+ *
21
+ * 4. betterstack_log
22
+ * → Query recent EasyOref logs from Better Stack.
23
+ * Answers: "what happened in the enrichment pipeline recently?"
24
+ * Uses existing Logtail token (observability.betterstack_token).
25
+ *
26
+ * Each tool returns a JSON string consumable by the LLM.
27
+ * Error handling: tool failures return { error, retry } objects.
28
+ */
29
+ import { z } from "zod";
30
+ /**
31
+ * Resolve whether a mentioned location is in the same defense zone
32
+ * as any of the user's monitored areas.
33
+ */
34
+ declare function resolveAreaProximity(mentioned: string, monitoredAreas: string[]): {
35
+ relevant: boolean;
36
+ sameZone: string | undefined;
37
+ monitoredMatch: string[];
38
+ reasoning: string;
39
+ };
40
+ export { resolveAreaProximity as _resolveAreaProximity };
41
+ export declare const readSourcesTool: import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
42
+ channel: z.ZodString;
43
+ limit: z.ZodDefault<z.ZodNumber>;
44
+ }, z.core.$strip>, {
45
+ channel: string;
46
+ limit: number;
47
+ }, {
48
+ channel: string;
49
+ limit?: number | undefined;
50
+ }, string, unknown, "read_telegram_sources">;
51
+ export declare const alertHistoryTool: import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
52
+ area: z.ZodString;
53
+ last_minutes: z.ZodDefault<z.ZodNumber>;
54
+ }, z.core.$strip>, {
55
+ area: string;
56
+ last_minutes: number;
57
+ }, {
58
+ area: string;
59
+ last_minutes?: number | undefined;
60
+ }, string, unknown, "alert_history">;
61
+ export declare const resolveAreaTool: import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
62
+ location: z.ZodString;
63
+ }, z.core.$strip>, {
64
+ location: string;
65
+ }, {
66
+ location: string;
67
+ }, string, unknown, "resolve_area">;
68
+ /** Format date as DD.MM.YYYY for Oref history API */
69
+ declare function formatOrefDate(d: Date): string;
70
+ export { formatOrefDate as _formatOrefDate };
71
+ export declare const betterstackLogTool: import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
72
+ query: z.ZodString;
73
+ last_minutes: z.ZodDefault<z.ZodNumber>;
74
+ }, z.core.$strip>, {
75
+ query: string;
76
+ last_minutes: number;
77
+ }, {
78
+ query: string;
79
+ last_minutes?: number | undefined;
80
+ }, string, unknown, "betterstack_log">;
81
+ export declare const clarifyTools: (import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
82
+ channel: z.ZodString;
83
+ limit: z.ZodDefault<z.ZodNumber>;
84
+ }, z.core.$strip>, {
85
+ channel: string;
86
+ limit: number;
87
+ }, {
88
+ channel: string;
89
+ limit?: number | undefined;
90
+ }, string, unknown, "read_telegram_sources"> | import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
91
+ area: z.ZodString;
92
+ last_minutes: z.ZodDefault<z.ZodNumber>;
93
+ }, z.core.$strip>, {
94
+ area: string;
95
+ last_minutes: number;
96
+ }, {
97
+ area: string;
98
+ last_minutes?: number | undefined;
99
+ }, string, unknown, "alert_history"> | import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
100
+ location: z.ZodString;
101
+ }, z.core.$strip>, {
102
+ location: string;
103
+ }, {
104
+ location: string;
105
+ }, string, unknown, "resolve_area"> | import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
106
+ query: z.ZodString;
107
+ last_minutes: z.ZodDefault<z.ZodNumber>;
108
+ }, z.core.$strip>, {
109
+ query: string;
110
+ last_minutes: number;
111
+ }, {
112
+ query: string;
113
+ last_minutes?: number | undefined;
114
+ }, string, unknown, "betterstack_log">)[];
115
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA2DxB;;;GAGG;AACH,iBAAS,oBAAoB,CAC3B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EAAE,GACvB;IACD,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,CAmFA;AAID,OAAO,EAAE,oBAAoB,IAAI,qBAAqB,EAAE,CAAC;AAIzD,eAAO,MAAM,eAAe;;;;;;;;;4CA2E3B,CAAC;AAIF,eAAO,MAAM,gBAAgB;;;;;;;;;oCAqG5B,CAAC;AAIF,eAAO,MAAM,eAAe;;;;;;mCA2C3B,CAAC;AAIF,qDAAqD;AACrD,iBAAS,cAAc,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAKvC;AAED,OAAO,EAAE,cAAc,IAAI,eAAe,EAAE,CAAC;AAI7C,eAAO,MAAM,kBAAkB;;;;;;;;;sCAwG9B,CAAC;AAIF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAKxB,CAAC"}
package/dist/tools.js ADDED
@@ -0,0 +1,439 @@
1
+ /**
2
+ * LangChain tool definitions for agentic clarification.
3
+ *
4
+ * 4 tools the LLM can choose to call (or not):
5
+ *
6
+ * 1. read_telegram_sources
7
+ * → Fetch last 1-4 posts from a Telegram news channel via MTProto.
8
+ * Returns actual message texts — the LLM extracts data from them.
9
+ * Rate-limited: max 4 posts/call, anti-flood jitter.
10
+ *
11
+ * 2. alert_history
12
+ * → Get recent alert history from Pikud HaOref.
13
+ * Answers: "was there really an alert in area X recently?"
14
+ * More useful than active alerts (bot already has those).
15
+ *
16
+ * 3. resolve_area
17
+ * → Determine if a mentioned location is relevant to user's
18
+ * monitored areas. "попадание в Петах Тикве" → relevant for
19
+ * Герцлия? (same defense zone / Gush Dan).
20
+ *
21
+ * 4. betterstack_log
22
+ * → Query recent EasyOref logs from Better Stack.
23
+ * Answers: "what happened in the enrichment pipeline recently?"
24
+ * Uses existing Logtail token (observability.betterstack_token).
25
+ *
26
+ * Each tool returns a JSON string consumable by the LLM.
27
+ * Error handling: tool failures return { error, retry } objects.
28
+ */
29
+ import { fetchRecentChannelPosts } from "@easyoref/gramjs";
30
+ import * as logger from "@easyoref/monitoring";
31
+ import { config } from "@easyoref/shared";
32
+ import { tool } from "@langchain/core/tools";
33
+ import { z } from "zod";
34
+ // ── Area proximity data ────────────────────────────────
35
+ /**
36
+ * Defense-zone proximity groups.
37
+ * Cities in the same group share Iron Dome coverage, similar ETA,
38
+ * and are typically alerted together in large barrages.
39
+ * Source: Pikud HaOref zone mapping.
40
+ */
41
+ const AREA_PROXIMITY_GROUPS = {
42
+ "גוש דן": [
43
+ "תל אביב",
44
+ "רמת גן",
45
+ "גבעתיים",
46
+ "בני ברק",
47
+ "חולון",
48
+ "בת ים",
49
+ "פתח תקווה",
50
+ "גבעת שמואל",
51
+ "אור יהודה",
52
+ "יהוד",
53
+ "קריית אונו",
54
+ ],
55
+ שרון: [
56
+ "הרצליה",
57
+ "רעננה",
58
+ "כפר סבא",
59
+ "הוד השרון",
60
+ "נתניה",
61
+ "רמת השרון",
62
+ "כוכב יאיר",
63
+ ],
64
+ מרכז: [
65
+ "ראשון לציון",
66
+ "רחובות",
67
+ "נס ציונה",
68
+ "לוד",
69
+ "רמלה",
70
+ "מודיעין",
71
+ "יבנה",
72
+ "שוהם",
73
+ ],
74
+ ירושלים: ["ירושלים", "בית שמש", "מעלה אדומים", "מבשרת ציון"],
75
+ חיפה: [
76
+ "חיפה",
77
+ "קריות",
78
+ "קריית אתא",
79
+ "קריית ביאליק",
80
+ "קריית מוצקין",
81
+ "טירת כרמל",
82
+ "נשר",
83
+ ],
84
+ "דרום-מערב": ["אשקלון", "אשדוד", "גן יבנה", "קריית מלאכי"],
85
+ "עוטף עזה": ["שדרות", "עוטף עזה", "נתיבות", "אופקים"],
86
+ "באר שבע": ["באר שבע", "ערד", "דימונה"],
87
+ "גליל עליון": ["קריית שמונה", "מטולה", "צפת", "ראש פינה"],
88
+ };
89
+ /**
90
+ * Resolve whether a mentioned location is in the same defense zone
91
+ * as any of the user's monitored areas.
92
+ */
93
+ function resolveAreaProximity(mentioned, monitoredAreas) {
94
+ const mentionedLower = mentioned.trim();
95
+ // 1. Direct match — mentioned location IS a monitored area
96
+ for (const m of monitoredAreas) {
97
+ if (m.includes(mentionedLower) ||
98
+ mentionedLower.includes(m.split(" ")[0] ?? "")) {
99
+ return {
100
+ relevant: true,
101
+ sameZone: undefined,
102
+ monitoredMatch: [m],
103
+ reasoning: `"${mentioned}" directly matches monitored area "${m}"`,
104
+ };
105
+ }
106
+ }
107
+ // 2. Zone-based proximity — find which zone the mentioned area belongs to
108
+ for (const [zone, cities] of Object.entries(AREA_PROXIMITY_GROUPS)) {
109
+ const mentionedInZone = cities.some((c) => mentionedLower.includes(c) || c.includes(mentionedLower));
110
+ if (!mentionedInZone)
111
+ continue;
112
+ // Check if any monitored area is in the same zone
113
+ const matchedMonitored = monitoredAreas.filter((m) => cities.some((c) => m.includes(c) || c.includes(m.split(" ")[0] ?? "")));
114
+ if (matchedMonitored.length > 0) {
115
+ return {
116
+ relevant: true,
117
+ sameZone: zone,
118
+ monitoredMatch: matchedMonitored,
119
+ reasoning: `"${mentioned}" is in zone "${zone}" together with monitored: ` +
120
+ matchedMonitored.join(", "),
121
+ };
122
+ }
123
+ return {
124
+ relevant: false,
125
+ sameZone: zone,
126
+ monitoredMatch: [],
127
+ reasoning: `"${mentioned}" is in zone "${zone}" but none of user's monitored ` +
128
+ `areas (${monitoredAreas.join(", ")}) are in that zone`,
129
+ };
130
+ }
131
+ // 3. Generic region keywords
132
+ const regionKeywords = {
133
+ מרכז: ["תל אביב", "רמת גן", "פתח תקווה", "ראשון לציון", "הרצליה", "חולון"],
134
+ צפון: ["חיפה", "קריות", "צפת", "קריית שמונה", "נצרת", "עכו", "טבריה"],
135
+ דרום: ["באר שבע", "אשדוד", "אשקלון", "שדרות", "אילת"],
136
+ };
137
+ for (const [region, cities] of Object.entries(regionKeywords)) {
138
+ if (!mentionedLower.includes(region))
139
+ continue;
140
+ const matchedMonitored = monitoredAreas.filter((m) => cities.some((c) => m.includes(c) || c.includes(m.split(" ")[0] ?? "")));
141
+ if (matchedMonitored.length > 0) {
142
+ return {
143
+ relevant: true,
144
+ sameZone: region,
145
+ monitoredMatch: matchedMonitored,
146
+ reasoning: `"${mentioned}" refers to region "${region}" which includes ` +
147
+ matchedMonitored.join(", "),
148
+ };
149
+ }
150
+ }
151
+ return {
152
+ relevant: false,
153
+ sameZone: undefined,
154
+ monitoredMatch: [],
155
+ reasoning: `"${mentioned}" could not be matched to any monitored area ` +
156
+ `(${monitoredAreas.join(", ")})`,
157
+ };
158
+ }
159
+ // ── Exported for testing ───────────────────────────────
160
+ export { resolveAreaProximity as _resolveAreaProximity };
161
+ // ── 1. Read Source Channels (MTProto) ──────────────────
162
+ export const readSourcesTool = tool(async ({ channel, limit, }) => {
163
+ try {
164
+ const safeLimit = Math.min(limit, config.agent.clarifyFetchCount);
165
+ const posts = await fetchRecentChannelPosts(channel, safeLimit);
166
+ if (posts.length === 0) {
167
+ return JSON.stringify({
168
+ channel,
169
+ posts: [],
170
+ note: "No recent posts found or channel not accessible",
171
+ });
172
+ }
173
+ const result = {
174
+ channel,
175
+ posts: posts.map((p) => ({
176
+ text: p.text.slice(0, 800),
177
+ ts: p.ts,
178
+ messageUrl: p.messageUrl,
179
+ })),
180
+ count: posts.length,
181
+ };
182
+ logger.info("Tool: read_telegram_sources executed", {
183
+ channel,
184
+ limit: safeLimit,
185
+ returned: posts.length,
186
+ });
187
+ return JSON.stringify(result);
188
+ }
189
+ catch (err) {
190
+ const errStr = String(err);
191
+ const isRateLimit = errStr.includes("FLOOD") || errStr.includes("rate limit");
192
+ logger.warn("Tool: read_telegram_sources failed", {
193
+ channel,
194
+ error: errStr,
195
+ });
196
+ return JSON.stringify({
197
+ error: `Failed to fetch from ${channel}: ${errStr}`,
198
+ retry: !isRateLimit,
199
+ });
200
+ }
201
+ }, {
202
+ name: "read_telegram_sources",
203
+ description: "Fetch last 1-4 posts from a Telegram news channel via MTProto. " +
204
+ "Returns actual message texts you can extract data from. " +
205
+ "Authoritative channels: @idf_telegram (IDF official), @N12LIVE (news), " +
206
+ "@israelsecurity (security), @ynetalerts (Ynet). " +
207
+ "Use when existing sources contradict each other or you need confirmation.",
208
+ schema: z.object({
209
+ channel: z
210
+ .string()
211
+ .describe("Channel username with @ prefix (e.g. @idf_telegram)"),
212
+ limit: z
213
+ .number()
214
+ .min(1)
215
+ .max(4)
216
+ .default(3)
217
+ .describe("Number of recent posts to fetch (1-4)"),
218
+ }),
219
+ });
220
+ // ── 2. Pikud HaOref Alert History ──────────────────────
221
+ export const alertHistoryTool = tool(async ({ area, last_minutes, }) => {
222
+ try {
223
+ const historyUrl = config.orefHistoryUrl ??
224
+ "https://www.oref.org.il/Shared/Ajax/GetAlarmsHistory.aspx?lang=he&fromDate=" +
225
+ formatOrefDate(new Date(Date.now() - last_minutes * 60_000)) +
226
+ "&toDate=" +
227
+ formatOrefDate(new Date());
228
+ const res = await fetch(historyUrl, {
229
+ headers: {
230
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
231
+ "X-Requested-With": "XMLHttpRequest",
232
+ Referer: "https://www.oref.org.il/",
233
+ Accept: "application/json, text/plain, */*",
234
+ },
235
+ signal: AbortSignal.timeout(5000),
236
+ });
237
+ if (!res.ok) {
238
+ return JSON.stringify({
239
+ error: `Oref history API returned ${res.status}`,
240
+ retry: true,
241
+ });
242
+ }
243
+ const text = await res.text();
244
+ if (!text.trim()) {
245
+ return JSON.stringify({
246
+ area,
247
+ alerts: [],
248
+ note: "No alert history returned for this period",
249
+ });
250
+ }
251
+ const parsed = JSON.parse(text);
252
+ const alerts = Array.isArray(parsed) ? parsed : [parsed];
253
+ // Filter by area
254
+ const relevant = alerts.filter((a) => {
255
+ const data = a.data ?? "";
256
+ return data.includes(area) || area.includes(data.split(" ")[0] ?? "");
257
+ });
258
+ const result = {
259
+ area,
260
+ last_minutes,
261
+ alerts: relevant.slice(0, 20).map((a) => ({
262
+ date: a.alertDate ?? a.date,
263
+ title: a.title,
264
+ data: a.data,
265
+ category: a.category_desc ?? a.category,
266
+ })),
267
+ total_in_period: alerts.length,
268
+ relevant_count: relevant.length,
269
+ queried_at: new Date().toISOString(),
270
+ };
271
+ logger.info("Tool: alert_history executed", {
272
+ area,
273
+ last_minutes,
274
+ total: alerts.length,
275
+ relevant: relevant.length,
276
+ });
277
+ return JSON.stringify(result);
278
+ }
279
+ catch (err) {
280
+ logger.warn("Tool: alert_history failed", { error: String(err) });
281
+ return JSON.stringify({
282
+ error: `Oref history API call failed: ${String(err)}`,
283
+ retry: true,
284
+ });
285
+ }
286
+ }, {
287
+ name: "alert_history",
288
+ description: "Get recent alert history from Pikud HaOref (Israel Home Front Command). " +
289
+ "Answers: 'was there really an alert in area X in the last N minutes?' " +
290
+ "More useful than active alerts (the bot already has the current alert). " +
291
+ "Use to verify channel claims about attacks in specific areas.",
292
+ schema: z.object({
293
+ area: z
294
+ .string()
295
+ .describe("Hebrew area name to search for in history (e.g. תל אביב)"),
296
+ last_minutes: z
297
+ .number()
298
+ .min(5)
299
+ .max(120)
300
+ .default(30)
301
+ .describe("How many minutes of history to search (5-120)"),
302
+ }),
303
+ });
304
+ // ── 3. Resolve Area Relevance ──────────────────────────
305
+ export const resolveAreaTool = tool(async ({ location }) => {
306
+ const monitoredAreas = config.areas;
307
+ if (monitoredAreas.length === 0) {
308
+ return JSON.stringify({
309
+ error: "No monitored areas configured",
310
+ hint: "User has not set up city monitoring",
311
+ });
312
+ }
313
+ const result = resolveAreaProximity(location, monitoredAreas);
314
+ logger.info("Tool: resolve_area executed", {
315
+ location,
316
+ relevant: result.relevant,
317
+ zone: result.sameZone,
318
+ });
319
+ return JSON.stringify({
320
+ location,
321
+ monitored_areas: monitoredAreas,
322
+ ...result,
323
+ });
324
+ }, {
325
+ name: "resolve_area",
326
+ description: "Determine if a location mentioned in news is relevant to the user's " +
327
+ "monitored areas. Uses defense-zone proximity: cities in the same Iron Dome " +
328
+ "coverage zone are considered relevant. " +
329
+ 'Example: "попадание в Петах Тикве" → relevant for Herzliya user ' +
330
+ "(both in Gush Dan / Sharon zone). " +
331
+ 'Use when a news post mentions a city or region like "center" and you need ' +
332
+ "to determine if it affects the user.",
333
+ schema: z.object({
334
+ location: z
335
+ .string()
336
+ .describe("City or region name in Hebrew as mentioned in news (e.g. פתח תקווה, מרכז)"),
337
+ }),
338
+ });
339
+ // ── Helper ─────────────────────────────────────────────
340
+ /** Format date as DD.MM.YYYY for Oref history API */
341
+ function formatOrefDate(d) {
342
+ const dd = String(d.getDate()).padStart(2, "0");
343
+ const mm = String(d.getMonth() + 1).padStart(2, "0");
344
+ const yyyy = d.getFullYear();
345
+ return `${dd}.${mm}.${yyyy}`;
346
+ }
347
+ export { formatOrefDate as _formatOrefDate };
348
+ // ── 4. Better Stack Log Query ──────────────────────────
349
+ export const betterstackLogTool = tool(async ({ query, last_minutes, }) => {
350
+ const token = config.logtailToken;
351
+ if (!token) {
352
+ return JSON.stringify({
353
+ error: "Better Stack token not configured",
354
+ hint: "Set observability.betterstack_token in config.yaml or LOGTAIL_TOKEN env",
355
+ });
356
+ }
357
+ try {
358
+ const now = new Date();
359
+ const from = new Date(now.getTime() - last_minutes * 60_000);
360
+ const params = new URLSearchParams({
361
+ query,
362
+ batch: "20",
363
+ from: from.toISOString(),
364
+ to: now.toISOString(),
365
+ order: "newest_first",
366
+ });
367
+ const res = await fetch(`https://logs.betterstack.com/api/v1/query?${params}`, {
368
+ headers: {
369
+ Authorization: `Bearer ${token}`,
370
+ Accept: "application/json",
371
+ },
372
+ signal: AbortSignal.timeout(8000),
373
+ });
374
+ if (!res.ok) {
375
+ const body = await res.text().catch(() => "");
376
+ return JSON.stringify({
377
+ error: `Better Stack API returned ${res.status}`,
378
+ body: body.slice(0, 200),
379
+ retry: res.status >= 500,
380
+ });
381
+ }
382
+ const json = (await res.json());
383
+ const events = Array.isArray(json.data) ? json.data : [];
384
+ const result = {
385
+ query,
386
+ last_minutes,
387
+ events: events.slice(0, 20).map((e) => {
388
+ const ev = e;
389
+ return {
390
+ dt: ev.dt ?? ev.timestamp,
391
+ message: ev.message ?? ev.msg,
392
+ level: ev.level ?? ev.severity,
393
+ context: ev.context ?? ev.metadata,
394
+ };
395
+ }),
396
+ total: events.length,
397
+ queried_at: now.toISOString(),
398
+ };
399
+ logger.info("Tool: betterstack_log executed", {
400
+ query,
401
+ last_minutes,
402
+ total: events.length,
403
+ });
404
+ return JSON.stringify(result);
405
+ }
406
+ catch (err) {
407
+ logger.warn("Tool: betterstack_log failed", { error: String(err) });
408
+ return JSON.stringify({
409
+ error: `Better Stack query failed: ${String(err)}`,
410
+ retry: true,
411
+ });
412
+ }
413
+ }, {
414
+ name: "betterstack_log",
415
+ description: "Query recent EasyOref logs from Better Stack (Logtail). " +
416
+ "Search for log entries matching a text query within a time window. " +
417
+ "Use when you need to understand what the enrichment pipeline did recently — " +
418
+ "e.g. which alerts were processed, what extractions were made, or why " +
419
+ "confidence was low. Returns up to 20 most recent matching log entries.",
420
+ schema: z.object({
421
+ query: z
422
+ .string()
423
+ .describe("Text to search for in logs (e.g. 'alert_history', 'Clarify', 'enrichment')"),
424
+ last_minutes: z
425
+ .number()
426
+ .min(1)
427
+ .max(60)
428
+ .default(15)
429
+ .describe("How many minutes of logs to search (1-60)"),
430
+ }),
431
+ });
432
+ // ── Exported tool array ────────────────────────────────
433
+ export const clarifyTools = [
434
+ readSourcesTool,
435
+ alertHistoryTool,
436
+ resolveAreaTool,
437
+ betterstackLogTool,
438
+ ];
439
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,MAAM,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,0DAA0D;AAE1D;;;;;GAKG;AACH,MAAM,qBAAqB,GAA6B;IACtD,QAAQ,EAAE;QACR,SAAS;QACT,QAAQ;QACR,SAAS;QACT,SAAS;QACT,OAAO;QACP,OAAO;QACP,WAAW;QACX,YAAY;QACZ,WAAW;QACX,MAAM;QACN,YAAY;KACb;IACD,IAAI,EAAE;QACJ,QAAQ;QACR,OAAO;QACP,SAAS;QACT,WAAW;QACX,OAAO;QACP,WAAW;QACX,WAAW;KACZ;IACD,IAAI,EAAE;QACJ,aAAa;QACb,QAAQ;QACR,UAAU;QACV,KAAK;QACL,MAAM;QACN,SAAS;QACT,MAAM;QACN,MAAM;KACP;IACD,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,CAAC;IAC5D,IAAI,EAAE;QACJ,MAAM;QACN,OAAO;QACP,WAAW;QACX,cAAc;QACd,cAAc;QACd,WAAW;QACX,KAAK;KACN;IACD,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,CAAC;IAC1D,UAAU,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC;IACrD,SAAS,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,CAAC;IACvC,YAAY,EAAE,CAAC,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC;CAC1D,CAAC;AAEF;;;GAGG;AACH,SAAS,oBAAoB,CAC3B,SAAiB,EACjB,cAAwB;IAOxB,MAAM,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAExC,2DAA2D;IAC3D,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC/B,IACE,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC1B,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAC9C,CAAC;YACD,OAAO;gBACL,QAAQ,EAAE,IAAI;gBACd,QAAQ,EAAE,SAAS;gBACnB,cAAc,EAAE,CAAC,CAAC,CAAC;gBACnB,SAAS,EAAE,IAAI,SAAS,sCAAsC,CAAC,GAAG;aACnE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAAE,CAAC;QACnE,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CACjC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAChE,CAAC;QACF,IAAI,CAAC,eAAe;YAAE,SAAS;QAE/B,kDAAkD;QAClD,MAAM,gBAAgB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACnD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CACvE,CAAC;QAEF,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,OAAO;gBACL,QAAQ,EAAE,IAAI;gBACd,QAAQ,EAAE,IAAI;gBACd,cAAc,EAAE,gBAAgB;gBAChC,SAAS,EACP,IAAI,SAAS,iBAAiB,IAAI,6BAA6B;oBAC/D,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;aAC9B,CAAC;QACJ,CAAC;QAED,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,QAAQ,EAAE,IAAI;YACd,cAAc,EAAE,EAAE;YAClB,SAAS,EACP,IAAI,SAAS,iBAAiB,IAAI,iCAAiC;gBACnE,UAAU,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB;SAC1D,CAAC;IACJ,CAAC;IAED,6BAA6B;IAC7B,MAAM,cAAc,GAA6B;QAC/C,IAAI,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,CAAC;QAC1E,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC;QACrE,IAAI,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC;KACtD,CAAC;IAEF,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,SAAS;QAC/C,MAAM,gBAAgB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACnD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CACvE,CAAC;QACF,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,OAAO;gBACL,QAAQ,EAAE,IAAI;gBACd,QAAQ,EAAE,MAAM;gBAChB,cAAc,EAAE,gBAAgB;gBAChC,SAAS,EACP,IAAI,SAAS,uBAAuB,MAAM,mBAAmB;oBAC7D,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;aAC9B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,SAAS;QACnB,cAAc,EAAE,EAAE;QAClB,SAAS,EACP,IAAI,SAAS,+CAA+C;YAC5D,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;KACnC,CAAC;AACJ,CAAC;AAED,0DAA0D;AAE1D,OAAO,EAAE,oBAAoB,IAAI,qBAAqB,EAAE,CAAC;AAEzD,0DAA0D;AAE1D,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CACjC,KAAK,EAAE,EACL,OAAO,EACP,KAAK,GAIN,EAAmB,EAAE;IACpB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAClE,MAAM,KAAK,GAAG,MAAM,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAEhE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,SAAS,CAAC;gBACpB,OAAO;gBACP,KAAK,EAAE,EAAE;gBACT,IAAI,EAAE,iDAAiD;aACxD,CAAC,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GAAG;YACb,OAAO;YACP,KAAK,EAAE,KAAK,CAAC,GAAG,CACd,CAAC,CAAoD,EAAE,EAAE,CAAC,CAAC;gBACzD,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;gBAC1B,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,UAAU,EAAE,CAAC,CAAC,UAAU;aACzB,CAAC,CACH;YACD,KAAK,EAAE,KAAK,CAAC,MAAM;SACpB,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE;YAClD,OAAO;YACP,KAAK,EAAE,SAAS;YAChB,QAAQ,EAAE,KAAK,CAAC,MAAM;SACvB,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,WAAW,GACf,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAE5D,MAAM,CAAC,IAAI,CAAC,oCAAoC,EAAE;YAChD,OAAO;YACP,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,KAAK,EAAE,wBAAwB,OAAO,KAAK,MAAM,EAAE;YACnD,KAAK,EAAE,CAAC,WAAW;SACpB,CAAC,CAAC;IACL,CAAC;AACH,CAAC,EACD;IACE,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EACT,iEAAiE;QACjE,0DAA0D;QAC1D,yEAAyE;QACzE,kDAAkD;QAClD,2EAA2E;IAC7E,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,QAAQ,CAAC,qDAAqD,CAAC;QAClE,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,CAAC,CAAC;aACN,OAAO,CAAC,CAAC,CAAC;aACV,QAAQ,CAAC,uCAAuC,CAAC;KACrD,CAAC;CACH,CACF,CAAC;AAEF,0DAA0D;AAE1D,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAClC,KAAK,EAAE,EACL,IAAI,EACJ,YAAY,GAIb,EAAmB,EAAE;IACpB,IAAI,CAAC;QACH,MAAM,UAAU,GACd,MAAM,CAAC,cAAc;YACrB,6EAA6E;gBAC3E,cAAc,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,GAAG,MAAM,CAAC,CAAC;gBAC5D,UAAU;gBACV,cAAc,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAE/B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE;YAClC,OAAO,EAAE;gBACP,YAAY,EACV,oEAAoE;gBACtE,kBAAkB,EAAE,gBAAgB;gBACpC,OAAO,EAAE,0BAA0B;gBACnC,MAAM,EAAE,mCAAmC;aAC5C;YACD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,SAAS,CAAC;gBACpB,KAAK,EAAE,6BAA6B,GAAG,CAAC,MAAM,EAAE;gBAChD,KAAK,EAAE,IAAI;aACZ,CAAC,CAAC;QACL,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC,SAAS,CAAC;gBACpB,IAAI;gBACJ,MAAM,EAAE,EAAE;gBACV,IAAI,EAAE,2CAA2C;aAClD,CAAC,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAEzD,iBAAiB;QACjB,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAA0B,EAAE,EAAE;YAC5D,MAAM,IAAI,GAAI,CAAC,CAAC,IAAe,IAAI,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG;YACb,IAAI;YACJ,YAAY;YACZ,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAA0B,EAAE,EAAE,CAAC,CAAC;gBACjE,IAAI,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI;gBAC3B,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,QAAQ,EAAE,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,QAAQ;aACxC,CAAC,CAAC;YACH,eAAe,EAAE,MAAM,CAAC,MAAM;YAC9B,cAAc,EAAE,QAAQ,CAAC,MAAM;YAC/B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACrC,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE;YAC1C,IAAI;YACJ,YAAY;YACZ,KAAK,EAAE,MAAM,CAAC,MAAM;YACpB,QAAQ,EAAE,QAAQ,CAAC,MAAM;SAC1B,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,KAAK,EAAE,iCAAiC,MAAM,CAAC,GAAG,CAAC,EAAE;YACrD,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;IACL,CAAC;AACH,CAAC,EACD;IACE,IAAI,EAAE,eAAe;IACrB,WAAW,EACT,0EAA0E;QAC1E,wEAAwE;QACxE,0EAA0E;QAC1E,+DAA+D;IACjE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,QAAQ,CAAC,0DAA0D,CAAC;QACvE,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,GAAG,CAAC;aACR,OAAO,CAAC,EAAE,CAAC;aACX,QAAQ,CAAC,+CAA+C,CAAC;KAC7D,CAAC;CACH,CACF,CAAC;AAEF,0DAA0D;AAE1D,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CACjC,KAAK,EAAE,EAAE,QAAQ,EAAwB,EAAmB,EAAE;IAC5D,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC;IAEpC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,KAAK,EAAE,+BAA+B;YACtC,IAAI,EAAE,qCAAqC;SAC5C,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAE9D,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE;QACzC,QAAQ;QACR,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,IAAI,EAAE,MAAM,CAAC,QAAQ;KACtB,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,QAAQ;QACR,eAAe,EAAE,cAAc;QAC/B,GAAG,MAAM;KACV,CAAC,CAAC;AACL,CAAC,EACD;IACE,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,sEAAsE;QACtE,6EAA6E;QAC7E,yCAAyC;QACzC,kEAAkE;QAClE,oCAAoC;QACpC,4EAA4E;QAC5E,sCAAsC;IACxC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,CACP,2EAA2E,CAC5E;KACJ,CAAC;CACH,CACF,CAAC;AAEF,0DAA0D;AAE1D,qDAAqD;AACrD,SAAS,cAAc,CAAC,CAAO;IAC7B,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAChD,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7B,OAAO,GAAG,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED,OAAO,EAAE,cAAc,IAAI,eAAe,EAAE,CAAC;AAE7C,0DAA0D;AAE1D,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CACpC,KAAK,EAAE,EACL,KAAK,EACL,YAAY,GAIb,EAAmB,EAAE;IACpB,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,KAAK,EAAE,mCAAmC;YAC1C,IAAI,EAAE,yEAAyE;SAChF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,YAAY,GAAG,MAAM,CAAC,CAAC;QAE7D,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,KAAK;YACL,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE;YACxB,EAAE,EAAE,GAAG,CAAC,WAAW,EAAE;YACrB,KAAK,EAAE,cAAc;SACtB,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,6CAA6C,MAAM,EAAE,EACrD;YACE,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,MAAM,EAAE,kBAAkB;aAC3B;YACD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CACF,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,OAAO,IAAI,CAAC,SAAS,CAAC;gBACpB,KAAK,EAAE,6BAA6B,GAAG,CAAC,MAAM,EAAE;gBAChD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;gBACxB,KAAK,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG;aACzB,CAAC,CAAC;QACL,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAyB,CAAC;QACxD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAEzD,MAAM,MAAM,GAAG;YACb,KAAK;YACL,YAAY;YACZ,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBACpC,MAAM,EAAE,GAAG,CAA4B,CAAC;gBACxC,OAAO;oBACL,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,SAAS;oBACzB,OAAO,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,GAAG;oBAC7B,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,QAAQ;oBAC9B,OAAO,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,QAAQ;iBACnC,CAAC;YACJ,CAAC,CAAC;YACF,KAAK,EAAE,MAAM,CAAC,MAAM;YACpB,UAAU,EAAE,GAAG,CAAC,WAAW,EAAE;SAC9B,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE;YAC5C,KAAK;YACL,YAAY;YACZ,KAAK,EAAE,MAAM,CAAC,MAAM;SACrB,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,KAAK,EAAE,8BAA8B,MAAM,CAAC,GAAG,CAAC,EAAE;YAClD,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;IACL,CAAC;AACH,CAAC,EACD;IACE,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACT,0DAA0D;QAC1D,qEAAqE;QACrE,8EAA8E;QAC9E,uEAAuE;QACvE,wEAAwE;IAC1E,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,QAAQ,CACP,4EAA4E,CAC7E;QACH,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,EAAE,CAAC;aACP,OAAO,CAAC,EAAE,CAAC;aACX,QAAQ,CAAC,2CAA2C,CAAC;KACzD,CAAC;CACH,CACF,CAAC;AAEF,0DAA0D;AAE1D,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,eAAe;IACf,gBAAgB;IAChB,eAAe;IACf,kBAAkB;CACnB,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * BullMQ worker — processes "enrich-alert" jobs.
3
+ *
4
+ * Session-aware scheduling:
5
+ * early_warning → every 20s, up to 30 min
6
+ * siren → every 20s, up to 15 min
7
+ * resolved → every 60s, up to 10 min (tail — detailed intel)
8
+ *
9
+ * After each job, checks the session phase and re-enqueues
10
+ * with the appropriate delay. Stops when phase expires.
11
+ */
12
+ export declare function startEnrichWorker(): void;
13
+ export declare function stopEnrichWorker(): Promise<void>;
14
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA+DH,wBAAgB,iBAAiB,IAAI,IAAI,CAsFxC;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKtD"}