hamtaa-texttools 1.0.4__py3-none-any.whl → 1.0.5__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 hamtaa-texttools might be problematic. Click here for more details.
- {hamtaa_texttools-1.0.4.dist-info → hamtaa_texttools-1.0.5.dist-info}/METADATA +192 -141
- hamtaa_texttools-1.0.5.dist-info/RECORD +30 -0
- {hamtaa_texttools-1.0.4.dist-info → hamtaa_texttools-1.0.5.dist-info}/licenses/LICENSE +20 -20
- {hamtaa_texttools-1.0.4.dist-info → hamtaa_texttools-1.0.5.dist-info}/top_level.txt +0 -0
- texttools/__init__.py +9 -9
- texttools/batch/__init__.py +4 -4
- texttools/batch/batch_manager.py +240 -240
- texttools/batch/batch_runner.py +212 -212
- texttools/formatters/base_formatter.py +33 -33
- texttools/formatters/{user_merge_formatter/user_merge_formatter.py → user_merge_formatter.py} +30 -30
- texttools/prompts/README.md +31 -31
- texttools/prompts/categorizer.yaml +28 -31
- texttools/prompts/custom_tool.yaml +7 -0
- texttools/prompts/keyword_extractor.yaml +18 -14
- texttools/prompts/ner_extractor.yaml +20 -21
- texttools/prompts/question_detector.yaml +13 -14
- texttools/prompts/question_generator.yaml +19 -22
- texttools/prompts/question_merger.yaml +45 -48
- texttools/prompts/rewriter.yaml +111 -0
- texttools/prompts/subject_question_generator.yaml +22 -26
- texttools/prompts/summarizer.yaml +13 -11
- texttools/prompts/translator.yaml +14 -14
- texttools/tools/__init__.py +4 -4
- texttools/tools/async_the_tool.py +277 -263
- texttools/tools/internals/async_operator.py +297 -288
- texttools/tools/internals/operator.py +295 -306
- texttools/tools/internals/output_models.py +52 -62
- texttools/tools/internals/prompt_loader.py +76 -82
- texttools/tools/the_tool.py +501 -400
- hamtaa_texttools-1.0.4.dist-info/RECORD +0 -29
- texttools/prompts/question_rewriter.yaml +0 -46
- {hamtaa_texttools-1.0.4.dist-info → hamtaa_texttools-1.0.5.dist-info}/WHEEL +0 -0
texttools/tools/the_tool.py
CHANGED
|
@@ -1,400 +1,501 @@
|
|
|
1
|
-
from typing import Literal, Any
|
|
2
|
-
|
|
3
|
-
from openai import OpenAI
|
|
4
|
-
|
|
5
|
-
from texttools.tools.internals.operator import Operator
|
|
6
|
-
import texttools.tools.internals.output_models as OutputModels
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class TheTool:
|
|
10
|
-
"""
|
|
11
|
-
High-level interface exposing specialized text tools for.
|
|
12
|
-
|
|
13
|
-
Each method configures the operator with a specific YAML prompt,
|
|
14
|
-
output schema, and flags, then delegates execution to `operator.run()`.
|
|
15
|
-
|
|
16
|
-
Supported capabilities:
|
|
17
|
-
- categorize: assign a text to one of several Islamic categories.
|
|
18
|
-
- extract_keywords: produce a keyword list from text.
|
|
19
|
-
- extract_entities: simple NER (name/type pairs).
|
|
20
|
-
- detect_question: binary check whether input is a question.
|
|
21
|
-
- generate_question_from_text: produce a new question from a text.
|
|
22
|
-
- merge_questions: combine multiple questions (default/reason modes).
|
|
23
|
-
-
|
|
24
|
-
- generate_questions_from_subject: generate multiple questions given a subject.
|
|
25
|
-
- summarize: produce a concise summary of a subject.
|
|
26
|
-
- translate: translate text between languages.
|
|
27
|
-
|
|
28
|
-
Usage pattern:
|
|
29
|
-
client = OpenAI(...)
|
|
30
|
-
tool = TheTool(client, model="gemma-3")
|
|
31
|
-
result = tool.categorize("متن ورودی ...", with_analysis=True)
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
def __init__(
|
|
35
|
-
self,
|
|
36
|
-
client: OpenAI,
|
|
37
|
-
*,
|
|
38
|
-
model: str,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
self
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
with_analysis
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
with_analysis
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
"""
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
def
|
|
216
|
-
self,
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
logprobs=logprobs,
|
|
251
|
-
top_logprobs=top_logprobs,
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
user_prompt: str =
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
1
|
+
from typing import Literal, Any
|
|
2
|
+
|
|
3
|
+
from openai import OpenAI
|
|
4
|
+
|
|
5
|
+
from texttools.tools.internals.operator import Operator
|
|
6
|
+
import texttools.tools.internals.output_models as OutputModels
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TheTool:
|
|
10
|
+
"""
|
|
11
|
+
High-level interface exposing specialized text tools for.
|
|
12
|
+
|
|
13
|
+
Each method configures the operator with a specific YAML prompt,
|
|
14
|
+
output schema, and flags, then delegates execution to `operator.run()`.
|
|
15
|
+
|
|
16
|
+
Supported capabilities:
|
|
17
|
+
- categorize: assign a text to one of several Islamic categories.
|
|
18
|
+
- extract_keywords: produce a keyword list from text.
|
|
19
|
+
- extract_entities: simple NER (name/type pairs).
|
|
20
|
+
- detect_question: binary check whether input is a question.
|
|
21
|
+
- generate_question_from_text: produce a new question from a text.
|
|
22
|
+
- merge_questions: combine multiple questions (default/reason modes).
|
|
23
|
+
- rewrite: rephrase questions (same meaning/different wording, or vice versa).
|
|
24
|
+
- generate_questions_from_subject: generate multiple questions given a subject.
|
|
25
|
+
- summarize: produce a concise summary of a subject.
|
|
26
|
+
- translate: translate text between languages.
|
|
27
|
+
|
|
28
|
+
Usage pattern:
|
|
29
|
+
client = OpenAI(...)
|
|
30
|
+
tool = TheTool(client, model="gemma-3")
|
|
31
|
+
result = tool.categorize("متن ورودی ...", with_analysis=True)
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
client: OpenAI,
|
|
37
|
+
*,
|
|
38
|
+
model: str = "google/gemma-3n-e4b-it",
|
|
39
|
+
user_prompt: str | None = None,
|
|
40
|
+
output_lang: str | None = None,
|
|
41
|
+
with_analysis: bool = False,
|
|
42
|
+
temperature: float = 0.0,
|
|
43
|
+
logprobs: bool = False,
|
|
44
|
+
top_logprobs: int = 3,
|
|
45
|
+
):
|
|
46
|
+
# Initialize Operator
|
|
47
|
+
self.operator = Operator(client=client)
|
|
48
|
+
|
|
49
|
+
# Initialize default values
|
|
50
|
+
self.model = model
|
|
51
|
+
self.user_prompt = user_prompt
|
|
52
|
+
self.output_lang = output_lang
|
|
53
|
+
self.with_analysis = with_analysis
|
|
54
|
+
self.temperature = temperature
|
|
55
|
+
self.logprobs = logprobs
|
|
56
|
+
self.top_logprobs = top_logprobs
|
|
57
|
+
|
|
58
|
+
def categorize(
|
|
59
|
+
self,
|
|
60
|
+
text: str,
|
|
61
|
+
model: str | None = None,
|
|
62
|
+
user_prompt: str | None = None,
|
|
63
|
+
output_lang: str | None = None,
|
|
64
|
+
with_analysis: bool | None = None,
|
|
65
|
+
temperature: float | None = None,
|
|
66
|
+
logprobs: bool | None = None,
|
|
67
|
+
top_logprobs: int | None = None,
|
|
68
|
+
) -> dict[str, str]:
|
|
69
|
+
"""
|
|
70
|
+
Categorize a text into a single Islamic studies domain category.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
text: Input string to categorize.
|
|
74
|
+
with_analysis: If True, first runs an LLM "analysis" step and
|
|
75
|
+
conditions the main prompt on that analysis.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
{"result": <category string>}
|
|
79
|
+
Example: {"result": "باورهای دینی"}
|
|
80
|
+
"""
|
|
81
|
+
return self.operator.run(
|
|
82
|
+
# Internal parameters
|
|
83
|
+
prompt_file="categorizer.yaml",
|
|
84
|
+
output_model=OutputModels.CategorizerOutput,
|
|
85
|
+
resp_format="parse",
|
|
86
|
+
# User parameters
|
|
87
|
+
text=text,
|
|
88
|
+
model=self.model if model is None else model,
|
|
89
|
+
user_prompt=self.user_prompt if user_prompt is None else user_prompt,
|
|
90
|
+
output_lang=self.output_lang if output_lang is None else output_lang,
|
|
91
|
+
with_analysis=self.with_analysis
|
|
92
|
+
if with_analysis is None
|
|
93
|
+
else with_analysis,
|
|
94
|
+
temperature=self.temperature if temperature is None else temperature,
|
|
95
|
+
logprobs=self.logprobs if logprobs is None else logprobs,
|
|
96
|
+
top_logprobs=self.top_logprobs if top_logprobs is None else top_logprobs,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def extract_keywords(
|
|
100
|
+
self,
|
|
101
|
+
text: str,
|
|
102
|
+
model: str | None = None,
|
|
103
|
+
user_prompt: str | None = None,
|
|
104
|
+
output_lang: str | None = None,
|
|
105
|
+
with_analysis: bool | None = None,
|
|
106
|
+
temperature: float | None = None,
|
|
107
|
+
logprobs: bool | None = None,
|
|
108
|
+
top_logprobs: int | None = None,
|
|
109
|
+
) -> dict[str, list[str]]:
|
|
110
|
+
"""
|
|
111
|
+
Extract salient keywords from text.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
text: Input string to analyze.
|
|
115
|
+
with_analysis: Whether to run an extra LLM reasoning step.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
{"result": [<keyword1>, <keyword2>, ...]}
|
|
119
|
+
"""
|
|
120
|
+
return self.operator.run(
|
|
121
|
+
# Internal parameters
|
|
122
|
+
prompt_file="keyword_extractor.yaml",
|
|
123
|
+
output_model=OutputModels.ListStrOutput,
|
|
124
|
+
resp_format="parse",
|
|
125
|
+
# User parameters
|
|
126
|
+
text=text,
|
|
127
|
+
model=self.model if model is None else model,
|
|
128
|
+
user_prompt=self.user_prompt if user_prompt is None else user_prompt,
|
|
129
|
+
output_lang=self.output_lang if output_lang is None else output_lang,
|
|
130
|
+
with_analysis=self.with_analysis
|
|
131
|
+
if with_analysis is None
|
|
132
|
+
else with_analysis,
|
|
133
|
+
temperature=self.temperature if temperature is None else temperature,
|
|
134
|
+
logprobs=self.logprobs if logprobs is None else logprobs,
|
|
135
|
+
top_logprobs=self.top_logprobs if top_logprobs is None else top_logprobs,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
def extract_entities(
|
|
139
|
+
self,
|
|
140
|
+
text: str,
|
|
141
|
+
model: str | None = None,
|
|
142
|
+
user_prompt: str | None = None,
|
|
143
|
+
output_lang: str | None = None,
|
|
144
|
+
with_analysis: bool | None = None,
|
|
145
|
+
temperature: float | None = None,
|
|
146
|
+
logprobs: bool | None = None,
|
|
147
|
+
top_logprobs: int | None = None,
|
|
148
|
+
) -> dict[str, list[dict[str, str]]]:
|
|
149
|
+
"""
|
|
150
|
+
Perform Named Entity Recognition (NER) over the input text.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
text: Input string.
|
|
154
|
+
with_analysis: Whether to run an extra LLM reasoning step.
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
{"result": [{"text": <entity>, "type": <entity_type>}, ...]}
|
|
158
|
+
"""
|
|
159
|
+
return self.operator.run(
|
|
160
|
+
# Internal parameters
|
|
161
|
+
prompt_file="ner_extractor.yaml",
|
|
162
|
+
output_model=OutputModels.ListDictStrStrOutput,
|
|
163
|
+
resp_format="parse",
|
|
164
|
+
# User parameters
|
|
165
|
+
text=text,
|
|
166
|
+
model=self.model if model is None else model,
|
|
167
|
+
user_prompt=self.user_prompt if user_prompt is None else user_prompt,
|
|
168
|
+
output_lang=self.output_lang if output_lang is None else output_lang,
|
|
169
|
+
with_analysis=self.with_analysis
|
|
170
|
+
if with_analysis is None
|
|
171
|
+
else with_analysis,
|
|
172
|
+
temperature=self.temperature if temperature is None else temperature,
|
|
173
|
+
logprobs=self.logprobs if logprobs is None else logprobs,
|
|
174
|
+
top_logprobs=self.top_logprobs if top_logprobs is None else top_logprobs,
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
def detect_question(
|
|
178
|
+
self,
|
|
179
|
+
text: str,
|
|
180
|
+
model: str | None = None,
|
|
181
|
+
user_prompt: str | None = None,
|
|
182
|
+
with_analysis: bool | None = None,
|
|
183
|
+
temperature: float | None = None,
|
|
184
|
+
logprobs: bool | None = None,
|
|
185
|
+
top_logprobs: int | None = None,
|
|
186
|
+
) -> dict[str, bool]:
|
|
187
|
+
"""
|
|
188
|
+
Detect if the input is phrased as a question.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
question: Input string to evaluate.
|
|
192
|
+
with_analysis: Whether to include an analysis step.
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
{"result": "true"} or {"result": "false"}
|
|
196
|
+
"""
|
|
197
|
+
return self.operator.run(
|
|
198
|
+
# Internal parameters
|
|
199
|
+
prompt_file="question_detector.yaml",
|
|
200
|
+
output_model=OutputModels.BoolOutput,
|
|
201
|
+
resp_format="parse",
|
|
202
|
+
output_lang=False,
|
|
203
|
+
# User parameters
|
|
204
|
+
text=text,
|
|
205
|
+
model=self.model if model is None else model,
|
|
206
|
+
user_prompt=self.user_prompt if user_prompt is None else user_prompt,
|
|
207
|
+
with_analysis=self.with_analysis
|
|
208
|
+
if with_analysis is None
|
|
209
|
+
else with_analysis,
|
|
210
|
+
temperature=self.temperature if temperature is None else temperature,
|
|
211
|
+
logprobs=self.logprobs if logprobs is None else logprobs,
|
|
212
|
+
top_logprobs=self.top_logprobs if top_logprobs is None else top_logprobs,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
def generate_question_from_text(
|
|
216
|
+
self,
|
|
217
|
+
text: str,
|
|
218
|
+
model: str | None = None,
|
|
219
|
+
user_prompt: str | None = None,
|
|
220
|
+
output_lang: str | None = None,
|
|
221
|
+
with_analysis: bool | None = None,
|
|
222
|
+
temperature: float | None = None,
|
|
223
|
+
logprobs: bool | None = None,
|
|
224
|
+
top_logprobs: int | None = None,
|
|
225
|
+
) -> dict[str, str]:
|
|
226
|
+
"""
|
|
227
|
+
Generate a single question from the given text.
|
|
228
|
+
|
|
229
|
+
Args:
|
|
230
|
+
text: Source text to derive a question from.
|
|
231
|
+
with_analysis: Whether to use analysis before generation.
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
{"result": <generated_question>}
|
|
235
|
+
"""
|
|
236
|
+
return self.operator.run(
|
|
237
|
+
# Internal parameters
|
|
238
|
+
prompt_file="question_generator.yaml",
|
|
239
|
+
output_model=OutputModels.StrOutput,
|
|
240
|
+
resp_format="parse",
|
|
241
|
+
# User parameters
|
|
242
|
+
text=text,
|
|
243
|
+
model=self.model if model is None else model,
|
|
244
|
+
user_prompt=self.user_prompt if user_prompt is None else user_prompt,
|
|
245
|
+
output_lang=self.output_lang if output_lang is None else output_lang,
|
|
246
|
+
with_analysis=self.with_analysis
|
|
247
|
+
if with_analysis is None
|
|
248
|
+
else with_analysis,
|
|
249
|
+
temperature=self.temperature if temperature is None else temperature,
|
|
250
|
+
logprobs=self.logprobs if logprobs is None else logprobs,
|
|
251
|
+
top_logprobs=self.top_logprobs if top_logprobs is None else top_logprobs,
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
def merge_questions(
|
|
255
|
+
self,
|
|
256
|
+
questions: list[str],
|
|
257
|
+
mode: Literal["default", "reason"] = "default",
|
|
258
|
+
model: str | None = None,
|
|
259
|
+
user_prompt: str | None = None,
|
|
260
|
+
output_lang: str | None = None,
|
|
261
|
+
with_analysis: bool | None = None,
|
|
262
|
+
temperature: float | None = None,
|
|
263
|
+
logprobs: bool | None = None,
|
|
264
|
+
top_logprobs: int | None = None,
|
|
265
|
+
) -> dict[str, str]:
|
|
266
|
+
"""
|
|
267
|
+
Merge multiple questions into a single unified question.
|
|
268
|
+
|
|
269
|
+
Args:
|
|
270
|
+
questions: List of question strings.
|
|
271
|
+
mode: Merge strategy:
|
|
272
|
+
- "default": simple merging.
|
|
273
|
+
- "reason": merging with reasoning explanation.
|
|
274
|
+
with_analysis: Whether to use an analysis step.
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
{"result": <merged_question>}
|
|
278
|
+
"""
|
|
279
|
+
text = ", ".join(questions)
|
|
280
|
+
return self.operator.run(
|
|
281
|
+
# Internal parameters
|
|
282
|
+
prompt_file="question_merger.yaml",
|
|
283
|
+
output_model=OutputModels.StrOutput,
|
|
284
|
+
resp_format="parse",
|
|
285
|
+
# User parameters
|
|
286
|
+
text=text,
|
|
287
|
+
mode=mode,
|
|
288
|
+
model=self.model if model is None else model,
|
|
289
|
+
user_prompt=self.user_prompt if user_prompt is None else user_prompt,
|
|
290
|
+
output_lang=self.output_lang if output_lang is None else output_lang,
|
|
291
|
+
with_analysis=self.with_analysis
|
|
292
|
+
if with_analysis is None
|
|
293
|
+
else with_analysis,
|
|
294
|
+
temperature=self.temperature if temperature is None else temperature,
|
|
295
|
+
logprobs=self.logprobs if logprobs is None else logprobs,
|
|
296
|
+
top_logprobs=self.top_logprobs if top_logprobs is None else top_logprobs,
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
def rewrite(
|
|
300
|
+
self,
|
|
301
|
+
text: str,
|
|
302
|
+
mode: Literal["positive", "negative", "hard_negative"] = "positive",
|
|
303
|
+
model: str | None = None,
|
|
304
|
+
user_prompt: str | None = None,
|
|
305
|
+
output_lang: str | None = None,
|
|
306
|
+
with_analysis: bool | None = None,
|
|
307
|
+
temperature: float | None = None,
|
|
308
|
+
logprobs: bool | None = None,
|
|
309
|
+
top_logprobs: int | None = None,
|
|
310
|
+
) -> dict[str, str]:
|
|
311
|
+
"""
|
|
312
|
+
Rewrite a question with different wording or meaning.
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
question: Input question to rewrite.
|
|
316
|
+
mode: Rewrite strategy:
|
|
317
|
+
- "positive": keep meaning, change words.
|
|
318
|
+
- "negative": alter meaning, preserve wording style.
|
|
319
|
+
with_analysis: Whether to include an analysis step.
|
|
320
|
+
|
|
321
|
+
Returns:
|
|
322
|
+
{"result": <rewritten_question>}
|
|
323
|
+
"""
|
|
324
|
+
return self.operator.run(
|
|
325
|
+
# Internal parameters
|
|
326
|
+
prompt_file="rewriter.yaml",
|
|
327
|
+
output_model=OutputModels.StrOutput,
|
|
328
|
+
resp_format="parse",
|
|
329
|
+
# User parameters
|
|
330
|
+
text=text,
|
|
331
|
+
mode=mode,
|
|
332
|
+
model=self.model if model is None else model,
|
|
333
|
+
user_prompt=self.user_prompt if user_prompt is None else user_prompt,
|
|
334
|
+
output_lang=self.output_lang if output_lang is None else output_lang,
|
|
335
|
+
with_analysis=self.with_analysis
|
|
336
|
+
if with_analysis is None
|
|
337
|
+
else with_analysis,
|
|
338
|
+
temperature=self.temperature if temperature is None else temperature,
|
|
339
|
+
logprobs=self.logprobs if logprobs is None else logprobs,
|
|
340
|
+
top_logprobs=self.top_logprobs if top_logprobs is None else top_logprobs,
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
def generate_questions_from_subject(
|
|
344
|
+
self,
|
|
345
|
+
text: str,
|
|
346
|
+
number_of_questions: int,
|
|
347
|
+
model: str | None = None,
|
|
348
|
+
user_prompt: str | None = None,
|
|
349
|
+
output_lang: str | None = None,
|
|
350
|
+
with_analysis: bool | None = None,
|
|
351
|
+
temperature: float | None = None,
|
|
352
|
+
logprobs: bool | None = None,
|
|
353
|
+
top_logprobs: int | None = None,
|
|
354
|
+
) -> dict[str, list[str]]:
|
|
355
|
+
"""
|
|
356
|
+
Generate a list of questions about a subject.
|
|
357
|
+
|
|
358
|
+
Args:
|
|
359
|
+
subject: Topic of interest.
|
|
360
|
+
number_of_questions: Number of questions to produce.
|
|
361
|
+
language: Target language for generated questions.
|
|
362
|
+
with_analysis: Whether to include an analysis step.
|
|
363
|
+
|
|
364
|
+
Returns:
|
|
365
|
+
{"result": [<question1>, <question2>, ...]}
|
|
366
|
+
"""
|
|
367
|
+
return self.operator.run(
|
|
368
|
+
# Internal parameters
|
|
369
|
+
prompt_file="subject_question_generator.yaml",
|
|
370
|
+
output_model=OutputModels.ReasonListStrOutput,
|
|
371
|
+
resp_format="parse",
|
|
372
|
+
# User parameters
|
|
373
|
+
text=text,
|
|
374
|
+
number_of_questions=number_of_questions,
|
|
375
|
+
model=self.model if model is None else model,
|
|
376
|
+
user_prompt=self.user_prompt if user_prompt is None else user_prompt,
|
|
377
|
+
output_lang=self.output_lang if output_lang is None else output_lang,
|
|
378
|
+
with_analysis=self.with_analysis
|
|
379
|
+
if with_analysis is None
|
|
380
|
+
else with_analysis,
|
|
381
|
+
temperature=self.temperature if temperature is None else temperature,
|
|
382
|
+
logprobs=self.logprobs if logprobs is None else logprobs,
|
|
383
|
+
top_logprobs=self.top_logprobs if top_logprobs is None else top_logprobs,
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
def summarize(
|
|
387
|
+
self,
|
|
388
|
+
text: str,
|
|
389
|
+
model: str | None = None,
|
|
390
|
+
user_prompt: str | None = None,
|
|
391
|
+
output_lang: str | None = None,
|
|
392
|
+
with_analysis: bool | None = None,
|
|
393
|
+
temperature: float | None = None,
|
|
394
|
+
logprobs: bool | None = None,
|
|
395
|
+
top_logprobs: int | None = None,
|
|
396
|
+
) -> dict[str, str]:
|
|
397
|
+
"""
|
|
398
|
+
Summarize the given subject text.
|
|
399
|
+
|
|
400
|
+
Args:
|
|
401
|
+
subject: Input text to summarize.
|
|
402
|
+
with_analysis: Whether to include an analysis step.
|
|
403
|
+
|
|
404
|
+
Returns:
|
|
405
|
+
{"result": <summary>}
|
|
406
|
+
"""
|
|
407
|
+
return self.operator.run(
|
|
408
|
+
# Internal parameters
|
|
409
|
+
prompt_file="summarizer.yaml",
|
|
410
|
+
output_model=OutputModels.StrOutput,
|
|
411
|
+
resp_format="parse",
|
|
412
|
+
# User paramaeters
|
|
413
|
+
text=text,
|
|
414
|
+
model=self.model if model is None else model,
|
|
415
|
+
user_prompt=self.user_prompt if user_prompt is None else user_prompt,
|
|
416
|
+
output_lang=self.output_lang if output_lang is None else output_lang,
|
|
417
|
+
with_analysis=self.with_analysis
|
|
418
|
+
if with_analysis is None
|
|
419
|
+
else with_analysis,
|
|
420
|
+
temperature=self.temperature if temperature is None else temperature,
|
|
421
|
+
logprobs=self.logprobs if logprobs is None else logprobs,
|
|
422
|
+
top_logprobs=self.top_logprobs if top_logprobs is None else top_logprobs,
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
def translate(
|
|
426
|
+
self,
|
|
427
|
+
text: str,
|
|
428
|
+
target_language: str,
|
|
429
|
+
model: str | None = None,
|
|
430
|
+
user_prompt: str | None = None,
|
|
431
|
+
with_analysis: bool | None = None,
|
|
432
|
+
temperature: float | None = None,
|
|
433
|
+
logprobs: bool | None = None,
|
|
434
|
+
top_logprobs: int | None = None,
|
|
435
|
+
) -> dict[str, str]:
|
|
436
|
+
"""
|
|
437
|
+
Translate text between languages.
|
|
438
|
+
|
|
439
|
+
Args:
|
|
440
|
+
text: Input string to translate.
|
|
441
|
+
target_language: Language code or name to translate into.
|
|
442
|
+
with_analysis: Whether to include an analysis step.
|
|
443
|
+
|
|
444
|
+
Returns:
|
|
445
|
+
{"result": <translated_text>}
|
|
446
|
+
"""
|
|
447
|
+
return self.operator.run(
|
|
448
|
+
# Internal parameters
|
|
449
|
+
prompt_file="translator.yaml",
|
|
450
|
+
output_model=OutputModels.StrOutput,
|
|
451
|
+
resp_format="parse",
|
|
452
|
+
output_lang=False,
|
|
453
|
+
# User parameters
|
|
454
|
+
text=text,
|
|
455
|
+
target_language=target_language,
|
|
456
|
+
model=self.model if model is None else model,
|
|
457
|
+
user_prompt=self.user_prompt if user_prompt is None else user_prompt,
|
|
458
|
+
with_analysis=self.with_analysis
|
|
459
|
+
if with_analysis is None
|
|
460
|
+
else with_analysis,
|
|
461
|
+
temperature=self.temperature if temperature is None else temperature,
|
|
462
|
+
logprobs=self.logprobs if logprobs is None else logprobs,
|
|
463
|
+
top_logprobs=self.top_logprobs if top_logprobs is None else top_logprobs,
|
|
464
|
+
)
|
|
465
|
+
|
|
466
|
+
def custom_tool(
|
|
467
|
+
self,
|
|
468
|
+
prompt: str,
|
|
469
|
+
output_model: Any,
|
|
470
|
+
model: str | None = None,
|
|
471
|
+
output_lang: str | None = None,
|
|
472
|
+
temperature: float | None = None,
|
|
473
|
+
logprobs: float | None = None,
|
|
474
|
+
top_logprobs: int | None = None,
|
|
475
|
+
) -> dict[str, Any]:
|
|
476
|
+
"""
|
|
477
|
+
Custom tool that can do almost anything!
|
|
478
|
+
|
|
479
|
+
Args:
|
|
480
|
+
prompt: Custom prompt.
|
|
481
|
+
output_model: Custom BaseModel output model.
|
|
482
|
+
|
|
483
|
+
Returns:
|
|
484
|
+
{"result": <Any>}
|
|
485
|
+
"""
|
|
486
|
+
return self.operator.run(
|
|
487
|
+
# Internal parameters
|
|
488
|
+
prompt_file="custom_tool.yaml",
|
|
489
|
+
resp_format="parse",
|
|
490
|
+
user_prompt=False,
|
|
491
|
+
with_analysis=False,
|
|
492
|
+
# User paramaeters
|
|
493
|
+
text=prompt,
|
|
494
|
+
output_model=output_model,
|
|
495
|
+
output_model_str=output_model.model_json_schema(),
|
|
496
|
+
model=self.model if model is None else model,
|
|
497
|
+
output_lang=self.output_lang if output_lang is None else output_lang,
|
|
498
|
+
temperature=self.temperature if temperature is None else temperature,
|
|
499
|
+
logprobs=self.logprobs if logprobs is None else logprobs,
|
|
500
|
+
top_logprobs=self.top_logprobs if top_logprobs is None else top_logprobs,
|
|
501
|
+
)
|