hamtaa-texttools 1.1.10__tar.gz → 1.1.12__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.
Files changed (40) hide show
  1. {hamtaa_texttools-1.1.10/hamtaa_texttools.egg-info → hamtaa_texttools-1.1.12}/PKG-INFO +2 -2
  2. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/README.md +1 -1
  3. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12/hamtaa_texttools.egg-info}/PKG-INFO +2 -2
  4. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/hamtaa_texttools.egg-info/SOURCES.txt +3 -4
  5. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/pyproject.toml +1 -1
  6. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/tests/test_all_async_tools.py +4 -1
  7. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/tests/test_all_tools.py +1 -0
  8. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/tests/test_output_validation.py +5 -1
  9. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/tools/async_tools.py +159 -3
  10. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/tools/internals/async_operator.py +20 -22
  11. hamtaa_texttools-1.1.10/texttools/tools/internals/base_operator.py → hamtaa_texttools-1.1.12/texttools/tools/internals/operator_utils.py +7 -20
  12. hamtaa_texttools-1.1.10/texttools/tools/internals/operator.py → hamtaa_texttools-1.1.12/texttools/tools/internals/sync_operator.py +20 -20
  13. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/tools/sync_tools.py +160 -4
  14. hamtaa_texttools-1.1.10/texttools/tools/internals/formatters.py +0 -24
  15. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/LICENSE +0 -0
  16. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/MANIFEST.in +0 -0
  17. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/hamtaa_texttools.egg-info/dependency_links.txt +0 -0
  18. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/hamtaa_texttools.egg-info/requires.txt +0 -0
  19. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/hamtaa_texttools.egg-info/top_level.txt +0 -0
  20. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/setup.cfg +0 -0
  21. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/tests/test_logprobs.py +0 -0
  22. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/__init__.py +0 -0
  23. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/batch/batch_config.py +0 -0
  24. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/batch/batch_runner.py +0 -0
  25. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/batch/internals/batch_manager.py +0 -0
  26. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/batch/internals/utils.py +0 -0
  27. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/prompts/README.md +0 -0
  28. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/prompts/categorizer.yaml +0 -0
  29. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/prompts/extract_entities.yaml +0 -0
  30. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/prompts/extract_keywords.yaml +0 -0
  31. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/prompts/is_question.yaml +0 -0
  32. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/prompts/merge_questions.yaml +0 -0
  33. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/prompts/rewrite.yaml +0 -0
  34. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/prompts/run_custom.yaml +0 -0
  35. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/prompts/subject_to_question.yaml +0 -0
  36. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/prompts/summarize.yaml +0 -0
  37. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/prompts/text_to_question.yaml +0 -0
  38. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/prompts/translate.yaml +0 -0
  39. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/tools/internals/output_models.py +0 -0
  40. {hamtaa_texttools-1.1.10 → hamtaa_texttools-1.1.12}/texttools/tools/internals/prompt_loader.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hamtaa-texttools
3
- Version: 1.1.10
3
+ Version: 1.1.12
4
4
  Summary: A high-level NLP toolkit built on top of modern LLMs.
5
5
  Author-email: Tohidi <the.mohammad.tohidi@gmail.com>, Montazer <montazerh82@gmail.com>, Givechi <mohamad.m.givechi@gmail.com>, MoosaviNejad <erfanmoosavi84@gmail.com>
6
6
  License: MIT License
@@ -79,7 +79,7 @@ TextTools provides several optional flags to customize LLM behavior:
79
79
 
80
80
  - **`temperature (float)`** → Determines how creative the model should respond. Takes a float number from `0.0` to `2.0`.
81
81
 
82
- - **`validator (Callable)`** → Forces TheTool to validate the output result based on your custom validator. Validator should return bool (True if there were no problem, False if the validation failed.) If validator failed, TheTool will retry to get another output by modifying `temperature`.
82
+ - **`validator (Callable)`** → Forces TheTool to validate the output result based on your custom validator. Validator should return bool (True if there were no problem, False if the validation failed.) If validator failed, TheTool will retry to get another output by modifying `temperature`. You can specify `max_validation_retries=<N>` to change the number of retries.
83
83
 
84
84
  All these parameters can be used individually or together to tailor the behavior of any tool in **TextTools**.
85
85
 
@@ -44,7 +44,7 @@ TextTools provides several optional flags to customize LLM behavior:
44
44
 
45
45
  - **`temperature (float)`** → Determines how creative the model should respond. Takes a float number from `0.0` to `2.0`.
46
46
 
47
- - **`validator (Callable)`** → Forces TheTool to validate the output result based on your custom validator. Validator should return bool (True if there were no problem, False if the validation failed.) If validator failed, TheTool will retry to get another output by modifying `temperature`.
47
+ - **`validator (Callable)`** → Forces TheTool to validate the output result based on your custom validator. Validator should return bool (True if there were no problem, False if the validation failed.) If validator failed, TheTool will retry to get another output by modifying `temperature`. You can specify `max_validation_retries=<N>` to change the number of retries.
48
48
 
49
49
  All these parameters can be used individually or together to tailor the behavior of any tool in **TextTools**.
50
50
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hamtaa-texttools
3
- Version: 1.1.10
3
+ Version: 1.1.12
4
4
  Summary: A high-level NLP toolkit built on top of modern LLMs.
5
5
  Author-email: Tohidi <the.mohammad.tohidi@gmail.com>, Montazer <montazerh82@gmail.com>, Givechi <mohamad.m.givechi@gmail.com>, MoosaviNejad <erfanmoosavi84@gmail.com>
6
6
  License: MIT License
@@ -79,7 +79,7 @@ TextTools provides several optional flags to customize LLM behavior:
79
79
 
80
80
  - **`temperature (float)`** → Determines how creative the model should respond. Takes a float number from `0.0` to `2.0`.
81
81
 
82
- - **`validator (Callable)`** → Forces TheTool to validate the output result based on your custom validator. Validator should return bool (True if there were no problem, False if the validation failed.) If validator failed, TheTool will retry to get another output by modifying `temperature`.
82
+ - **`validator (Callable)`** → Forces TheTool to validate the output result based on your custom validator. Validator should return bool (True if there were no problem, False if the validation failed.) If validator failed, TheTool will retry to get another output by modifying `temperature`. You can specify `max_validation_retries=<N>` to change the number of retries.
83
83
 
84
84
  All these parameters can be used individually or together to tailor the behavior of any tool in **TextTools**.
85
85
 
@@ -31,8 +31,7 @@ texttools/prompts/translate.yaml
31
31
  texttools/tools/async_tools.py
32
32
  texttools/tools/sync_tools.py
33
33
  texttools/tools/internals/async_operator.py
34
- texttools/tools/internals/base_operator.py
35
- texttools/tools/internals/formatters.py
36
- texttools/tools/internals/operator.py
34
+ texttools/tools/internals/operator_utils.py
37
35
  texttools/tools/internals/output_models.py
38
- texttools/tools/internals/prompt_loader.py
36
+ texttools/tools/internals/prompt_loader.py
37
+ texttools/tools/internals/sync_operator.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hamtaa-texttools"
7
- version = "1.1.10"
7
+ version = "1.1.12"
8
8
  authors = [
9
9
  { name = "Tohidi", email = "the.mohammad.tohidi@gmail.com" },
10
10
  { name = "Montazer", email = "montazerh82@gmail.com" },
@@ -28,9 +28,12 @@ async def main():
28
28
  merged_task = t.merge_questions(
29
29
  ["چرا ما موجوداتی اجتماعی هستیم؟", "چرا باید در کنار هم زندگی کنیم؟"],
30
30
  mode="default",
31
+ with_analysis=True,
31
32
  )
32
33
  rewritten_task = t.rewrite(
33
- "چرا ما انسان ها، موجوداتی اجتماعی هستیم؟", mode="positive"
34
+ "چرا ما انسان ها، موجوداتی اجتماعی هستیم؟",
35
+ mode="positive",
36
+ user_prompt="Be carefull",
34
37
  )
35
38
  questions_task = t.subject_to_question("Friendship", 3)
36
39
  summary_task = t.summarize("Tomorrow, we will be dead by the car crash")
@@ -49,6 +49,7 @@ print(repr(merged))
49
49
  rewritten = t.rewrite(
50
50
  "چرا ما انسان ها، موجوداتی اجتماعی هستیم؟",
51
51
  mode="positive",
52
+ with_analysis=True,
52
53
  )
53
54
  print(repr(rewritten))
54
55
 
@@ -26,6 +26,10 @@ def validate(result: Any) -> bool:
26
26
 
27
27
  # Question from Text Generator
28
28
  question = t.text_to_question(
29
- "زندگی", output_lang="Persian", validator=validate, temperature=1.0
29
+ "زندگی",
30
+ output_lang="Persian",
31
+ validator=validate,
32
+ max_validation_retries=5,
33
+ temperature=1.0,
30
34
  )
31
35
  print(question)
@@ -35,15 +35,27 @@ class AsyncTheTool:
35
35
  logprobs: bool = False,
36
36
  top_logprobs: int | None = None,
37
37
  validator: Callable[[Any], bool] | None = None,
38
+ max_validation_retries: int | None = None,
38
39
  ) -> OM.ToolOutput:
39
40
  """
40
41
  Categorize a text into a single Islamic studies domain category.
41
42
 
43
+ Arguments:
44
+ text: The input text to categorize
45
+ with_analysis: Whether to include detailed reasoning analysis
46
+ user_prompt: Additional instructions for the categorization
47
+ temperature: Controls randomness (0.0 = deterministic, 1.0 = creative)
48
+ logprobs: Whether to return token probability information
49
+ top_logprobs: Number of top token alternatives to return if logprobs enabled
50
+ validator: Custom validation function to validate the output
51
+ max_validation_retries: Maximum number of retry attempts if validation fails
52
+
42
53
  Returns:
43
54
  ToolOutput: Object containing:
44
55
  - result (str): The assigned Islamic studies category
45
56
  - logprobs (list | None): Probability data if logprobs enabled
46
57
  - analysis (str | None): Detailed reasoning if with_analysis enabled
58
+ - errors (list(str) | None): Errors occured during tool call
47
59
  """
48
60
  return await self._operator.run(
49
61
  # User parameters
@@ -54,6 +66,7 @@ class AsyncTheTool:
54
66
  logprobs=logprobs,
55
67
  top_logprobs=top_logprobs,
56
68
  validator=validator,
69
+ max_validation_retries=max_validation_retries,
57
70
  # Internal parameters
58
71
  prompt_file="categorizer.yaml",
59
72
  output_model=OM.CategorizerOutput,
@@ -71,15 +84,28 @@ class AsyncTheTool:
71
84
  logprobs: bool = False,
72
85
  top_logprobs: int | None = None,
73
86
  validator: Callable[[Any], bool] | None = None,
87
+ max_validation_retries: int | None = None,
74
88
  ) -> OM.ToolOutput:
75
89
  """
76
90
  Extract salient keywords from text.
77
91
 
92
+ Arguments:
93
+ text: The input text to extract keywords from
94
+ with_analysis: Whether to include detailed reasoning analysis
95
+ output_lang: Language for the output response
96
+ user_prompt: Additional instructions for keyword extraction
97
+ temperature: Controls randomness (0.0 = deterministic, 1.0 = creative)
98
+ logprobs: Whether to return token probability information
99
+ top_logprobs: Number of top token alternatives to return if logprobs enabled
100
+ validator: Custom validation function to validate the output
101
+ max_validation_retries: Maximum number of retry attempts if validation fails
102
+
78
103
  Returns:
79
104
  ToolOutput: Object containing:
80
105
  - result (list[str]): List of extracted keywords
81
106
  - logprobs (list | None): Probability data if logprobs enabled
82
107
  - analysis (str | None): Detailed reasoning if with_analysis enabled
108
+ - errors (list(str) | None): Errors occured during tool call
83
109
  """
84
110
  return await self._operator.run(
85
111
  # User parameters
@@ -91,6 +117,7 @@ class AsyncTheTool:
91
117
  logprobs=logprobs,
92
118
  top_logprobs=top_logprobs,
93
119
  validator=validator,
120
+ max_validation_retries=max_validation_retries,
94
121
  # Internal parameters
95
122
  prompt_file="extract_keywords.yaml",
96
123
  output_model=OM.ListStrOutput,
@@ -107,15 +134,28 @@ class AsyncTheTool:
107
134
  logprobs: bool = False,
108
135
  top_logprobs: int | None = None,
109
136
  validator: Callable[[Any], bool] | None = None,
137
+ max_validation_retries: int | None = None,
110
138
  ) -> OM.ToolOutput:
111
139
  """
112
140
  Perform Named Entity Recognition (NER) over the input text.
113
141
 
142
+ Arguments:
143
+ text: The input text to extract entities from
144
+ with_analysis: Whether to include detailed reasoning analysis
145
+ output_lang: Language for the output response
146
+ user_prompt: Additional instructions for entity extraction
147
+ temperature: Controls randomness (0.0 = deterministic, 1.0 = creative)
148
+ logprobs: Whether to return token probability information
149
+ top_logprobs: Number of top token alternatives to return if logprobs enabled
150
+ validator: Custom validation function to validate the output
151
+ max_validation_retries: Maximum number of retry attempts if validation fails
152
+
114
153
  Returns:
115
154
  ToolOutput: Object containing:
116
155
  - result (list[dict]): List of entities with 'text' and 'type' keys
117
156
  - logprobs (list | None): Probability data if logprobs enabled
118
157
  - analysis (str | None): Detailed reasoning if with_analysis enabled
158
+ - errors (list(str) | None): Errors occured during tool call
119
159
  """
120
160
  return await self._operator.run(
121
161
  # User parameters
@@ -127,6 +167,7 @@ class AsyncTheTool:
127
167
  logprobs=logprobs,
128
168
  top_logprobs=top_logprobs,
129
169
  validator=validator,
170
+ max_validation_retries=max_validation_retries,
130
171
  # Internal parameters
131
172
  prompt_file="extract_entities.yaml",
132
173
  output_model=OM.ListDictStrStrOutput,
@@ -142,15 +183,27 @@ class AsyncTheTool:
142
183
  logprobs: bool = False,
143
184
  top_logprobs: int | None = None,
144
185
  validator: Callable[[Any], bool] | None = None,
186
+ max_validation_retries: int | None = None,
145
187
  ) -> OM.ToolOutput:
146
188
  """
147
189
  Detect if the input is phrased as a question.
148
190
 
191
+ Arguments:
192
+ text: The input text to analyze
193
+ with_analysis: Whether to include detailed reasoning analysis
194
+ user_prompt: Additional instructions for question detection
195
+ temperature: Controls randomness (0.0 = deterministic, 1.0 = creative)
196
+ logprobs: Whether to return token probability information
197
+ top_logprobs: Number of top token alternatives to return if logprobs enabled
198
+ validator: Custom validation function to validate the output
199
+ max_validation_retries: Maximum number of retry attempts if validation fails
200
+
149
201
  Returns:
150
202
  ToolOutput: Object containing:
151
203
  - result (bool): True if text is a question, False otherwise
152
204
  - logprobs (list | None): Probability data if logprobs enabled
153
205
  - analysis (str | None): Detailed reasoning if with_analysis enabled
206
+ - errors (list(str) | None): Errors occured during tool call
154
207
  """
155
208
  return await self._operator.run(
156
209
  # User parameters
@@ -161,6 +214,7 @@ class AsyncTheTool:
161
214
  logprobs=logprobs,
162
215
  top_logprobs=top_logprobs,
163
216
  validator=validator,
217
+ max_validation_retries=max_validation_retries,
164
218
  # Internal parameters
165
219
  prompt_file="is_question.yaml",
166
220
  output_model=OM.BoolOutput,
@@ -178,15 +232,28 @@ class AsyncTheTool:
178
232
  logprobs: bool = False,
179
233
  top_logprobs: int | None = None,
180
234
  validator: Callable[[Any], bool] | None = None,
235
+ max_validation_retries: int | None = None,
181
236
  ) -> OM.ToolOutput:
182
237
  """
183
238
  Generate a single question from the given text.
184
239
 
240
+ Arguments:
241
+ text: The input text to generate a question from
242
+ with_analysis: Whether to include detailed reasoning analysis
243
+ output_lang: Language for the output question
244
+ user_prompt: Additional instructions for question generation
245
+ temperature: Controls randomness (0.0 = deterministic, 1.0 = creative)
246
+ logprobs: Whether to return token probability information
247
+ top_logprobs: Number of top token alternatives to return if logprobs enabled
248
+ validator: Custom validation function to validate the output
249
+ max_validation_retries: Maximum number of retry attempts if validation fails
250
+
185
251
  Returns:
186
252
  ToolOutput: Object containing:
187
253
  - result (str): The generated question
188
254
  - logprobs (list | None): Probability data if logprobs enabled
189
255
  - analysis (str | None): Detailed reasoning if with_analysis enabled
256
+ - errors (list(str) | None): Errors occured during tool call
190
257
  """
191
258
  return await self._operator.run(
192
259
  # User parameters
@@ -198,6 +265,7 @@ class AsyncTheTool:
198
265
  logprobs=logprobs,
199
266
  top_logprobs=top_logprobs,
200
267
  validator=validator,
268
+ max_validation_retries=max_validation_retries,
201
269
  # Internal parameters
202
270
  prompt_file="text_to_question.yaml",
203
271
  output_model=OM.StrOutput,
@@ -215,15 +283,29 @@ class AsyncTheTool:
215
283
  top_logprobs: int | None = None,
216
284
  mode: Literal["default", "reason"] = "default",
217
285
  validator: Callable[[Any], bool] | None = None,
286
+ max_validation_retries: int | None = None,
218
287
  ) -> OM.ToolOutput:
219
288
  """
220
289
  Merge multiple questions into a single unified question.
221
290
 
291
+ Arguments:
292
+ text: List of questions to merge
293
+ with_analysis: Whether to include detailed reasoning analysis
294
+ output_lang: Language for the output merged question
295
+ user_prompt: Additional instructions for question merging
296
+ temperature: Controls randomness (0.0 = deterministic, 1.0 = creative)
297
+ logprobs: Whether to return token probability information
298
+ top_logprobs: Number of top token alternatives to return if logprobs enabled
299
+ mode: Merging strategy - 'default' for direct merge, 'reason' for reasoned merge
300
+ validator: Custom validation function to validate the output
301
+ max_validation_retries: Maximum number of retry attempts if validation fails
302
+
222
303
  Returns:
223
304
  ToolOutput: Object containing:
224
305
  - result (str): The merged question
225
306
  - logprobs (list | None): Probability data if logprobs enabled
226
307
  - analysis (str | None): Detailed reasoning if with_analysis enabled
308
+ - errors (list(str) | None): Errors occured during tool call
227
309
  """
228
310
  text = ", ".join(text)
229
311
  return await self._operator.run(
@@ -236,6 +318,7 @@ class AsyncTheTool:
236
318
  logprobs=logprobs,
237
319
  top_logprobs=top_logprobs,
238
320
  validator=validator,
321
+ max_validation_retries=max_validation_retries,
239
322
  # Internal parameters
240
323
  prompt_file="merge_questions.yaml",
241
324
  output_model=OM.StrOutput,
@@ -253,15 +336,29 @@ class AsyncTheTool:
253
336
  top_logprobs: int | None = None,
254
337
  mode: Literal["positive", "negative", "hard_negative"] = "positive",
255
338
  validator: Callable[[Any], bool] | None = None,
339
+ max_validation_retries: int | None = None,
256
340
  ) -> OM.ToolOutput:
257
341
  """
258
342
  Rewrite a text with different modes.
259
343
 
344
+ Arguments:
345
+ text: The input text to rewrite
346
+ with_analysis: Whether to include detailed reasoning analysis
347
+ output_lang: Language for the output rewritten text
348
+ user_prompt: Additional instructions for rewriting
349
+ temperature: Controls randomness (0.0 = deterministic, 1.0 = creative)
350
+ logprobs: Whether to return token probability information
351
+ top_logprobs: Number of top token alternatives to return if logprobs enabled
352
+ mode: Rewriting mode - 'positive', 'negative', or 'hard_negative'
353
+ validator: Custom validation function to validate the output
354
+ max_validation_retries: Maximum number of retry attempts if validation fails
355
+
260
356
  Returns:
261
357
  ToolOutput: Object containing:
262
358
  - result (str): The rewritten text
263
359
  - logprobs (list | None): Probability data if logprobs enabled
264
360
  - analysis (str | None): Detailed reasoning if with_analysis enabled
361
+ - errors (list(str) | None): Errors occured during tool call
265
362
  """
266
363
  return await self._operator.run(
267
364
  # User parameters
@@ -273,6 +370,7 @@ class AsyncTheTool:
273
370
  logprobs=logprobs,
274
371
  top_logprobs=top_logprobs,
275
372
  validator=validator,
373
+ max_validation_retries=max_validation_retries,
276
374
  # Internal parameters
277
375
  prompt_file="rewrite.yaml",
278
376
  output_model=OM.StrOutput,
@@ -290,15 +388,29 @@ class AsyncTheTool:
290
388
  logprobs: bool = False,
291
389
  top_logprobs: int | None = None,
292
390
  validator: Callable[[Any], bool] | None = None,
391
+ max_validation_retries: int | None = None,
293
392
  ) -> OM.ToolOutput:
294
393
  """
295
394
  Generate a list of questions about a subject.
296
395
 
396
+ Arguments:
397
+ text: The subject text to generate questions about
398
+ number_of_questions: Number of questions to generate
399
+ with_analysis: Whether to include detailed reasoning analysis
400
+ output_lang: Language for the output questions
401
+ user_prompt: Additional instructions for question generation
402
+ temperature: Controls randomness (0.0 = deterministic, 1.0 = creative)
403
+ logprobs: Whether to return token probability information
404
+ top_logprobs: Number of top token alternatives to return if logprobs enabled
405
+ validator: Custom validation function to validate the output
406
+ max_validation_retries: Maximum number of retry attempts if validation fails
407
+
297
408
  Returns:
298
409
  ToolOutput: Object containing:
299
410
  - result (list[str]): List of generated questions
300
411
  - logprobs (list | None): Probability data if logprobs enabled
301
412
  - analysis (str | None): Detailed reasoning if with_analysis enabled
413
+ - errors (list(str) | None): Errors occured during tool call
302
414
  """
303
415
  return await self._operator.run(
304
416
  # User parameters
@@ -311,6 +423,7 @@ class AsyncTheTool:
311
423
  logprobs=logprobs,
312
424
  top_logprobs=top_logprobs,
313
425
  validator=validator,
426
+ max_validation_retries=max_validation_retries,
314
427
  # Internal parameters
315
428
  prompt_file="subject_to_question.yaml",
316
429
  output_model=OM.ReasonListStrOutput,
@@ -327,15 +440,28 @@ class AsyncTheTool:
327
440
  logprobs: bool = False,
328
441
  top_logprobs: int | None = None,
329
442
  validator: Callable[[Any], bool] | None = None,
443
+ max_validation_retries: int | None = None,
330
444
  ) -> OM.ToolOutput:
331
445
  """
332
446
  Summarize the given subject text.
333
447
 
448
+ Arguments:
449
+ text: The input text to summarize
450
+ with_analysis: Whether to include detailed reasoning analysis
451
+ output_lang: Language for the output summary
452
+ user_prompt: Additional instructions for summarization
453
+ temperature: Controls randomness (0.0 = deterministic, 1.0 = creative)
454
+ logprobs: Whether to return token probability information
455
+ top_logprobs: Number of top token alternatives to return if logprobs enabled
456
+ validator: Custom validation function to validate the output
457
+ max_validation_retries: Maximum number of retry attempts if validation fails
458
+
334
459
  Returns:
335
460
  ToolOutput: Object containing:
336
461
  - result (str): The summary text
337
462
  - logprobs (list | None): Probability data if logprobs enabled
338
463
  - analysis (str | None): Detailed reasoning if with_analysis enabled
464
+ - errors (list(str) | None): Errors occured during tool call
339
465
  """
340
466
  return await self._operator.run(
341
467
  # User parameters
@@ -347,6 +473,7 @@ class AsyncTheTool:
347
473
  logprobs=logprobs,
348
474
  top_logprobs=top_logprobs,
349
475
  validator=validator,
476
+ max_validation_retries=max_validation_retries,
350
477
  # Internal parameters
351
478
  prompt_file="summarize.yaml",
352
479
  output_model=OM.StrOutput,
@@ -363,15 +490,28 @@ class AsyncTheTool:
363
490
  logprobs: bool = False,
364
491
  top_logprobs: int | None = None,
365
492
  validator: Callable[[Any], bool] | None = None,
493
+ max_validation_retries: int | None = None,
366
494
  ) -> OM.ToolOutput:
367
495
  """
368
496
  Translate text between languages.
369
497
 
498
+ Arguments:
499
+ text: The input text to translate
500
+ target_language: The target language for translation
501
+ with_analysis: Whether to include detailed reasoning analysis
502
+ user_prompt: Additional instructions for translation
503
+ temperature: Controls randomness (0.0 = deterministic, 1.0 = creative)
504
+ logprobs: Whether to return token probability information
505
+ top_logprobs: Number of top token alternatives to return if logprobs enabled
506
+ validator: Custom validation function to validate the output
507
+ max_validation_retries: Maximum number of retry attempts if validation fails
508
+
370
509
  Returns:
371
510
  ToolOutput: Object containing:
372
511
  - result (str): The translated text
373
512
  - logprobs (list | None): Probability data if logprobs enabled
374
513
  - analysis (str | None): Detailed reasoning if with_analysis enabled
514
+ - errors (list(str) | None): Errors occured during tool call
375
515
  """
376
516
  return await self._operator.run(
377
517
  # User parameters
@@ -383,6 +523,7 @@ class AsyncTheTool:
383
523
  logprobs=logprobs,
384
524
  top_logprobs=top_logprobs,
385
525
  validator=validator,
526
+ max_validation_retries=max_validation_retries,
386
527
  # Internal parameters
387
528
  prompt_file="translate.yaml",
388
529
  output_model=OM.StrOutput,
@@ -398,13 +539,27 @@ class AsyncTheTool:
398
539
  temperature: float | None = None,
399
540
  logprobs: bool | None = None,
400
541
  top_logprobs: int | None = None,
542
+ validator: Callable[[Any], bool] | None = None,
543
+ max_validation_retries: int | None = None,
401
544
  ) -> OM.ToolOutput:
402
545
  """
403
546
  Custom tool that can do almost anything!
404
547
 
548
+ Arguments:
549
+ text: The user prompt
550
+ output_lang: Language for the output summary
551
+ temperature: Controls randomness (0.0 = deterministic, 1.0 = creative)
552
+ logprobs: Whether to return token probability information
553
+ top_logprobs: Number of top token alternatives to return if logprobs enabled
554
+ validator: Custom validation function to validate the output
555
+ max_validation_retries: Maximum number of retry attempts if validation fails
556
+
405
557
  Returns:
406
- ToolOutput: Object with fields:
407
- - result (str): The output result
558
+ ToolOutput: Object containing:
559
+ - result (str): The translated text
560
+ - logprobs (list | None): Probability data if logprobs enabled
561
+ - analysis (str | None): Detailed reasoning if with_analysis enabled
562
+ - errors (list(str) | None): Errors occured during tool call
408
563
  """
409
564
  return await self._operator.run(
410
565
  # User paramaeters
@@ -415,10 +570,11 @@ class AsyncTheTool:
415
570
  temperature=temperature,
416
571
  logprobs=logprobs,
417
572
  top_logprobs=top_logprobs,
573
+ validator=validator,
574
+ max_validation_retries=max_validation_retries,
418
575
  # Internal parameters
419
576
  prompt_file="run_custom.yaml",
420
577
  user_prompt=None,
421
578
  with_analysis=False,
422
579
  mode=None,
423
- validator=None,
424
580
  )
@@ -5,8 +5,7 @@ from openai import AsyncOpenAI
5
5
  from pydantic import BaseModel
6
6
 
7
7
  from texttools.tools.internals.output_models import ToolOutput
8
- from texttools.tools.internals.base_operator import BaseOperator
9
- from texttools.tools.internals.formatters import Formatter
8
+ from texttools.tools.internals.operator_utils import OperatorUtils
10
9
  from texttools.tools.internals.prompt_loader import PromptLoader
11
10
 
12
11
  # Base Model type for output models
@@ -15,7 +14,7 @@ T = TypeVar("T", bound=BaseModel)
15
14
  logger = logging.getLogger("texttools.async_operator")
16
15
 
17
16
 
18
- class AsyncOperator(BaseOperator):
17
+ class AsyncOperator:
19
18
  """
20
19
  Core engine for running text-processing operations with an LLM (Async).
21
20
 
@@ -26,7 +25,8 @@ class AsyncOperator(BaseOperator):
26
25
  """
27
26
 
28
27
  def __init__(self, client: AsyncOpenAI, model: str):
29
- super().__init__(client, model)
28
+ self._client = client
29
+ self._model = model
30
30
 
31
31
  async def _analyze(self, prompt_configs: dict[str, str], temperature: float) -> str:
32
32
  """
@@ -34,7 +34,7 @@ class AsyncOperator(BaseOperator):
34
34
  Returns the analyzed content as a string.
35
35
  """
36
36
  analyze_prompt = prompt_configs["analyze_template"]
37
- analyze_message = [self._build_user_message(analyze_prompt)]
37
+ analyze_message = [OperatorUtils.build_user_message(analyze_prompt)]
38
38
  completion = await self._client.chat.completions.create(
39
39
  model=self._model,
40
40
  messages=analyze_message,
@@ -53,7 +53,7 @@ class AsyncOperator(BaseOperator):
53
53
  ) -> tuple[T, Any]:
54
54
  """
55
55
  Parses a chat completion using OpenAI's structured output format.
56
- Returns both the parsed object and the raw completion for logging.
56
+ Returns both the parsed object and the raw completion for logprobs.
57
57
  """
58
58
  request_kwargs = {
59
59
  "model": self._model,
@@ -81,6 +81,7 @@ class AsyncOperator(BaseOperator):
81
81
  logprobs: bool,
82
82
  top_logprobs: int | None,
83
83
  validator: Callable[[Any], bool] | None,
84
+ max_validation_retries: int | None,
84
85
  # Internal parameters
85
86
  prompt_file: str,
86
87
  output_model: Type[T],
@@ -91,7 +92,6 @@ class AsyncOperator(BaseOperator):
91
92
  Execute the async LLM pipeline with the given input text. (Async)
92
93
  """
93
94
  prompt_loader = PromptLoader()
94
- formatter = Formatter()
95
95
  output = ToolOutput()
96
96
 
97
97
  try:
@@ -108,46 +108,44 @@ class AsyncOperator(BaseOperator):
108
108
  if with_analysis:
109
109
  analysis = await self._analyze(prompt_configs, temperature)
110
110
  messages.append(
111
- self._build_user_message(f"Based on this analysis: {analysis}")
111
+ OperatorUtils.build_user_message(
112
+ f"Based on this analysis: {analysis}"
113
+ )
112
114
  )
113
115
 
114
116
  if output_lang:
115
117
  messages.append(
116
- self._build_user_message(
118
+ OperatorUtils.build_user_message(
117
119
  f"Respond only in the {output_lang} language."
118
120
  )
119
121
  )
120
122
 
121
123
  if user_prompt:
122
124
  messages.append(
123
- self._build_user_message(f"Consider this instruction {user_prompt}")
125
+ OperatorUtils.build_user_message(
126
+ f"Consider this instruction {user_prompt}"
127
+ )
124
128
  )
125
129
 
126
- messages.append(self._build_user_message(prompt_configs["main_template"]))
127
- messages = formatter.user_merge_format(messages)
130
+ messages.append(
131
+ OperatorUtils.build_user_message(prompt_configs["main_template"])
132
+ )
128
133
 
129
134
  parsed, completion = await self._parse_completion(
130
135
  messages, output_model, temperature, logprobs, top_logprobs
131
136
  )
132
137
 
133
- # Ensure output_model has a `result` field
134
- if not hasattr(parsed, "result"):
135
- error = "The provided output_model must define a field named 'result'"
136
- logger.error(error)
137
- output.errors.append(error)
138
- return output
139
-
140
138
  output.result = parsed.result
141
139
 
142
140
  # Retry logic if validation fails
143
141
  if validator and not validator(output.result):
144
- for attempt in range(self.MAX_RETRIES):
142
+ for attempt in range(max_validation_retries):
145
143
  logger.warning(
146
144
  f"Validation failed, retrying for the {attempt + 1} time."
147
145
  )
148
146
 
149
147
  # Generate new temperature for retry
150
- retry_temperature = self._get_retry_temp(temperature)
148
+ retry_temperature = OperatorUtils.get_retry_temp(temperature)
151
149
  try:
152
150
  parsed, completion = await self._parse_completion(
153
151
  messages,
@@ -179,7 +177,7 @@ class AsyncOperator(BaseOperator):
179
177
  output.errors.append("Validation failed after all retry attempts")
180
178
 
181
179
  if logprobs:
182
- output.logprobs = self._extract_logprobs(completion)
180
+ output.logprobs = OperatorUtils.extract_logprobs(completion)
183
181
 
184
182
  if with_analysis:
185
183
  output.analysis = analysis