新增 Jira 渠道扩展,支持在 Yuxi 平台中集成 Jira 项目管理渠道。 包含以下功能模块: - config: 渠道配置管理 - gateway: SSE/WebSocket 网关接入 - outbound: 外发消息与工单管理 - streaming: 流式消息处理 - parse: Jira 内容解析 - format: 消息格式转换 - agent_tools: Agent 工具集成 - security: 安全校验 - dedupe: 消息去重 - loopbreaker: 循环响应防护 - monitor: 渠道状态监控 - status: 会话与工单状态管理 - types: 类型定义
43 lines
1.3 KiB
Python
43 lines
1.3 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
import time
|
|
from collections import defaultdict
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class JiraLoopBreaker:
|
|
def __init__(self, max_comments_per_issue_per_minute: int = 8):
|
|
self._counters: dict[str, list[float]] = defaultdict(list)
|
|
self._max = max_comments_per_issue_per_minute
|
|
self._tripped: dict[str, float] = {}
|
|
|
|
def record_and_check(self, issue_key: str) -> bool:
|
|
now = time.monotonic()
|
|
window = [t for t in self._counters.get(issue_key, []) if now - t < 60]
|
|
if len(window) >= self._max:
|
|
self._tripped[issue_key] = now
|
|
logger.warning(
|
|
"Jira loop breaker tripped for issue=%s, comments=%d",
|
|
issue_key,
|
|
len(window),
|
|
)
|
|
return False
|
|
window.append(now)
|
|
self._counters[issue_key] = window
|
|
return True
|
|
|
|
def is_tripped(self, issue_key: str) -> bool:
|
|
now = time.monotonic()
|
|
trip_time = self._tripped.get(issue_key)
|
|
if trip_time and now - trip_time < 300:
|
|
return True
|
|
if trip_time and now - trip_time >= 300:
|
|
del self._tripped[issue_key]
|
|
return False
|
|
|
|
def reset_issue(self, issue_key: str):
|
|
self._counters.pop(issue_key, None)
|
|
self._tripped.pop(issue_key, None)
|