@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 @@
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AAGH,OAAO,EAIL,wBAAwB,EAOzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAGL,YAAY,EAGZ,WAAW,EACZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBrB,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,OAAO,UAAU,CAAC,KAAK,CAAC;AAoCrD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAkBO,CAAC;AAE/B,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,CAAC;AAEpC,eAAO,MAAM,aAAa,GAAU,OAAO,OAAO,KAAG,OAAO,CAAC,IAAI,CAyBhE,CAAC"}
package/dist/graph.js ADDED
@@ -0,0 +1,162 @@
1
+ /**
2
+ * LangGraph.js enrichment pipeline — phase-aware, time-validated.
3
+ *
4
+ * ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────────---──┐
5
+ * │ filter │───▶│ extract │───▶│ vote │───▶│ shouldClarify │
6
+ * └─────────┘ └─────────┘ └─────────┘ └──────┬───---──┘
7
+ * │
8
+ * ┌──────────────┴──────────────┐
9
+ * │ │
10
+ * [low conf] [high conf]
11
+ * │ │
12
+ * ▼ ▼
13
+ * ┌────────────┐ ┌─────────┐
14
+ * │ clarify │ │ edit │
15
+ * └──────┬─────┘ └─────────┘
16
+ * │ ▲
17
+ * ▼ │
18
+ * ┌────────────┐ │
19
+ * │ revote │───────────────────────┘
20
+ * └────────────┘
21
+ *
22
+ * ── Node responsibilities ──────────────────────────────────────────────────
23
+ *
24
+ * filter: Collect Telegram posts from Redis, apply deterministic noise
25
+ * filters (area lists, summaries, IDF press releases). Returns
26
+ * ChannelTracking structure.
27
+ *
28
+ * extract: LLM-powered extraction pipeline:
29
+ * 1. Cheap model → which channels have relevant intel?
30
+ * 2. Expensive model → extract structured data per post
31
+ * 3. Post-filter → deterministic validation
32
+ *
33
+ * vote: Consensus voting (deterministic, 0 tokens). Aggregates multiple
34
+ * extractions into a single VotedResult using median/majority.
35
+ *
36
+ * shouldClarify: Conditional routing:
37
+ * - Low confidence (< threshold) → clarify
38
+ * - Single-source Lebanon for central Israel → clarify (suspicious)
39
+ * - Already clarified → edit
40
+ * - MCP tools disabled → edit
41
+ *
42
+ * clarify: ReAct agent with tools (read_telegram, alert_history,
43
+ * resolve_area, betterstack_log). Fetches more data to resolve
44
+ * contradictions. Output: new extractions.
45
+ *
46
+ * revote: Re-run vote with additional extractions from clarify.
47
+ *
48
+ * edit: Build enriched message text and edit Telegram message.
49
+ *
50
+ * ── Why this pipeline? ─────────────────────────────────────────────────────
51
+ *
52
+ * 1. Cheap → Expensive: Saves tokens. Pre-filter with cheap model ($0.001)
53
+ * before spending on per-post extraction ($0.01 each).
54
+ *
55
+ * 2. ReAct clarification: Low-confidence results aren't "failed" —
56
+ * they're signals that more data is needed. The LLM decides what tools
57
+ * to use rather than a hardcoded threshold.
58
+ *
59
+ * 3. Carry-forward: previousEnrichment preserves data between phases.
60
+ * If origin was confirmed in early_warning, it carries to red_alert/resolved.
61
+ *
62
+ * 4. Time validation: LLM instructions emphasize checking if sources
63
+ * are about THIS alert vs. previous attacks. Critical for accuracy.
64
+ */
65
+ import * as logger from "@easyoref/monitoring";
66
+ import { AlertTypeSchema, ChannelTrackingSchema, EnrichmentDataSchema, RunEnrichmentInputSchema, TelegramMessageSchema, ValidatedExtractionSchema, VotedResultSchema, config, createEmptyEnrichmentData, validateSafe, } from "@easyoref/shared";
67
+ import { END, MemorySaver, ReducedValue, START, StateGraph, StateSchema, } from "@langchain/langgraph";
68
+ import { z } from "zod";
69
+ import { clarifyNode } from "./nodes/clarify-node.js";
70
+ import { editNode } from "./nodes/edit-node.js";
71
+ import { extractNode } from "./nodes/extract-node.js";
72
+ import { filterNode } from "./nodes/filter-node.js";
73
+ import { voteNode } from "./nodes/vote-node.js";
74
+ export const AgentState = new StateSchema({
75
+ alertId: z.string(),
76
+ alertTs: z.number(),
77
+ alertType: AlertTypeSchema,
78
+ alertAreas: z.array(z.string()),
79
+ chatId: z.string(),
80
+ messageId: z.number(),
81
+ isCaption: z.boolean(),
82
+ currentText: z.string(),
83
+ tracking: ChannelTrackingSchema.optional(),
84
+ extractions: new ReducedValue(z.array(ValidatedExtractionSchema), {
85
+ reducer: (previous, current) => [...previous, ...current],
86
+ }),
87
+ votedResult: VotedResultSchema.optional(),
88
+ clarifyAttempted: z.boolean().default(false),
89
+ previousEnrichment: EnrichmentDataSchema.optional(),
90
+ monitoringLabel: z.string().optional(),
91
+ telegramMessages: new ReducedValue(z.array(TelegramMessageSchema), {
92
+ reducer: (previous, current) => [...previous, ...current],
93
+ }),
94
+ });
95
+ const shouldClarify = (state) => {
96
+ if (state.clarifyAttempted)
97
+ return "edit";
98
+ if (!config.agent.mcpTools)
99
+ return "edit";
100
+ if (!state.votedResult)
101
+ return "edit";
102
+ if (state.votedResult.confidence < config.agent.confidenceThreshold) {
103
+ logger.info("Agent: routing to clarify (low confidence)", {
104
+ confidence: state.votedResult.confidence,
105
+ });
106
+ return "clarify";
107
+ }
108
+ const origins = state.votedResult.countryOrigins;
109
+ if (origins && origins.length === 1 && state.votedResult.sourcesCount === 1) {
110
+ if (origins[0].name === "Lebanon" &&
111
+ state.alertAreas.some((area) => area.includes("תל אביב") ||
112
+ area.includes("גוש דן") ||
113
+ area.includes("שרון") ||
114
+ area.includes("מרכז"))) {
115
+ logger.info("Agent: routing to clarify (suspicious Lebanon origin)", {});
116
+ return "clarify";
117
+ }
118
+ }
119
+ return "edit";
120
+ };
121
+ const checkpointer = new MemorySaver();
122
+ export const buildGraph = () => new StateGraph(AgentState)
123
+ .addNode("filter", filterNode)
124
+ .addNode("extract", extractNode)
125
+ .addNode("vote", voteNode)
126
+ .addNode("clarify", clarifyNode)
127
+ .addNode("revote", voteNode)
128
+ .addNode("edit", editNode)
129
+ .addEdge(START, "filter")
130
+ .addEdge("filter", "extract")
131
+ .addEdge("extract", "vote")
132
+ .addConditionalEdges("vote", shouldClarify, {
133
+ clarify: "clarify",
134
+ edit: "edit",
135
+ })
136
+ .addEdge("clarify", "revote")
137
+ .addEdge("revote", "edit")
138
+ .addEdge("edit", END)
139
+ .compile({ checkpointer });
140
+ export { RunEnrichmentInputSchema };
141
+ export const runEnrichment = async (input) => {
142
+ const validation = validateSafe(RunEnrichmentInputSchema, input);
143
+ if (!validation.ok) {
144
+ logger.error("Enrichment: invalid input", { error: validation.error });
145
+ throw new Error(`Invalid enrichment input: ${validation.error}`);
146
+ }
147
+ const validInput = validation.data;
148
+ await buildGraph().invoke({
149
+ alertId: validInput.alertId,
150
+ alertTs: validInput.alertTs,
151
+ alertType: validInput.alertType,
152
+ alertAreas: validInput.alertAreas,
153
+ chatId: validInput.chatId,
154
+ messageId: validInput.messageId,
155
+ isCaption: validInput.isCaption,
156
+ telegramMessages: validInput.telegramMessages,
157
+ currentText: validInput.currentText,
158
+ previousEnrichment: createEmptyEnrichmentData(),
159
+ monitoringLabel: validInput.monitoringLabel,
160
+ }, { configurable: { thread_id: validInput.alertId } });
161
+ };
162
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AAEH,OAAO,KAAK,MAAM,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,MAAM,EACN,yBAAyB,EACzB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,GAAG,EACH,WAAW,EACX,YAAY,EACZ,KAAK,EACL,UAAU,EACV,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,WAAW,CAAC;IACxC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,SAAS,EAAE,eAAe;IAC1B,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC/B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;IACtB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,QAAQ,EAAE,qBAAqB,CAAC,QAAQ,EAAE;IAC1C,WAAW,EAAE,IAAI,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,yBAAyB,CAAC,EAAE;QAChE,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC;KAC1D,CAAC;IACF,WAAW,EAAE,iBAAiB,CAAC,QAAQ,EAAE;IACzC,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC5C,kBAAkB,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IACnD,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACtC,gBAAgB,EAAE,IAAI,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,EAAE;QACjE,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC;KAC1D,CAAC;CACH,CAAC,CAAC;AAIH,MAAM,aAAa,GAAG,CAAC,KAAqB,EAAsB,EAAE;IAClE,IAAI,KAAK,CAAC,gBAAgB;QAAE,OAAO,MAAM,CAAC;IAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC1C,IAAI,CAAC,KAAK,CAAC,WAAW;QAAE,OAAO,MAAM,CAAC;IAEtC,IAAI,KAAK,CAAC,WAAW,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;QACpE,MAAM,CAAC,IAAI,CAAC,4CAA4C,EAAE;YACxD,UAAU,EAAE,KAAK,CAAC,WAAW,CAAC,UAAU;SACzC,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,cAAc,CAAC;IACjD,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,EAAE,CAAC;QAC5E,IACE,OAAO,CAAC,CAAC,CAAE,CAAC,IAAI,KAAK,SAAS;YAC9B,KAAK,CAAC,UAAU,CAAC,IAAI,CACnB,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;gBACxB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACvB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACrB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CACxB,EACD,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,uDAAuD,EAAE,EAAE,CAAC,CAAC;YACzE,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC;AAEvC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE,CAC7B,IAAI,UAAU,CAAC,UAAU,CAAC;KACvB,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC;KAC7B,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC;KAC/B,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC;KACzB,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC;KAC/B,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC;KAC3B,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC;KACzB,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC;KACxB,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC;KAC5B,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC;KAC1B,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE;IAC1C,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;CACb,CAAC;KACD,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC;KAC5B,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC;KACzB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;KACpB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;AAG/B,OAAO,EAAE,wBAAwB,EAAE,CAAC;AAEpC,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,KAAc,EAAiB,EAAE;IACnE,MAAM,UAAU,GAAG,YAAY,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;IACjE,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;QACnB,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC;IAEnC,MAAM,UAAU,EAAE,CAAC,MAAM,CACvB;QACE,OAAO,EAAE,UAAU,CAAC,OAAO;QAC3B,OAAO,EAAE,UAAU,CAAC,OAAO;QAC3B,SAAS,EAAE,UAAU,CAAC,SAAS;QAC/B,UAAU,EAAE,UAAU,CAAC,UAAU;QACjC,MAAM,EAAE,UAAU,CAAC,MAAM;QACzB,SAAS,EAAE,UAAU,CAAC,SAAS;QAC/B,SAAS,EAAE,UAAU,CAAC,SAAS;QAC/B,gBAAgB,EAAE,UAAU,CAAC,gBAAgB;QAC7C,WAAW,EAAE,UAAU,CAAC,WAAW;QACnC,kBAAkB,EAAE,yBAAyB,EAAE;QAC/C,eAAe,EAAE,UAAU,CAAC,eAAe;KAC5C,EACD,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,OAAO,EAAE,EAAE,CACpD,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * EasyOref Agent Package
3
+ *
4
+ * LangGraph-based enrichment pipeline for Israeli missile alert processing.
5
+ */
6
+ export * from "./graph.js";
7
+ export * from "./nodes/clarify-node.js";
8
+ export * from "./nodes/edit-node.js";
9
+ export * from "./nodes/extract-node.js";
10
+ export * from "./nodes/filter-node.js";
11
+ export * from "./nodes/vote-node.js";
12
+ export * from "./models.js";
13
+ export * from "./runtime/auth.js";
14
+ export * from "./runtime/dry-run.js";
15
+ export * from "./runtime/queue.js";
16
+ export * from "./runtime/redis.js";
17
+ export * from "./runtime/worker.js";
18
+ export { alertHistoryTool } from "./tools/alert-history.js";
19
+ export { betterstackLogTool } from "./tools/betterstack-log.js";
20
+ export { clarifyTools } from "./tools/index.js";
21
+ export { readSourcesTool } from "./tools/read-sources.js";
22
+ export { resolveAreaTool } from "./tools/resolve-area.js";
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAE3B,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AAErC,cAAc,aAAa,CAAC;AAE5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * EasyOref Agent Package
3
+ *
4
+ * LangGraph-based enrichment pipeline for Israeli missile alert processing.
5
+ */
6
+ export * from "./graph.js";
7
+ export * from "./nodes/clarify-node.js";
8
+ export * from "./nodes/edit-node.js";
9
+ export * from "./nodes/extract-node.js";
10
+ export * from "./nodes/filter-node.js";
11
+ export * from "./nodes/vote-node.js";
12
+ export * from "./models.js";
13
+ export * from "./runtime/auth.js";
14
+ export * from "./runtime/dry-run.js";
15
+ export * from "./runtime/queue.js";
16
+ export * from "./runtime/redis.js";
17
+ export * from "./runtime/worker.js";
18
+ export { alertHistoryTool } from "./tools/alert-history.js";
19
+ export { betterstackLogTool } from "./tools/betterstack-log.js";
20
+ export { clarifyTools } from "./tools/index.js";
21
+ export { readSourcesTool } from "./tools/read-sources.js";
22
+ export { resolveAreaTool } from "./tools/resolve-area.js";
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAE3B,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AAErC,cAAc,aAAa,CAAC;AAE5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * LLM models configuration.
3
+ */
4
+ import { ChatOpenRouter } from "@langchain/openrouter";
5
+ export declare const filterModel: ChatOpenRouter;
6
+ export declare const extractModel: ChatOpenRouter;
7
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,eAAO,MAAM,WAAW,gBAKtB,CAAC;AAEH,eAAO,MAAM,YAAY,gBAKvB,CAAC"}
package/dist/models.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * LLM models configuration.
3
+ */
4
+ import { ChatOpenRouter } from "@langchain/openrouter";
5
+ import { config } from "@easyoref/shared";
6
+ export const filterModel = new ChatOpenRouter({
7
+ apiKey: config.agent.apiKey,
8
+ model: config.agent.filterModel,
9
+ temperature: 0,
10
+ maxTokens: 200,
11
+ });
12
+ export const extractModel = new ChatOpenRouter({
13
+ apiKey: config.agent.apiKey,
14
+ model: config.agent.extractModel,
15
+ temperature: 0,
16
+ maxTokens: 500,
17
+ });
18
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,cAAc,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;IAC3B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW;IAC/B,WAAW,EAAE,CAAC;IACd,SAAS,EAAE,GAAG;CACf,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,cAAc,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;IAC3B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY;IAChC,WAAW,EAAE,CAAC;IACd,SAAS,EAAE,GAAG;CACf,CAAC,CAAC"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Clarify Node — optional ReAct tool calling for low-confidence enrichment.
3
+ */
4
+ import type { AgentStateType } from "../graph.js";
5
+ export declare const clarifyAgent: import("langchain").ReactAgent<import("langchain").AgentTypeConfig<{
6
+ newPosts: {
7
+ channel: string;
8
+ text: string;
9
+ ts: number;
10
+ messageUrl?: string | undefined;
11
+ }[];
12
+ newExtractions: {
13
+ channel: string;
14
+ regionRelevance: number;
15
+ sourceTrust: number;
16
+ tone: "calm" | "neutral" | "alarmist";
17
+ confidence: number;
18
+ timeRelevance: number;
19
+ valid: boolean;
20
+ countryOrigin?: string | undefined;
21
+ rocketCount?: number | undefined;
22
+ isCassette?: boolean | undefined;
23
+ intercepted?: number | undefined;
24
+ interceptedQual?: {
25
+ type: "all";
26
+ } | {
27
+ type: "most";
28
+ } | {
29
+ type: "many";
30
+ } | {
31
+ type: "few";
32
+ } | {
33
+ type: "exists";
34
+ } | {
35
+ type: "none";
36
+ } | {
37
+ type: "more_than";
38
+ value: number;
39
+ } | {
40
+ type: "less_than";
41
+ value: number;
42
+ } | undefined;
43
+ seaImpact?: number | undefined;
44
+ seaImpactQual?: {
45
+ type: "all";
46
+ } | {
47
+ type: "most";
48
+ } | {
49
+ type: "many";
50
+ } | {
51
+ type: "few";
52
+ } | {
53
+ type: "exists";
54
+ } | {
55
+ type: "none";
56
+ } | {
57
+ type: "more_than";
58
+ value: number;
59
+ } | {
60
+ type: "less_than";
61
+ value: number;
62
+ } | undefined;
63
+ openAreaImpact?: number | undefined;
64
+ openAreaImpactQual?: {
65
+ type: "all";
66
+ } | {
67
+ type: "most";
68
+ } | {
69
+ type: "many";
70
+ } | {
71
+ type: "few";
72
+ } | {
73
+ type: "exists";
74
+ } | {
75
+ type: "none";
76
+ } | {
77
+ type: "more_than";
78
+ value: number;
79
+ } | {
80
+ type: "less_than";
81
+ value: number;
82
+ } | undefined;
83
+ hitsConfirmed?: number | undefined;
84
+ hitLocation?: string | undefined;
85
+ hitType?: "direct" | "shrapnel" | undefined;
86
+ hitDetail?: string | undefined;
87
+ casualties?: number | undefined;
88
+ injuries?: number | undefined;
89
+ injuriesCause?: "rocket" | "rushing_to_shelter" | undefined;
90
+ etaRefinedMinutes?: number | undefined;
91
+ rocketDetail?: string | undefined;
92
+ rejectReason?: string | undefined;
93
+ messageUrl?: string | undefined;
94
+ }[];
95
+ toolCallCount: number;
96
+ clarified: boolean;
97
+ }, undefined, import("langchain").AnyAnnotationRoot, readonly import("langchain").AgentMiddleware<any, any, any, readonly (import("@langchain/core/tools").ClientTool | import("@langchain/core/tools").ServerTool)[]>[], readonly (import("langchain").DynamicStructuredTool<import("zod").ZodObject<{
98
+ channel: import("zod").ZodString;
99
+ limit: import("zod").ZodDefault<import("zod").ZodNumber>;
100
+ }, import("zod/v4/core").$strip>, {
101
+ channel: string;
102
+ limit: number;
103
+ }, {
104
+ channel: string;
105
+ limit?: number | undefined;
106
+ }, string, unknown, "read_telegram_sources"> | import("langchain").DynamicStructuredTool<import("zod").ZodObject<{
107
+ area: import("zod").ZodString;
108
+ lastMinutes: import("zod").ZodDefault<import("zod").ZodNumber>;
109
+ }, import("zod/v4/core").$strip>, {
110
+ area: string;
111
+ lastMinutes: number;
112
+ }, {
113
+ area: string;
114
+ lastMinutes?: number | undefined;
115
+ }, string, unknown, "alert_history"> | import("langchain").DynamicStructuredTool<import("zod").ZodObject<{
116
+ location: import("zod").ZodString;
117
+ }, import("zod/v4/core").$strip>, {
118
+ location: string;
119
+ }, {
120
+ location: string;
121
+ }, string, unknown, "resolve_area"> | import("langchain").DynamicStructuredTool<import("zod").ZodObject<{
122
+ query: import("zod").ZodString;
123
+ lastMinutes: import("zod").ZodDefault<import("zod").ZodNumber>;
124
+ }, import("zod/v4/core").$strip>, {
125
+ query: string;
126
+ lastMinutes: number;
127
+ }, {
128
+ query: string;
129
+ lastMinutes?: number | undefined;
130
+ }, string, unknown, "betterstack_log">)[]>>;
131
+ export declare const clarifyNode: (state: AgentStateType) => Promise<Partial<AgentStateType>>;
132
+ //# sourceMappingURL=clarify-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clarify-node.d.ts","sourceRoot":"","sources":["../../src/nodes/clarify-node.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2CA4BvB,CAAC;AAkDH,eAAO,MAAM,WAAW,GACtB,OAAO,cAAc,KACpB,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CA2EjC,CAAC"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Clarify Node — optional ReAct tool calling for low-confidence enrichment.
3
+ */
4
+ import * as logger from "@easyoref/monitoring";
5
+ import { ClarifyOutputSchema, pushSessionPost, } from "@easyoref/shared";
6
+ import { createAgent, toolStrategy } from "langchain";
7
+ import { filterModel } from "../models.js";
8
+ import { clarifyTools } from "../tools/index.js";
9
+ export const clarifyAgent = createAgent({
10
+ model: filterModel,
11
+ tools: clarifyTools,
12
+ responseFormat: toolStrategy(ClarifyOutputSchema),
13
+ systemPrompt: `
14
+ You are the clarification agent for EasyOref — an Israeli missile alert enrichment system.
15
+
16
+ The voting pipeline analyzed Telegram channel posts and produced a result with
17
+ low confidence or contradictions. You have access to 4 tools:
18
+
19
+ 1. read_telegram_sources — fetch last N posts from a Telegram news channel
20
+ 2. alert_history — get recent alert history from Pikud HaOref.
21
+ 3. resolve_area — check if a location mentioned in news is relevant to user's areas.
22
+ 4. betterstack_log — query recent EasyOref logs from Better Stack.
23
+
24
+ CRITICAL — TIME VALIDATION:
25
+ You receive the alert time (Israel timezone). Channel posts may be about PREVIOUS
26
+ attacks or ongoing military operations (not THIS specific alert). When in doubt:
27
+ - Use alert_history to verify if an alert really occurred at the claimed time/area.
28
+ - If a post discusses events from hours ago, it is STALE — ignore it.
29
+
30
+ You decide whether tools would help:
31
+ - If contradictions can be resolved with existing data → respond immediately, no tools.
32
+ - If an authoritative source (IDF, N12) could settle a disagreement → fetch 1-4 posts.
33
+ - If you need to verify whether an alert occurred → check alert_history.
34
+
35
+ Always respect an output format.
36
+ `,
37
+ });
38
+ function describeContradictions(extractions, voted) {
39
+ const issues = [];
40
+ if (voted.countryOrigins && voted.countryOrigins.length > 1) {
41
+ const names = voted.countryOrigins.map((c) => c.name).join(", ");
42
+ issues.push(`Multiple origin countries reported: ${names}`);
43
+ }
44
+ if (voted.rocketCountMin &&
45
+ voted.rocketCountMax &&
46
+ voted.rocketCountMax - voted.rocketCountMin > 3) {
47
+ issues.push(`Wide rocket count range: ${voted.rocketCountMin}–${voted.rocketCountMax}`);
48
+ }
49
+ if ((voted.interceptedConfidence ?? 0) < 0.5 &&
50
+ voted.intercepted !== undefined) {
51
+ issues.push(`Intercepted count (${voted.intercepted}) has low confidence: ${(voted.interceptedConfidence ?? 0).toFixed(2)}`);
52
+ }
53
+ issues.push(`Overall confidence: ${voted.confidence}`);
54
+ issues.push(`Sources count: ${voted.sourcesCount}`);
55
+ return issues.join("\n");
56
+ }
57
+ export const clarifyNode = async (state) => {
58
+ if (!state.votedResult) {
59
+ logger.info("Agent: clarify skipped — no voted result", {
60
+ alertId: state.alertId,
61
+ });
62
+ return { clarifyAttempted: true };
63
+ }
64
+ logger.info("Agent: clarify triggered", {
65
+ alertId: state.alertId,
66
+ confidence: state.votedResult.confidence,
67
+ });
68
+ try {
69
+ const contradictions = describeContradictions(state.extractions, state.votedResult);
70
+ const alertTimeIL = new Date(state.alertTs).toLocaleTimeString("he-IL", {
71
+ hour: "2-digit",
72
+ minute: "2-digit",
73
+ timeZone: "Asia/Jerusalem",
74
+ });
75
+ const userPrompt = `Alert region: ${state.alertAreas.join(", ")}\n` +
76
+ `Alert type: ${state.alertType}\n` +
77
+ `Alert time: ${alertTimeIL} (Israel)\n` +
78
+ `Message ID: ${state.messageId}\n\n` +
79
+ `Current voted result:\n` +
80
+ JSON.stringify(state.votedResult, undefined, 2) +
81
+ `\n\nContradictions & issues:\n${contradictions}\n\n` +
82
+ `Existing extractions (${state.extractions.filter((e) => e.valid).length} valid):\n` +
83
+ state.extractions
84
+ .filter((e) => e.valid)
85
+ .map((e) => ` [${e.channel}] country=${e.countryOrigin}, rockets=${e.rocketCount}, ` +
86
+ `intercepted=${e.intercepted}, hits=${e.hitsConfirmed}, conf=${e.confidence}`)
87
+ .join("\n") +
88
+ `\n\nDecide: would fetching more data from authoritative channels resolve these issues?`;
89
+ const result = await clarifyAgent.invoke({ messages: [userPrompt] });
90
+ const output = result.structuredResponse;
91
+ const newPosts = [];
92
+ if (output?.newPosts) {
93
+ for (const p of output.newPosts) {
94
+ const post = {
95
+ channel: p.channel,
96
+ text: p.text,
97
+ ts: p.ts,
98
+ messageUrl: p.messageUrl,
99
+ };
100
+ newPosts.push(post);
101
+ await pushSessionPost(post);
102
+ }
103
+ }
104
+ return {
105
+ extractions: [...state.extractions, ...(output?.newExtractions ?? [])],
106
+ votedResult: undefined,
107
+ clarifyAttempted: true,
108
+ };
109
+ }
110
+ catch (err) {
111
+ logger.error("Agent: clarify failed", {
112
+ alertId: state.alertId,
113
+ error: String(err),
114
+ });
115
+ return { clarifyAttempted: true };
116
+ }
117
+ };
118
+ //# sourceMappingURL=clarify-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clarify-node.js","sourceRoot":"","sources":["../../src/nodes/clarify-node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Clarify Node — optional ReAct tool calling for low-confidence enrichment.
3
+ */
4
+ import type { AgentStateType } from "../graph.js";
5
+ export declare const clarifyNode: (state: AgentStateType) => Promise<Partial<AgentStateType>>;
6
+ //# sourceMappingURL=clarify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clarify.d.ts","sourceRoot":"","sources":["../../src/nodes/clarify.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAwFlD,eAAO,MAAM,WAAW,GACtB,OAAO,cAAc,KACpB,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CA2EjC,CAAC"}