unique_toolkit 1.16.5__py3-none-any.whl → 1.17.0__py3-none-any.whl
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.
Potentially problematic release.
This version of unique_toolkit might be problematic. Click here for more details.
- unique_toolkit/agentic/tools/a2a/postprocessing/_display.py +140 -88
- unique_toolkit/agentic/tools/a2a/postprocessing/config.py +9 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/postprocessor.py +7 -1
- unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +1211 -323
- {unique_toolkit-1.16.5.dist-info → unique_toolkit-1.17.0.dist-info}/METADATA +4 -1
- {unique_toolkit-1.16.5.dist-info → unique_toolkit-1.17.0.dist-info}/RECORD +8 -8
- {unique_toolkit-1.16.5.dist-info → unique_toolkit-1.17.0.dist-info}/LICENSE +0 -0
- {unique_toolkit-1.16.5.dist-info → unique_toolkit-1.17.0.dist-info}/WHEEL +0 -0
|
@@ -1,122 +1,174 @@
|
|
|
1
1
|
import re
|
|
2
|
-
from
|
|
3
|
-
from typing import Literal, override
|
|
2
|
+
from typing import Literal
|
|
4
3
|
|
|
5
4
|
from unique_toolkit.agentic.tools.a2a.postprocessing.config import (
|
|
6
5
|
SubAgentResponseDisplayMode,
|
|
7
6
|
)
|
|
8
7
|
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
) -> str:
|
|
15
|
-
raise NotImplementedError()
|
|
9
|
+
def _wrap_text(text: str, start_text: str, end_text: str) -> str:
|
|
10
|
+
text = text.strip()
|
|
11
|
+
start_text = start_text.strip()
|
|
12
|
+
end_text = end_text.strip()
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
raise NotImplementedError()
|
|
14
|
+
if start_text != "":
|
|
15
|
+
start_text = f"{start_text}\n"
|
|
20
16
|
|
|
17
|
+
if end_text != "":
|
|
18
|
+
end_text = f"\n{end_text}"
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
def __init__(self, mode: Literal["open", "closed"]) -> None:
|
|
24
|
-
self._mode = mode
|
|
20
|
+
return f"{start_text}{text}{end_text}"
|
|
25
21
|
|
|
26
|
-
DETAILS_CLOSED_TEMPLATE = (
|
|
27
|
-
"<details><summary>{display_name}</summary>\n"
|
|
28
|
-
"\n"
|
|
29
|
-
'<div style="display: none;">{assistant_id}</div>\n'
|
|
30
|
-
"\n"
|
|
31
|
-
"{answer}\n"
|
|
32
|
-
"</details>\n"
|
|
33
|
-
"<br>\n"
|
|
34
|
-
"\n"
|
|
35
|
-
)
|
|
36
22
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"<
|
|
46
|
-
|
|
47
|
-
|
|
23
|
+
def _join_text_blocks(*blocks: str, sep: str = "\n") -> str:
|
|
24
|
+
return sep.join(block.strip() for block in blocks)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _wrap_with_details_tag(
|
|
28
|
+
text, mode: Literal["open", "closed"], summary_name: str | None = None
|
|
29
|
+
) -> str:
|
|
30
|
+
if summary_name is not None:
|
|
31
|
+
summary_tag = _wrap_text(summary_name, "<summary>", "</summary>")
|
|
32
|
+
text = _join_text_blocks(summary_tag, text)
|
|
33
|
+
|
|
34
|
+
if mode == "open":
|
|
35
|
+
text = _wrap_text(text, "<details open>", "</details>")
|
|
36
|
+
else:
|
|
37
|
+
text = _wrap_text(text, "<details>", "</details>")
|
|
38
|
+
|
|
39
|
+
return text
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
_BLOCK_BORDER_STYLE = (
|
|
43
|
+
"overflow-y: auto; border: 1px solid #ccc; padding: 8px; margin-top: 8px;"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _wrap_with_block_border(text: str) -> str:
|
|
48
|
+
return _wrap_text(text, f"<div style='{_BLOCK_BORDER_STYLE}'>", "</div>")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
_QUOTE_BORDER_STYLE = (
|
|
52
|
+
"margin-left: 20px; border-left: 2px solid #ccc; padding-left: 10px;"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _wrap_with_quote_border(text: str) -> str:
|
|
57
|
+
return _wrap_text(text, f"<div style='{_QUOTE_BORDER_STYLE}'>", "</div>")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _wrap_strong(text: str) -> str:
|
|
61
|
+
return _wrap_text(text, "<strong>", "</strong>")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _wrap_hidden_div(text: str) -> str:
|
|
65
|
+
return _wrap_text(text, '<div style="display: none;">', "</div>")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _add_line_break(text: str, before: bool = True, after: bool = True) -> str:
|
|
69
|
+
start_tag = ""
|
|
70
|
+
if before:
|
|
71
|
+
start_tag = "<br>"
|
|
48
72
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
73
|
+
end_tag = ""
|
|
74
|
+
if after:
|
|
75
|
+
end_tag = "<br>"
|
|
76
|
+
|
|
77
|
+
return _wrap_text(text, start_tag, end_tag)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _get_display_template(
|
|
81
|
+
mode: SubAgentResponseDisplayMode,
|
|
82
|
+
add_quote_border: bool,
|
|
83
|
+
add_block_border: bool,
|
|
84
|
+
answer_placeholder: str = "answer",
|
|
85
|
+
assistant_id_placeholder: str = "assistant_id",
|
|
86
|
+
display_name_placeholder: str = "display_name",
|
|
87
|
+
) -> str:
|
|
88
|
+
if mode == SubAgentResponseDisplayMode.HIDDEN:
|
|
89
|
+
return ""
|
|
90
|
+
|
|
91
|
+
assistant_id_placeholder = _wrap_hidden_div("{%s}" % assistant_id_placeholder)
|
|
92
|
+
display_name_placeholder = _wrap_strong("{%s}" % display_name_placeholder)
|
|
93
|
+
template = _join_text_blocks(
|
|
94
|
+
assistant_id_placeholder, "{%s}" % answer_placeholder, sep="\n\n"
|
|
95
|
+
) # Double line break is needed for markdown formatting
|
|
96
|
+
|
|
97
|
+
if add_quote_border:
|
|
98
|
+
template = _wrap_with_quote_border(template)
|
|
99
|
+
|
|
100
|
+
match mode:
|
|
101
|
+
case SubAgentResponseDisplayMode.DETAILS_OPEN:
|
|
102
|
+
template = _wrap_with_details_tag(
|
|
103
|
+
template, "open", display_name_placeholder
|
|
104
|
+
)
|
|
105
|
+
case SubAgentResponseDisplayMode.DETAILS_CLOSED:
|
|
106
|
+
template = _wrap_with_details_tag(
|
|
107
|
+
template, "closed", display_name_placeholder
|
|
58
108
|
)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
r"<summary>(.*?)</summary>\s*"
|
|
63
|
-
rf"<div style=\"display: none;\">{re.escape(assistant_id)}</div>\s*"
|
|
64
|
-
r"(.*?)\s*"
|
|
65
|
-
r"</details>\s*"
|
|
66
|
-
r"<br>\s*"
|
|
109
|
+
case SubAgentResponseDisplayMode.PLAIN:
|
|
110
|
+
display_name_placeholder = _add_line_break(
|
|
111
|
+
display_name_placeholder, before=False, after=True
|
|
67
112
|
)
|
|
113
|
+
template = _join_text_blocks(display_name_placeholder, template)
|
|
114
|
+
# Add a hidden block border to seperate sub agent answers from the rest of the text.
|
|
115
|
+
hidden_block_border = _wrap_hidden_div("sub_agent_answer_block")
|
|
116
|
+
template = _join_text_blocks(template, hidden_block_border)
|
|
68
117
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return self.DETAILS_OPEN_TEMPLATE
|
|
72
|
-
else:
|
|
73
|
-
return self.DETAILS_CLOSED_TEMPLATE
|
|
118
|
+
if add_block_border:
|
|
119
|
+
template = _wrap_with_block_border(template)
|
|
74
120
|
|
|
75
|
-
|
|
76
|
-
def build_response_display(
|
|
77
|
-
self, display_name: str, assistant_id: str, answer: str
|
|
78
|
-
) -> str:
|
|
79
|
-
return self._get_template().format(
|
|
80
|
-
assistant_id=assistant_id, display_name=display_name, answer=answer
|
|
81
|
-
)
|
|
121
|
+
return template
|
|
82
122
|
|
|
83
|
-
@override
|
|
84
|
-
def remove_response_display(self, assistant_id: str, text: str) -> str:
|
|
85
|
-
return re.sub(self._get_detect_re(assistant_id=assistant_id), "", text)
|
|
86
123
|
|
|
124
|
+
def _get_display_removal_re(
|
|
125
|
+
assistant_id: str,
|
|
126
|
+
mode: SubAgentResponseDisplayMode,
|
|
127
|
+
add_quote_border: bool,
|
|
128
|
+
add_block_border: bool,
|
|
129
|
+
) -> re.Pattern[str]:
|
|
130
|
+
template = _get_display_template(
|
|
131
|
+
mode=mode,
|
|
132
|
+
add_quote_border=add_quote_border,
|
|
133
|
+
add_block_border=add_block_border,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
pattern = template.format(
|
|
137
|
+
assistant_id=re.escape(assistant_id), answer=r"(.*?)", display_name=r"(.*?)"
|
|
138
|
+
)
|
|
87
139
|
|
|
88
|
-
|
|
89
|
-
SubAgentResponseDisplayMode.DETAILS_OPEN: _DetailsResponseDisplayHandler(
|
|
90
|
-
mode="open"
|
|
91
|
-
),
|
|
92
|
-
SubAgentResponseDisplayMode.DETAILS_CLOSED: _DetailsResponseDisplayHandler(
|
|
93
|
-
mode="closed"
|
|
94
|
-
),
|
|
95
|
-
}
|
|
140
|
+
return re.compile(pattern, flags=re.DOTALL)
|
|
96
141
|
|
|
97
142
|
|
|
98
143
|
def _build_sub_agent_answer_display(
|
|
99
144
|
display_name: str,
|
|
100
145
|
display_mode: SubAgentResponseDisplayMode,
|
|
146
|
+
add_quote_border: bool,
|
|
147
|
+
add_block_border: bool,
|
|
101
148
|
answer: str,
|
|
102
149
|
assistant_id: str,
|
|
103
150
|
) -> str:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return
|
|
151
|
+
template = _get_display_template(
|
|
152
|
+
mode=display_mode,
|
|
153
|
+
add_quote_border=add_quote_border,
|
|
154
|
+
add_block_border=add_block_border,
|
|
155
|
+
)
|
|
156
|
+
return template.format(
|
|
110
157
|
display_name=display_name, answer=answer, assistant_id=assistant_id
|
|
111
158
|
)
|
|
112
159
|
|
|
113
160
|
|
|
114
161
|
def _remove_sub_agent_answer_from_text(
|
|
115
|
-
display_mode: SubAgentResponseDisplayMode,
|
|
162
|
+
display_mode: SubAgentResponseDisplayMode,
|
|
163
|
+
add_quote_border: bool,
|
|
164
|
+
add_block_border: bool,
|
|
165
|
+
text: str,
|
|
166
|
+
assistant_id: str,
|
|
116
167
|
) -> str:
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
168
|
+
pattern = _get_display_removal_re(
|
|
169
|
+
assistant_id=assistant_id,
|
|
170
|
+
mode=display_mode,
|
|
171
|
+
add_quote_border=add_quote_border,
|
|
172
|
+
add_block_border=add_block_border,
|
|
173
|
+
)
|
|
174
|
+
return re.sub(pattern, "", text)
|
|
@@ -9,6 +9,7 @@ class SubAgentResponseDisplayMode(StrEnum):
|
|
|
9
9
|
HIDDEN = "hidden"
|
|
10
10
|
DETAILS_OPEN = "details_open"
|
|
11
11
|
DETAILS_CLOSED = "details_closed"
|
|
12
|
+
PLAIN = "plain"
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class SubAgentDisplayConfig(BaseModel):
|
|
@@ -22,3 +23,11 @@ class SubAgentDisplayConfig(BaseModel):
|
|
|
22
23
|
default=True,
|
|
23
24
|
description="If set, sub agent responses will be removed from the history on subsequent calls to the assistant.",
|
|
24
25
|
)
|
|
26
|
+
add_quote_border: bool = Field(
|
|
27
|
+
default=True,
|
|
28
|
+
description="If set, a quote border is added to the left of the sub agent response.",
|
|
29
|
+
)
|
|
30
|
+
add_block_border: bool = Field(
|
|
31
|
+
default=False,
|
|
32
|
+
description="If set, a block border is added around the sub agent response.",
|
|
33
|
+
)
|
|
@@ -107,6 +107,8 @@ class SubAgentResponsesPostprocessor(Postprocessor):
|
|
|
107
107
|
assistant_id=assistant_id,
|
|
108
108
|
display_mode=display_mode,
|
|
109
109
|
answer=message["text"],
|
|
110
|
+
add_quote_border=tool_info["display_config"].add_quote_border,
|
|
111
|
+
add_block_border=tool_info["display_config"].add_block_border,
|
|
110
112
|
)
|
|
111
113
|
)
|
|
112
114
|
|
|
@@ -122,7 +124,9 @@ class SubAgentResponsesPostprocessor(Postprocessor):
|
|
|
122
124
|
for ref in message["references"]
|
|
123
125
|
)
|
|
124
126
|
|
|
125
|
-
loop_response.message.text =
|
|
127
|
+
loop_response.message.text = (
|
|
128
|
+
"\n\n".join(answers) + "<br>\n\n" + loop_response.message.text.strip()
|
|
129
|
+
)
|
|
126
130
|
|
|
127
131
|
return True
|
|
128
132
|
|
|
@@ -135,6 +139,8 @@ class SubAgentResponsesPostprocessor(Postprocessor):
|
|
|
135
139
|
display_mode=display_config.mode,
|
|
136
140
|
text=text,
|
|
137
141
|
assistant_id=assistant_id,
|
|
142
|
+
add_quote_border=display_config.add_quote_border,
|
|
143
|
+
add_block_border=display_config.add_block_border,
|
|
138
144
|
)
|
|
139
145
|
return text
|
|
140
146
|
|