dialectical-framework 0.7.4__tar.gz → 0.7.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/PKG-INFO +4 -3
  2. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/pyproject.toml +4 -4
  3. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/domain/cycle.py +1 -5
  4. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/wheel_builder_transition_calculator.py +9 -6
  5. dialectical_framework-0.7.6/src/dialectical_framework/protocols/polarity_extractor.py +101 -0
  6. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/protocols/ratable.py +14 -3
  7. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/concepts/polarity_extractor_basic.py +22 -2
  8. dialectical_framework-0.7.4/src/dialectical_framework/protocols/polarity_extractor.py +0 -55
  9. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/LICENSE +0 -0
  10. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/README.md +0 -0
  11. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/__init__.py +0 -0
  12. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/ai_dto/__init__.py +0 -0
  13. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/ai_dto/action_plan_dto.py +0 -0
  14. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/ai_dto/causal_cycle_assessment_dto.py +0 -0
  15. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/ai_dto/causal_cycle_dto.py +0 -0
  16. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/ai_dto/causal_cycles_deck_dto.py +0 -0
  17. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/ai_dto/constructive_convergence_transition_audit_dto.py +0 -0
  18. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/ai_dto/dialectical_component_dto.py +0 -0
  19. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/ai_dto/dialectical_components_deck_dto.py +0 -0
  20. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/ai_dto/dto_mapper.py +0 -0
  21. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/ai_dto/reciprocal_solution_dto.py +0 -0
  22. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/ai_dto/transition_summary_dto.py +0 -0
  23. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/__init__.py +0 -0
  24. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/consultant.py +0 -0
  25. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/decorator_action_reflection.py +0 -0
  26. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/decorator_discrete_spiral.py +0 -0
  27. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/decorator_discrete_spiral_audited.py +0 -0
  28. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/domain/__init__.py +0 -0
  29. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/domain/assessable_cycle.py +0 -0
  30. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/domain/interpretation.py +0 -0
  31. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/domain/rationale.py +0 -0
  32. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/domain/spiral.py +0 -0
  33. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/domain/transformation.py +0 -0
  34. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/domain/transition.py +0 -0
  35. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/domain/transition_cell_to_cell.py +0 -0
  36. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/domain/transition_segment_to_segment.py +0 -0
  37. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/strategic_consultant.py +0 -0
  38. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/think_action_reflection.py +0 -0
  39. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/think_constructive_convergence.py +0 -0
  40. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/analyst/think_constructive_convergence_auditor.py +0 -0
  41. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/brain.py +0 -0
  42. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/dialectical_reasoning.py +0 -0
  43. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/enums/__init__.py +0 -0
  44. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/enums/causality_type.py +0 -0
  45. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/enums/di.py +0 -0
  46. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/enums/dialectical_reasoning_mode.py +0 -0
  47. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/enums/predicate.py +0 -0
  48. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/protocols/__init__.py +0 -0
  49. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/protocols/assessable.py +0 -0
  50. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/protocols/causality_sequencer.py +0 -0
  51. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/protocols/content_fidelity_evaluator.py +0 -0
  52. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/protocols/has_brain.py +0 -0
  53. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/protocols/has_config.py +0 -0
  54. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/protocols/reloadable.py +0 -0
  55. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/protocols/thesis_extractor.py +0 -0
  56. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/settings.py +0 -0
  57. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/__init__.py +0 -0
  58. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/causality/__init__.py +0 -0
  59. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/causality/causality_sequencer_balanced.py +0 -0
  60. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/causality/causality_sequencer_desirable.py +0 -0
  61. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/causality/causality_sequencer_feasible.py +0 -0
  62. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/causality/causality_sequencer_realistic.py +0 -0
  63. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/concepts/__init__.py +0 -0
  64. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/concepts/thesis_extractor_basic.py +0 -0
  65. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/domain/__init__.py +0 -0
  66. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/domain/dialectical_analysis.py +0 -0
  67. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/domain/dialectical_component.py +0 -0
  68. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/domain/dialectical_components_deck.py +0 -0
  69. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/domain/directed_graph.py +0 -0
  70. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/domain/synthesis.py +0 -0
  71. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/domain/wheel.py +0 -0
  72. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/domain/wheel_segment.py +0 -0
  73. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/domain/wisdom_unit.py +0 -0
  74. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/polarity/__init__.py +0 -0
  75. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/polarity/polarity_reasoner.py +0 -0
  76. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/polarity/reason_fast.py +0 -0
  77. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/polarity/reason_fast_and_simple.py +0 -0
  78. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/polarity/reason_fast_polarized_conflict.py +0 -0
  79. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/reverse_engineer.py +0 -0
  80. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/synthesist/wheel_builder.py +0 -0
  81. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/utils/__init__.py +0 -0
  82. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/utils/dc_replace.py +0 -0
  83. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/utils/decompose_probability_uniformly.py +0 -0
  84. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/utils/dw_report.py +0 -0
  85. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/utils/extend_tpl.py +0 -0
  86. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/utils/gm.py +0 -0
  87. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/utils/is_async.py +0 -0
  88. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/utils/pm.py +0 -0
  89. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/utils/use_brain.py +0 -0
  90. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/validator/__init__.py +0 -0
  91. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/validator/basic_checks.py +0 -0
  92. {dialectical_framework-0.7.4 → dialectical_framework-0.7.6}/src/dialectical_framework/validator/check.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dialectical-framework
3
- Version: 0.7.4
3
+ Version: 0.7.6
4
4
  Summary: A dialectical framework for augmented intelligence. AI reasoning powered with dialectics supports humans in: system optimization (psychology, engineering, business, politics, etc.); dispute resolution (mediation, conflicts, negotiations, etc.); decision-making (dilemmas, challenging situations, win-win, etc.).
5
5
  License: MIT
6
6
  Keywords: dialectics,dialectical-reasoning,synthesis,thesis-antithesis,ai,artificial-intelligence,llm,reasoning-framework,philosophy,logic,argumentation,conflict-resolution,decision-making,critical-thinking,semantic-graph,mirascope,pydantic,wisdom-units,polarity-reasoning
@@ -28,8 +28,9 @@ Classifier: Topic :: Sociology
28
28
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
29
29
  Classifier: Topic :: Text Processing :: Linguistic
30
30
  Requires-Dist: dependency-injector (>=4.48.2,<5.0.0)
31
- Requires-Dist: mirascope[anthropic,azure,bedrock,langfuse,litellm,openai,tenacity] (>=1.25.6,<2.0.0)
32
- Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
31
+ Requires-Dist: litellm (>=1.79.3,<2.0.0)
32
+ Requires-Dist: mirascope[anthropic,azure,bedrock,langfuse,openai,tenacity] (>=1.25.7,<2.0.0)
33
+ Requires-Dist: python-dotenv (>=1.2.1,<2.0.0)
33
34
  Requires-Dist: tabulate (>=0.9.0,<0.10.0)
34
35
  Project-URL: Homepage, https://github.com/dialexity/dialectical-framework
35
36
  Project-URL: Repository, https://github.com/dialexity/dialectical-framework
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "dialectical-framework"
3
- version = "0.7.4"
3
+ version = "0.7.6"
4
4
  description = "A dialectical framework for augmented intelligence. AI reasoning powered with dialectics supports humans in: system optimization (psychology, engineering, business, politics, etc.); dispute resolution (mediation, conflicts, negotiations, etc.); decision-making (dilemmas, challenging situations, win-win, etc.)."
5
5
  authors = ["Evaldas Taroza <evaldas@dialexity.com>"]
6
6
  readme = "README.md"
@@ -48,14 +48,14 @@ mirascope = {extras = [
48
48
  "azure",
49
49
  "openai",
50
50
  "anthropic",
51
- "litellm",
52
51
  "bedrock",
53
52
  "langfuse",
54
53
  "tenacity"
55
- ], version = "^1.25.6"}
56
- python-dotenv = "^1.1.1"
54
+ ], version = "^1.25.7"}
55
+ python-dotenv = "^1.2.1"
57
56
  tabulate = "^0.9.0"
58
57
  dependency-injector = "^4.48.2"
58
+ litellm = "^1.79.3"
59
59
 
60
60
  [tool.poetry.group.dev.dependencies]
61
61
  pytest = "^8.4.1"
@@ -25,15 +25,11 @@ class Cycle(AssessableCycle[TransitionCellToCell]):
25
25
  causality_type: CausalityType = Field(
26
26
  ..., description="The type of causality in the cycle."
27
27
  )
28
+
28
29
  causality_direction: Literal["clockwise", "counterclockwise"] = Field(
29
30
  default="clockwise", description="The direction of causality in the ring."
30
31
  )
31
32
 
32
- argumentation: str = Field(
33
- default="",
34
- description="Circumstances or contexts where this cycle would be most applicable or useful.",
35
- )
36
-
37
33
  def __init__(
38
34
  self,
39
35
  dialectical_components: list[DialecticalComponent],
@@ -77,21 +77,24 @@ class WheelBuilderTransitionCalculator(WheelBuilder, ABC):
77
77
  self._take_transition(wheel=wheel, transition=tr)
78
78
  elif isinstance(at, list):
79
79
  # Calculate for some
80
+ if hasattr(self.decorated_builder, "calculate_transitions"):
81
+ await self.decorated_builder.calculate_transitions(
82
+ wheel=wheel, at=at
83
+ )
80
84
  for ref in at:
81
- if hasattr(self.decorated_builder, "calculate_transitions"):
82
- await self.decorated_builder.calculate_transitions(
83
- wheel=wheel, at=ref
84
- )
85
+ segment = wheel.wheel_segment_at(ref)
85
86
  # This is for subclasses to implement
86
- trs_i = await self._do_calculate_transitions(wheel=wheel, at=ref)
87
+ trs_i = await self._do_calculate_transitions(wheel=wheel, at=segment)
87
88
  for tr in trs_i:
88
89
  self._take_transition(wheel=wheel, transition=tr)
89
90
  else:
90
91
  # Calculate for one
91
92
  if hasattr(self.decorated_builder, "calculate_transitions"):
92
93
  await self.decorated_builder.calculate_transitions(wheel=wheel, at=at)
94
+
95
+ segment = wheel.wheel_segment_at(at)
93
96
  # This is for subclasses to implement
94
- trs = await self._do_calculate_transitions(wheel=wheel, at=at)
97
+ trs = await self._do_calculate_transitions(wheel=wheel, at=segment)
95
98
  for tr in trs:
96
99
  self._take_transition(wheel=wheel, transition=tr)
97
100
 
@@ -0,0 +1,101 @@
1
+ from abc import abstractmethod
2
+ from typing import Union
3
+
4
+ from dialectical_framework.protocols.thesis_extractor import ThesisExtractor
5
+ from dialectical_framework.synthesist.domain.dialectical_component import DialecticalComponent
6
+ from dialectical_framework.synthesist.domain.dialectical_components_deck import DialecticalComponentsDeck
7
+
8
+
9
+ class PolarityExtractor(ThesisExtractor):
10
+ @abstractmethod
11
+ async def extract_polarities(
12
+ self,
13
+ *,
14
+ given: Union[str, list[str | None], list[tuple[str | None, str | None]]] = None,
15
+ at: None | int | list[int] = None,
16
+ not_like_these: list[str] | None = None
17
+ ) -> list[tuple[DialecticalComponent, DialecticalComponent]]:
18
+ """
19
+ Extract polarities (thesis-antithesis pairs) with optional selective generation.
20
+
21
+ This method provides flexible polarity extraction with support for partial inputs and
22
+ selective generation control. It intelligently generates missing components while avoiding
23
+ duplicates across the entire matrix.
24
+
25
+ Parameters
26
+ ----------
27
+ given : Union[str, list[str | None], list[tuple[str | None, str | None]]], optional
28
+ Input specification for polarities. Supports multiple formats:
29
+
30
+ **Simple formats:**
31
+ - `None` or `[]`: Generate a single complete polarity pair from scratch
32
+ - `"text"`: Use "text" as thesis, generate its antithesis
33
+
34
+ **List formats:**
35
+ - `["thesis1", "thesis2"]`: Each string becomes a thesis, generate antitheses
36
+ - `[None, "text"]`: Generate thesis for first, use "text" for second
37
+ - `[(None, None)]`: Generate one complete polarity pair
38
+ - `[("thesis", None)]`: Use provided thesis, generate antithesis
39
+ - `[(None, "antithesis")]`: Generate thesis (opposite) for provided antithesis
40
+ - `[("thesis", "antithesis")]`: Both provided, no generation needed
41
+
42
+ **Mixed formats:**
43
+ - `[("Love", None), (None, "Hate"), ("Peace", "War"), (None, None)]`
44
+ Handles any combination of complete, partial, or empty tuples
45
+
46
+ Maximum 4 polarities supported.
47
+
48
+ at : None | int | list[int], optional
49
+ Selective generation control (0-based indices):
50
+
51
+ - `None` (default): Generate ALL missing components across the matrix.
52
+ Returns complete polarities with no empty statements.
53
+
54
+ - `int` (e.g., `at=0`): Generate ONLY at that specific index.
55
+ Other indices preserve provided values but leave missing parts empty.
56
+
57
+ - `list[int]` (e.g., `at=[0, 2]`): Generate at multiple specific indices.
58
+ Only specified indices are completed; others remain incomplete.
59
+
60
+ **Deduplication:** When `at` is specified, all known statements from the
61
+ entire `given` matrix are passed as `not_like_these` to avoid duplicate
62
+ concepts during generation.
63
+
64
+ **Complete tuples:** If an index in `at` has both thesis and antithesis
65
+ already provided, no generation occurs—the tuple is simply preserved.
66
+
67
+ not_like_these: list[str] | None, optional
68
+ Some statements to hint that we don't need to generate them.
69
+
70
+ Returns
71
+ -------
72
+ list[tuple[DialecticalComponent, DialecticalComponent]]
73
+ List of (thesis, antithesis) tuples with proper aliases and indices.
74
+
75
+ **When `at=None` (default):**
76
+ All tuples are complete (no empty statements).
77
+
78
+ **When `at` is specified:**
79
+ - Indices in `at`: Complete tuples (both components have statements)
80
+ - Indices NOT in `at`: May contain empty components:
81
+ - `(DialecticalComponent(statement="thesis"), DialecticalComponent(statement=""))`
82
+ if only thesis was provided
83
+ - `(DialecticalComponent(statement=""), DialecticalComponent(statement="antithesis"))`
84
+ if only antithesis was provided
85
+ - `(DialecticalComponent(statement=""), DialecticalComponent(statement=""))`
86
+ if neither was provided
87
+
88
+ Raises
89
+ ------
90
+ IndexError
91
+ If any index in `at` is out of bounds (negative or >= length of `given`)
92
+ ValueError
93
+ If more than 4 polarities are requested
94
+ """
95
+ ...
96
+
97
+ @abstractmethod
98
+ async def extract_multiple_antitheses( self, *, theses: list[str], not_like_these: list[str] | None = None) -> DialecticalComponentsDeck: ...
99
+
100
+ @abstractmethod
101
+ async def extract_single_antithesis(self, *, thesis: str, not_like_these: list[str] | None = None) -> DialecticalComponent: ...
@@ -12,15 +12,26 @@ if TYPE_CHECKING:
12
12
  pass
13
13
 
14
14
  class Ratable(Assessable, ABC):
15
- model_config = ConfigDict(arbitrary_types_allowed=True)
15
+ model_config = ConfigDict(
16
+ arbitrary_types_allowed=True,
17
+ populate_by_name=True
18
+ )
16
19
 
17
20
  rating: float | None = Field(
18
21
  default=None, ge=0.0, le=1.0,
19
22
  description="Importance/quality rating."
20
23
  )
21
24
 
22
- manual_relevance: float | None = Field(default=None, description="Manual override for relevance")
23
- manual_probability: float | None = Field(default=None, description="Manual override for probability")
25
+ manual_relevance: float | None = Field(
26
+ default=None,
27
+ description="Manual override for relevance",
28
+ alias="relevance"
29
+ )
30
+ manual_probability: float | None = Field(
31
+ default=None,
32
+ description="Manual override for probability",
33
+ alias="probability"
34
+ )
24
35
 
25
36
  @computed_field
26
37
  @property
@@ -109,9 +109,28 @@ class PolarityExtractorBasic(ThesisExtractorBasic, PolarityExtractor):
109
109
  self,
110
110
  *,
111
111
  given: Union[str, list[str | None], list[tuple[str | None, str | None]]] = None,
112
- at: None | int | list[int] = None
112
+ at: None | int | list[int] = None,
113
+ not_like_these: list[str] | None = None
113
114
  ) -> list[tuple[DialecticalComponent, DialecticalComponent]]:
115
+ """
116
+ Implementation Notes
117
+ -------------------
118
+ 1. **Two-phase generation:** First generates missing theses for `(None, None)`
119
+ entries, then generates missing antitheses/opposites in batch.
120
+
121
+ 2. **Batch optimization:** Multiple missing components are generated in a single
122
+ AI call when possible for efficiency.
123
+
124
+ 3. **Alias assignment:** Components receive proper aliases:
125
+ - Single polarity: `T`, `A`
126
+ - Multiple polarities: `T1`, `A1`, `T2`, `A2`, etc.
114
127
 
128
+ 4. **Index tracking:** Each component tracks its human-friendly index (1-based)
129
+ for display purposes.
130
+
131
+ 5. **Safe with complete tuples:** Specifying an index in `at` with an already
132
+ complete tuple is harmless—it's preserved with no generation.
133
+ """
115
134
  if not given or len(given) == 0:
116
135
  given = None
117
136
 
@@ -146,7 +165,8 @@ class PolarityExtractorBasic(ThesisExtractorBasic, PolarityExtractor):
146
165
  )
147
166
 
148
167
  # Collect all provided statements to avoid duplicates
149
- not_like_these = []
168
+ if not_like_these is None:
169
+ not_like_these = []
150
170
  for thesis, antithesis in given:
151
171
  if thesis:
152
172
  not_like_these.append(thesis)
@@ -1,55 +0,0 @@
1
- from abc import abstractmethod
2
- from typing import Union
3
-
4
- from dialectical_framework.protocols.thesis_extractor import ThesisExtractor
5
- from dialectical_framework.synthesist.domain.dialectical_component import DialecticalComponent
6
- from dialectical_framework.synthesist.domain.dialectical_components_deck import DialecticalComponentsDeck
7
-
8
-
9
- class PolarityExtractor(ThesisExtractor):
10
- @abstractmethod
11
- async def extract_polarities(
12
- self,
13
- *,
14
- given: Union[str, list[str | None], list[tuple[str | None, str | None]]] = None,
15
- at: None | int | list[int] = None
16
- ) -> list[tuple[DialecticalComponent, DialecticalComponent]]:
17
- """
18
- Extract polarities (thesis-antithesis pairs) with optional selective generation.
19
-
20
- Args:
21
- given: Input specification for polarities:
22
- - None: Extract a single polarity
23
- - str: Extract a single polarity for that thesis
24
- - [str]: Extract a single polarity for that thesis
25
- - [None, str]: Extract two polarities for theses
26
- - [(None, None)]: Extract a single polarity
27
- - [(None, some_thesis)]: A thesis will be extracted
28
- - More tuples: All given theses/antitheses will be taken into account
29
-
30
- at: Selective generation control:
31
- - None (default): Generate all missing components in the given matrix
32
- - int: Generate only at that specific index (0-based)
33
- - list[int]: Generate only at those specific indices (0-based)
34
-
35
- When at is specified, all other known theses/antitheses from the given matrix
36
- are passed as not_like_these to avoid duplicates.
37
-
38
- Returns:
39
- List of (thesis, antithesis) tuples.
40
-
41
- When at=None (default): All tuples are complete (no None values).
42
- When at is specified: Only indices in 'at' are complete; other indices may contain:
43
- - (DialecticalComponent, DialecticalComponent(with statement="")) if only thesis was provided
44
- - (DialecticalComponent(with statement=""), DialecticalComponent) if only antithesis was provided
45
-
46
- Raises:
47
- IndexError: If any index in 'at' is out of bounds
48
- """
49
- ...
50
-
51
- @abstractmethod
52
- async def extract_multiple_antitheses( self, *, theses: list[str], not_like_these: list[str] | None = None) -> DialecticalComponentsDeck: ...
53
-
54
- @abstractmethod
55
- async def extract_single_antithesis(self, *, thesis: str, not_like_these: list[str] | None = None) -> DialecticalComponent: ...