dialectical-framework 0.6.5__tar.gz → 0.7.0__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.
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/PKG-INFO +3 -2
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/README.md +2 -2
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/pyproject.toml +1 -1
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/domain/cycle.py +1 -1
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/dialectical_reasoning.py +4 -2
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/enums/di.py +1 -1
- dialectical_framework-0.7.0/src/dialectical_framework/protocols/polarity_extractor.py +22 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/causality/causality_sequencer_balanced.py +1 -1
- dialectical_framework-0.7.0/src/dialectical_framework/synthesist/concepts/polarity_extractor_basic.py +264 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/concepts/thesis_extractor_basic.py +10 -9
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/polarity/polarity_reasoner.py +1 -1
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/wheel_builder.py +4 -3
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/LICENSE +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/__init__.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/ai_dto/__init__.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/ai_dto/action_plan_dto.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/ai_dto/causal_cycle_assessment_dto.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/ai_dto/causal_cycle_dto.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/ai_dto/causal_cycles_deck_dto.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/ai_dto/constructive_convergence_transition_audit_dto.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/ai_dto/dialectical_component_dto.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/ai_dto/dialectical_components_deck_dto.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/ai_dto/dto_mapper.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/ai_dto/reciprocal_solution_dto.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/ai_dto/transition_summary_dto.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/__init__.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/consultant.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/decorator_action_reflection.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/decorator_discrete_spiral.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/decorator_discrete_spiral_audited.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/domain/__init__.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/domain/assessable_cycle.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/domain/interpretation.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/domain/rationale.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/domain/spiral.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/domain/transformation.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/domain/transition.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/domain/transition_cell_to_cell.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/domain/transition_segment_to_segment.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/strategic_consultant.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/think_action_reflection.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/think_constructive_convergence.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/think_constructive_convergence_auditor.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/analyst/wheel_builder_transition_calculator.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/brain.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/enums/__init__.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/enums/causality_type.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/enums/dialectical_reasoning_mode.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/enums/predicate.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/protocols/__init__.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/protocols/assessable.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/protocols/causality_sequencer.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/protocols/content_fidelity_evaluator.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/protocols/has_brain.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/protocols/has_config.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/protocols/ratable.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/protocols/reloadable.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/protocols/thesis_extractor.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/settings.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/__init__.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/causality/__init__.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/causality/causality_sequencer_desirable.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/causality/causality_sequencer_feasible.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/causality/causality_sequencer_realistic.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/concepts/__init__.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/domain/__init__.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/domain/dialectical_analysis.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/domain/dialectical_component.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/domain/dialectical_components_deck.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/domain/directed_graph.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/domain/synthesis.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/domain/wheel.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/domain/wheel_segment.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/domain/wisdom_unit.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/polarity/__init__.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/polarity/reason_blind.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/polarity/reason_conversational.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/polarity/reason_fast.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/polarity/reason_fast_and_simple.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/polarity/reason_fast_polarized_conflict.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/synthesist/reverse_engineer.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/utils/__init__.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/utils/dc_replace.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/utils/decompose_probability_uniformly.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/utils/dw_report.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/utils/extend_tpl.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/utils/gm.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/utils/is_async.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/utils/pm.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/utils/use_brain.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/validator/__init__.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/validator/basic_checks.py +0 -0
- {dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/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.
|
|
3
|
+
Version: 0.7.0
|
|
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
|
|
@@ -35,7 +35,7 @@ Project-URL: Homepage, https://github.com/dialexity/dialectical-framework
|
|
|
35
35
|
Project-URL: Repository, https://github.com/dialexity/dialectical-framework
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
37
37
|
|
|
38
|
-
# Dialectical Framework
|
|
38
|
+
# Dialectical Reasoning Framework
|
|
39
39
|
Turn stories, strategies, or systems into insight. Auto-generate Dialectical Wheels (DWs) from any text to reveal blind spots, surface polarities, and trace dynamic paths toward synthesis.
|
|
40
40
|
DWs are semantic maps that expose tension, transformation, and coherence within a system—whether narrative, ethical, organizational, or technological.
|
|
41
41
|
|
|
@@ -132,3 +132,4 @@ Working beta product [Argument Inspector](https://dialexity.com/start). Useful f
|
|
|
132
132
|
|
|
133
133
|
### "Spiral" Lila game
|
|
134
134
|
In [this blog post](https://dialexity.com/blog/spiral-lila-with-character-traits/) we explain how the ancient Lila (Leela) game has been elevated to a new level.
|
|
135
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Dialectical Framework
|
|
1
|
+
# Dialectical Reasoning Framework
|
|
2
2
|
Turn stories, strategies, or systems into insight. Auto-generate Dialectical Wheels (DWs) from any text to reveal blind spots, surface polarities, and trace dynamic paths toward synthesis.
|
|
3
3
|
DWs are semantic maps that expose tension, transformation, and coherence within a system—whether narrative, ethical, organizational, or technological.
|
|
4
4
|
|
|
@@ -94,4 +94,4 @@ Working beta product [Argument Inspector](https://dialexity.com/start). Useful f
|
|
|
94
94
|
[The Atlas of Feelings](https://dialexity.com/blog/atlas-of-feelings-character-qualities/) is the Plutchik's wheel converted into the „vortex“ model, whereby the most gentle emotions are inside of the wheel, whereas the rudest are outside. As everything is interconnected with dialectical rules, we can understand human nature better.
|
|
95
95
|
|
|
96
96
|
### "Spiral" Lila game
|
|
97
|
-
In [this blog post](https://dialexity.com/blog/spiral-lila-with-character-traits/) we explain how the ancient Lila (Leela) game has been elevated to a new level.
|
|
97
|
+
In [this blog post](https://dialexity.com/blog/spiral-lila-with-character-traits/) we explain how the ancient Lila (Leela) game has been elevated to a new level.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "dialectical-framework"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.7.0"
|
|
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"
|
|
@@ -37,7 +37,7 @@ class Cycle(AssessableCycle[TransitionCellToCell]):
|
|
|
37
37
|
def __init__(
|
|
38
38
|
self,
|
|
39
39
|
dialectical_components: list[DialecticalComponent],
|
|
40
|
-
causality_type: CausalityType = CausalityType.
|
|
40
|
+
causality_type: CausalityType = CausalityType.BALANCED,
|
|
41
41
|
default_transition_probability: float | None = None,
|
|
42
42
|
**data,
|
|
43
43
|
):
|
|
@@ -7,6 +7,7 @@ from dialectical_framework.brain import Brain
|
|
|
7
7
|
from dialectical_framework.enums.causality_type import CausalityType
|
|
8
8
|
from dialectical_framework.protocols.causality_sequencer import \
|
|
9
9
|
CausalitySequencer
|
|
10
|
+
from dialectical_framework.protocols.polarity_extractor import PolarityExtractor
|
|
10
11
|
from dialectical_framework.protocols.thesis_extractor import ThesisExtractor
|
|
11
12
|
from dialectical_framework.settings import Settings
|
|
12
13
|
from dialectical_framework.synthesist.causality.causality_sequencer_balanced import \
|
|
@@ -17,6 +18,7 @@ from dialectical_framework.synthesist.causality.causality_sequencer_feasible imp
|
|
|
17
18
|
CausalitySequencerFeasible
|
|
18
19
|
from dialectical_framework.synthesist.causality.causality_sequencer_realistic import \
|
|
19
20
|
CausalitySequencerRealistic
|
|
21
|
+
from dialectical_framework.synthesist.concepts.polarity_extractor_basic import PolarityExtractorBasic
|
|
20
22
|
from dialectical_framework.synthesist.concepts.thesis_extractor_basic import \
|
|
21
23
|
ThesisExtractorBasic
|
|
22
24
|
from dialectical_framework.synthesist.polarity.polarity_reasoner import \
|
|
@@ -76,8 +78,8 @@ class DialecticalReasoning(containers.DeclarativeContainer):
|
|
|
76
78
|
settings=settings,
|
|
77
79
|
)
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
polarity_extractor: providers.Factory[PolarityExtractor] = providers.Factory(
|
|
82
|
+
PolarityExtractorBasic,
|
|
81
83
|
)
|
|
82
84
|
|
|
83
85
|
wheel_builder: providers.Factory[WheelBuilder] = providers.Factory(WheelBuilder)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
|
|
3
|
+
from dialectical_framework.protocols.thesis_extractor import ThesisExtractor
|
|
4
|
+
from dialectical_framework.synthesist.domain.dialectical_component import DialecticalComponent
|
|
5
|
+
from dialectical_framework.synthesist.domain.dialectical_components_deck import DialecticalComponentsDeck
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class PolarityExtractor(ThesisExtractor):
|
|
9
|
+
@abstractmethod
|
|
10
|
+
async def extract_polarities( self, *, given: list[tuple[str | None, str | None]]) -> list[tuple[DialecticalComponent, DialecticalComponent]]:
|
|
11
|
+
"""
|
|
12
|
+
Given tuple of (None, None) a single polarity will be extracted.
|
|
13
|
+
Given tuple of (None, some_thesis) a theses will be extracted.
|
|
14
|
+
Given more tuples, all the given theses/antitheses will be taken into account.
|
|
15
|
+
"""
|
|
16
|
+
...
|
|
17
|
+
|
|
18
|
+
@abstractmethod
|
|
19
|
+
async def extract_multiple_antitheses( self, *, theses: list[str], not_like_these: list[str] | None = None) -> DialecticalComponentsDeck: ...
|
|
20
|
+
|
|
21
|
+
@abstractmethod
|
|
22
|
+
async def extract_single_antithesis(self, *, thesis: str, not_like_these: list[str] | None = None) -> DialecticalComponent: ...
|
|
@@ -216,7 +216,7 @@ class CausalitySequencerBalanced(CausalitySequencer, HasBrain, SettingsAware):
|
|
|
216
216
|
CausalCycleDto(
|
|
217
217
|
aliases=[ordered_wisdom_units[0].t.alias, ordered_wisdom_units[0].a.alias],
|
|
218
218
|
probability=1.0,
|
|
219
|
-
reasoning_explanation="Single unit
|
|
219
|
+
reasoning_explanation="Single unit cycle",
|
|
220
220
|
argumentation="Default unit cycle"
|
|
221
221
|
)
|
|
222
222
|
]
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
from mirascope import Messages, prompt_template
|
|
2
|
+
from mirascope.integrations.langfuse import with_langfuse
|
|
3
|
+
|
|
4
|
+
from dialectical_framework.ai_dto.dialectical_component_dto import \
|
|
5
|
+
DialecticalComponentDto
|
|
6
|
+
from dialectical_framework.ai_dto.dialectical_components_deck_dto import \
|
|
7
|
+
DialecticalComponentsDeckDto
|
|
8
|
+
from dialectical_framework.ai_dto.dto_mapper import (map_from_dto,
|
|
9
|
+
map_list_from_dto)
|
|
10
|
+
from dialectical_framework.protocols.polarity_extractor import PolarityExtractor
|
|
11
|
+
from dialectical_framework.synthesist.concepts.thesis_extractor_basic import ThesisExtractorBasic
|
|
12
|
+
from dialectical_framework.synthesist.domain.dialectical_component import DialecticalComponent
|
|
13
|
+
from dialectical_framework.synthesist.domain.dialectical_components_deck import \
|
|
14
|
+
DialecticalComponentsDeck
|
|
15
|
+
from dialectical_framework.synthesist.domain.wheel_segment import ALIAS_T
|
|
16
|
+
from dialectical_framework.synthesist.domain.wisdom_unit import ALIAS_A
|
|
17
|
+
from dialectical_framework.utils.use_brain import use_brain
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class PolarityExtractorBasic(ThesisExtractorBasic, PolarityExtractor):
|
|
21
|
+
|
|
22
|
+
@prompt_template(
|
|
23
|
+
"""
|
|
24
|
+
MESSAGES:
|
|
25
|
+
{thesis_extraction}
|
|
26
|
+
|
|
27
|
+
ASSISTANT:
|
|
28
|
+
T = {thesis}
|
|
29
|
+
|
|
30
|
+
USER:
|
|
31
|
+
A dialectical opposition presents the conceptual or functional antithesis of the original statement that creates direct opposition, while potentially still allowing their mutual coexistence. For instance, Love vs. Hate or Indifference; Science vs. Superstition, Faith/Belief; Human-caused Global Warming vs. Natural Cycles.
|
|
32
|
+
|
|
33
|
+
Generate a dialectical opposition (A) of the thesis "{thesis}" (T). Be detailed enough to show deep understanding, yet concise enough to maintain clarity.
|
|
34
|
+
|
|
35
|
+
Output the dialectical component A within {component_length} word(s), the shorter, the better. Compose the explanation how it was derived in the passive voice. Don't mention any special denotations such as "T" or "A" in the explanation.
|
|
36
|
+
|
|
37
|
+
{rule_out}
|
|
38
|
+
"""
|
|
39
|
+
)
|
|
40
|
+
def prompt_single_antithesis(self, *, thesis: str, not_like_these: list[str] | None = None) -> Messages.Type:
|
|
41
|
+
rule_out = ""
|
|
42
|
+
|
|
43
|
+
if not_like_these:
|
|
44
|
+
rule_out = "**Rules**\nIMPORTANT: The output must be different than these already known theses:\n" + "\n".join(not_like_these)
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
"computed_fields": {
|
|
48
|
+
'thesis_extraction': self.prompt_single_thesis(),
|
|
49
|
+
"thesis": thesis,
|
|
50
|
+
"rule_out": rule_out,
|
|
51
|
+
"component_length": self.settings.component_length,
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@prompt_template(
|
|
56
|
+
"""
|
|
57
|
+
MESSAGES:
|
|
58
|
+
{theses_extraction}
|
|
59
|
+
|
|
60
|
+
ASSISTANT:
|
|
61
|
+
{theses}
|
|
62
|
+
|
|
63
|
+
USER:
|
|
64
|
+
A dialectical opposition presents the conceptual or functional antithesis of the original statement that creates direct opposition, while potentially still allowing their mutual coexistence. For instance, Love vs. Hate or Indifference; Science vs. Superstition, Faith/Belief; Human-caused Global Warming vs. Natural Cycles.
|
|
65
|
+
|
|
66
|
+
For each thesis, generate a dialectical opposition (A). Be detailed enough to show deep understanding, yet concise enough to maintain clarity.
|
|
67
|
+
|
|
68
|
+
**Output Format:**
|
|
69
|
+
A1 = [antithesis of T1 in 1-{component_length} words]
|
|
70
|
+
Explanation: [The explanation how it was derived in the passive voice]
|
|
71
|
+
|
|
72
|
+
A2 = [antithesis of T2 in 1-{component_length} words]
|
|
73
|
+
Explanation: [The explanation how it was derived in the passive voice]
|
|
74
|
+
|
|
75
|
+
...
|
|
76
|
+
|
|
77
|
+
Ax = [antithesis of Tx in 1-{component_length} words]
|
|
78
|
+
Explanation: [The explanation how it was derived in the passive voice]
|
|
79
|
+
|
|
80
|
+
**Rules**
|
|
81
|
+
Make sure to output {count} antitheses, i.e. one for each thesis, no more no less.
|
|
82
|
+
{rule_out}
|
|
83
|
+
"""
|
|
84
|
+
)
|
|
85
|
+
def prompt_multiple_antitheses(self, *, theses: list[str], not_like_these: list[str] | None = None) -> Messages.Type:
|
|
86
|
+
rule_out = ""
|
|
87
|
+
|
|
88
|
+
if not_like_these:
|
|
89
|
+
rule_out = "IMPORTANT: The output antitheses must be different than these already known theses/antitheses:\n" + "\n".join(
|
|
90
|
+
not_like_these)
|
|
91
|
+
|
|
92
|
+
theses_str = "\n".join(f"T{i + 1} = {thesis}" for i, thesis in enumerate(theses))
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
"computed_fields": {
|
|
96
|
+
"theses_extraction": self.prompt_multiple_theses(count=len(theses)),
|
|
97
|
+
"theses": theses_str,
|
|
98
|
+
"count": len(theses),
|
|
99
|
+
"rule_out": rule_out,
|
|
100
|
+
"component_length": self.settings.component_length,
|
|
101
|
+
},
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async def extract_polarities(self, *, given: list[tuple[str | None, str | None]]) \
|
|
105
|
+
-> list[tuple[DialecticalComponent, DialecticalComponent]]:
|
|
106
|
+
count = len(given)
|
|
107
|
+
if count > 4 or count < 1:
|
|
108
|
+
raise ValueError(
|
|
109
|
+
f"Incorrect number of polarities requested. Max 4 are supported."
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Collect all provided statements to avoid duplicates
|
|
113
|
+
not_like_these = []
|
|
114
|
+
for thesis, antithesis in given:
|
|
115
|
+
if thesis:
|
|
116
|
+
not_like_these.append(thesis)
|
|
117
|
+
if antithesis:
|
|
118
|
+
not_like_these.append(antithesis)
|
|
119
|
+
|
|
120
|
+
theses_to_find = []
|
|
121
|
+
theses_indices = []
|
|
122
|
+
|
|
123
|
+
# For every tuple that has both None, we want to first find theses
|
|
124
|
+
empty_count = 0
|
|
125
|
+
for i, (thesis, antithesis) in enumerate(given):
|
|
126
|
+
if thesis is None and antithesis is None:
|
|
127
|
+
empty_count += 1
|
|
128
|
+
theses_indices.append(i)
|
|
129
|
+
|
|
130
|
+
# Extract missing theses for empty positions
|
|
131
|
+
if empty_count == 1:
|
|
132
|
+
t = await self.extract_single_thesis(not_like_these=not_like_these)
|
|
133
|
+
not_like_these.append(t.statement)
|
|
134
|
+
theses_to_find = [t]
|
|
135
|
+
elif empty_count > 1:
|
|
136
|
+
ts = await self.extract_multiple_theses(count=empty_count, not_like_these=not_like_these)
|
|
137
|
+
not_like_these.extend(t.statement for t in ts.dialectical_components)
|
|
138
|
+
theses_to_find = ts.dialectical_components
|
|
139
|
+
|
|
140
|
+
# Initialize result list with placeholders
|
|
141
|
+
result: list[tuple[DialecticalComponent | None, DialecticalComponent | None]] = [(None, None) for _ in range(len(given))]
|
|
142
|
+
|
|
143
|
+
# Determine the index to use: 0 if only one tuple, otherwise 1-based index
|
|
144
|
+
def get_friendly_index(i: int) -> int:
|
|
145
|
+
return 0 if count == 1 else i + 1
|
|
146
|
+
|
|
147
|
+
# Helper to get the correct alias
|
|
148
|
+
def get_alias(base_alias: str, i: int) -> str:
|
|
149
|
+
return base_alias if count == 1 else f"{base_alias}{i + 1}"
|
|
150
|
+
|
|
151
|
+
# Fill in known statements and place found theses in correct positions
|
|
152
|
+
thesis_counter = 0
|
|
153
|
+
for i, (thesis, antithesis) in enumerate(given):
|
|
154
|
+
friendly_idx = get_friendly_index(i)
|
|
155
|
+
if thesis is not None and antithesis is not None:
|
|
156
|
+
# Both provided - just create components with correct aliases
|
|
157
|
+
t = DialecticalComponent(alias=get_alias(ALIAS_T, i), statement=thesis)
|
|
158
|
+
t.set_human_friendly_index(friendly_idx)
|
|
159
|
+
a = DialecticalComponent(alias=get_alias(ALIAS_A, i), statement=antithesis)
|
|
160
|
+
a.set_human_friendly_index(friendly_idx)
|
|
161
|
+
result[i] = (t, a)
|
|
162
|
+
elif thesis is not None:
|
|
163
|
+
# Thesis provided, need to find antithesis
|
|
164
|
+
t = DialecticalComponent(alias=get_alias(ALIAS_T, i), statement=thesis)
|
|
165
|
+
t.set_human_friendly_index(friendly_idx)
|
|
166
|
+
result[i] = (t, None)
|
|
167
|
+
elif antithesis is not None:
|
|
168
|
+
# Antithesis provided, need to find its opposite (which goes in thesis position)
|
|
169
|
+
a = DialecticalComponent(alias=get_alias(ALIAS_A, i), statement=antithesis)
|
|
170
|
+
a.set_human_friendly_index(friendly_idx)
|
|
171
|
+
result[i] = (None, a)
|
|
172
|
+
elif i in theses_indices:
|
|
173
|
+
# Both empty - use found thesis
|
|
174
|
+
t = theses_to_find[thesis_counter]
|
|
175
|
+
t.alias = get_alias(ALIAS_T, i)
|
|
176
|
+
t.set_human_friendly_index(friendly_idx)
|
|
177
|
+
result[i] = (t, None)
|
|
178
|
+
thesis_counter += 1
|
|
179
|
+
|
|
180
|
+
# Collect all statements that need opposites
|
|
181
|
+
statements_needing_opposites = []
|
|
182
|
+
indices_needing_opposites = []
|
|
183
|
+
is_thesis_position = [] # Track which position the opposite should go to
|
|
184
|
+
|
|
185
|
+
for i, (t, a) in enumerate(result):
|
|
186
|
+
if t is None:
|
|
187
|
+
# Need to find opposite for the provided antithesis
|
|
188
|
+
statements_needing_opposites.append(a.statement)
|
|
189
|
+
indices_needing_opposites.append(i)
|
|
190
|
+
is_thesis_position.append(True) # Opposite goes to thesis position
|
|
191
|
+
elif a is None:
|
|
192
|
+
# Need to find opposite for the provided thesis
|
|
193
|
+
statements_needing_opposites.append(t.statement)
|
|
194
|
+
indices_needing_opposites.append(i)
|
|
195
|
+
is_thesis_position.append(False) # Opposite goes to antithesis position
|
|
196
|
+
|
|
197
|
+
# Extract all opposites in one batch
|
|
198
|
+
if len(statements_needing_opposites) == 1:
|
|
199
|
+
opposite = await self.extract_single_antithesis(
|
|
200
|
+
thesis=statements_needing_opposites[0],
|
|
201
|
+
not_like_these=not_like_these
|
|
202
|
+
)
|
|
203
|
+
opposites = [opposite]
|
|
204
|
+
elif len(statements_needing_opposites) > 1:
|
|
205
|
+
deck = await self.extract_multiple_antitheses(
|
|
206
|
+
theses=statements_needing_opposites,
|
|
207
|
+
not_like_these=not_like_these
|
|
208
|
+
)
|
|
209
|
+
opposites = deck.dialectical_components
|
|
210
|
+
else:
|
|
211
|
+
opposites = []
|
|
212
|
+
|
|
213
|
+
# Place the opposites in the correct positions with correct aliases
|
|
214
|
+
for idx, opposite, is_t_pos in zip(indices_needing_opposites, opposites, is_thesis_position):
|
|
215
|
+
friendly_idx = get_friendly_index(idx)
|
|
216
|
+
if is_t_pos:
|
|
217
|
+
# Opposite goes to thesis position
|
|
218
|
+
opposite.alias = get_alias(ALIAS_T, idx)
|
|
219
|
+
opposite.set_human_friendly_index(friendly_idx)
|
|
220
|
+
result[idx] = (opposite, result[idx][1])
|
|
221
|
+
else:
|
|
222
|
+
# Opposite goes to antithesis position
|
|
223
|
+
opposite.alias = get_alias(ALIAS_A, idx)
|
|
224
|
+
opposite.set_human_friendly_index(friendly_idx)
|
|
225
|
+
result[idx] = (result[idx][0], opposite)
|
|
226
|
+
|
|
227
|
+
return result
|
|
228
|
+
|
|
229
|
+
async def extract_multiple_antitheses(self, *, theses: list[str], not_like_these: list[str] | None = None) \
|
|
230
|
+
-> DialecticalComponentsDeck:
|
|
231
|
+
count = len(theses)
|
|
232
|
+
|
|
233
|
+
@with_langfuse()
|
|
234
|
+
@use_brain(brain=self.brain, response_model=DialecticalComponentsDeckDto)
|
|
235
|
+
async def _find_antitheses():
|
|
236
|
+
return self.prompt_multiple_antitheses(theses=theses, not_like_these=not_like_these)
|
|
237
|
+
|
|
238
|
+
deck_dto = await _find_antitheses()
|
|
239
|
+
components = map_list_from_dto(deck_dto.dialectical_components, DialecticalComponent)
|
|
240
|
+
# It may happen that AI will return theses as well, so let's be prepared to filter out only the antitheses
|
|
241
|
+
antitheses = []
|
|
242
|
+
for dc in components:
|
|
243
|
+
if dc.alias.startswith(ALIAS_A):
|
|
244
|
+
antitheses.append(dc)
|
|
245
|
+
|
|
246
|
+
if len(antitheses) < count:
|
|
247
|
+
raise ValueError(f"AI returned {len(antitheses)} antitheses but {count} were requested.")
|
|
248
|
+
|
|
249
|
+
# Take only the requested count if AI returned more
|
|
250
|
+
deck = DialecticalComponentsDeck(dialectical_components=antitheses[:count])
|
|
251
|
+
if count == 1 and len(deck.dialectical_components) == 1:
|
|
252
|
+
dc: DialecticalComponent = deck.dialectical_components[0]
|
|
253
|
+
dc.set_human_friendly_index(0)
|
|
254
|
+
return deck
|
|
255
|
+
|
|
256
|
+
async def extract_single_antithesis(self, *, thesis: str, not_like_these: list[str] | None = None) \
|
|
257
|
+
-> DialecticalComponent:
|
|
258
|
+
@with_langfuse()
|
|
259
|
+
@use_brain(brain=self.brain, response_model=DialecticalComponentDto)
|
|
260
|
+
async def _find_antithesis():
|
|
261
|
+
return self.prompt_single_antithesis(thesis=thesis, not_like_these=not_like_these)
|
|
262
|
+
|
|
263
|
+
dc_dto = await _find_antithesis()
|
|
264
|
+
return map_from_dto(dc_dto, DialecticalComponent)
|
|
@@ -106,7 +106,7 @@ class ThesisExtractorBasic(ThesisExtractor, HasBrain, SettingsAware):
|
|
|
106
106
|
rule_out = ""
|
|
107
107
|
|
|
108
108
|
if not_like_these:
|
|
109
|
-
rule_out = "IMPORTANT: The output concepts must
|
|
109
|
+
rule_out = "IMPORTANT: The output concepts must be different than these already known theses:\n" + "\n".join(
|
|
110
110
|
not_like_these)
|
|
111
111
|
|
|
112
112
|
return {
|
|
@@ -129,14 +129,15 @@ class ThesisExtractorBasic(ThesisExtractor, HasBrain, SettingsAware):
|
|
|
129
129
|
async def _find_theses():
|
|
130
130
|
return self.prompt_multiple_theses(count=count, not_like_these=not_like_these)
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
132
|
+
deck_dto = await _find_theses()
|
|
133
|
+
components = map_list_from_dto(deck_dto.dialectical_components, DialecticalComponent)
|
|
134
|
+
if len(components) < count:
|
|
135
|
+
raise ValueError(f"AI returned {len(components)} components but {count} were requested.")
|
|
136
|
+
# Take only the requested count if AI returned more
|
|
137
|
+
deck = DialecticalComponentsDeck(dialectical_components=components[:count])
|
|
138
|
+
if count == 1 and len(deck.dialectical_components) == 1:
|
|
139
|
+
dc: DialecticalComponent = deck.dialectical_components[0]
|
|
140
|
+
dc.set_human_friendly_index(0)
|
|
140
141
|
return deck
|
|
141
142
|
|
|
142
143
|
async def extract_single_thesis(self, *, not_like_these: list[str] | None = None) -> DialecticalComponent:
|
|
@@ -108,7 +108,7 @@ class PolarityReasoner(HasBrain, Reloadable):
|
|
|
108
108
|
"""
|
|
109
109
|
A dialectical opposition presents the conceptual or functional antithesis of the original statement that creates direct opposition, while potentially still allowing their mutual coexistence. For instance, Love vs. Hate or Indifference; Science vs. Superstition, Faith/Belief; Human-caused Global Warming vs. Natural Cycles.
|
|
110
110
|
|
|
111
|
-
Generate a dialectical opposition (A) of the thesis "{thesis}" (T). Be detailed enough to show deep understanding, yet concise enough to maintain clarity.
|
|
111
|
+
Generate a dialectical opposition (A) of the thesis "{thesis}" (T). Be detailed enough to show deep understanding, yet concise enough to maintain clarity.
|
|
112
112
|
|
|
113
113
|
Output the dialectical component A within {component_length} word(s), the shorter, the better. Compose the explanation how it was derived in the passive voice. Don't mention any special denotations such as "T" or "A" in the explanation.
|
|
114
114
|
"""
|
|
@@ -7,6 +7,7 @@ from dependency_injector.wiring import Provide
|
|
|
7
7
|
from dialectical_framework.ai_dto.dto_mapper import (map_from_dto,
|
|
8
8
|
map_list_from_dto)
|
|
9
9
|
from dialectical_framework.analyst.domain.cycle import Cycle
|
|
10
|
+
from dialectical_framework.protocols.polarity_extractor import PolarityExtractor
|
|
10
11
|
from dialectical_framework.synthesist.domain.dialectical_component import DialecticalComponent
|
|
11
12
|
from dialectical_framework.synthesist.domain.dialectical_components_deck import \
|
|
12
13
|
DialecticalComponentsDeck
|
|
@@ -26,7 +27,7 @@ from dialectical_framework.synthesist.domain.wisdom_unit import WisdomUnit
|
|
|
26
27
|
class WheelBuilder(SettingsAware):
|
|
27
28
|
def __init__(
|
|
28
29
|
self,
|
|
29
|
-
|
|
30
|
+
polarity_extractor: PolarityExtractor = Provide[DI.polarity_extractor],
|
|
30
31
|
causality_sequencer: CausalitySequencer = Provide[DI.causality_sequencer],
|
|
31
32
|
polarity_reasoner: PolarityReasoner = Provide[DI.polarity_reasoner],
|
|
32
33
|
*,
|
|
@@ -38,7 +39,7 @@ class WheelBuilder(SettingsAware):
|
|
|
38
39
|
|
|
39
40
|
# TODO: reloading singletons isn't very good design here, because we're guessing the parameters...
|
|
40
41
|
|
|
41
|
-
self.__extractor =
|
|
42
|
+
self.__extractor = polarity_extractor
|
|
42
43
|
self.__extractor.reload(text=text)
|
|
43
44
|
|
|
44
45
|
self.__sequencer = causality_sequencer
|
|
@@ -56,7 +57,7 @@ class WheelBuilder(SettingsAware):
|
|
|
56
57
|
return self.__text
|
|
57
58
|
|
|
58
59
|
@property
|
|
59
|
-
def extractor(self) ->
|
|
60
|
+
def extractor(self) -> PolarityExtractor:
|
|
60
61
|
return self.__extractor
|
|
61
62
|
|
|
62
63
|
@property
|
|
File without changes
|
{dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/brain.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/settings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/utils/gm.py
RENAMED
|
File without changes
|
|
File without changes
|
{dialectical_framework-0.6.5 → dialectical_framework-0.7.0}/src/dialectical_framework/utils/pm.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|