hamtaa-texttools 0.1.43__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.

Files changed (70) hide show
  1. hamtaa_texttools-1.0.0.dist-info/METADATA +129 -0
  2. hamtaa_texttools-1.0.0.dist-info/RECORD +17 -0
  3. hamtaa_texttools-1.0.0.dist-info/licenses/LICENSE +21 -0
  4. {hamtaa_texttools-0.1.43.dist-info → hamtaa_texttools-1.0.0.dist-info}/top_level.txt +0 -0
  5. texttools/__init__.py +4 -21
  6. texttools/formatters/base_formatter.py +33 -0
  7. texttools/formatters/user_merge_formatter/user_merge_formatter.py +47 -0
  8. texttools/tools/__init__.py +2 -32
  9. texttools/tools/operator.py +236 -0
  10. texttools/tools/output_models.py +54 -0
  11. texttools/tools/prompt_loader.py +84 -0
  12. texttools/tools/the_tool.py +291 -0
  13. texttools/utils/__init__.py +4 -0
  14. texttools/{batch_manager → utils/batch_manager}/__init__.py +2 -0
  15. texttools/{batch_manager → utils/batch_manager}/batch_manager.py +11 -12
  16. texttools/{batch_manager → utils/batch_manager}/batch_runner.py +20 -15
  17. hamtaa_texttools-0.1.43.dist-info/METADATA +0 -60
  18. hamtaa_texttools-0.1.43.dist-info/RECORD +0 -60
  19. texttools/base/__init__.py +0 -3
  20. texttools/base/base_categorizer.py +0 -40
  21. texttools/base/base_keyword_extractor.py +0 -35
  22. texttools/base/base_ner_extractor.py +0 -61
  23. texttools/base/base_question_detector.py +0 -35
  24. texttools/base/base_question_generator.py +0 -99
  25. texttools/base/base_question_merger.py +0 -59
  26. texttools/base/base_question_rewriter.py +0 -61
  27. texttools/base/base_router.py +0 -33
  28. texttools/base/base_summarizer.py +0 -55
  29. texttools/base/base_task_performer.py +0 -53
  30. texttools/base/base_translator.py +0 -38
  31. texttools/formatter/__init__.py +0 -1
  32. texttools/formatter/base.py +0 -26
  33. texttools/formatter/gemma3_formatter.py +0 -51
  34. texttools/handlers/__init__.py +0 -6
  35. texttools/handlers/categorizer/__init__.py +0 -6
  36. texttools/handlers/categorizer/categorizer.py +0 -61
  37. texttools/handlers/handlers.py +0 -88
  38. texttools/tools/categorizer/__init__.py +0 -2
  39. texttools/tools/categorizer/encoder_model/__init__.py +0 -1
  40. texttools/tools/categorizer/encoder_model/encoder_vectorizer.py +0 -51
  41. texttools/tools/categorizer/llm/__init__.py +0 -2
  42. texttools/tools/categorizer/llm/gemma_categorizer.py +0 -169
  43. texttools/tools/categorizer/llm/openai_categorizer.py +0 -80
  44. texttools/tools/keyword_extractor/__init__.py +0 -1
  45. texttools/tools/keyword_extractor/gemma_extractor.py +0 -138
  46. texttools/tools/merger/__init__.py +0 -2
  47. texttools/tools/merger/gemma_question_merger.py +0 -214
  48. texttools/tools/ner/__init__.py +0 -1
  49. texttools/tools/ner/gemma_ner_extractor.py +0 -157
  50. texttools/tools/question_detector/__init__.py +0 -2
  51. texttools/tools/question_detector/gemma_detector.py +0 -130
  52. texttools/tools/question_detector/llm_detector.py +0 -112
  53. texttools/tools/question_generator/__init__.py +0 -1
  54. texttools/tools/question_generator/gemma_question_generator.py +0 -198
  55. texttools/tools/reranker/__init__.py +0 -3
  56. texttools/tools/reranker/reranker.py +0 -137
  57. texttools/tools/reranker/scorer.py +0 -216
  58. texttools/tools/reranker/sorter.py +0 -278
  59. texttools/tools/rewriter/__init__.py +0 -2
  60. texttools/tools/rewriter/gemma_question_rewriter.py +0 -213
  61. texttools/tools/router/__init__.py +0 -0
  62. texttools/tools/router/gemma_router.py +0 -169
  63. texttools/tools/subject_to_question/__init__.py +0 -1
  64. texttools/tools/subject_to_question/gemma_question_generator.py +0 -224
  65. texttools/tools/summarizer/__init__.py +0 -2
  66. texttools/tools/summarizer/gemma_summarizer.py +0 -140
  67. texttools/tools/summarizer/llm_summerizer.py +0 -108
  68. texttools/tools/translator/__init__.py +0 -1
  69. texttools/tools/translator/gemma_translator.py +0 -202
  70. {hamtaa_texttools-0.1.43.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
- )
@@ -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)
@@ -1 +0,0 @@
1
- from .gemma3_formatter import Gemma3Formatter
@@ -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,51 +0,0 @@
1
- from typing import Literal
2
-
3
- from texttools.formatter.base import ChatFormatter
4
-
5
-
6
- class Gemma3Formatter(ChatFormatter):
7
- """
8
- Formatter that merges consecutive user messages (strings) with '\n'
9
- and leaves assistant messages alone. No image‐handling, no extra tokens.
10
- """
11
-
12
- ROLE = "role"
13
- USER_ROLE = "user"
14
- ASSISTANT_ROLE = "assistant"
15
- CONTENT = "content"
16
- VALID_ROLES = {USER_ROLE, ASSISTANT_ROLE}
17
-
18
- def format(
19
- self, messages: list[dict[Literal["role", "content"], str]]
20
- ) -> list[dict[str, str]]:
21
- """
22
- :param messages: list of {"role": ..., "content": ...}, where role is "user", "assistant", or "system"
23
- :return: a new list where consecutive "user" messages are merged into single entries
24
- """
25
-
26
- merged: list[dict[str, str]] = []
27
-
28
- for msg in messages:
29
- role, content = msg[self.ROLE], msg[self.CONTENT].strip()
30
-
31
- # Replace "system" role with "user" role
32
- if role == "system":
33
- role = self.USER_ROLE
34
-
35
- # Raise value error if msg["role"] wan't a valid role
36
- if role not in self.VALID_ROLES:
37
- raise ValueError(f"Unexpected role: {role}")
38
-
39
- # Merge with previous user turn
40
- if (
41
- merged
42
- and role == self.USER_ROLE
43
- and merged[-1][self.ROLE] == self.USER_ROLE
44
- ):
45
- merged[-1][self.CONTENT] += "\n" + content
46
-
47
- # Otherwise, start a new turn
48
- else:
49
- merged.append({self.ROLE: role, self.CONTENT: content})
50
-
51
- return merged
@@ -1,6 +0,0 @@
1
- from .handlers import (
2
- NoOpResultHandler,
3
- PrintResultHandler,
4
- ResultHandler,
5
- SaveToFileResultHandler,
6
- )
@@ -1,6 +0,0 @@
1
- from .categorizer import (
2
- ResultHandler,
3
- NoOpResultHandler,
4
- PrintResultHandler,
5
- SaveToElasticResultHandler,
6
- )