hamtaa-texttools 1.1.1__py3-none-any.whl → 1.1.16__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.
- {hamtaa_texttools-1.1.1.dist-info → hamtaa_texttools-1.1.16.dist-info}/METADATA +98 -26
- hamtaa_texttools-1.1.16.dist-info/RECORD +31 -0
- texttools/__init__.py +6 -8
- texttools/batch/batch_config.py +26 -0
- texttools/batch/batch_runner.py +105 -151
- texttools/batch/{batch_manager.py → internals/batch_manager.py} +39 -40
- texttools/batch/internals/utils.py +16 -0
- texttools/prompts/README.md +4 -4
- texttools/prompts/categorize.yaml +77 -0
- texttools/prompts/detect_entity.yaml +22 -0
- texttools/prompts/extract_keywords.yaml +68 -18
- texttools/tools/async_tools.py +804 -0
- texttools/tools/internals/async_operator.py +90 -69
- texttools/tools/internals/models.py +183 -0
- texttools/tools/internals/operator_utils.py +54 -0
- texttools/tools/internals/prompt_loader.py +13 -14
- texttools/tools/internals/sync_operator.py +201 -0
- texttools/tools/sync_tools.py +804 -0
- hamtaa_texttools-1.1.1.dist-info/RECORD +0 -30
- texttools/batch/__init__.py +0 -4
- texttools/prompts/categorizer.yaml +0 -28
- texttools/tools/__init__.py +0 -4
- texttools/tools/async_the_tool.py +0 -414
- texttools/tools/internals/base_operator.py +0 -91
- texttools/tools/internals/operator.py +0 -179
- texttools/tools/internals/output_models.py +0 -59
- texttools/tools/the_tool.py +0 -412
- {hamtaa_texttools-1.1.1.dist-info → hamtaa_texttools-1.1.16.dist-info}/WHEEL +0 -0
- {hamtaa_texttools-1.1.1.dist-info → hamtaa_texttools-1.1.16.dist-info}/licenses/LICENSE +0 -0
- {hamtaa_texttools-1.1.1.dist-info → hamtaa_texttools-1.1.16.dist-info}/top_level.txt +0 -0
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
hamtaa_texttools-1.1.1.dist-info/licenses/LICENSE,sha256=Hb2YOBKy2MJQLnyLrX37B4ZVuac8eaIcE71SvVIMOLg,1082
|
|
2
|
-
texttools/__init__.py,sha256=v3tQCH_Cjj47fCpuhK6sKSVAqEjNkc-cZbY4OJa4IZw,202
|
|
3
|
-
texttools/batch/__init__.py,sha256=q50JsQsmQGp_8RW0KNasYeYWVV0R4FUNZ-ujXwEJemY,143
|
|
4
|
-
texttools/batch/batch_manager.py,sha256=leVIFkR-3HpDkQi_MK3TgFNnHYsCN-wbS4mTWoPmO3c,8828
|
|
5
|
-
texttools/batch/batch_runner.py,sha256=cgiCYLIBQQC0dBWM8_lVP9c5QLJoAmS2ijMtp0p3U2o,10313
|
|
6
|
-
texttools/prompts/README.md,sha256=rclMaCV1N8gT1KcpZu0-ka0dKGNg2f1CEcRMdQkgQOc,1379
|
|
7
|
-
texttools/prompts/categorizer.yaml,sha256=GMqIIzQFhgnlpkgU1qi3FAD3mD4A2jiWD5TilQ2XnnE,1204
|
|
8
|
-
texttools/prompts/extract_entities.yaml,sha256=KiKjeDpHaeh3JVtZ6q1pa3k4DYucUIU9WnEcRTCA-SE,651
|
|
9
|
-
texttools/prompts/extract_keywords.yaml,sha256=0O7ypL_OsEOxtvlQ2CZjnsv9637DJwAKprZsf9Vo2_s,769
|
|
10
|
-
texttools/prompts/is_question.yaml,sha256=d0-vKRbXWkxvO64ikvxRjEmpAXGpCYIPGhgexvPPjws,471
|
|
11
|
-
texttools/prompts/merge_questions.yaml,sha256=0J85GvTirZB4ELwH3sk8ub_WcqqpYf6PrMKr3djlZeo,1792
|
|
12
|
-
texttools/prompts/rewrite.yaml,sha256=LO7He_IA3MZKz8a-LxH9DHJpOjpYwaYN1pbjp1Y0tFo,5392
|
|
13
|
-
texttools/prompts/run_custom.yaml,sha256=38OkCoVITbuuS9c08UZSP1jZW4WjSmRIi8fR0RAiPu4,108
|
|
14
|
-
texttools/prompts/subject_to_question.yaml,sha256=C7x7rNNm6U_ZG9HOn6zuzYOtvJUZ2skuWbL1-aYdd3E,1147
|
|
15
|
-
texttools/prompts/summarize.yaml,sha256=o6rxGPfWtZd61Duvm8NVvCJqfq73b-wAuMSKR6UYUqY,459
|
|
16
|
-
texttools/prompts/text_to_question.yaml,sha256=UheKYpDn6iyKI8NxunHZtFpNyfCLZZe5cvkuXpurUJY,783
|
|
17
|
-
texttools/prompts/translate.yaml,sha256=mGT2uBCei6uucWqVbs4silk-UV060v3G0jnt0P6sr50,634
|
|
18
|
-
texttools/tools/__init__.py,sha256=hG1I28Q7BJ1Dbs95x6QMKXdsAlC5Eh_tqC-EbAibwiU,114
|
|
19
|
-
texttools/tools/async_the_tool.py,sha256=h6-Zkedet-eRUrkV5fANNoh4WmoqhXU5wJEHpd8nyNU,14377
|
|
20
|
-
texttools/tools/the_tool.py,sha256=lKy3_CKcWo2cBLQ7dDgvh7-oos7UOx1NYM26tcMhwaI,14143
|
|
21
|
-
texttools/tools/internals/async_operator.py,sha256=Kj-DLBKcKbZPCJYn4lVo4Iiei11M04pwgWpIl8L69aM,6169
|
|
22
|
-
texttools/tools/internals/base_operator.py,sha256=OWJe8ybA6qmmoc7ysYeB8ccHPneDlEtmFGH1jLWQCeY,3135
|
|
23
|
-
texttools/tools/internals/formatters.py,sha256=tACNLP6PeoqaRpNudVxBaHA25zyWqWYPZQuYysIu88g,941
|
|
24
|
-
texttools/tools/internals/operator.py,sha256=g1E1WkgnKRDgOs6fEFu0-gPCw1Bniwb4VI9Er3Op_gk,6063
|
|
25
|
-
texttools/tools/internals/output_models.py,sha256=gbVbzBWeyHUVNsCBuawdgz9ZEzsC7wfygGgZJsAaexY,1662
|
|
26
|
-
texttools/tools/internals/prompt_loader.py,sha256=rbitJD3e8vAdcooP1Yx6KnSI83g28ho-FegfZ1cJ4j4,1979
|
|
27
|
-
hamtaa_texttools-1.1.1.dist-info/METADATA,sha256=Cc1Rq94QyXgJ8SNhsBgyUfhho3oywzGpx6y16s50b-Q,7144
|
|
28
|
-
hamtaa_texttools-1.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
29
|
-
hamtaa_texttools-1.1.1.dist-info/top_level.txt,sha256=5Mh0jIxxZ5rOXHGJ6Mp-JPKviywwN0MYuH0xk5bEWqE,10
|
|
30
|
-
hamtaa_texttools-1.1.1.dist-info/RECORD,,
|
texttools/batch/__init__.py
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
main_template: |
|
|
2
|
-
تو یک متخصص علوم دینی هستی
|
|
3
|
-
من یک متن به تو میدهم و تو باید
|
|
4
|
-
آن متن را در یکی از دسته بندی های زیر طبقه بندی کنی
|
|
5
|
-
دسته بندی ها:
|
|
6
|
-
"باورهای دینی",
|
|
7
|
-
"اخلاق اسلامی",
|
|
8
|
-
"احکام و فقه",
|
|
9
|
-
"تاریخ اسلام و شخصیت ها",
|
|
10
|
-
"منابع دینی",
|
|
11
|
-
"دین و جامعه/سیاست",
|
|
12
|
-
"عرفان و معنویت",
|
|
13
|
-
"هیچکدام",
|
|
14
|
-
فقط با این فرمت json پاسخ بده:
|
|
15
|
-
{{
|
|
16
|
-
"reason": "<دلیل انتخابت رو به صورت خلاصه بگو>",
|
|
17
|
-
"result": "<یکی از دسته بندی ها>"
|
|
18
|
-
}}
|
|
19
|
-
متنی که باید طبقه بندی کنی:
|
|
20
|
-
{input}
|
|
21
|
-
|
|
22
|
-
analyze_template: |
|
|
23
|
-
ما میخواهیم متنی که داده می شود را طبقه بندی کنیم.
|
|
24
|
-
برای بهبود طبقه بندی، نیاز به آنالیز متن داریم.
|
|
25
|
-
متنی که داده می شود را آنالیز کن و ایده اصلی و آنالیزی کوتاه از آن را بنویس.
|
|
26
|
-
آنالیز باید بسیار خلاصه باشد
|
|
27
|
-
نهایتا 20 کلمه
|
|
28
|
-
{input}
|
texttools/tools/__init__.py
DELETED
|
@@ -1,414 +0,0 @@
|
|
|
1
|
-
from typing import Literal, Any
|
|
2
|
-
|
|
3
|
-
from openai import AsyncOpenAI
|
|
4
|
-
|
|
5
|
-
from texttools.tools.internals.async_operator import AsyncOperator
|
|
6
|
-
import texttools.tools.internals.output_models as OutputModels
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class AsyncTheTool:
|
|
10
|
-
"""
|
|
11
|
-
Async counterpart to TheTool.
|
|
12
|
-
|
|
13
|
-
Each method configures the async operator with a specific YAML prompt,
|
|
14
|
-
output schema, and flags, then delegates execution to `operator.run()`.
|
|
15
|
-
|
|
16
|
-
Usage:
|
|
17
|
-
async_client = AsyncOpenAI(...)
|
|
18
|
-
tool = TheToolAsync(async_client, model="model-name")
|
|
19
|
-
result = await tool.categorize("text ...", with_analysis=True)
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
def __init__(
|
|
23
|
-
self,
|
|
24
|
-
client: AsyncOpenAI,
|
|
25
|
-
model: str,
|
|
26
|
-
):
|
|
27
|
-
self.operator = AsyncOperator(client=client, model=model)
|
|
28
|
-
|
|
29
|
-
async def categorize(
|
|
30
|
-
self,
|
|
31
|
-
text: str,
|
|
32
|
-
with_analysis: bool = False,
|
|
33
|
-
user_prompt: str | None = None,
|
|
34
|
-
temperature: float | None = 0.0,
|
|
35
|
-
logprobs: bool = False,
|
|
36
|
-
top_logprobs: int | None = None,
|
|
37
|
-
) -> dict[str, str]:
|
|
38
|
-
"""
|
|
39
|
-
Categorize a text into a single Islamic studies domain category.
|
|
40
|
-
|
|
41
|
-
Returns:
|
|
42
|
-
ToolOutput: Object containing:
|
|
43
|
-
- result (str): The assigned Islamic studies category
|
|
44
|
-
- logprobs (list | None): Probability data if logprobs enabled
|
|
45
|
-
- analysis (str | None): Detailed reasoning if with_analysis enabled
|
|
46
|
-
"""
|
|
47
|
-
return await self.operator.run(
|
|
48
|
-
# User parameters
|
|
49
|
-
text=text,
|
|
50
|
-
with_analysis=with_analysis,
|
|
51
|
-
user_prompt=user_prompt,
|
|
52
|
-
temperature=temperature,
|
|
53
|
-
logprobs=logprobs,
|
|
54
|
-
top_logprobs=top_logprobs,
|
|
55
|
-
# Internal parameters
|
|
56
|
-
prompt_file="categorizer.yaml",
|
|
57
|
-
output_model=OutputModels.CategorizerOutput,
|
|
58
|
-
resp_format="parse",
|
|
59
|
-
mode=None,
|
|
60
|
-
output_lang=None,
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
async def extract_keywords(
|
|
64
|
-
self,
|
|
65
|
-
text: str,
|
|
66
|
-
with_analysis: bool = False,
|
|
67
|
-
output_lang: str | None = None,
|
|
68
|
-
user_prompt: str | None = None,
|
|
69
|
-
temperature: float | None = 0.0,
|
|
70
|
-
logprobs: bool = False,
|
|
71
|
-
top_logprobs: int | None = None,
|
|
72
|
-
) -> dict[str, list[str]]:
|
|
73
|
-
"""
|
|
74
|
-
Extract salient keywords from text.
|
|
75
|
-
|
|
76
|
-
Returns:
|
|
77
|
-
ToolOutput: Object containing:
|
|
78
|
-
- result (list[str]): List of extracted keywords
|
|
79
|
-
- logprobs (list | None): Probability data if logprobs enabled
|
|
80
|
-
- analysis (str | None): Detailed reasoning if with_analysis enabled
|
|
81
|
-
"""
|
|
82
|
-
return await self.operator.run(
|
|
83
|
-
# User parameters
|
|
84
|
-
text=text,
|
|
85
|
-
with_analysis=with_analysis,
|
|
86
|
-
output_lang=output_lang,
|
|
87
|
-
user_prompt=user_prompt,
|
|
88
|
-
temperature=temperature,
|
|
89
|
-
logprobs=logprobs,
|
|
90
|
-
top_logprobs=top_logprobs,
|
|
91
|
-
# Internal parameters
|
|
92
|
-
prompt_file="extract_keywords.yaml",
|
|
93
|
-
output_model=OutputModels.ListStrOutput,
|
|
94
|
-
resp_format="parse",
|
|
95
|
-
mode=None,
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
async def extract_entities(
|
|
99
|
-
self,
|
|
100
|
-
text: str,
|
|
101
|
-
with_analysis: bool = False,
|
|
102
|
-
output_lang: str | None = None,
|
|
103
|
-
user_prompt: str | None = None,
|
|
104
|
-
temperature: float | None = 0.0,
|
|
105
|
-
logprobs: bool = False,
|
|
106
|
-
top_logprobs: int | None = None,
|
|
107
|
-
) -> dict[str, list[dict[str, str]]]:
|
|
108
|
-
"""
|
|
109
|
-
Perform Named Entity Recognition (NER) over the input text.
|
|
110
|
-
|
|
111
|
-
Returns:
|
|
112
|
-
ToolOutput: Object containing:
|
|
113
|
-
- result (list[dict]): List of entities with 'text' and 'type' keys
|
|
114
|
-
- logprobs (list | None): Probability data if logprobs enabled
|
|
115
|
-
- analysis (str | None): Detailed reasoning if with_analysis enabled
|
|
116
|
-
"""
|
|
117
|
-
return await self.operator.run(
|
|
118
|
-
# User parameters
|
|
119
|
-
text=text,
|
|
120
|
-
with_analysis=with_analysis,
|
|
121
|
-
output_lang=output_lang,
|
|
122
|
-
user_prompt=user_prompt,
|
|
123
|
-
temperature=temperature,
|
|
124
|
-
logprobs=logprobs,
|
|
125
|
-
top_logprobs=top_logprobs,
|
|
126
|
-
# Internal parameters
|
|
127
|
-
prompt_file="extract_entities.yaml",
|
|
128
|
-
output_model=OutputModels.ListDictStrStrOutput,
|
|
129
|
-
resp_format="parse",
|
|
130
|
-
mode=None,
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
async def is_question(
|
|
134
|
-
self,
|
|
135
|
-
text: str,
|
|
136
|
-
with_analysis: bool = False,
|
|
137
|
-
user_prompt: str | None = None,
|
|
138
|
-
temperature: float | None = 0.0,
|
|
139
|
-
logprobs: bool = False,
|
|
140
|
-
top_logprobs: int | None = None,
|
|
141
|
-
) -> dict[str, bool]:
|
|
142
|
-
"""
|
|
143
|
-
Detect if the input is phrased as a question.
|
|
144
|
-
|
|
145
|
-
Returns:
|
|
146
|
-
ToolOutput: Object containing:
|
|
147
|
-
- result (bool): True if text is a question, False otherwise
|
|
148
|
-
- logprobs (list | None): Probability data if logprobs enabled
|
|
149
|
-
- analysis (str | None): Detailed reasoning if with_analysis enabled
|
|
150
|
-
"""
|
|
151
|
-
return await self.operator.run(
|
|
152
|
-
# User parameters
|
|
153
|
-
text=text,
|
|
154
|
-
with_analysis=with_analysis,
|
|
155
|
-
user_prompt=user_prompt,
|
|
156
|
-
temperature=temperature,
|
|
157
|
-
logprobs=logprobs,
|
|
158
|
-
top_logprobs=top_logprobs,
|
|
159
|
-
# Internal parameters
|
|
160
|
-
prompt_file="is_question.yaml",
|
|
161
|
-
output_model=OutputModels.BoolOutput,
|
|
162
|
-
resp_format="parse",
|
|
163
|
-
mode=None,
|
|
164
|
-
output_lang=None,
|
|
165
|
-
)
|
|
166
|
-
|
|
167
|
-
async def text_to_question(
|
|
168
|
-
self,
|
|
169
|
-
text: str,
|
|
170
|
-
with_analysis: bool = False,
|
|
171
|
-
output_lang: str | None = None,
|
|
172
|
-
user_prompt: str | None = None,
|
|
173
|
-
temperature: float | None = 0.0,
|
|
174
|
-
logprobs: bool = False,
|
|
175
|
-
top_logprobs: int | None = None,
|
|
176
|
-
) -> dict[str, str]:
|
|
177
|
-
"""
|
|
178
|
-
Generate a single question from the given text.
|
|
179
|
-
|
|
180
|
-
Returns:
|
|
181
|
-
ToolOutput: Object containing:
|
|
182
|
-
- result (str): The generated question
|
|
183
|
-
- logprobs (list | None): Probability data if logprobs enabled
|
|
184
|
-
- analysis (str | None): Detailed reasoning if with_analysis enabled
|
|
185
|
-
"""
|
|
186
|
-
return await self.operator.run(
|
|
187
|
-
# User parameters
|
|
188
|
-
text=text,
|
|
189
|
-
with_analysis=with_analysis,
|
|
190
|
-
output_lang=output_lang,
|
|
191
|
-
user_prompt=user_prompt,
|
|
192
|
-
temperature=temperature,
|
|
193
|
-
logprobs=logprobs,
|
|
194
|
-
top_logprobs=top_logprobs,
|
|
195
|
-
# Internal parameters
|
|
196
|
-
prompt_file="text_to_question.yaml",
|
|
197
|
-
output_model=OutputModels.StrOutput,
|
|
198
|
-
resp_format="parse",
|
|
199
|
-
mode=None,
|
|
200
|
-
)
|
|
201
|
-
|
|
202
|
-
async def merge_questions(
|
|
203
|
-
self,
|
|
204
|
-
text: list[str],
|
|
205
|
-
with_analysis: bool = False,
|
|
206
|
-
output_lang: str | None = None,
|
|
207
|
-
user_prompt: str | None = None,
|
|
208
|
-
temperature: float | None = 0.0,
|
|
209
|
-
logprobs: bool = False,
|
|
210
|
-
top_logprobs: int | None = None,
|
|
211
|
-
mode: Literal["default", "reason"] = "default",
|
|
212
|
-
) -> dict[str, str]:
|
|
213
|
-
"""
|
|
214
|
-
Merge multiple questions into a single unified question.
|
|
215
|
-
|
|
216
|
-
Returns:
|
|
217
|
-
ToolOutput: Object containing:
|
|
218
|
-
- result (str): The merged question
|
|
219
|
-
- logprobs (list | None): Probability data if logprobs enabled
|
|
220
|
-
- analysis (str | None): Detailed reasoning if with_analysis enabled
|
|
221
|
-
"""
|
|
222
|
-
text = ", ".join(text)
|
|
223
|
-
return await self.operator.run(
|
|
224
|
-
# User parameters
|
|
225
|
-
text=text,
|
|
226
|
-
with_analysis=with_analysis,
|
|
227
|
-
output_lang=output_lang,
|
|
228
|
-
user_prompt=user_prompt,
|
|
229
|
-
temperature=temperature,
|
|
230
|
-
logprobs=logprobs,
|
|
231
|
-
top_logprobs=top_logprobs,
|
|
232
|
-
# Internal parameters
|
|
233
|
-
prompt_file="merge_questions.yaml",
|
|
234
|
-
output_model=OutputModels.StrOutput,
|
|
235
|
-
resp_format="parse",
|
|
236
|
-
mode=mode,
|
|
237
|
-
)
|
|
238
|
-
|
|
239
|
-
async def rewrite(
|
|
240
|
-
self,
|
|
241
|
-
text: str,
|
|
242
|
-
with_analysis: bool = False,
|
|
243
|
-
output_lang: str | None = None,
|
|
244
|
-
user_prompt: str | None = None,
|
|
245
|
-
temperature: float | None = 0.0,
|
|
246
|
-
logprobs: bool = False,
|
|
247
|
-
top_logprobs: int | None = None,
|
|
248
|
-
mode: Literal["positive", "negative", "hard_negative"] = "positive",
|
|
249
|
-
) -> dict[str, str]:
|
|
250
|
-
"""
|
|
251
|
-
Rewrite a text with different modes.
|
|
252
|
-
|
|
253
|
-
Returns:
|
|
254
|
-
ToolOutput: Object containing:
|
|
255
|
-
- result (str): The rewritten text
|
|
256
|
-
- logprobs (list | None): Probability data if logprobs enabled
|
|
257
|
-
- analysis (str | None): Detailed reasoning if with_analysis enabled
|
|
258
|
-
"""
|
|
259
|
-
return await self.operator.run(
|
|
260
|
-
# User parameters
|
|
261
|
-
text=text,
|
|
262
|
-
with_analysis=with_analysis,
|
|
263
|
-
output_lang=output_lang,
|
|
264
|
-
user_prompt=user_prompt,
|
|
265
|
-
temperature=temperature,
|
|
266
|
-
logprobs=logprobs,
|
|
267
|
-
top_logprobs=top_logprobs,
|
|
268
|
-
# Internal parameters
|
|
269
|
-
prompt_file="rewrite.yaml",
|
|
270
|
-
output_model=OutputModels.StrOutput,
|
|
271
|
-
resp_format="parse",
|
|
272
|
-
mode=mode,
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
async def subject_to_question(
|
|
276
|
-
self,
|
|
277
|
-
text: str,
|
|
278
|
-
number_of_questions: int,
|
|
279
|
-
with_analysis: bool = False,
|
|
280
|
-
output_lang: str | None = None,
|
|
281
|
-
user_prompt: str | None = None,
|
|
282
|
-
temperature: float | None = 0.0,
|
|
283
|
-
logprobs: bool = False,
|
|
284
|
-
top_logprobs: int | None = None,
|
|
285
|
-
) -> dict[str, list[str]]:
|
|
286
|
-
"""
|
|
287
|
-
Generate a list of questions about a subject.
|
|
288
|
-
|
|
289
|
-
Returns:
|
|
290
|
-
ToolOutput: Object containing:
|
|
291
|
-
- result (list[str]): List of generated questions
|
|
292
|
-
- logprobs (list | None): Probability data if logprobs enabled
|
|
293
|
-
- analysis (str | None): Detailed reasoning if with_analysis enabled
|
|
294
|
-
"""
|
|
295
|
-
return await self.operator.run(
|
|
296
|
-
# User parameters
|
|
297
|
-
text=text,
|
|
298
|
-
number_of_questions=number_of_questions,
|
|
299
|
-
with_analysis=with_analysis,
|
|
300
|
-
output_lang=output_lang,
|
|
301
|
-
user_prompt=user_prompt,
|
|
302
|
-
temperature=temperature,
|
|
303
|
-
logprobs=logprobs,
|
|
304
|
-
top_logprobs=top_logprobs,
|
|
305
|
-
# Internal parameters
|
|
306
|
-
prompt_file="subject_to_question.yaml",
|
|
307
|
-
output_model=OutputModels.ReasonListStrOutput,
|
|
308
|
-
resp_format="parse",
|
|
309
|
-
mode=None,
|
|
310
|
-
)
|
|
311
|
-
|
|
312
|
-
async def summarize(
|
|
313
|
-
self,
|
|
314
|
-
text: str,
|
|
315
|
-
with_analysis: bool = False,
|
|
316
|
-
output_lang: str | None = None,
|
|
317
|
-
user_prompt: str | None = None,
|
|
318
|
-
temperature: float | None = 0.0,
|
|
319
|
-
logprobs: bool = False,
|
|
320
|
-
top_logprobs: int | None = None,
|
|
321
|
-
) -> dict[str, str]:
|
|
322
|
-
"""
|
|
323
|
-
Summarize the given subject text.
|
|
324
|
-
|
|
325
|
-
Returns:
|
|
326
|
-
ToolOutput: Object containing:
|
|
327
|
-
- result (str): The summary text
|
|
328
|
-
- logprobs (list | None): Probability data if logprobs enabled
|
|
329
|
-
- analysis (str | None): Detailed reasoning if with_analysis enabled
|
|
330
|
-
"""
|
|
331
|
-
return await self.operator.run(
|
|
332
|
-
# User parameters
|
|
333
|
-
text=text,
|
|
334
|
-
with_analysis=with_analysis,
|
|
335
|
-
output_lang=output_lang,
|
|
336
|
-
user_prompt=user_prompt,
|
|
337
|
-
temperature=temperature,
|
|
338
|
-
logprobs=logprobs,
|
|
339
|
-
top_logprobs=top_logprobs,
|
|
340
|
-
# Internal parameters
|
|
341
|
-
prompt_file="summarize.yaml",
|
|
342
|
-
output_model=OutputModels.StrOutput,
|
|
343
|
-
resp_format="parse",
|
|
344
|
-
mode=None,
|
|
345
|
-
)
|
|
346
|
-
|
|
347
|
-
async def translate(
|
|
348
|
-
self,
|
|
349
|
-
text: str,
|
|
350
|
-
target_language: str,
|
|
351
|
-
with_analysis: bool = False,
|
|
352
|
-
user_prompt: str | None = None,
|
|
353
|
-
temperature: float | None = 0.0,
|
|
354
|
-
logprobs: bool = False,
|
|
355
|
-
top_logprobs: int | None = None,
|
|
356
|
-
) -> dict[str, str]:
|
|
357
|
-
"""
|
|
358
|
-
Translate text between languages.
|
|
359
|
-
|
|
360
|
-
Returns:
|
|
361
|
-
ToolOutput: Object containing:
|
|
362
|
-
- result (str): The translated text
|
|
363
|
-
- logprobs (list | None): Probability data if logprobs enabled
|
|
364
|
-
- analysis (str | None): Detailed reasoning if with_analysis enabled
|
|
365
|
-
"""
|
|
366
|
-
return await self.operator.run(
|
|
367
|
-
# User parameters
|
|
368
|
-
text=text,
|
|
369
|
-
target_language=target_language,
|
|
370
|
-
with_analysis=with_analysis,
|
|
371
|
-
user_prompt=user_prompt,
|
|
372
|
-
temperature=temperature,
|
|
373
|
-
logprobs=logprobs,
|
|
374
|
-
top_logprobs=top_logprobs,
|
|
375
|
-
# Internal parameters
|
|
376
|
-
prompt_file="translate.yaml",
|
|
377
|
-
output_model=OutputModels.StrOutput,
|
|
378
|
-
resp_format="parse",
|
|
379
|
-
mode=None,
|
|
380
|
-
output_lang=None,
|
|
381
|
-
)
|
|
382
|
-
|
|
383
|
-
async def run_custom(
|
|
384
|
-
self,
|
|
385
|
-
prompt: str,
|
|
386
|
-
output_model: Any,
|
|
387
|
-
output_lang: str | None = None,
|
|
388
|
-
temperature: float | None = None,
|
|
389
|
-
logprobs: bool | None = None,
|
|
390
|
-
top_logprobs: int | None = None,
|
|
391
|
-
) -> dict[str, Any]:
|
|
392
|
-
"""
|
|
393
|
-
Custom tool that can do almost anything!
|
|
394
|
-
|
|
395
|
-
Returns:
|
|
396
|
-
ToolOutput: Object with fields:
|
|
397
|
-
- result (str): The output result
|
|
398
|
-
"""
|
|
399
|
-
return await self.operator.run(
|
|
400
|
-
# User paramaeters
|
|
401
|
-
text=prompt,
|
|
402
|
-
output_model=output_model,
|
|
403
|
-
output_model_str=output_model.model_json_schema(),
|
|
404
|
-
output_lang=output_lang,
|
|
405
|
-
temperature=temperature,
|
|
406
|
-
logprobs=logprobs,
|
|
407
|
-
top_logprobs=top_logprobs,
|
|
408
|
-
# Internal parameters
|
|
409
|
-
prompt_file="run_custom.yaml",
|
|
410
|
-
resp_format="parse",
|
|
411
|
-
user_prompt=None,
|
|
412
|
-
with_analysis=False,
|
|
413
|
-
mode=None,
|
|
414
|
-
)
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
from typing import TypeVar, Type, Any
|
|
2
|
-
import json
|
|
3
|
-
import re
|
|
4
|
-
import math
|
|
5
|
-
import logging
|
|
6
|
-
|
|
7
|
-
from pydantic import BaseModel
|
|
8
|
-
from openai import OpenAI, AsyncOpenAI
|
|
9
|
-
|
|
10
|
-
# Base Model type for output models
|
|
11
|
-
T = TypeVar("T", bound=BaseModel)
|
|
12
|
-
|
|
13
|
-
# Configure logger
|
|
14
|
-
logger = logging.getLogger("base_operator")
|
|
15
|
-
logger.setLevel(logging.INFO)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class BaseOperator:
|
|
19
|
-
def __init__(self, client: OpenAI | AsyncOpenAI, model: str):
|
|
20
|
-
self.client = client
|
|
21
|
-
self.model = model
|
|
22
|
-
|
|
23
|
-
def _build_user_message(self, prompt: str) -> dict[str, str]:
|
|
24
|
-
return {"role": "user", "content": prompt}
|
|
25
|
-
|
|
26
|
-
def _clean_json_response(self, response: str) -> str:
|
|
27
|
-
"""
|
|
28
|
-
Clean JSON response by removing code block markers and whitespace.
|
|
29
|
-
Handles cases like:
|
|
30
|
-
- ```json{"result": "value"}```
|
|
31
|
-
"""
|
|
32
|
-
stripped = response.strip()
|
|
33
|
-
cleaned = re.sub(r"^```(?:json)?\s*", "", stripped)
|
|
34
|
-
cleaned = re.sub(r"\s*```$", "", cleaned)
|
|
35
|
-
|
|
36
|
-
return cleaned.strip()
|
|
37
|
-
|
|
38
|
-
def _convert_to_output_model(
|
|
39
|
-
self, response_string: str, output_model: Type[T]
|
|
40
|
-
) -> Type[T]:
|
|
41
|
-
"""
|
|
42
|
-
Convert a JSON response string to output model.
|
|
43
|
-
|
|
44
|
-
Args:
|
|
45
|
-
response_string: The JSON string (may contain code block markers)
|
|
46
|
-
output_model: Your Pydantic output model class (e.g., StrOutput, ListStrOutput)
|
|
47
|
-
|
|
48
|
-
Returns:
|
|
49
|
-
Instance of your output model
|
|
50
|
-
"""
|
|
51
|
-
# Clean the response string
|
|
52
|
-
cleaned_json = self._clean_json_response(response_string)
|
|
53
|
-
|
|
54
|
-
# Fix Python-style booleans
|
|
55
|
-
cleaned_json = cleaned_json.replace("False", "false").replace("True", "true")
|
|
56
|
-
|
|
57
|
-
# Convert string to Python dictionary
|
|
58
|
-
response_dict = json.loads(cleaned_json)
|
|
59
|
-
|
|
60
|
-
# Convert dictionary to output model
|
|
61
|
-
return output_model(**response_dict)
|
|
62
|
-
|
|
63
|
-
def _extract_logprobs(self, completion: dict) -> list[dict[str, Any]]:
|
|
64
|
-
logprobs_data = []
|
|
65
|
-
ignore_pattern = re.compile(r'^(result|[\s\[\]\{\}",:]+)$')
|
|
66
|
-
|
|
67
|
-
for choice in completion.choices:
|
|
68
|
-
if not getattr(choice, "logprobs", None):
|
|
69
|
-
logger.error("logprobs is not avalible in the chosen model.")
|
|
70
|
-
return []
|
|
71
|
-
|
|
72
|
-
for logprob_item in choice.logprobs.content:
|
|
73
|
-
if ignore_pattern.match(logprob_item.token):
|
|
74
|
-
continue
|
|
75
|
-
token_entry = {
|
|
76
|
-
"token": logprob_item.token,
|
|
77
|
-
"prob": round(math.exp(logprob_item.logprob), 8),
|
|
78
|
-
"top_alternatives": [],
|
|
79
|
-
}
|
|
80
|
-
for alt in logprob_item.top_logprobs:
|
|
81
|
-
if ignore_pattern.match(alt.token):
|
|
82
|
-
continue
|
|
83
|
-
token_entry["top_alternatives"].append(
|
|
84
|
-
{
|
|
85
|
-
"token": alt.token,
|
|
86
|
-
"prob": round(math.exp(alt.logprob), 8),
|
|
87
|
-
}
|
|
88
|
-
)
|
|
89
|
-
logprobs_data.append(token_entry)
|
|
90
|
-
|
|
91
|
-
return logprobs_data
|