Skip to content

注册表相关工具 (Registry Utils)

make_hashable_key

make_hashable_key(*args: Any, **kwargs: Any) -> tuple

Converts the given arguments and keyword arguments into a hashable key.

将给定的参数和关键字参数转换为可哈希键。

Parameters:

Name Type Description Default
args Any

The positional arguments to convert. Can be any type.

要转换的位置参数。可以是任何类型。

()
kwargs Any

The keyword arguments to convert. Can be any type.

要转换的关键字参数。可以是任何类型。

{}

Returns:

Name Type Description
tuple tuple

A hashable key representing the given arguments and keyword arguments.

表示给定参数和关键字参数的可哈希键。

Example

make_hashable_key(1, "abc", [4, 5, 6], x=[7, 8, 9]) (1, 'abc', (4, 5, 6), ('x', (7, 8, 9)))

Source code in tfrobot/registry/utils.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def make_hashable_key(*args: Any, **kwargs: Any) -> tuple:
    """
    Converts the given arguments and keyword arguments into a hashable key.

    将给定的参数和关键字参数转换为可哈希键。

    Args:
        args (Any): The positional arguments to convert. Can be any type.

            要转换的位置参数。可以是任何类型。
        kwargs (Any): The keyword arguments to convert. Can be any type.

            要转换的关键字参数。可以是任何类型。

    Returns:
        tuple: A hashable key representing the given arguments and keyword arguments.

            表示给定参数和关键字参数的可哈希键。

    Example:
        >>> make_hashable_key(1, "abc", [4, 5, 6], x=[7, 8, 9])
        (1, 'abc', (4, 5, 6), ('x', (7, 8, 9)))
    """
    hashable_args = tuple(tuple(arg) if isinstance(arg, list) or isinstance(arg, set) else arg for arg in args)
    hashable_kwargs = {k: tuple(v) if isinstance(v, list) or isinstance(v, set) else v for k, v in kwargs.items()}
    return hashable_args + tuple(sorted(hashable_kwargs.items()))

generate_register_name

generate_register_name(
    obj: Union[
        BaseModel,
        Type[BaseModel],
        type,
        SavableProtocol,
        Callable,
    ],
) -> str

Generates a unique register name for the provided object. The TFRobot library manages the registration names for key objects globally, including but not limited to the following types: BaseTool, BaseLLM, BasePrompt, BaseChain, BaseMemory, BaseMemoryStore, BaseBrain, Callable. This global management facilitates subsequent searching, calling, serialization, and deserialization operations, hence the need to generate a unique registration name for each object.

为提供的对象生成唯一的注册名称。TFRobot库全局管理各个重点对象的注册名称,包括但不限于以下类型:BaseTool, BaseLLM, BasePrompt, BaseChain, BaseMemory, BaseMemoryStore, BaseBrain, Callable。这种全局管理有利于后续的查找、调用、序列化和反序列化操作, 因此需要为每个对象生成一个唯一的注册名称。

The name generation strategy is as follows: 0 If the class declares __register_name__: ClassVar[str] explicitly, use that value verbatim (with spaces → underscores). Highest priority; introduced for stable URI authority on RegisterMap families like HashStrategy (e.g., hash-strategy://default instead of hash-strategy://defaulthashstrategy). Pre-existing families (BaseLLM / OCRAgent / Embedding) don't declare it and fall through to the legacy strategies below. 1 If the class itself is being registered, it first tries to use its name attribute's default value. If it does not have a name attribute or if it's empty, it uses the classname in lowercase. 2 If an instance is being registered, first check whether the instance is an instance of BaseModel or its subclasses. If it is, use its class to generate a registration name. If it is not, directly use class.name.lower(). 3 If it's a function, it uses the function name along with the docstring as the key. 4 All objects must be a subclass of BaseModel, an instance of a subclass, or of Callable type.

名称生成策略如下: 0 如果类显式声明 __register_name__: ClassVar[str],直接采用该值(空格转下划线)。优先级最高; 为 HashStrategy 等家族提供稳定的 URI authority(如 hash-strategy://default 而非 hash-strategy://defaulthashstrategy)。既有家族(BaseLLM / OCRAgent / Embedding)未声明该 ClassVar, 会回落到下面的旧策略,行为不变。 1 如果类本身正在注册,则首先尝试使用其name属性的默认值。如果它没有name属性或者为空,则使用小写的类名。 2 如果实例正在注册,则首先判断是实例是否是BaseModel及其子类的实例,如果是,取其__class__生成注册名。如果不是,直接使用 class.name.lower() 3 如果是函数,则使用函数名称和文档字符串作为键。 4 所有对象必须是BaseModel的子类、子类的实例或Callable类型。

Parameters:

Name Type Description Default
obj Union[Type[BaseModel], BaseModel, Callable]

The object for which to generate a registration name.

需要生成注册名的对象。

required

Returns:

Name Type Description
str str

The generated unique registration name.

生成的唯一注册名称。

Source code in tfrobot/registry/utils.py
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
def generate_register_name(obj: Union[BaseModel, Type[BaseModel], type, SavableProtocol, Callable]) -> str:
    """
    Generates a unique register name for the provided object. The TFRobot library manages the registration names for
    key objects globally, including but not limited to the following types: BaseTool, BaseLLM, BasePrompt, BaseChain,
    BaseMemory, BaseMemoryStore, BaseBrain, Callable. This global management facilitates subsequent searching,
    calling, serialization, and deserialization operations, hence the need to generate a unique registration name for
    each object.

    为提供的对象生成唯一的注册名称。TFRobot库全局管理各个重点对象的注册名称,包括但不限于以下类型:BaseTool, BaseLLM,
    BasePrompt, BaseChain, BaseMemory, BaseMemoryStore, BaseBrain, Callable。这种全局管理有利于后续的查找、调用、序列化和反序列化操作,
    因此需要为每个对象生成一个唯一的注册名称。

    The name generation strategy is as follows:
    0 If the class declares ``__register_name__: ClassVar[str]`` explicitly, use that value verbatim
    (with spaces → underscores). Highest priority; introduced for stable URI authority on
    RegisterMap families like HashStrategy (e.g., ``hash-strategy://default`` instead of
    ``hash-strategy://defaulthashstrategy``). Pre-existing families (BaseLLM / OCRAgent / Embedding)
    don't declare it and fall through to the legacy strategies below.
    1 If the class itself is being registered, it first tries to use its name attribute's default value. If it does not
    have a name attribute or if it's empty, it uses the classname in lowercase.
    2 If an instance is being registered, first check whether the instance is an instance of BaseModel or its
    subclasses. If it is, use its class to generate a registration name. If it is not, directly use class.name.lower().
    3 If it's a function, it uses the function name along with the docstring as the key.
    4 All objects must be a subclass of BaseModel, an instance of a subclass, or of Callable type.

    名称生成策略如下:
    0 如果类显式声明 ``__register_name__: ClassVar[str]``,直接采用该值(空格转下划线)。优先级最高;
    为 HashStrategy 等家族提供稳定的 URI authority(如 ``hash-strategy://default`` 而非
    ``hash-strategy://defaulthashstrategy``)。既有家族(BaseLLM / OCRAgent / Embedding)未声明该 ClassVar,
    会回落到下面的旧策略,行为不变。
    1 如果类本身正在注册,则首先尝试使用其name属性的默认值。如果它没有name属性或者为空,则使用小写的类名。
    2 如果实例正在注册,则首先判断是实例是否是BaseModel及其子类的实例,如果是,取其__class__生成注册名。如果不是,直接使用 __class__.__name__.lower()
    3 如果是函数,则使用函数名称和文档字符串作为键。
    4 所有对象必须是BaseModel的子类、子类的实例或Callable类型。

    Args:
        obj (Union[Type[BaseModel], BaseModel, Callable]): The object for which to generate a registration name.

            需要生成注册名的对象。

    Returns:
        str: The generated unique registration name.

            生成的唯一注册名称。
    """
    register_name: str
    if isinstance(obj, BaseModel):
        obj = obj.__class__

    from tfrobot.neural.model_proxy import NeuralProxy

    if inspect.isclass(obj) and issubclass(obj, (BaseModel, NeuralProxy)):
        # TFROB-376 (D20 / D19 衍生): 显式声明 `__register_name__: ClassVar[str]` 优先级最高。
        # 让 HashStrategy 等家族用稳定的 URI authority(`hash-strategy://default`)而非类名 lower case
        # (`defaulthashstrategy`)。仅当类显式声明该 ClassVar 时启用,BaseLLM/OCRAgent/Embedding 等
        # 既有家族不受影响(它们都没声明 __register_name__)。
        explicit = getattr(obj, "__register_name__", None)
        if isinstance(explicit, str) and explicit:
            register_name = explicit.replace(" ", "_")
        elif hasattr(obj, "name") and getattr(obj, "name") and isinstance(getattr(obj, "name"), str):
            register_name = getattr(obj, "name").replace(" ", "_")
        else:
            register_name = obj.__name__.lower()
    elif inspect.isfunction(obj):
        doc_string = obj.__doc__ or "unnamed_function"
        register_name = f"{obj.__name__}_{doc_string}".replace(" ", "_").lower()
    else:
        register_name = obj.__class__.__name__.lower() if not inspect.isclass(obj) else obj.__name__.lower()
    return register_name