Skip to content
This repository was archived by the owner on Jun 5, 2025. It is now read-only.

Commit 3d4fd0e

Browse files
committed
feat: remove duplicated alerts
Sometimes the different client tools generate multiple requests when the user requests a task. This generates what it looks as a duplicate alert, but is not really a total duplicate as it belongs to different request. But for the user does not provide so much value to have it, so proceed with deduplicating those alerts, based on the code snippet and details of the alert Also remove dogecoin regex as it's giving false positives Closes: #875
1 parent dde0570 commit 3d4fd0e

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

signatures.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@
281281
- Bitcoin SegWit: \b(bc1)[a-zA-HJ-NP-Z0-9]{39,59}\b
282282
- Ethereum: \b0x[a-fA-F0-9]{40}\b
283283
- Litecoin: \b(L|M)[a-km-zA-HJ-NP-Z1-9]{26,33}\b
284-
- Dogecoin: \b(D|A)[a-km-zA-HJ-NP-Z1-9]{25,34}\b
285284
- Ripple: \br[rK][a-zA-Z0-9]{25,35}\b
286285
- Monero: \b4[0-9AB][1-9A-HJ-NP-Za-km-z]{93}\b
287286
- Tron: \bT[a-zA-HJ-NP-Z0-9]{33}\b

src/codegate/api/v1.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,7 @@ async def get_workspace_alerts(workspace_name: str) -> List[Optional[v1_models.A
390390

391391
try:
392392
alerts = await dbreader.get_alerts_by_workspace(ws.id, AlertSeverity.CRITICAL.value)
393+
alerts = v1_processing.remove_duplicate_alerts(alerts)
393394
prompts_outputs = await dbreader.get_prompts_with_output(ws.id)
394395
return await v1_processing.parse_get_alert_conversation(alerts, prompts_outputs)
395396
except Exception:

src/codegate/api/v1_processing.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ async def _is_system_prompt(message: str) -> bool:
6262
return False
6363

6464

65-
async def parse_request(request_str: str) -> Tuple[Optional[List[str]], str]:
65+
async def parse_request(request_str: str) -> Tuple[Optional[List[str]], str]: # noqa: C901
6666
"""
6767
Parse the request string from the pipeline and return the message and the model.
6868
"""
@@ -105,7 +105,7 @@ async def parse_request(request_str: str) -> Tuple[Optional[List[str]], str]:
105105
return messages, model
106106

107107

108-
async def parse_output(output_str: str) -> Optional[str]:
108+
async def parse_output(output_str: str) -> Optional[str]: # noqa: C901
109109
"""
110110
Parse the output string from the pipeline and return the message.
111111
"""
@@ -499,3 +499,37 @@ async def parse_workspace_token_usage(
499499
for p_qa in partial_question_answers:
500500
token_usage_agg.add_model_token_usage(p_qa.model_token_usage)
501501
return token_usage_agg
502+
503+
504+
def remove_duplicate_alerts(alerts):
505+
unique_alerts = []
506+
seen = defaultdict(list)
507+
508+
for alert in sorted(
509+
alerts, key=lambda x: x.timestamp, reverse=True
510+
): # Sort alerts by timestamp descending
511+
if alert.trigger_type != "codegate-secrets":
512+
unique_alerts.append(alert)
513+
continue
514+
515+
# Extract trigger string content until "Context"
516+
trigger_string_content = alert.trigger_string.split("Context")[0]
517+
518+
key = (
519+
alert.code_snippet,
520+
alert.trigger_type,
521+
alert.trigger_category,
522+
trigger_string_content,
523+
)
524+
525+
# If key exists and new alert is more recent, replace it
526+
if key in seen:
527+
existing_alert = seen[key]
528+
if abs((alert.timestamp - existing_alert.timestamp).total_seconds()) < 5:
529+
seen[key] = alert # Replace with newer alert
530+
continue
531+
532+
seen[key] = alert
533+
unique_alerts.append(alert)
534+
535+
return list(seen.values())

0 commit comments

Comments
 (0)