@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.
- package/__tests__/clarify.test.ts +827 -0
- package/__tests__/config.test.ts +304 -0
- package/__tests__/enrichment.integration.test.ts +871 -0
- package/__tests__/graph.test.ts +661 -0
- package/dist/auth.d.ts +11 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +54 -0
- package/dist/auth.js.map +1 -0
- package/dist/dry-run.d.ts +12 -0
- package/dist/dry-run.d.ts.map +1 -0
- package/dist/dry-run.js +236 -0
- package/dist/dry-run.js.map +1 -0
- package/dist/extract.d.ts +180 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +210 -0
- package/dist/extract.js.map +1 -0
- package/dist/graph.d.ts +4083 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +162 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/models.d.ts +7 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +18 -0
- package/dist/models.js.map +1 -0
- package/dist/nodes/clarify-node.d.ts +132 -0
- package/dist/nodes/clarify-node.d.ts.map +1 -0
- package/dist/nodes/clarify-node.js +118 -0
- package/dist/nodes/clarify-node.js.map +1 -0
- package/dist/nodes/clarify.d.ts +6 -0
- package/dist/nodes/clarify.d.ts.map +1 -0
- package/dist/nodes/clarify.js +124 -0
- package/dist/nodes/clarify.js.map +1 -0
- package/dist/nodes/edit-node.d.ts +71 -0
- package/dist/nodes/edit-node.d.ts.map +1 -0
- package/dist/nodes/edit-node.js +496 -0
- package/dist/nodes/edit-node.js.map +1 -0
- package/dist/nodes/edit.d.ts +6 -0
- package/dist/nodes/edit.d.ts.map +1 -0
- package/dist/nodes/edit.js +22 -0
- package/dist/nodes/edit.js.map +1 -0
- package/dist/nodes/extract-node.d.ts +174 -0
- package/dist/nodes/extract-node.d.ts.map +1 -0
- package/dist/nodes/extract-node.js +233 -0
- package/dist/nodes/extract-node.js.map +1 -0
- package/dist/nodes/extract.d.ts +6 -0
- package/dist/nodes/extract.d.ts.map +1 -0
- package/dist/nodes/extract.js +49 -0
- package/dist/nodes/extract.js.map +1 -0
- package/dist/nodes/filter-agent.d.ts +11 -0
- package/dist/nodes/filter-agent.d.ts.map +1 -0
- package/dist/nodes/filter-agent.js +60 -0
- package/dist/nodes/filter-agent.js.map +1 -0
- package/dist/nodes/filter-node.d.ts +9 -0
- package/dist/nodes/filter-node.d.ts.map +1 -0
- package/dist/nodes/filter-node.js +111 -0
- package/dist/nodes/filter-node.js.map +1 -0
- package/dist/nodes/filters.d.ts +13 -0
- package/dist/nodes/filters.d.ts.map +1 -0
- package/dist/nodes/filters.js +111 -0
- package/dist/nodes/filters.js.map +1 -0
- package/dist/nodes/message-node.d.ts +71 -0
- package/dist/nodes/message-node.d.ts.map +1 -0
- package/dist/nodes/message-node.js +491 -0
- package/dist/nodes/message-node.js.map +1 -0
- package/dist/nodes/message.d.ts +71 -0
- package/dist/nodes/message.d.ts.map +1 -0
- package/dist/nodes/message.js +496 -0
- package/dist/nodes/message.js.map +1 -0
- package/dist/nodes/vote-node.d.ts +13 -0
- package/dist/nodes/vote-node.d.ts.map +1 -0
- package/dist/nodes/vote-node.js +232 -0
- package/dist/nodes/vote-node.js.map +1 -0
- package/dist/nodes/vote.d.ts +13 -0
- package/dist/nodes/vote.d.ts.map +1 -0
- package/dist/nodes/vote.js +232 -0
- package/dist/nodes/vote.js.map +1 -0
- package/dist/queue.d.ts +15 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +41 -0
- package/dist/queue.js.map +1 -0
- package/dist/redis.d.ts +8 -0
- package/dist/redis.d.ts.map +1 -0
- package/dist/redis.js +33 -0
- package/dist/redis.js.map +1 -0
- package/dist/runtime/auth.d.ts +11 -0
- package/dist/runtime/auth.d.ts.map +1 -0
- package/dist/runtime/auth.js +54 -0
- package/dist/runtime/auth.js.map +1 -0
- package/dist/runtime/dry-run.d.ts +12 -0
- package/dist/runtime/dry-run.d.ts.map +1 -0
- package/dist/runtime/dry-run.js +236 -0
- package/dist/runtime/dry-run.js.map +1 -0
- package/dist/runtime/queue.d.ts +15 -0
- package/dist/runtime/queue.d.ts.map +1 -0
- package/dist/runtime/queue.js +41 -0
- package/dist/runtime/queue.js.map +1 -0
- package/dist/runtime/redis.d.ts +8 -0
- package/dist/runtime/redis.d.ts.map +1 -0
- package/dist/runtime/redis.js +33 -0
- package/dist/runtime/redis.js.map +1 -0
- package/dist/runtime/worker.d.ts +14 -0
- package/dist/runtime/worker.d.ts.map +1 -0
- package/dist/runtime/worker.js +135 -0
- package/dist/runtime/worker.js.map +1 -0
- package/dist/tools/alert-history.d.ts +18 -0
- package/dist/tools/alert-history.d.ts.map +1 -0
- package/dist/tools/alert-history.js +98 -0
- package/dist/tools/alert-history.js.map +1 -0
- package/dist/tools/betterstack-log.d.ts +15 -0
- package/dist/tools/betterstack-log.d.ts.map +1 -0
- package/dist/tools/betterstack-log.js +80 -0
- package/dist/tools/betterstack-log.js.map +1 -0
- package/dist/tools/index.d.ts +44 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +20 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/read-sources.d.ts +15 -0
- package/dist/tools/read-sources.d.ts.map +1 -0
- package/dist/tools/read-sources.js +67 -0
- package/dist/tools/read-sources.js.map +1 -0
- package/dist/tools/resolve-area.d.ts +19 -0
- package/dist/tools/resolve-area.d.ts.map +1 -0
- package/dist/tools/resolve-area.js +147 -0
- package/dist/tools/resolve-area.js.map +1 -0
- package/dist/tools.d.ts +115 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +439 -0
- package/dist/tools.js.map +1 -0
- package/dist/worker.d.ts +14 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +135 -0
- package/dist/worker.js.map +1 -0
- package/package.json +26 -0
- package/src/graph.ts +200 -0
- package/src/index.ts +27 -0
- package/src/models.ts +20 -0
- package/src/nodes/clarify-node.ts +172 -0
- package/src/nodes/edit-node.ts +695 -0
- package/src/nodes/extract-node.ts +299 -0
- package/src/nodes/filter-node.ts +139 -0
- package/src/nodes/message.ts +695 -0
- package/src/nodes/vote-node.ts +354 -0
- package/src/nodes/vote.ts +354 -0
- package/src/runtime/auth.ts +63 -0
- package/src/runtime/dry-run.ts +303 -0
- package/src/runtime/queue.ts +53 -0
- package/src/runtime/redis.ts +38 -0
- package/src/runtime/worker.ts +167 -0
- package/src/tools/alert-history.ts +120 -0
- package/src/tools/betterstack-log.ts +102 -0
- package/src/tools/index.ts +23 -0
- package/src/tools/read-sources.ts +86 -0
- package/src/tools/resolve-area.ts +202 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter Node — deterministic pre-filters + LLM channel relevance.
|
|
3
|
+
*/
|
|
4
|
+
import * as logger from "@easyoref/monitoring";
|
|
5
|
+
import { getActiveSession, getChannelPosts, getEnrichmentData, getLastUpdateTs, } from "@easyoref/shared";
|
|
6
|
+
import { createAgent, providerStrategy } from "langchain";
|
|
7
|
+
import { filterModel } from "../models.js";
|
|
8
|
+
import { FilterOutputSchema } from "@easyoref/shared";
|
|
9
|
+
export const filterAgent = createAgent({
|
|
10
|
+
model: filterModel,
|
|
11
|
+
responseFormat: providerStrategy(FilterOutputSchema),
|
|
12
|
+
systemPrompt: `You pre-filter Telegram channels for an Israeli missile alert system.
|
|
13
|
+
Given channels with their latest messages, identify which contain IMPORTANT military intel:
|
|
14
|
+
- Country of origin (where rockets/missiles launched from)
|
|
15
|
+
- Impact location (where they hit)
|
|
16
|
+
- Warhead type / cassette munitions
|
|
17
|
+
- Damage / destruction reports
|
|
18
|
+
- Interception reports (Iron Dome, David's Sling)
|
|
19
|
+
- Casualty / injury reports
|
|
20
|
+
|
|
21
|
+
IGNORE channels that only contain:
|
|
22
|
+
- Panic, speculation, or unverified rumors
|
|
23
|
+
- Rehashes of official alerts without new data
|
|
24
|
+
- General commentary without actionable facts
|
|
25
|
+
|
|
26
|
+
Return relevant channel names.`,
|
|
27
|
+
});
|
|
28
|
+
const OREF_LINK_PATTERN = /oref\.org\.il/i;
|
|
29
|
+
const OREF_CHANNEL_PATTERN = /pikud|פיקוד|oref/i;
|
|
30
|
+
const IDF_CHANNEL_PATTERN = /idf|צה"?ל|tsahal/i;
|
|
31
|
+
function isNoise(post) {
|
|
32
|
+
if (OREF_CHANNEL_PATTERN.test(post.channel) && post.text.length > 300)
|
|
33
|
+
return true;
|
|
34
|
+
if (OREF_LINK_PATTERN.test(post.text))
|
|
35
|
+
return true;
|
|
36
|
+
const commaCount = (post.text.match(/,/g) || []).length;
|
|
37
|
+
if (commaCount >= 8)
|
|
38
|
+
return true;
|
|
39
|
+
const timeParenCount = (post.text.match(/\(\d{1,2}:\d{2}\)/g) || []).length;
|
|
40
|
+
if (timeParenCount >= 2)
|
|
41
|
+
return true;
|
|
42
|
+
if (/\d+\s+минут[ыа]?\b/i.test(post.text))
|
|
43
|
+
return true;
|
|
44
|
+
if (IDF_CHANNEL_PATTERN.test(post.channel) && post.text.length > 400)
|
|
45
|
+
return true;
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
function toNewsMessage(post) {
|
|
49
|
+
return {
|
|
50
|
+
channelId: post.channel,
|
|
51
|
+
sourceType: "telegram_channel",
|
|
52
|
+
timestamp: post.ts,
|
|
53
|
+
text: post.text,
|
|
54
|
+
sourceUrl: post.messageUrl,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function buildChannelTracking(posts, sessionStartTs, lastUpdateTs) {
|
|
58
|
+
const channelMap = new Map();
|
|
59
|
+
for (const post of posts) {
|
|
60
|
+
if (isNoise(post))
|
|
61
|
+
continue;
|
|
62
|
+
if (post.ts < sessionStartTs)
|
|
63
|
+
continue;
|
|
64
|
+
if (!channelMap.has(post.channel)) {
|
|
65
|
+
channelMap.set(post.channel, { previous: [], latest: [] });
|
|
66
|
+
}
|
|
67
|
+
const bucket = channelMap.get(post.channel);
|
|
68
|
+
const newsMessage = toNewsMessage(post);
|
|
69
|
+
if (lastUpdateTs > 0 && post.ts <= lastUpdateTs) {
|
|
70
|
+
bucket.previous.push(newsMessage);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
bucket.latest.push(newsMessage);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const channelsWithUpdates = [];
|
|
77
|
+
for (const [channel, { previous, latest }] of channelMap) {
|
|
78
|
+
if (latest.length > 0) {
|
|
79
|
+
channelsWithUpdates.push({
|
|
80
|
+
channel,
|
|
81
|
+
processedMessages: previous.sort((a, b) => a.timestamp - b.timestamp),
|
|
82
|
+
unprocessedMessages: latest.sort((a, b) => a.timestamp - b.timestamp),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
trackStartTimestamp: sessionStartTs,
|
|
88
|
+
lastUpdateTimestamp: lastUpdateTs,
|
|
89
|
+
channelsWithUpdates: channelsWithUpdates,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export const filterNode = async (state) => {
|
|
93
|
+
const posts = await getChannelPosts(state.alertId);
|
|
94
|
+
const previousEnrichment = await getEnrichmentData();
|
|
95
|
+
const session = await getActiveSession();
|
|
96
|
+
const sessionStartTs = session?.sessionStartTs ?? state.alertTs;
|
|
97
|
+
const lastUpdateTs = await getLastUpdateTs();
|
|
98
|
+
if (posts.length === 0) {
|
|
99
|
+
logger.info("Agent: no posts", { alertId: state.alertId });
|
|
100
|
+
return { tracking: undefined, previousEnrichment };
|
|
101
|
+
}
|
|
102
|
+
const tracking = buildChannelTracking(posts, sessionStartTs, lastUpdateTs);
|
|
103
|
+
logger.info("Agent: channel tracking", {
|
|
104
|
+
alertId: state.alertId,
|
|
105
|
+
totalPosts: posts.length,
|
|
106
|
+
channelsWithUpdates: tracking.channelsWithUpdates.length,
|
|
107
|
+
totalNewPosts: tracking.channelsWithUpdates.reduce((total, channel) => total + channel.unprocessedMessages.length, 0),
|
|
108
|
+
});
|
|
109
|
+
return { tracking, previousEnrichment };
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=filter-node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter-node.js","sourceRoot":"","sources":["../../src/nodes/filter-node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter Node — deterministic pre-filters, zero LLM tokens.
|
|
3
|
+
*
|
|
4
|
+
* Filters out noise:
|
|
5
|
+
* - Pikud HaOref area list "простыни" (high comma count)
|
|
6
|
+
* - Summary/recap posts with timestamp patterns "(HH:MM)", "X минут"
|
|
7
|
+
* - IDF/Tsahal press releases (long official texts)
|
|
8
|
+
*
|
|
9
|
+
* Builds ChannelTracking structure for the LLM pipeline.
|
|
10
|
+
*/
|
|
11
|
+
import type { AgentStateType } from "../graph.js";
|
|
12
|
+
export declare const filterNode: (state: AgentStateType) => Promise<Partial<AgentStateType>>;
|
|
13
|
+
//# sourceMappingURL=filters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filters.d.ts","sourceRoot":"","sources":["../../src/nodes/filters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA0GlD,eAAO,MAAM,UAAU,GACrB,OAAO,cAAc,KACpB,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CA6BjC,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter Node — deterministic pre-filters, zero LLM tokens.
|
|
3
|
+
*
|
|
4
|
+
* Filters out noise:
|
|
5
|
+
* - Pikud HaOref area list "простыни" (high comma count)
|
|
6
|
+
* - Summary/recap posts with timestamp patterns "(HH:MM)", "X минут"
|
|
7
|
+
* - IDF/Tsahal press releases (long official texts)
|
|
8
|
+
*
|
|
9
|
+
* Builds ChannelTracking structure for the LLM pipeline.
|
|
10
|
+
*/
|
|
11
|
+
import * as logger from "@easyoref/monitoring";
|
|
12
|
+
import { getActiveSession, getChannelPosts, getEnrichmentData, getLastUpdateTs, } from "@easyoref/shared";
|
|
13
|
+
// ── Noise detectors ────────────────────────────────────
|
|
14
|
+
const OREF_LINK_PATTERN = /oref\.org\.il/i;
|
|
15
|
+
const OREF_CHANNEL_PATTERN = /pikud|פיקוד|oref/i;
|
|
16
|
+
const IDF_CHANNEL_PATTERN = /idf|צה"?ל|tsahal/i;
|
|
17
|
+
function isAreaListNoise(text) {
|
|
18
|
+
if (OREF_LINK_PATTERN.test(text))
|
|
19
|
+
return true;
|
|
20
|
+
const commaCount = (text.match(/,/g) || []).length;
|
|
21
|
+
return commaCount >= 8;
|
|
22
|
+
}
|
|
23
|
+
function isSummaryPost(text) {
|
|
24
|
+
const timeParenCount = (text.match(/\(\d{1,2}:\d{2}\)/g) || []).length;
|
|
25
|
+
if (timeParenCount >= 2)
|
|
26
|
+
return true;
|
|
27
|
+
if (/\d+\s+минут[ыа]?\b/i.test(text))
|
|
28
|
+
return true;
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
function isIdfPressRelease(channel, text) {
|
|
32
|
+
if (!IDF_CHANNEL_PATTERN.test(channel))
|
|
33
|
+
return false;
|
|
34
|
+
return text.length > 400;
|
|
35
|
+
}
|
|
36
|
+
function isNoise(post) {
|
|
37
|
+
if (OREF_CHANNEL_PATTERN.test(post.channel) && post.text.length > 300)
|
|
38
|
+
return true;
|
|
39
|
+
if (isAreaListNoise(post.text))
|
|
40
|
+
return true;
|
|
41
|
+
if (isSummaryPost(post.text))
|
|
42
|
+
return true;
|
|
43
|
+
if (isIdfPressRelease(post.channel, post.text))
|
|
44
|
+
return true;
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
// ── Channel tracking ────────────────────────────────────
|
|
48
|
+
function toTrackedMessage(post) {
|
|
49
|
+
return {
|
|
50
|
+
timestamp: post.ts,
|
|
51
|
+
text: post.text,
|
|
52
|
+
url: post.messageUrl,
|
|
53
|
+
channel: post.channel,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function buildChannelTracking(posts, sessionStartTimestamp, lastUpdateTimestamp) {
|
|
57
|
+
const channelMap = new Map();
|
|
58
|
+
for (const post of posts) {
|
|
59
|
+
if (isNoise(post))
|
|
60
|
+
continue;
|
|
61
|
+
if (post.ts < sessionStartTimestamp)
|
|
62
|
+
continue;
|
|
63
|
+
if (!channelMap.has(post.channel)) {
|
|
64
|
+
channelMap.set(post.channel, { previous: [], latest: [] });
|
|
65
|
+
}
|
|
66
|
+
const bucket = channelMap.get(post.channel);
|
|
67
|
+
const trackedMessage = toTrackedMessage(post);
|
|
68
|
+
if (lastUpdateTimestamp > 0 && post.ts <= lastUpdateTimestamp) {
|
|
69
|
+
bucket.previous.push(trackedMessage);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
bucket.latest.push(trackedMessage);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const channelsWithUpdates = [];
|
|
76
|
+
for (const [channel, { previous, latest }] of channelMap) {
|
|
77
|
+
if (latest.length > 0) {
|
|
78
|
+
channelsWithUpdates.push({
|
|
79
|
+
channel,
|
|
80
|
+
prev_tracked_messages: previous.sort((a, b) => a.timestamp - b.timestamp),
|
|
81
|
+
last_tracked_messages: latest.sort((a, b) => a.timestamp - b.timestamp),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
track_start_timestamp: sessionStartTimestamp,
|
|
87
|
+
last_update_timestamp: lastUpdateTimestamp,
|
|
88
|
+
channels_with_updates: channelsWithUpdates,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
// ── Node ───────────────────────────────────────────────
|
|
92
|
+
export const filterNode = async (state) => {
|
|
93
|
+
const posts = await getChannelPosts(state.alertId);
|
|
94
|
+
const previousEnrichment = await getEnrichmentData();
|
|
95
|
+
const session = await getActiveSession();
|
|
96
|
+
const sessionStartTimestamp = session?.sessionStartTs ?? state.alertTs;
|
|
97
|
+
const lastUpdateTimestamp = await getLastUpdateTs();
|
|
98
|
+
if (posts.length === 0) {
|
|
99
|
+
logger.info("Agent: no posts", { alertId: state.alertId });
|
|
100
|
+
return { tracking: undefined, previousEnrichment };
|
|
101
|
+
}
|
|
102
|
+
const tracking = buildChannelTracking(posts, sessionStartTimestamp, lastUpdateTimestamp);
|
|
103
|
+
logger.info("Agent: channel tracking", {
|
|
104
|
+
alertId: state.alertId,
|
|
105
|
+
total_posts: posts.length,
|
|
106
|
+
channels_with_updates: tracking.channels_with_updates.length,
|
|
107
|
+
total_new_posts: tracking.channels_with_updates.reduce((total, channel) => total + channel.last_tracked_messages.length, 0),
|
|
108
|
+
});
|
|
109
|
+
return { tracking, previousEnrichment };
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=filters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filters.js","sourceRoot":"","sources":["../../src/nodes/filters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message building and Telegram editing.
|
|
3
|
+
*
|
|
4
|
+
* Builds enriched message text from voted consensus + carry-forward data.
|
|
5
|
+
* Uses inline [[1]](url) citations. No superscripts. No footer sources.
|
|
6
|
+
*/
|
|
7
|
+
import type { AlertType, CitedSource, EnrichmentData, InlineCite, VotedResult } from "@easyoref/shared";
|
|
8
|
+
/** EN country name → Russian */
|
|
9
|
+
export declare const COUNTRY_RU: Record<string, string>;
|
|
10
|
+
/** Format inline citations: [[1]](url), [[2]](url) */
|
|
11
|
+
export declare function inlineCites(indices: number[], citedSources: CitedSource[]): string;
|
|
12
|
+
/** Get InlineCite[] from citation indices */
|
|
13
|
+
export declare function extractCites(indices: number[], citedSources: CitedSource[]): InlineCite[];
|
|
14
|
+
/** Format inline citations from InlineCite[] (carry-forward data) */
|
|
15
|
+
export declare function inlineCitesFromData(cites: InlineCite[]): string;
|
|
16
|
+
/**
|
|
17
|
+
* Build a global URL→index map across ALL enrichment fields.
|
|
18
|
+
* Deduplicates by URL so the same source gets the same [N] everywhere.
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildGlobalCiteMap(enrichment: EnrichmentData): Map<string, number>;
|
|
21
|
+
/** Format inline citations using global numbering */
|
|
22
|
+
export declare function renderCitesGlobal(cites: InlineCite[], globalMap: Map<string, number>): string;
|
|
23
|
+
export declare const SKIP = 0.6;
|
|
24
|
+
export declare const UNCERTAIN = 0.75;
|
|
25
|
+
export declare const CERTAIN = 0.95;
|
|
26
|
+
/** Strip custom-emoji monitoring line from message text */
|
|
27
|
+
export declare const MONITORING_RE: RegExp;
|
|
28
|
+
export declare function stripMonitoring(text: string): string;
|
|
29
|
+
export declare function appendMonitoring(text: string, label: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Build enrichment data from current vote + previous enrichment (carry-forward).
|
|
32
|
+
* Returns updated EnrichmentData for Redis persistence.
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildEnrichmentFromVote(r: VotedResult, prev: EnrichmentData, alertType: AlertType, alertTs: number): EnrichmentData;
|
|
35
|
+
/**
|
|
36
|
+
* Build the enriched message text from current message + enrichment data.
|
|
37
|
+
* Uses inline [[1]](url) citations.
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildEnrichedMessage(currentText: string, alertType: AlertType, alertTs: number, enrichment: EnrichmentData, monitoringLabel?: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Insert a line before </blockquote> (or legacy time line as fallback).
|
|
42
|
+
*/
|
|
43
|
+
export declare function insertBeforeBlockEnd(text: string, line: string): string;
|
|
44
|
+
/** @deprecated Use insertBeforeBlockEnd */
|
|
45
|
+
export declare const insertBeforeTimeLine: typeof insertBeforeBlockEnd;
|
|
46
|
+
export interface TelegramTargetMessage {
|
|
47
|
+
chatId: string;
|
|
48
|
+
messageId: number;
|
|
49
|
+
isCaption: boolean;
|
|
50
|
+
}
|
|
51
|
+
export interface EditMessageInput {
|
|
52
|
+
alertId: string;
|
|
53
|
+
alertTs: number;
|
|
54
|
+
alertType: AlertType;
|
|
55
|
+
chatId: string;
|
|
56
|
+
messageId: number;
|
|
57
|
+
isCaption: boolean;
|
|
58
|
+
telegramMessages?: TelegramTargetMessage[];
|
|
59
|
+
currentText: string;
|
|
60
|
+
votedResult: VotedResult | undefined;
|
|
61
|
+
previousEnrichment: EnrichmentData;
|
|
62
|
+
monitoringLabel?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Edit the Telegram message with enriched data.
|
|
66
|
+
*/
|
|
67
|
+
export declare const editTelegramMessage: (input: EditMessageInput) => Promise<void>;
|
|
68
|
+
export declare const editMessage: (input: EditMessageInput) => Promise<void>;
|
|
69
|
+
import type { AgentStateType } from "../graph.js";
|
|
70
|
+
export declare const editNode: (state: AgentStateType) => Promise<Partial<AgentStateType>>;
|
|
71
|
+
//# sourceMappingURL=message-node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-node.d.ts","sourceRoot":"","sources":["../../src/nodes/message-node.ts"],"names":[],"mappings":"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"}
|