hamtaa-texttools 1.0.2__py3-none-any.whl → 1.0.3__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.
Files changed (30) hide show
  1. {hamtaa_texttools-1.0.2.dist-info → hamtaa_texttools-1.0.3.dist-info}/METADATA +18 -6
  2. hamtaa_texttools-1.0.3.dist-info/RECORD +29 -0
  3. texttools/__init__.py +3 -3
  4. texttools/{utils/batch_manager → batch}/batch_runner.py +1 -1
  5. texttools/formatters/user_merge_formatter/user_merge_formatter.py +0 -17
  6. texttools/prompts/README.md +5 -5
  7. texttools/prompts/categorizer.yaml +16 -10
  8. texttools/prompts/keyword_extractor.yaml +4 -1
  9. texttools/prompts/ner_extractor.yaml +4 -1
  10. texttools/prompts/question_detector.yaml +5 -2
  11. texttools/prompts/question_generator.yaml +4 -3
  12. texttools/prompts/question_merger.yaml +6 -4
  13. texttools/prompts/question_rewriter.yaml +6 -4
  14. texttools/prompts/subject_question_generator.yaml +3 -4
  15. texttools/prompts/summarizer.yaml +1 -0
  16. texttools/prompts/translator.yaml +1 -0
  17. texttools/tools/__init__.py +2 -1
  18. texttools/tools/async_the_tool.py +263 -0
  19. texttools/tools/internals/async_operator.py +288 -0
  20. texttools/tools/{operator.py → internals/operator.py} +133 -63
  21. texttools/tools/{output_models.py → internals/output_models.py} +8 -0
  22. texttools/tools/{prompt_loader.py → internals/prompt_loader.py} +16 -18
  23. texttools/tools/the_tool.py +181 -72
  24. hamtaa_texttools-1.0.2.dist-info/RECORD +0 -28
  25. texttools/utils/__init__.py +0 -4
  26. {hamtaa_texttools-1.0.2.dist-info → hamtaa_texttools-1.0.3.dist-info}/WHEEL +0 -0
  27. {hamtaa_texttools-1.0.2.dist-info → hamtaa_texttools-1.0.3.dist-info}/licenses/LICENSE +0 -0
  28. {hamtaa_texttools-1.0.2.dist-info → hamtaa_texttools-1.0.3.dist-info}/top_level.txt +0 -0
  29. /texttools/{utils/batch_manager → batch}/__init__.py +0 -0
  30. /texttools/{utils/batch_manager → batch}/batch_manager.py +0 -0
@@ -1,9 +1,9 @@
1
- from typing import Literal, Any
1
+ from typing import Literal, Any, Optional
2
2
 
3
3
  from openai import OpenAI
4
4
 
5
- from texttools.tools.operator import Operator
6
- import texttools.tools.output_models as OutputModels
5
+ from texttools.tools.internals.operator import Operator
6
+ import texttools.tools.internals.output_models as OutputModels
7
7
 
8
8
 
9
9
  class TheTool:
@@ -46,7 +46,14 @@ class TheTool:
46
46
  **client_kwargs,
47
47
  )
48
48
 
49
- def categorize(self, text: str, with_analysis: bool = False) -> dict[str, str]:
49
+ def categorize(
50
+ self,
51
+ text: str,
52
+ with_analysis: bool = False,
53
+ user_prompt: str = "",
54
+ logprobs: bool = False,
55
+ top_logprobs: int = 8,
56
+ ) -> dict[str, str]:
50
57
  """
51
58
  Categorize a text into a single Islamic studies domain category.
52
59
 
@@ -59,16 +66,28 @@ class TheTool:
59
66
  {"result": <category string>}
60
67
  Example: {"result": "باورهای دینی"}
61
68
  """
62
- self.operator.PROMPT_FILE = "categorizer.yaml"
63
- self.operator.OUTPUT_MODEL = OutputModels.CategorizerOutput
64
- self.operator.WITH_ANALYSIS = with_analysis
65
- self.operator.USE_MODES = False
66
69
 
67
- results = self.operator.run(text)
70
+ results = self.operator.run(
71
+ text,
72
+ prompt_file="categorizer.yaml",
73
+ output_model=OutputModels.CategorizerOutput,
74
+ with_analysis=with_analysis,
75
+ resp_format="parse",
76
+ user_prompt=user_prompt,
77
+ logprobs=logprobs,
78
+ top_logprobs=top_logprobs,
79
+ )
80
+
68
81
  return results
69
82
 
70
83
  def extract_keywords(
71
- self, text: str, with_analysis: bool = False
84
+ self,
85
+ text: str,
86
+ output_lang: Optional[str] = None,
87
+ with_analysis: bool = False,
88
+ user_prompt: str = "",
89
+ logprobs: bool = False,
90
+ top_logprobs: int = 3,
72
91
  ) -> dict[str, list[str]]:
73
92
  """
74
93
  Extract salient keywords from text.
@@ -80,16 +99,28 @@ class TheTool:
80
99
  Returns:
81
100
  {"result": [<keyword1>, <keyword2>, ...]}
82
101
  """
83
- self.operator.PROMPT_FILE = "keyword_extractor.yaml"
84
- self.operator.OUTPUT_MODEL = OutputModels.ListStrOutput
85
- self.operator.WITH_ANALYSIS = with_analysis
86
- self.operator.USE_MODES = False
102
+ results = self.operator.run(
103
+ text,
104
+ prompt_file="keyword_extractor.yaml",
105
+ output_model=OutputModels.ListStrOutput,
106
+ with_analysis=with_analysis,
107
+ resp_format="parse",
108
+ user_prompt=user_prompt,
109
+ output_lang=output_lang,
110
+ logprobs=logprobs,
111
+ top_logprobs=top_logprobs,
112
+ )
87
113
 
88
- results = self.operator.run(text)
89
114
  return results
90
115
 
91
116
  def extract_entities(
92
- self, text: str, with_analysis: bool = False
117
+ self,
118
+ text: str,
119
+ output_lang: Optional[str] = None,
120
+ with_analysis: bool = False,
121
+ user_prompt: str = "",
122
+ logprobs: bool = False,
123
+ top_logprobs: int = 3,
93
124
  ) -> dict[str, list[dict[str, str]]]:
94
125
  """
95
126
  Perform Named Entity Recognition (NER) over the input text.
@@ -101,17 +132,29 @@ class TheTool:
101
132
  Returns:
102
133
  {"result": [{"text": <entity>, "type": <entity_type>}, ...]}
103
134
  """
104
- self.operator.PROMPT_FILE = "ner_extractor.yaml"
105
- self.operator.OUTPUT_MODEL = OutputModels.ListDictStrStrOutput
106
- self.operator.WITH_ANALYSIS = with_analysis
107
- self.operator.USE_MODES = False
135
+ results = self.operator.run(
136
+ text,
137
+ prompt_file="ner_extractor.yaml",
138
+ output_model=OutputModels.ListDictStrStrOutput,
139
+ with_analysis=with_analysis,
140
+ resp_format="parse",
141
+ user_prompt=user_prompt,
142
+ output_lang=output_lang,
143
+ logprobs=logprobs,
144
+ top_logprobs=top_logprobs,
145
+ )
108
146
 
109
- results = self.operator.run(text)
110
147
  return results
111
148
 
112
149
  def detect_question(
113
- self, question: str, with_analysis: bool = False
114
- ) -> dict[str, str]:
150
+ self,
151
+ question: str,
152
+ output_lang: Optional[str] = None,
153
+ with_analysis: bool = False,
154
+ user_prompt: str = "",
155
+ logprobs: bool = False,
156
+ top_logprobs: int = 2,
157
+ ) -> dict[str, bool]:
115
158
  """
116
159
  Detect if the input is phrased as a question.
117
160
 
@@ -122,16 +165,28 @@ class TheTool:
122
165
  Returns:
123
166
  {"result": "true"} or {"result": "false"}
124
167
  """
125
- self.operator.PROMPT_FILE = "question_detector.yaml"
126
- self.operator.OUTPUT_MODEL = OutputModels.StrOutput
127
- self.operator.WITH_ANALYSIS = with_analysis
128
- self.operator.USE_MODES = False
168
+ results = self.operator.run(
169
+ question,
170
+ prompt_file="question_detector.yaml",
171
+ output_model=OutputModels.BoolOutput,
172
+ with_analysis=with_analysis,
173
+ resp_format="parse",
174
+ user_prompt=user_prompt,
175
+ output_lang=output_lang,
176
+ logprobs=logprobs,
177
+ top_logprobs=top_logprobs,
178
+ )
129
179
 
130
- results = self.operator.run(question)
131
180
  return results
132
181
 
133
182
  def generate_question_from_text(
134
- self, text: str, with_analysis: bool = False
183
+ self,
184
+ text: str,
185
+ output_lang: Optional[str] = None,
186
+ with_analysis: bool = False,
187
+ user_prompt: str = "",
188
+ logprobs: bool = False,
189
+ top_logprobs: int = 3,
135
190
  ) -> dict[str, str]:
136
191
  """
137
192
  Generate a single question from the given text.
@@ -143,19 +198,29 @@ class TheTool:
143
198
  Returns:
144
199
  {"result": <generated_question>}
145
200
  """
146
- self.operator.PROMPT_FILE = "question_generator.yaml"
147
- self.operator.OUTPUT_MODEL = OutputModels.StrOutput
148
- self.operator.WITH_ANALYSIS = with_analysis
149
- self.operator.USE_MODES = False
201
+ results = self.operator.run(
202
+ text,
203
+ prompt_file="question_generator.yaml",
204
+ output_model=OutputModels.StrOutput,
205
+ with_analysis=with_analysis,
206
+ resp_format="parse",
207
+ user_prompt=user_prompt,
208
+ output_lang=output_lang,
209
+ logprobs=logprobs,
210
+ top_logprobs=top_logprobs,
211
+ )
150
212
 
151
- results = self.operator.run(text)
152
213
  return results
153
214
 
154
215
  def merge_questions(
155
216
  self,
156
217
  questions: list[str],
157
- mode: Literal["default_mode", "reason_mode"] = "default_mode",
218
+ output_lang: Optional[str] = None,
219
+ mode: Literal["default", "reason"] = "default",
158
220
  with_analysis: bool = False,
221
+ user_prompt: str = "",
222
+ logprobs: bool = False,
223
+ top_logprobs: int = 3,
159
224
  ) -> dict[str, str]:
160
225
  """
161
226
  Merge multiple questions into a single unified question.
@@ -163,8 +228,8 @@ class TheTool:
163
228
  Args:
164
229
  questions: List of question strings.
165
230
  mode: Merge strategy:
166
- - "default_mode": simple merging.
167
- - "reason_mode": merging with reasoning explanation.
231
+ - "default": simple merging.
232
+ - "reason": merging with reasoning explanation.
168
233
  with_analysis: Whether to use an analysis step.
169
234
 
170
235
  Returns:
@@ -172,23 +237,34 @@ class TheTool:
172
237
  """
173
238
  question_str = ", ".join(questions)
174
239
 
175
- self.operator.PROMPT_FILE = "question_merger.yaml"
176
- self.operator.OUTPUT_MODEL = OutputModels.StrOutput
177
- self.operator.WITH_ANALYSIS = with_analysis
178
- self.operator.USE_MODES = True
179
- self.operator.MODE = mode
240
+ results = self.operator.run(
241
+ question_str,
242
+ prompt_file="question_merger.yaml",
243
+ output_model=OutputModels.StrOutput,
244
+ with_analysis=with_analysis,
245
+ use_modes=True,
246
+ mode=mode,
247
+ resp_format="parse",
248
+ user_prompt=user_prompt,
249
+ output_lang=output_lang,
250
+ logprobs=logprobs,
251
+ top_logprobs=top_logprobs,
252
+ )
180
253
 
181
- results = self.operator.run(question_str)
182
254
  return results
183
255
 
184
256
  def rewrite_question(
185
257
  self,
186
258
  question: str,
259
+ output_lang: Optional[str] = None,
187
260
  mode: Literal[
188
- "same_meaning_different_wording_mode",
189
- "different_meaning_similar_wording_mode",
190
- ] = "same_meaning_different_wording_mode",
261
+ "same_meaning_different_wording",
262
+ "different_meaning_similar_wording",
263
+ ] = "same_meaning_different_wording",
191
264
  with_analysis: bool = False,
265
+ user_prompt: str = "",
266
+ logprobs: bool = False,
267
+ top_logprobs: int = 3,
192
268
  ) -> dict[str, str]:
193
269
  """
194
270
  Rewrite a question with different wording or meaning.
@@ -196,28 +272,38 @@ class TheTool:
196
272
  Args:
197
273
  question: Input question to rewrite.
198
274
  mode: Rewrite strategy:
199
- - "same_meaning_different_wording_mode": keep meaning, change words.
200
- - "different_meaning_similar_wording_mode": alter meaning, preserve wording style.
275
+ - "same_meaning_different_wording": keep meaning, change words.
276
+ - "different_meaning_similar_wording": alter meaning, preserve wording style.
201
277
  with_analysis: Whether to include an analysis step.
202
278
 
203
279
  Returns:
204
280
  {"result": <rewritten_question>}
205
281
  """
206
- self.operator.PROMPT_FILE = "question_rewriter.yaml"
207
- self.operator.OUTPUT_MODEL = OutputModels.StrOutput
208
- self.operator.WITH_ANALYSIS = with_analysis
209
- self.operator.USE_MODES = True
210
- self.operator.MODE = mode
282
+ results = self.operator.run(
283
+ question,
284
+ prompt_file="question_rewriter.yaml",
285
+ output_model=OutputModels.StrOutput,
286
+ with_analysis=with_analysis,
287
+ use_modes=True,
288
+ mode=mode,
289
+ resp_format="parse",
290
+ user_prompt=user_prompt,
291
+ output_lang=output_lang,
292
+ logprobs=logprobs,
293
+ top_logprobs=top_logprobs,
294
+ )
211
295
 
212
- results = self.operator.run(question)
213
296
  return results
214
297
 
215
298
  def generate_questions_from_subject(
216
299
  self,
217
300
  subject: str,
218
301
  number_of_questions: int,
219
- language: str = "English",
302
+ output_lang: Optional[str] = None,
220
303
  with_analysis: bool = False,
304
+ user_prompt: str = "",
305
+ logprobs: bool = False,
306
+ top_logprobs: int = 3,
221
307
  ) -> dict[str, list[str]]:
222
308
  """
223
309
  Generate a list of questions about a subject.
@@ -231,19 +317,30 @@ class TheTool:
231
317
  Returns:
232
318
  {"result": [<question1>, <question2>, ...]}
233
319
  """
234
- self.operator.PROMPT_FILE = "subject_question_generator.yaml"
235
- self.operator.OUTPUT_MODEL = OutputModels.ReasonListStrOutput
236
- self.operator.WITH_ANALYSIS = with_analysis
237
- self.operator.USE_MODES = False
238
-
239
320
  results = self.operator.run(
240
321
  subject,
322
+ prompt_file="subject_question_generator.yaml",
323
+ output_model=OutputModels.ReasonListStrOutput,
324
+ with_analysis=with_analysis,
325
+ resp_format="parse",
326
+ user_prompt=user_prompt,
241
327
  number_of_questions=number_of_questions,
242
- language=language,
328
+ output_lang=output_lang,
329
+ logprobs=logprobs,
330
+ top_logprobs=top_logprobs,
243
331
  )
332
+
244
333
  return results
245
334
 
246
- def summarize(self, subject: str, with_analysis: bool = False) -> dict[str, str]:
335
+ def summarize(
336
+ self,
337
+ text: str,
338
+ output_lang: Optional[str] = None,
339
+ with_analysis: bool = False,
340
+ user_prompt: str = "",
341
+ logprobs: bool = False,
342
+ top_logprobs: int = 3,
343
+ ) -> dict[str, str]:
247
344
  """
248
345
  Summarize the given subject text.
249
346
 
@@ -254,12 +351,18 @@ class TheTool:
254
351
  Returns:
255
352
  {"result": <summary>}
256
353
  """
257
- self.operator.PROMPT_FILE = "summarizer.yaml"
258
- self.operator.OUTPUT_MODEL = OutputModels.StrOutput
259
- self.operator.WITH_ANALYSIS = with_analysis
260
- self.operator.USE_MODES = False
354
+ results = self.operator.run(
355
+ text,
356
+ prompt_file="summarizer.yaml",
357
+ output_model=OutputModels.StrOutput,
358
+ with_analysis=with_analysis,
359
+ resp_format="parse",
360
+ user_prompt=user_prompt,
361
+ output_lang=output_lang,
362
+ logprobs=logprobs,
363
+ top_logprobs=top_logprobs,
364
+ )
261
365
 
262
- results = self.operator.run(subject)
263
366
  return results
264
367
 
265
368
  def translate(
@@ -267,6 +370,9 @@ class TheTool:
267
370
  text: str,
268
371
  target_language: str,
269
372
  with_analysis: bool = False,
373
+ user_prompt: str = "",
374
+ logprobs: bool = False,
375
+ top_logprobs: int = 3,
270
376
  ) -> dict[str, str]:
271
377
  """
272
378
  Translate text between languages.
@@ -279,13 +385,16 @@ class TheTool:
279
385
  Returns:
280
386
  {"result": <translated_text>}
281
387
  """
282
- self.operator.PROMPT_FILE = "translator.yaml"
283
- self.operator.OUTPUT_MODEL = OutputModels.StrOutput
284
- self.operator.WITH_ANALYSIS = with_analysis
285
- self.operator.USE_MODES = False
286
-
287
388
  results = self.operator.run(
288
389
  text,
390
+ prompt_file="translator.yaml",
391
+ output_model=OutputModels.StrOutput,
392
+ with_analysis=with_analysis,
393
+ resp_format="parse",
394
+ user_prompt=user_prompt,
289
395
  target_language=target_language,
396
+ logprobs=logprobs,
397
+ top_logprobs=top_logprobs,
290
398
  )
399
+
291
400
  return results
@@ -1,28 +0,0 @@
1
- hamtaa_texttools-1.0.2.dist-info/licenses/LICENSE,sha256=TJch8KUnfKaKJFkaRqgtghB7rtprhaHyGirYKr90U4o,1062
2
- texttools/__init__.py,sha256=DEPDeR8rKRye57x9kq00Adq9GOLFkmaWRq9sGBNQZ_c,241
3
- texttools/formatters/base_formatter.py,sha256=sUrISJcczTLDPMiMETG-kyfZ64u0NubFpT3mjEQBskk,1147
4
- texttools/formatters/user_merge_formatter/user_merge_formatter.py,sha256=R-e64Gwq6jARcpsnPYsgNIX7eqFDi0BtfiZOATvwxqo,1692
5
- texttools/prompts/README.md,sha256=OJwlvlsKYW2ukdCMvvvxEGu8ncNx8MY9L3pzQTqWlGo,1364
6
- texttools/prompts/categorizer.yaml,sha256=XZtZaMEqH646W4GNC7flI0TROoUAA7w-wBV-Y6dJT7U,756
7
- texttools/prompts/keyword_extractor.yaml,sha256=KUATHGFrrKZ50Rg3TJO-Ivx7reKxPH0AE8-wXKp0PgE,460
8
- texttools/prompts/ner_extractor.yaml,sha256=IeGsIPDsD_Cq6tyDToTK4xOOq1ZF3hedZs7AWNMupCk,597
9
- texttools/prompts/question_detector.yaml,sha256=0yoSetf7_RWhhHoOCJBTY-GKB-_TrW7BDbyk0W6fvEU,408
10
- texttools/prompts/question_generator.yaml,sha256=GXrX1N6I5C5Hw6Pc_TRa_qQ2P4HWM7Vh8T28CUCrFKQ,950
11
- texttools/prompts/question_merger.yaml,sha256=2hPVjlCkM0aatVrGJrfCZRkBNPapXcYYH5WQkPLt30s,2148
12
- texttools/prompts/question_rewriter.yaml,sha256=5Yen8M5RrkWnH3eNoYUtKjXW7_IWKeVui8GTMqAs1Y4,1985
13
- texttools/prompts/subject_question_generator.yaml,sha256=FmmMjeFwKJHubBZHGesG7DDKazuhyDMsDRWd0A8ILjI,1426
14
- texttools/prompts/summarizer.yaml,sha256=t95zcRLd8PI18nx_030ROqG8UWtsgUMnNr9H8Y1ui_c,360
15
- texttools/prompts/translator.yaml,sha256=JOWXywPmHXJbJYD17Z-XMxBhXwdGbR02SdMNGc_sTZ4,614
16
- texttools/tools/__init__.py,sha256=Gzqlobmbgd5wOvy27JYPKB74MFtqDgFy6LwlRygN240,53
17
- texttools/tools/operator.py,sha256=g3ZC5OSxG_oZQkkMbfzc8uUvw0FNvehNB5jPPY26KEg,7972
18
- texttools/tools/output_models.py,sha256=EdMGvPEp0k8l9Ps48Arw7GMcXSmdRLPrvAhaYnVqGj8,1099
19
- texttools/tools/prompt_loader.py,sha256=zrCgLNGkFV60u6b7CN4dNcml4cGLrC2ei0WcMfD28Bc,2817
20
- texttools/tools/the_tool.py,sha256=lEMVpqhJvPqVzSWx8NlmYV7jqZ1ul3IqJ9nHJLjz0bw,9653
21
- texttools/utils/__init__.py,sha256=XL_cVGbe8wKf8HQh_Q1JEZgGOlmpLijPoHNvzi1aYnc,167
22
- texttools/utils/batch_manager/__init__.py,sha256=WcnujCd_5XotN6emVCfDaO_lMpyk8EwJYcFgNRks5q0,139
23
- texttools/utils/batch_manager/batch_manager.py,sha256=N7dg1bE0QpGYjHtM0E9DWtXErZR_z0byls9d8RQdUbs,9104
24
- texttools/utils/batch_manager/batch_runner.py,sha256=3dhzmHrvCKqQVTtxeBIiUhCyRwKiQp_WmWqGX2WTG-o,7602
25
- hamtaa_texttools-1.0.2.dist-info/METADATA,sha256=jLnwyMWFXxCAn4gZFRVlWWE14nWaB5VF17zaB3r6IFg,5114
26
- hamtaa_texttools-1.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- hamtaa_texttools-1.0.2.dist-info/top_level.txt,sha256=5Mh0jIxxZ5rOXHGJ6Mp-JPKviywwN0MYuH0xk5bEWqE,10
28
- hamtaa_texttools-1.0.2.dist-info/RECORD,,
@@ -1,4 +0,0 @@
1
- from .batch_manager.batch_manager import SimpleBatchManager
2
- from .batch_manager.batch_runner import BatchJobRunner
3
-
4
- __all__ = ["SimpleBatchManager", "BatchJobRunner"]
File without changes