使用contextvars重构上下文标记功能

This commit is contained in:
jingrow 2025-11-01 03:46:11 +08:00
parent 92700c638a
commit 99491e0b9b
2 changed files with 13 additions and 12 deletions

View File

@ -6,7 +6,7 @@ import functools
import inspect
import logging
import os
import threading
from contextvars import ContextVar
from jingrow.model.page import Page
from jingrow.config import Config
from jingrow.utils.jingrow_api import upload_file_to_jingrow
@ -14,8 +14,7 @@ from jingrow.utils.jingrow_api import upload_file_to_jingrow
_local = {}
# 【通用执行上下文标记】用于标记当前调用链的来源,防止循环触发等场景
# 使用 thread-local 存储,轻量且精确(同一线程内有效)
_update_source_context = threading.local()
_update_source_context: ContextVar[Optional[str]] = ContextVar('update_source', default=None)
# 统一 Jingrow 日志记录器(仅为本模块及调用方提供最小可用输出,不修改全局 root logger
_root_logger = logging.getLogger("jingrow")
@ -70,31 +69,33 @@ def update_pg(pagetype: str, name: str, data: Dict[str, Any]):
def skip_hooks(source: str = "agent"):
"""
设置上下文标记表示当前调用链来自指定来源如智能体执行
用于跳过某些钩子防止循环触发等场景
用于跳过某些钩子防止循环触发等场景
使用 contextvars.ContextVar支持同步和异步上下文传播
"""
try:
_update_source_context.source = source
_update_source_context.set(source)
except Exception:
pass
def restore_hooks():
"""
清除上下文标记恢复正常的钩子执行
清除上下文标记恢复正常的钩子执行
注意contextvars 会自动管理上下文生命周期通常在 try-finally 中使用
"""
try:
if hasattr(_update_source_context, 'source'):
delattr(_update_source_context, 'source')
_update_source_context.set(None)
except Exception:
pass
def get_hook_source() -> Optional[str]:
"""
获取当前调用链的来源标识用于判断是否跳过某些钩子
获取当前调用链的来源标识用于判断是否跳过某些钩子
在异步环境中也能正确获取上下文值
"""
try:
return getattr(_update_source_context, 'source', None)
return _update_source_context.get()
except Exception:
return None

View File

@ -38,14 +38,14 @@ def run_agent(pg=None, method=None, event=None, page=None, **kwargs):
"""本地版 Local Ai Agent 事件驱动机制。
- 支持按 pagetype module 分组合并去重
- condition 支持 Jinja2 表达式
- 使用上下文标记防止无限循环
- 使用 contextvars 上下文标记防止无限循环支持同步和异步场景
"""
# 兼容多种调用方式
pg = pg or page
method = event or method or kwargs.get("event")
# 【防无限循环】检查上下文标记:如果当前调用来自智能体执行,跳过
# 使用轻量级 thread-local 上下文标记,防止循环触发
# 使用 contextvars.ContextVar 上下文标记,支持同步和异步场景,防止循环触发
if jingrow.get_hook_source() == "agent":
return