agi-med-common 5.0.15__tar.gz → 5.0.16__tar.gz
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.
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/PKG-INFO +1 -2
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/pyproject.toml +5 -5
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/__init__.py +9 -4
- agi_med_common-5.0.16/src/agi_med_common/api/classifier_api.py +14 -0
- agi_med_common-5.0.16/src/agi_med_common/api/text_generator_api.py +6 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/models/__init__.py +1 -0
- agi_med_common-5.0.16/src/agi_med_common/models/chat.py +107 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/models/chat_item.py +11 -7
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/models/widget.py +3 -1
- agi_med_common-5.0.16/src/agi_med_common/type_union.py +63 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/utils.py +11 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common.egg-info/PKG-INFO +1 -2
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common.egg-info/SOURCES.txt +4 -6
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common.egg-info/requires.txt +0 -1
- agi_med_common-5.0.15/requirements.txt +0 -3
- agi_med_common-5.0.15/src/agi_med_common/api/critic_api.py +0 -6
- agi_med_common-5.0.15/src/agi_med_common/api/text_processor_api.py +0 -6
- agi_med_common-5.0.15/src/agi_med_common/logger/__init__.py +0 -2
- agi_med_common-5.0.15/src/agi_med_common/logger/log_level_enum.py +0 -15
- agi_med_common-5.0.15/src/agi_med_common/logger/logger.py +0 -28
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/README.md +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/setup.cfg +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/api/chat_manager_api.py +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/api/content_interpreter_api.py +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/api/content_interpreter_remote_api.py +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/file_storage.py +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/models/_base.py +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/models/base_config_models/__init__.py +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/models/base_config_models/gigachat_config.py +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/models/enums.py +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/models/tracks.py +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/parallel_map.py +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/validators.py +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/xml_parser.py +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common.egg-info/dependency_links.txt +0 -0
- {agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common.egg-info/top_level.txt +0 -0
@@ -1,12 +1,11 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: agi_med_common
|
3
|
-
Version: 5.0.
|
3
|
+
Version: 5.0.16
|
4
4
|
Summary: Сommon for agi-med team
|
5
5
|
Author: AGI-MED-TEAM
|
6
6
|
Requires-Python: >=3.11
|
7
7
|
Description-Content-Type: text/markdown
|
8
8
|
Requires-Dist: pydantic<=3.0.0,>=2.9.2
|
9
|
-
Requires-Dist: loguru~=0.7.2
|
10
9
|
Requires-Dist: tqdm==4.67.*
|
11
10
|
|
12
11
|
# agi-med-common
|
@@ -5,17 +5,17 @@ build-backend = "setuptools.build_meta"
|
|
5
5
|
[project]
|
6
6
|
name = 'agi_med_common'
|
7
7
|
requires-python = ">= 3.11"
|
8
|
-
|
9
8
|
authors = [{ name = 'AGI-MED-TEAM' }]
|
10
9
|
description = 'Сommon for agi-med team'
|
11
10
|
readme = 'README.md'
|
12
|
-
|
13
|
-
|
11
|
+
dynamic = ['version']
|
12
|
+
dependencies = [
|
13
|
+
"pydantic>=2.9.2,<=3.0.0",
|
14
|
+
"tqdm==4.67.*",
|
15
|
+
]
|
14
16
|
|
15
17
|
[tool.setuptools.packages.find]
|
16
18
|
where = ["src"]
|
17
19
|
|
18
|
-
|
19
20
|
[tool.setuptools.dynamic]
|
20
21
|
version = { attr = "agi_med_common.__version__" }
|
21
|
-
dependencies = { file = ['requirements.txt'] }
|
@@ -1,12 +1,17 @@
|
|
1
|
-
__version__ = "5.0.
|
1
|
+
__version__ = "5.0.16"
|
2
2
|
|
3
|
-
from .logger import LogLevelEnum, logger_init, log_llm_error
|
4
3
|
from .models import (
|
5
4
|
MTRSLabelEnum,
|
6
5
|
ChatItem,
|
7
6
|
InnerContextItem,
|
8
7
|
OuterContextItem,
|
9
8
|
ReplicaItem,
|
9
|
+
Chat,
|
10
|
+
Context,
|
11
|
+
ChatMessage,
|
12
|
+
AIMessage,
|
13
|
+
HumanMessage,
|
14
|
+
MiscMessage,
|
10
15
|
)
|
11
16
|
from .models.widget import Widget
|
12
17
|
from .file_storage import FileStorage, ResourceId
|
@@ -19,5 +24,5 @@ from .models.tracks import TrackInfo, DomainInfo
|
|
19
24
|
from .api.chat_manager_api import ChatManagerAPI
|
20
25
|
from .api.content_interpreter_api import ContentInterpreterAPI, Interpretation
|
21
26
|
from .api.content_interpreter_remote_api import ContentInterpreterRemoteAPI
|
22
|
-
from .api.
|
23
|
-
from .api.
|
27
|
+
from .api.text_generator_api import TextGeneratorAPI
|
28
|
+
from .api.classifier_api import ClassifierAPI
|
@@ -0,0 +1,14 @@
|
|
1
|
+
from typing import List
|
2
|
+
|
3
|
+
from agi_med_common.models import ChatItem
|
4
|
+
|
5
|
+
|
6
|
+
Value = str
|
7
|
+
|
8
|
+
|
9
|
+
class ClassifierAPI:
|
10
|
+
def get_values(self) -> List[Value]:
|
11
|
+
raise NotImplementedError
|
12
|
+
|
13
|
+
def evaluate(self, chat: ChatItem, request_id: str = "") -> Value:
|
14
|
+
raise NotImplementedError
|
@@ -2,5 +2,6 @@ from ._base import _Base
|
|
2
2
|
|
3
3
|
from .enums import MTRSLabelEnum, DiagnosticsXMLTagEnum, MTRSXMLTagEnum, DoctorChoiceXMLTagEnum
|
4
4
|
from .chat_item import ChatItem, OuterContextItem, InnerContextItem, ReplicaItem
|
5
|
+
from .chat import Chat, Context, ChatMessage, AIMessage, HumanMessage, MiscMessage
|
5
6
|
from .base_config_models import GigaChatConfig
|
6
7
|
from .tracks import TrackInfo, DomainInfo
|
@@ -0,0 +1,107 @@
|
|
1
|
+
from datetime import datetime
|
2
|
+
from typing import Any, List, Dict, Literal
|
3
|
+
|
4
|
+
from agi_med_common.models.widget import Widget
|
5
|
+
from agi_med_common.type_union import TypeUnion
|
6
|
+
from agi_med_common.utils import first_nonnull
|
7
|
+
from pydantic import Field
|
8
|
+
|
9
|
+
from ._base import _Base
|
10
|
+
|
11
|
+
|
12
|
+
_DT_FORMAT: str = "%Y-%m-%d-%H-%M-%S"
|
13
|
+
_EXAMPLE_DT: str = datetime(year=1970, month=1, day=1).strftime(_DT_FORMAT)
|
14
|
+
StrDict = Dict[str, Any]
|
15
|
+
ContentBase = str | Widget | StrDict
|
16
|
+
Content = ContentBase | List[ContentBase]
|
17
|
+
|
18
|
+
|
19
|
+
def now_pretty() -> str:
|
20
|
+
return datetime.now().strftime(_DT_FORMAT)
|
21
|
+
|
22
|
+
|
23
|
+
class Context(_Base):
|
24
|
+
client_id: str = Field("", examples=["543216789"])
|
25
|
+
user_id: str = Field("", examples=["123456789"])
|
26
|
+
session_id: str = Field("", examples=["987654321"])
|
27
|
+
track_id: str = Field(examples=["Hello"])
|
28
|
+
extra: StrDict | None = Field(None, examples=[None])
|
29
|
+
|
30
|
+
def create_id(self, short: bool = False) -> str:
|
31
|
+
uid, sid, cid = self.user_id, self.session_id, self.client_id
|
32
|
+
if short:
|
33
|
+
return f"{cid}_{uid}_{sid}"
|
34
|
+
return f"client_{cid}_user_{uid}_session_{sid}"
|
35
|
+
|
36
|
+
|
37
|
+
def _get_str_field(obj: dict, field) -> str | None:
|
38
|
+
if not isinstance(obj, dict):
|
39
|
+
return None
|
40
|
+
text = obj.get(field)
|
41
|
+
if text is not None and isinstance(text, str):
|
42
|
+
return text
|
43
|
+
return None
|
44
|
+
|
45
|
+
|
46
|
+
def _get_text(obj: Content) -> str:
|
47
|
+
if isinstance(obj, str):
|
48
|
+
return obj
|
49
|
+
if isinstance(obj, list):
|
50
|
+
return "".join(map(_get_text, obj))
|
51
|
+
if isinstance(obj, dict) and obj.get("type") == "text":
|
52
|
+
return _get_str_field(obj, "text") or ""
|
53
|
+
return ""
|
54
|
+
|
55
|
+
|
56
|
+
def _get_resource_id(obj: Content) -> str | None:
|
57
|
+
if isinstance(obj, list):
|
58
|
+
return first_nonnull(_get_str_field(el, "resource_id") for el in obj)
|
59
|
+
if isinstance(obj, dict) and obj.get("type") == "resource_id":
|
60
|
+
return _get_str_field(obj, "resource_id")
|
61
|
+
return None
|
62
|
+
|
63
|
+
|
64
|
+
class BaseMessage(_Base):
|
65
|
+
type: str
|
66
|
+
content: Content = Field("", examples=["Привет"])
|
67
|
+
date_time: str = Field(default_factory=now_pretty, examples=[_EXAMPLE_DT])
|
68
|
+
extra: StrDict | None = Field(None, examples=[None])
|
69
|
+
|
70
|
+
@property
|
71
|
+
def text(self) -> str:
|
72
|
+
return _get_text(self.content)
|
73
|
+
|
74
|
+
@property
|
75
|
+
def resource_id(self) -> str | None:
|
76
|
+
return _get_resource_id(self.content)
|
77
|
+
|
78
|
+
@staticmethod
|
79
|
+
def DATETIME_FORMAT() -> str:
|
80
|
+
return _DT_FORMAT
|
81
|
+
|
82
|
+
def with_now_datetime(self):
|
83
|
+
return self.model_copy(update=dict(date_time=now_pretty()))
|
84
|
+
|
85
|
+
|
86
|
+
class HumanMessage(BaseMessage):
|
87
|
+
type: Literal["human"] = "human"
|
88
|
+
|
89
|
+
|
90
|
+
class AIMessage(BaseMessage):
|
91
|
+
type: Literal["ai"] = "ai"
|
92
|
+
state: str = Field("", examples=["COLLECTION"])
|
93
|
+
|
94
|
+
|
95
|
+
class MiscMessage(BaseMessage):
|
96
|
+
type: Literal["misc"] = "misc"
|
97
|
+
|
98
|
+
|
99
|
+
ChatMessage = TypeUnion[HumanMessage, AIMessage, MiscMessage]
|
100
|
+
|
101
|
+
|
102
|
+
class Chat(_Base):
|
103
|
+
context: Context
|
104
|
+
messages: List[ChatMessage] = []
|
105
|
+
|
106
|
+
def create_id(self, short: bool = False) -> str:
|
107
|
+
return self.context.create_id(short)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import json
|
2
|
+
import warnings
|
2
3
|
from datetime import datetime
|
3
4
|
from typing import Any, List
|
4
5
|
|
@@ -97,8 +98,8 @@ class ChatItem(_Base):
|
|
97
98
|
return [replica.to_dict().get(field, None) for replica in self.inner_context.replicas]
|
98
99
|
|
99
100
|
@classmethod
|
100
|
-
def parse(cls,
|
101
|
-
return _parse_chat(
|
101
|
+
def parse(cls, chat_obj: str | dict) -> "ChatItem":
|
102
|
+
return _parse_chat(chat_obj)
|
102
103
|
|
103
104
|
|
104
105
|
def _is_moderation_int_error(err):
|
@@ -117,17 +118,20 @@ def _is_moderation_int_errors(ex):
|
|
117
118
|
return all(map(_is_moderation_int_error, errs))
|
118
119
|
|
119
120
|
|
120
|
-
def _parse_chat(
|
121
|
+
def _parse_chat(chat_obj: str | dict) -> ChatItem:
|
122
|
+
if isinstance(chat_obj, dict):
|
123
|
+
return ChatItem(**chat_obj)
|
121
124
|
try:
|
122
|
-
return ChatItem.model_validate_json(
|
125
|
+
return ChatItem.model_validate_json(chat_obj)
|
123
126
|
except ValidationError as ex:
|
124
127
|
if _is_moderation_int_errors(ex):
|
125
|
-
|
128
|
+
msg = "Failed to parse ChatItem, fallback to old version with `Moderation:int`"
|
126
129
|
else:
|
127
|
-
|
130
|
+
msg = f"Failed to parse: {ex}"
|
131
|
+
warnings.warn(msg)
|
128
132
|
|
129
133
|
# old version
|
130
|
-
chat_dict = json.loads(
|
134
|
+
chat_dict = json.loads(chat_obj)
|
131
135
|
for rep in chat_dict["InnerContext"]["Replicas"]:
|
132
136
|
rep["Moderation"] = "OK"
|
133
137
|
|
@@ -1,8 +1,10 @@
|
|
1
|
-
from typing import List, Self
|
1
|
+
from typing import List, Self, Literal
|
2
|
+
|
2
3
|
from pydantic import BaseModel, model_validator
|
3
4
|
|
4
5
|
|
5
6
|
class Widget(BaseModel):
|
7
|
+
type: Literal["widget"] = "widget"
|
6
8
|
buttons: List[List[str]] | None = None
|
7
9
|
ibuttons: List[List[str]] | None = None
|
8
10
|
|
@@ -0,0 +1,63 @@
|
|
1
|
+
from typing import Any, Union, Annotated, get_args, get_origin, Literal
|
2
|
+
|
3
|
+
from pydantic import Discriminator, BaseModel, Tag
|
4
|
+
|
5
|
+
|
6
|
+
class _TypeUnionMeta(type):
|
7
|
+
def __getitem__(cls, types):
|
8
|
+
if not isinstance(types, tuple):
|
9
|
+
types = (types,)
|
10
|
+
|
11
|
+
for tp in types:
|
12
|
+
if not isinstance(tp, type) or not issubclass(tp, BaseModel):
|
13
|
+
raise ValueError(f"Type {tp} must derived from BaseModel")
|
14
|
+
|
15
|
+
# Create tagged union
|
16
|
+
tagged_types = []
|
17
|
+
type_map = {}
|
18
|
+
type_names = set()
|
19
|
+
for t in types:
|
20
|
+
type_annot = t.__annotations__.get("type")
|
21
|
+
if not type_annot or get_origin(type_annot) != Literal:
|
22
|
+
raise ValueError(f"Type {t} must have a 'type' Literal[..] field for discrimination")
|
23
|
+
type_name = get_args(type_annot)[0]
|
24
|
+
type_map[type_name] = t
|
25
|
+
tagged_types.append(Annotated[t, Tag(type_name)])
|
26
|
+
type_names.add(type_name)
|
27
|
+
|
28
|
+
# Create the union type
|
29
|
+
union_type = Union[tuple(tagged_types)]
|
30
|
+
|
31
|
+
# Create discriminator function
|
32
|
+
def type_discriminator(v: Any) -> str:
|
33
|
+
if isinstance(v, types):
|
34
|
+
return v.type
|
35
|
+
if isinstance(v, dict):
|
36
|
+
tp = v.get("type")
|
37
|
+
return tp if tp in type_names else None
|
38
|
+
return None
|
39
|
+
|
40
|
+
# Add discriminator
|
41
|
+
return Annotated[union_type, Discriminator(type_discriminator)]
|
42
|
+
|
43
|
+
|
44
|
+
class TypeUnion(metaclass=_TypeUnionMeta):
|
45
|
+
"""
|
46
|
+
Wrapper around Union which derive type from field 'type' for effective deserialization via TypeAdapter.
|
47
|
+
|
48
|
+
Usage example:
|
49
|
+
```
|
50
|
+
class BaseFruit(BaseModel):
|
51
|
+
type: str
|
52
|
+
|
53
|
+
class Apple(BaseFruit):
|
54
|
+
type: Literal['apple'] = 'apple'
|
55
|
+
|
56
|
+
class Orange(BaseFruit):
|
57
|
+
type: Literal['orange'] = 'orange'
|
58
|
+
|
59
|
+
Fruit = TypeUnion[Apple, Orange]
|
60
|
+
```
|
61
|
+
"""
|
62
|
+
|
63
|
+
pass
|
@@ -3,6 +3,7 @@ import json
|
|
3
3
|
import os
|
4
4
|
from datetime import datetime
|
5
5
|
from pathlib import Path
|
6
|
+
from typing import Iterable
|
6
7
|
|
7
8
|
|
8
9
|
def make_session_id() -> str:
|
@@ -36,17 +37,20 @@ def try_parse_int(text: str) -> int | None:
|
|
36
37
|
except (ValueError, TypeError):
|
37
38
|
return None
|
38
39
|
|
40
|
+
|
39
41
|
def try_parse_float(text: str) -> float | None:
|
40
42
|
try:
|
41
43
|
return float(text)
|
42
44
|
except (ValueError, TypeError):
|
43
45
|
return None
|
44
46
|
|
47
|
+
|
45
48
|
def try_parse_bool(v: str | bool) -> bool:
|
46
49
|
if isinstance(v, bool):
|
47
50
|
return v
|
48
51
|
return v.lower() in ("yes", "true", "t", "1")
|
49
52
|
|
53
|
+
|
50
54
|
def pretty_line(text: str, cut_count: int = 100) -> str:
|
51
55
|
if len(text) > 100:
|
52
56
|
text_cut = text[:cut_count]
|
@@ -56,3 +60,10 @@ def pretty_line(text: str, cut_count: int = 100) -> str:
|
|
56
60
|
text_pretty = text
|
57
61
|
text_pretty = text_pretty.replace("\n", "\\n")
|
58
62
|
return text_pretty
|
63
|
+
|
64
|
+
|
65
|
+
def first_nonnull(obj: Iterable):
|
66
|
+
for elem in obj:
|
67
|
+
if elem:
|
68
|
+
return elem
|
69
|
+
return None
|
@@ -1,12 +1,11 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: agi_med_common
|
3
|
-
Version: 5.0.
|
3
|
+
Version: 5.0.16
|
4
4
|
Summary: Сommon for agi-med team
|
5
5
|
Author: AGI-MED-TEAM
|
6
6
|
Requires-Python: >=3.11
|
7
7
|
Description-Content-Type: text/markdown
|
8
8
|
Requires-Dist: pydantic<=3.0.0,>=2.9.2
|
9
|
-
Requires-Dist: loguru~=0.7.2
|
10
9
|
Requires-Dist: tqdm==4.67.*
|
11
10
|
|
12
11
|
# agi-med-common
|
@@ -1,9 +1,9 @@
|
|
1
1
|
README.md
|
2
2
|
pyproject.toml
|
3
|
-
requirements.txt
|
4
3
|
src/agi_med_common/__init__.py
|
5
4
|
src/agi_med_common/file_storage.py
|
6
5
|
src/agi_med_common/parallel_map.py
|
6
|
+
src/agi_med_common/type_union.py
|
7
7
|
src/agi_med_common/utils.py
|
8
8
|
src/agi_med_common/validators.py
|
9
9
|
src/agi_med_common/xml_parser.py
|
@@ -13,15 +13,13 @@ src/agi_med_common.egg-info/dependency_links.txt
|
|
13
13
|
src/agi_med_common.egg-info/requires.txt
|
14
14
|
src/agi_med_common.egg-info/top_level.txt
|
15
15
|
src/agi_med_common/api/chat_manager_api.py
|
16
|
+
src/agi_med_common/api/classifier_api.py
|
16
17
|
src/agi_med_common/api/content_interpreter_api.py
|
17
18
|
src/agi_med_common/api/content_interpreter_remote_api.py
|
18
|
-
src/agi_med_common/api/
|
19
|
-
src/agi_med_common/api/text_processor_api.py
|
20
|
-
src/agi_med_common/logger/__init__.py
|
21
|
-
src/agi_med_common/logger/log_level_enum.py
|
22
|
-
src/agi_med_common/logger/logger.py
|
19
|
+
src/agi_med_common/api/text_generator_api.py
|
23
20
|
src/agi_med_common/models/__init__.py
|
24
21
|
src/agi_med_common/models/_base.py
|
22
|
+
src/agi_med_common/models/chat.py
|
25
23
|
src/agi_med_common/models/chat_item.py
|
26
24
|
src/agi_med_common/models/enums.py
|
27
25
|
src/agi_med_common/models/tracks.py
|
@@ -1,15 +0,0 @@
|
|
1
|
-
from enum import StrEnum, auto
|
2
|
-
|
3
|
-
|
4
|
-
class LogLevelEnum(StrEnum):
|
5
|
-
@staticmethod
|
6
|
-
def _generate_next_value_(name: str, start: int, count: int, last_values: list[str]) -> str:
|
7
|
-
return name.upper()
|
8
|
-
|
9
|
-
TRACE = auto() # logger.trace()
|
10
|
-
DEBUG = auto() # logger.debug()
|
11
|
-
INFO = auto() # logger.info()
|
12
|
-
SUCCESS = auto() # logger.success()
|
13
|
-
WARNING = auto() # logger.warning()
|
14
|
-
ERROR = auto() # logger.error()
|
15
|
-
CRITICAL = auto() # logger.critical()
|
@@ -1,28 +0,0 @@
|
|
1
|
-
import sys
|
2
|
-
|
3
|
-
from loguru import logger
|
4
|
-
|
5
|
-
from . import LogLevelEnum
|
6
|
-
|
7
|
-
|
8
|
-
def logger_init(log_level: LogLevelEnum) -> None:
|
9
|
-
logger.remove()
|
10
|
-
extra = {"request_id": "SYSTEM_LOG"}
|
11
|
-
format_ = "{time:DD-MM-YYYY HH:mm:ss} | <level>{level: <8}</level> | {extra[request_id]}"
|
12
|
-
format_ = f"{format_} | <level>{{message}}</level>"
|
13
|
-
logger.add(sys.stdout, colorize=True, format=format_, level=log_level)
|
14
|
-
logger.configure(extra=extra)
|
15
|
-
|
16
|
-
|
17
|
-
def log_llm_error(
|
18
|
-
text: str | None = None,
|
19
|
-
vector: list[float] | None = None,
|
20
|
-
model: str = "gigachat",
|
21
|
-
) -> None:
|
22
|
-
if text is not None and not text:
|
23
|
-
logger.error(f"No response from {model}!!!")
|
24
|
-
return None
|
25
|
-
if vector is not None and all(not item for item in vector):
|
26
|
-
logger.error(f"No response from {model} encoder!!!")
|
27
|
-
return None
|
28
|
-
return None
|
File without changes
|
File without changes
|
File without changes
|
{agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common/api/content_interpreter_api.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{agi_med_common-5.0.15 → agi_med_common-5.0.16}/src/agi_med_common.egg-info/dependency_links.txt
RENAMED
File without changes
|
File without changes
|