hamtaa-texttools 0.1.44__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of hamtaa-texttools might be problematic. Click here for more details.
- hamtaa_texttools-1.0.0.dist-info/METADATA +129 -0
- hamtaa_texttools-1.0.0.dist-info/RECORD +17 -0
- hamtaa_texttools-1.0.0.dist-info/licenses/LICENSE +21 -0
- {hamtaa_texttools-0.1.44.dist-info → hamtaa_texttools-1.0.0.dist-info}/top_level.txt +0 -0
- texttools/__init__.py +4 -21
- texttools/formatters/base_formatter.py +33 -0
- texttools/formatters/user_merge_formatter/user_merge_formatter.py +47 -0
- texttools/tools/__init__.py +2 -32
- texttools/tools/operator.py +236 -0
- texttools/tools/output_models.py +54 -0
- texttools/tools/prompt_loader.py +84 -0
- texttools/tools/the_tool.py +291 -0
- texttools/utils/__init__.py +4 -0
- texttools/{batch_manager → utils/batch_manager}/__init__.py +2 -0
- texttools/{batch_manager → utils/batch_manager}/batch_manager.py +11 -12
- texttools/{batch_manager → utils/batch_manager}/batch_runner.py +20 -15
- hamtaa_texttools-0.1.44.dist-info/METADATA +0 -60
- hamtaa_texttools-0.1.44.dist-info/RECORD +0 -60
- texttools/base/__init__.py +0 -3
- texttools/base/base_categorizer.py +0 -40
- texttools/base/base_keyword_extractor.py +0 -35
- texttools/base/base_ner_extractor.py +0 -61
- texttools/base/base_question_detector.py +0 -35
- texttools/base/base_question_generator.py +0 -99
- texttools/base/base_question_merger.py +0 -59
- texttools/base/base_question_rewriter.py +0 -61
- texttools/base/base_router.py +0 -33
- texttools/base/base_summarizer.py +0 -55
- texttools/base/base_task_performer.py +0 -53
- texttools/base/base_translator.py +0 -38
- texttools/formatter/__init__.py +0 -1
- texttools/formatter/base.py +0 -26
- texttools/formatter/gemma3_formatter.py +0 -54
- texttools/handlers/__init__.py +0 -6
- texttools/handlers/categorizer/__init__.py +0 -6
- texttools/handlers/categorizer/categorizer.py +0 -61
- texttools/handlers/handlers.py +0 -88
- texttools/tools/categorizer/__init__.py +0 -2
- texttools/tools/categorizer/encoder_model/__init__.py +0 -1
- texttools/tools/categorizer/encoder_model/encoder_vectorizer.py +0 -51
- texttools/tools/categorizer/llm/__init__.py +0 -2
- texttools/tools/categorizer/llm/gemma_categorizer.py +0 -169
- texttools/tools/categorizer/llm/openai_categorizer.py +0 -80
- texttools/tools/keyword_extractor/__init__.py +0 -1
- texttools/tools/keyword_extractor/gemma_extractor.py +0 -138
- texttools/tools/merger/__init__.py +0 -2
- texttools/tools/merger/gemma_question_merger.py +0 -214
- texttools/tools/ner/__init__.py +0 -1
- texttools/tools/ner/gemma_ner_extractor.py +0 -157
- texttools/tools/question_detector/__init__.py +0 -2
- texttools/tools/question_detector/gemma_detector.py +0 -114
- texttools/tools/question_detector/llm_detector.py +0 -112
- texttools/tools/question_generator/__init__.py +0 -1
- texttools/tools/question_generator/gemma_question_generator.py +0 -198
- texttools/tools/reranker/__init__.py +0 -3
- texttools/tools/reranker/reranker.py +0 -137
- texttools/tools/reranker/scorer.py +0 -216
- texttools/tools/reranker/sorter.py +0 -278
- texttools/tools/rewriter/__init__.py +0 -2
- texttools/tools/rewriter/gemma_question_rewriter.py +0 -213
- texttools/tools/router/__init__.py +0 -0
- texttools/tools/router/gemma_router.py +0 -169
- texttools/tools/subject_to_question/__init__.py +0 -1
- texttools/tools/subject_to_question/gemma_question_generator.py +0 -224
- texttools/tools/summarizer/__init__.py +0 -2
- texttools/tools/summarizer/gemma_summarizer.py +0 -140
- texttools/tools/summarizer/llm_summerizer.py +0 -108
- texttools/tools/translator/__init__.py +0 -1
- texttools/tools/translator/gemma_translator.py +0 -202
- {hamtaa_texttools-0.1.44.dist-info → hamtaa_texttools-1.0.0.dist-info}/WHEEL +0 -0
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from abc import ABC, abstractmethod
|
|
3
|
-
from enum import Enum
|
|
4
|
-
from typing import Optional
|
|
5
|
-
|
|
6
|
-
from texttools.handlers import NoOpResultHandler, ResultHandler
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class BaseCategorizer(ABC):
|
|
10
|
-
def __init__(
|
|
11
|
-
self,
|
|
12
|
-
handlers: Optional[list[ResultHandler]] = None,
|
|
13
|
-
):
|
|
14
|
-
"""
|
|
15
|
-
handlers: List of ResultHandler objects that will process results after categorization.
|
|
16
|
-
"""
|
|
17
|
-
self.handlers = handlers or [NoOpResultHandler()]
|
|
18
|
-
|
|
19
|
-
@abstractmethod
|
|
20
|
-
def categorize(self, text: str) -> Enum:
|
|
21
|
-
"""
|
|
22
|
-
Categorize the input text.
|
|
23
|
-
Must return one of the Enum members defined in self.categories.
|
|
24
|
-
"""
|
|
25
|
-
pass
|
|
26
|
-
|
|
27
|
-
def preprocess(self, text: str) -> str:
|
|
28
|
-
"""
|
|
29
|
-
Optional: Preprocess text before categorization.
|
|
30
|
-
"""
|
|
31
|
-
return text
|
|
32
|
-
|
|
33
|
-
def _dispatch(self, results: dict) -> None:
|
|
34
|
-
for handler in self.handlers:
|
|
35
|
-
try:
|
|
36
|
-
handler.handle(results)
|
|
37
|
-
except Exception:
|
|
38
|
-
logging.error(
|
|
39
|
-
f"Handler {handler.__class__.__name__} failed", exc_info=True
|
|
40
|
-
)
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Any, Optional
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class BaseKeywordExtractor(ABC):
|
|
6
|
-
"""
|
|
7
|
-
Base class for all detectors that output a list of keywords.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
def __init__(
|
|
11
|
-
self,
|
|
12
|
-
handlers: Optional[list[Any]] = None,
|
|
13
|
-
):
|
|
14
|
-
self.handlers = handlers or []
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
def extract_keywords(self, text: str) -> list[str]:
|
|
18
|
-
"""
|
|
19
|
-
Extract keywords from the input text.
|
|
20
|
-
Should return a list of strings, where each string is a keyword.
|
|
21
|
-
"""
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
def preprocess(self, text: str) -> str:
|
|
25
|
-
"""
|
|
26
|
-
Optional text preprocessing step.
|
|
27
|
-
"""
|
|
28
|
-
return text.strip()
|
|
29
|
-
|
|
30
|
-
def _dispatch(self, result: dict) -> None:
|
|
31
|
-
"""
|
|
32
|
-
Dispatch the result to handlers.
|
|
33
|
-
"""
|
|
34
|
-
for handler in self.handlers:
|
|
35
|
-
handler.handle(result)
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from abc import ABC, abstractmethod
|
|
3
|
-
from typing import Any, Optional
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class BaseNERExtractor(ABC):
|
|
7
|
-
"""
|
|
8
|
-
Base class for all Named Entity Recognition (NER) systems.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
def __init__(self, handlers: Optional[list[Any]] = None):
|
|
12
|
-
"""
|
|
13
|
-
Initializes the BaseNERExtractor with optional result handlers.
|
|
14
|
-
|
|
15
|
-
:param handlers: Optional list of handlers to process the NER results.
|
|
16
|
-
"""
|
|
17
|
-
self.handlers = handlers or []
|
|
18
|
-
|
|
19
|
-
@abstractmethod
|
|
20
|
-
def extract_entities(self, text: str) -> list[dict[str, str]]:
|
|
21
|
-
"""
|
|
22
|
-
Extracts named entities from the input text.
|
|
23
|
-
|
|
24
|
-
:param text: The text from which to extract entities.
|
|
25
|
-
:return: A list of dictionaries, where each dictionary represents an entity
|
|
26
|
-
and typically includes 'text' and 'type' keys (e.g.,
|
|
27
|
-
[{"text": "John Doe", "type": "PERSON"}, ...]).
|
|
28
|
-
"""
|
|
29
|
-
pass
|
|
30
|
-
|
|
31
|
-
def preprocess(self, text: str) -> str:
|
|
32
|
-
"""
|
|
33
|
-
Optional: Preprocess the input text before entity extraction.
|
|
34
|
-
|
|
35
|
-
:param text: Raw input text.
|
|
36
|
-
:return: Preprocessed text.
|
|
37
|
-
"""
|
|
38
|
-
return text.strip()
|
|
39
|
-
|
|
40
|
-
def _dispatch(
|
|
41
|
-
self, entities: list[dict[str, str]], original_text: Optional[str] = None
|
|
42
|
-
) -> None:
|
|
43
|
-
"""
|
|
44
|
-
Sends the extracted entities to any registered result handlers.
|
|
45
|
-
|
|
46
|
-
:param entities: The list of extracted entities.
|
|
47
|
-
:param original_text: Optionally pass the original text.
|
|
48
|
-
"""
|
|
49
|
-
result_data = {
|
|
50
|
-
"entities": entities,
|
|
51
|
-
}
|
|
52
|
-
if original_text is not None:
|
|
53
|
-
result_data["original_text"] = original_text
|
|
54
|
-
|
|
55
|
-
for handler in self.handlers:
|
|
56
|
-
try:
|
|
57
|
-
handler.handle(result_data)
|
|
58
|
-
except Exception:
|
|
59
|
-
logging.error(
|
|
60
|
-
f"Handler {handler.__class__.__name__} failed", exc_info=True
|
|
61
|
-
)
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Any, Optional
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class BaseQuestionDetector(ABC):
|
|
6
|
-
"""
|
|
7
|
-
Base class for all detectors that output a boolean (True/False).
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
def __init__(
|
|
11
|
-
self,
|
|
12
|
-
handlers: Optional[list[Any]] = None,
|
|
13
|
-
):
|
|
14
|
-
self.handlers = handlers or []
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
def detect(self, text: str) -> bool:
|
|
18
|
-
"""
|
|
19
|
-
Detect if the input text meets the condition.
|
|
20
|
-
Should return True or False.
|
|
21
|
-
"""
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
def preprocess(self, text: str) -> str:
|
|
25
|
-
"""
|
|
26
|
-
Optional text preprocessing step.
|
|
27
|
-
"""
|
|
28
|
-
return text.strip()
|
|
29
|
-
|
|
30
|
-
def _dispatch(self, result: dict) -> None:
|
|
31
|
-
"""
|
|
32
|
-
Dispatch the result to handlers.
|
|
33
|
-
"""
|
|
34
|
-
for handler in self.handlers:
|
|
35
|
-
handler.handle(result)
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from abc import ABC, abstractmethod
|
|
3
|
-
from typing import Any, Optional
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class BaseQuestionGenerator(ABC):
|
|
7
|
-
"""
|
|
8
|
-
Base class for all systems that generate a question from a given answer.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
def __init__(self, handlers: Optional[list[Any]] = None):
|
|
12
|
-
"""
|
|
13
|
-
Initializes the BaseQuestionGenerator with optional result handlers.
|
|
14
|
-
|
|
15
|
-
:param handlers: Optional list of handlers to process the generation results.
|
|
16
|
-
"""
|
|
17
|
-
self.handlers = handlers or []
|
|
18
|
-
|
|
19
|
-
@abstractmethod
|
|
20
|
-
def generate_question(self, answer: str) -> str:
|
|
21
|
-
"""
|
|
22
|
-
Generates an appropriate question for the provided answer.
|
|
23
|
-
|
|
24
|
-
:param answer: The answer string for which a question needs to be generated.
|
|
25
|
-
:return: The generated question string.
|
|
26
|
-
"""
|
|
27
|
-
pass
|
|
28
|
-
|
|
29
|
-
def preprocess(self, text: str) -> str:
|
|
30
|
-
"""
|
|
31
|
-
Optional: Preprocess the input answer text before question generation.
|
|
32
|
-
|
|
33
|
-
:param text: Raw input answer text.
|
|
34
|
-
:return: Preprocessed text.
|
|
35
|
-
"""
|
|
36
|
-
return text.strip()
|
|
37
|
-
|
|
38
|
-
def _dispatch(self, result_data: dict) -> None:
|
|
39
|
-
"""
|
|
40
|
-
Sends the generated question and original answer to any registered result handlers.
|
|
41
|
-
|
|
42
|
-
:param result_data: A dictionary containing the results (e.g., {"original_answer": ..., "generated_question": ...}).
|
|
43
|
-
"""
|
|
44
|
-
for handler in self.handlers:
|
|
45
|
-
try:
|
|
46
|
-
handler.handle(result_data)
|
|
47
|
-
except Exception:
|
|
48
|
-
logging.error(
|
|
49
|
-
f"Handler {handler.__class__.__name__} failed", exc_info=True
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class BaseQuestionGeneratorFromSubject(ABC):
|
|
54
|
-
"""
|
|
55
|
-
Base class for all systems that generate a question from a given subject
|
|
56
|
-
it will curate some number of questions
|
|
57
|
-
|
|
58
|
-
"""
|
|
59
|
-
|
|
60
|
-
def __init__(self, handlers: Optional[list[Any]] = None):
|
|
61
|
-
"""
|
|
62
|
-
Initializes the BaseQuestionGeneratorFromSubject with optional result handlers.
|
|
63
|
-
|
|
64
|
-
:param handlers: Optional list of handlers to process the generation results.
|
|
65
|
-
"""
|
|
66
|
-
self.handlers = handlers or []
|
|
67
|
-
|
|
68
|
-
@abstractmethod
|
|
69
|
-
def generate_question(self, subject: str) -> str:
|
|
70
|
-
"""
|
|
71
|
-
Generates an appropriate question for the provided answer.
|
|
72
|
-
|
|
73
|
-
:param answer: The answer string for which a question needs to be generated.
|
|
74
|
-
:return: The generated question string.
|
|
75
|
-
"""
|
|
76
|
-
pass
|
|
77
|
-
|
|
78
|
-
def preprocess(self, text: str) -> str:
|
|
79
|
-
"""
|
|
80
|
-
Optional: Preprocess the input answer text before question generation.
|
|
81
|
-
|
|
82
|
-
:param text: Raw input answer text.
|
|
83
|
-
:return: Preprocessed text.
|
|
84
|
-
"""
|
|
85
|
-
return text.strip()
|
|
86
|
-
|
|
87
|
-
def _dispatch(self, result_data: dict) -> None:
|
|
88
|
-
"""
|
|
89
|
-
Sends the generated question and original answer to any registered result handlers.
|
|
90
|
-
|
|
91
|
-
:param result_data: A dictionary containing the results (e.g., {"original_answer": ..., "generated_question": ...}).
|
|
92
|
-
"""
|
|
93
|
-
for handler in self.handlers:
|
|
94
|
-
try:
|
|
95
|
-
handler.handle(result_data)
|
|
96
|
-
except Exception:
|
|
97
|
-
logging.error(
|
|
98
|
-
f"Handler {handler.__class__.__name__} failed", exc_info=True
|
|
99
|
-
)
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from abc import ABC, abstractmethod
|
|
3
|
-
from enum import Enum
|
|
4
|
-
from typing import Any, Optional
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class MergingMode(Enum):
|
|
8
|
-
"""
|
|
9
|
-
Defines the two modes for question merging.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
DEFAULT_MODE = "immediate merging"
|
|
13
|
-
REASON_MODE = "merging with reasoning"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class BaseQuestionsMerger(ABC):
|
|
17
|
-
"""
|
|
18
|
-
Base class for all systems that merges more that one question with preserving the contents.
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
def __init__(self, handlers: Optional[list[Any]] = None):
|
|
22
|
-
"""
|
|
23
|
-
Initializes the BaseQuestionsMerger with optional result handlers.
|
|
24
|
-
:param handlers: Optional list of handlers to process the merged results.
|
|
25
|
-
"""
|
|
26
|
-
self.handlers = handlers or []
|
|
27
|
-
|
|
28
|
-
@abstractmethod
|
|
29
|
-
def merging_question(self, questions: list[str], mode: MergingMode) -> str:
|
|
30
|
-
"""
|
|
31
|
-
merges the input questions based on the specified mode.
|
|
32
|
-
|
|
33
|
-
:param question: The original questions' string as a list.
|
|
34
|
-
:param mode: The MergingMode indicating how the questions should be merged.
|
|
35
|
-
:return: The rephrased and merged question string.
|
|
36
|
-
"""
|
|
37
|
-
pass
|
|
38
|
-
|
|
39
|
-
def preprocess(self, text: str) -> str:
|
|
40
|
-
"""
|
|
41
|
-
Optional: Preprocess the input questions' text before merging.
|
|
42
|
-
|
|
43
|
-
:param text: Raw input question's texts.
|
|
44
|
-
:return: Preprocessed text.
|
|
45
|
-
"""
|
|
46
|
-
return text.strip()
|
|
47
|
-
|
|
48
|
-
def _dispatch(self, result_data: dict) -> None:
|
|
49
|
-
"""
|
|
50
|
-
Sends the merged question and original questions to any registered result handlers.
|
|
51
|
-
:param result_data: A dictionary containing the results (e.g., {"original_question": ..., "rewritten_question": ..., "mode": ...}).
|
|
52
|
-
"""
|
|
53
|
-
for handler in self.handlers:
|
|
54
|
-
try:
|
|
55
|
-
handler.handle(result_data)
|
|
56
|
-
except Exception:
|
|
57
|
-
logging.error(
|
|
58
|
-
f"Handler {handler.__class__.__name__} failed", exc_info=True
|
|
59
|
-
)
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from abc import ABC, abstractmethod
|
|
3
|
-
from enum import Enum
|
|
4
|
-
from typing import Any, Optional
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class RewriteMode(Enum):
|
|
8
|
-
"""
|
|
9
|
-
Defines the two modes for question rewriting.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
SAME_MEANING_DIFFERENT_WORDING = "same_meaning_different_wording"
|
|
13
|
-
DIFFERENT_MEANING_SIMILAR_WORDING = "different_meaning_similar_wording"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class BaseQuestionRewriter(ABC):
|
|
17
|
-
"""
|
|
18
|
-
Base class for all systems that rewrite a question with different wording.
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
def __init__(self, handlers: Optional[list[Any]] = None):
|
|
22
|
-
"""
|
|
23
|
-
Initializes the BaseQuestionRewriter with optional result handlers.
|
|
24
|
-
|
|
25
|
-
:param handlers: Optional list of handlers to process the rewriting results.
|
|
26
|
-
"""
|
|
27
|
-
self.handlers = handlers or []
|
|
28
|
-
|
|
29
|
-
@abstractmethod
|
|
30
|
-
def rewrite_question(self, question: str, mode: RewriteMode) -> str:
|
|
31
|
-
"""
|
|
32
|
-
Rewrites the input question based on the specified mode.
|
|
33
|
-
|
|
34
|
-
:param question: The original question string.
|
|
35
|
-
:param mode: The RewriteMode indicating how the question should be rewritten.
|
|
36
|
-
:return: The rephrased question string.
|
|
37
|
-
"""
|
|
38
|
-
pass
|
|
39
|
-
|
|
40
|
-
def preprocess(self, text: str) -> str:
|
|
41
|
-
"""
|
|
42
|
-
Optional: Preprocess the input question text before rewriting.
|
|
43
|
-
|
|
44
|
-
:param text: Raw input question text.
|
|
45
|
-
:return: Preprocessed text.
|
|
46
|
-
"""
|
|
47
|
-
return text.strip()
|
|
48
|
-
|
|
49
|
-
def _dispatch(self, result_data: dict) -> None:
|
|
50
|
-
"""
|
|
51
|
-
Sends the rewritten question and original question to any registered result handlers.
|
|
52
|
-
|
|
53
|
-
:param result_data: A dictionary containing the results (e.g., {"original_question": ..., "rewritten_question": ..., "mode": ...}).
|
|
54
|
-
"""
|
|
55
|
-
for handler in self.handlers:
|
|
56
|
-
try:
|
|
57
|
-
handler.handle(result_data)
|
|
58
|
-
except Exception:
|
|
59
|
-
logging.error(
|
|
60
|
-
f"Handler {handler.__class__.__name__} failed", exc_info=True
|
|
61
|
-
)
|
texttools/base/base_router.py
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
|
-
from texttools.handlers import NoOpResultHandler, ResultHandler
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class BaseRouter(ABC):
|
|
8
|
-
def __init__(self, handlers: Optional[list[ResultHandler]] = None):
|
|
9
|
-
"""
|
|
10
|
-
Base class for routers
|
|
11
|
-
|
|
12
|
-
:param handlers: Optional list of handlers to process the summarization result.
|
|
13
|
-
"""
|
|
14
|
-
self.handlers = handlers or [NoOpResultHandler()]
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
def route(self, text: str) -> str:
|
|
18
|
-
"""
|
|
19
|
-
decides and classifies the inputted text between the choices that it has
|
|
20
|
-
|
|
21
|
-
:param text: The text to summarize.
|
|
22
|
-
:return: A route for the given text.
|
|
23
|
-
"""
|
|
24
|
-
pass
|
|
25
|
-
|
|
26
|
-
def preprocess(self, text: str) -> str:
|
|
27
|
-
"""
|
|
28
|
-
Optional: Preprocess the input text before summarization.
|
|
29
|
-
|
|
30
|
-
:param text: Raw input text.
|
|
31
|
-
:return: Preprocessed text.
|
|
32
|
-
"""
|
|
33
|
-
return text.strip()
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from abc import ABC, abstractmethod
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
|
-
from texttools.handlers import NoOpResultHandler, ResultHandler
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class BaseSummarizer(ABC):
|
|
9
|
-
def __init__(self, handlers: Optional[list[ResultHandler]] = None):
|
|
10
|
-
"""
|
|
11
|
-
Base class for text summarization.
|
|
12
|
-
|
|
13
|
-
:param handlers: Optional list of handlers to process the summarization result.
|
|
14
|
-
"""
|
|
15
|
-
self.handlers = handlers or [NoOpResultHandler()]
|
|
16
|
-
|
|
17
|
-
@abstractmethod
|
|
18
|
-
def summarize(self, text: str) -> str:
|
|
19
|
-
"""
|
|
20
|
-
Generate a summary for the input text.
|
|
21
|
-
|
|
22
|
-
:param text: The text to summarize.
|
|
23
|
-
:return: A summary string.
|
|
24
|
-
"""
|
|
25
|
-
pass
|
|
26
|
-
|
|
27
|
-
def preprocess(self, text: str) -> str:
|
|
28
|
-
"""
|
|
29
|
-
Optional: Preprocess the input text before summarization.
|
|
30
|
-
|
|
31
|
-
:param text: Raw input text.
|
|
32
|
-
:return: Preprocessed text.
|
|
33
|
-
"""
|
|
34
|
-
return text
|
|
35
|
-
|
|
36
|
-
def _dispatch(self, summary: str, original_text: Optional[str] = None) -> None:
|
|
37
|
-
"""
|
|
38
|
-
Send the summary result to any registered result handlers.
|
|
39
|
-
|
|
40
|
-
:param summary: The generated summary.
|
|
41
|
-
:param original_text: Optionally pass the original text.
|
|
42
|
-
"""
|
|
43
|
-
result_data = {
|
|
44
|
-
"summary": summary,
|
|
45
|
-
}
|
|
46
|
-
if original_text is not None:
|
|
47
|
-
result_data["original_text"] = original_text
|
|
48
|
-
|
|
49
|
-
for handler in self.handlers:
|
|
50
|
-
try:
|
|
51
|
-
handler.handle(result_data)
|
|
52
|
-
except Exception:
|
|
53
|
-
logging.error(
|
|
54
|
-
f"Handler {handler.__class__.__name__} failed", exc_info=True
|
|
55
|
-
)
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from abc import ABC, abstractmethod
|
|
3
|
-
from typing import Any, Optional
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class BaseTaskPerformer(ABC):
|
|
7
|
-
"""
|
|
8
|
-
Base class for common functionalities of LLM-based task performers.
|
|
9
|
-
This includes features like text preprocessing and dispatching results
|
|
10
|
-
to registered handlers.
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
def __init__(self, handlers: Optional[list[Any]] = None):
|
|
14
|
-
"""
|
|
15
|
-
Initializes the BaseTaskPerformer with optional result handlers.
|
|
16
|
-
|
|
17
|
-
:param handlers: An optional list of handlers to process the component's results.
|
|
18
|
-
"""
|
|
19
|
-
self.handlers = handlers or []
|
|
20
|
-
|
|
21
|
-
def _preprocess(self, text: str) -> str:
|
|
22
|
-
"""
|
|
23
|
-
Preprocesses input text by stripping leading/trailing whitespace.
|
|
24
|
-
This can be extended for more complex preprocessing if needed.
|
|
25
|
-
|
|
26
|
-
:param text: The raw input text.
|
|
27
|
-
:return: The preprocessed text.
|
|
28
|
-
"""
|
|
29
|
-
return text.strip()
|
|
30
|
-
|
|
31
|
-
@abstractmethod
|
|
32
|
-
def perform(self, *args, **kwargs) -> Any:
|
|
33
|
-
"""
|
|
34
|
-
Abstract method to be implemented by concrete task performers.
|
|
35
|
-
This method will execute the primary task of the class (e.g., scoring, sorting).
|
|
36
|
-
The signature of args and kwargs will vary based on the specific task.
|
|
37
|
-
"""
|
|
38
|
-
pass
|
|
39
|
-
|
|
40
|
-
def _dispatch(self, result_data: dict[str, Any]) -> None:
|
|
41
|
-
"""
|
|
42
|
-
Dispatches the component's results to any registered result handlers.
|
|
43
|
-
Each handler receives a dictionary of result data.
|
|
44
|
-
|
|
45
|
-
:param result_data: A dictionary containing the results specific to the component.
|
|
46
|
-
"""
|
|
47
|
-
for handler in self.handlers:
|
|
48
|
-
try:
|
|
49
|
-
handler.handle(result_data)
|
|
50
|
-
except Exception as e:
|
|
51
|
-
logging.error(
|
|
52
|
-
f"Handler {handler.__class__.__name__} failed: {e}", exc_info=True
|
|
53
|
-
)
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Any, Optional
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class BaseTranslator(ABC):
|
|
6
|
-
"""
|
|
7
|
-
Base class for all translators that output a translated string.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
def __init__(
|
|
11
|
-
self,
|
|
12
|
-
handlers: Optional[list[Any]] = None,
|
|
13
|
-
):
|
|
14
|
-
self.handlers = handlers or []
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
def translate(
|
|
18
|
-
self, text: str, target_language: str, source_language: Optional[str] = None
|
|
19
|
-
) -> str:
|
|
20
|
-
"""
|
|
21
|
-
Translate the input text from the source language to the target language.
|
|
22
|
-
Should return the translated string.
|
|
23
|
-
The source_language can be optional if the LLM can detect it automatically.
|
|
24
|
-
"""
|
|
25
|
-
pass
|
|
26
|
-
|
|
27
|
-
def preprocess(self, text: str) -> str:
|
|
28
|
-
"""
|
|
29
|
-
Optional text preprocessing step.
|
|
30
|
-
"""
|
|
31
|
-
return text.strip()
|
|
32
|
-
|
|
33
|
-
def _dispatch(self, result: dict) -> None:
|
|
34
|
-
"""
|
|
35
|
-
Dispatch the result to handlers.
|
|
36
|
-
"""
|
|
37
|
-
for handler in self.handlers:
|
|
38
|
-
handler.handle(result)
|
texttools/formatter/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .gemma3_formatter import Gemma3Formatter
|
texttools/formatter/base.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Any, Optional
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class ChatFormatter(ABC):
|
|
6
|
-
"""
|
|
7
|
-
Given (raw_text, reason, maybe other hints), produce whatever payload
|
|
8
|
-
A) single string prompt (for providers that don t support multiple messages), or
|
|
9
|
-
B) list of {role, content} dicts, or
|
|
10
|
-
C) whatever shape the provider needs.
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
@abstractmethod
|
|
14
|
-
def format(
|
|
15
|
-
self,
|
|
16
|
-
text: str,
|
|
17
|
-
reason: Optional[str],
|
|
18
|
-
schema_instr: str,
|
|
19
|
-
prompt_template: Optional[str],
|
|
20
|
-
) -> Any:
|
|
21
|
-
"""
|
|
22
|
-
- For an OpenAI style API, this might return list[{"role": "user"/"assistant", "content": "…"}].
|
|
23
|
-
- For a one shot “text only” API, this might return a single string combining everything.
|
|
24
|
-
- For some niche service, it might return JSON: {"inputs": […], "parameters": {…}}.
|
|
25
|
-
"""
|
|
26
|
-
pass
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
from texttools.formatter.base import ChatFormatter
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class Gemma3Formatter(ChatFormatter):
|
|
5
|
-
"""
|
|
6
|
-
Formatter that merges consecutive user messages (strings) with '\n'
|
|
7
|
-
and leaves assistant messages alone. No image‐handling, no extra tokens.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
ROLE = "role"
|
|
11
|
-
CONTENT = "content"
|
|
12
|
-
USER_ROLE = "user"
|
|
13
|
-
ASSISTANT_ROLE = "assistant"
|
|
14
|
-
VALID_ROLES = {USER_ROLE, ASSISTANT_ROLE}
|
|
15
|
-
VALID_KEYS = {ROLE, CONTENT}
|
|
16
|
-
|
|
17
|
-
def format(self, messages: list[dict[str, str]]) -> list[dict[str, str]]:
|
|
18
|
-
"""
|
|
19
|
-
:param messages: list of {"role": ..., "content": ...}, where role is "user", "assistant", or "system"
|
|
20
|
-
:return: a new list where consecutive "user" messages are merged into single entries
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
merged: list[dict[str, str]] = []
|
|
24
|
-
|
|
25
|
-
for message in messages:
|
|
26
|
-
# Validate keys strictly
|
|
27
|
-
if set(message.keys()) != self.VALID_KEYS:
|
|
28
|
-
raise ValueError(
|
|
29
|
-
f"Message dict keys must be exactly {self.VALID_KEYS}, got {set(message.keys())}"
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
role, content = message[self.ROLE], message[self.CONTENT].strip()
|
|
33
|
-
|
|
34
|
-
# Replace "system" role with "user" role
|
|
35
|
-
if role == "system":
|
|
36
|
-
role = self.USER_ROLE
|
|
37
|
-
|
|
38
|
-
# Raise value error if message["role"] wan't a valid role
|
|
39
|
-
if role not in self.VALID_ROLES:
|
|
40
|
-
raise ValueError(f"Unexpected role: {role}")
|
|
41
|
-
|
|
42
|
-
# Merge with previous user turn
|
|
43
|
-
if (
|
|
44
|
-
merged
|
|
45
|
-
and role == self.USER_ROLE
|
|
46
|
-
and merged[-1][self.ROLE] == self.USER_ROLE
|
|
47
|
-
):
|
|
48
|
-
merged[-1][self.CONTENT] += "\n" + content
|
|
49
|
-
|
|
50
|
-
# Otherwise, start a new turn
|
|
51
|
-
else:
|
|
52
|
-
merged.append({self.ROLE: role, self.CONTENT: content})
|
|
53
|
-
|
|
54
|
-
return merged
|
texttools/handlers/__init__.py
DELETED