dialectical-framework 1.6.1__tar.gz → 1.6.2__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-1.6.1 → dialectical_framework-1.6.2}/PKG-INFO +1 -1
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/pyproject.toml +1 -1
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/orchestrator/tools/inspect_node.py +11 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/causality/causality_estimator.py +13 -1
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/causality/causality_estimator_balanced.py +119 -54
- dialectical_framework-1.6.2/src/dialectical_framework/concerns/causality/causality_estimator_criteria.py +35 -0
- dialectical_framework-1.6.2/src/dialectical_framework/concerns/causality/causality_estimator_desirable.py +13 -0
- dialectical_framework-1.6.2/src/dialectical_framework/concerns/causality/causality_estimator_feasible.py +13 -0
- dialectical_framework-1.6.2/src/dialectical_framework/concerns/causality/causality_estimator_realistic.py +13 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/causality_estimation.py +85 -24
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/synthesis_generation.py +6 -2
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/transformation_generation.py +1 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/repositories/node_repository.py +41 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/utils/dc_replace.py +5 -4
- dialectical_framework-1.6.1/src/dialectical_framework/concerns/causality/causality_estimator_criteria.py +0 -71
- dialectical_framework-1.6.1/src/dialectical_framework/concerns/causality/causality_estimator_desirable.py +0 -50
- dialectical_framework-1.6.1/src/dialectical_framework/concerns/causality/causality_estimator_feasible.py +0 -50
- dialectical_framework-1.6.1/src/dialectical_framework/concerns/causality/causality_estimator_realistic.py +0 -50
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/LICENSE +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/README.md +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/advisor/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/advisor/advisor.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/advisor/system_prompts.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/advisor/tools/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/advisor/tools/anchor.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/advisor/tools/explore.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/advisor/tools/ingest.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/advisor/tools/sync.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/agent_context.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/analyst/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/analyst/analyst.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/analyst/skills/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/analyst/skills/anchor_theses.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/analyst/skills/edit_perspective.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/analyst/skills/expand_polarities.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/analyst/skills/find_polarities.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/analyst/skills/introduce_polarity.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/analyst/skills/surface_theses.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/analyst/system_prompts.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/analyst/tools/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/analyst/tools/create_dx_input.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/analyst/tools/place_statement.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/apps.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/conversation_facilitator.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/execution_report.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/explorer/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/explorer/explorer.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/explorer/skills/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/explorer/skills/build_wheels.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/explorer/skills/explore_transformations.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/explorer/skills/generate_synthesis.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/explorer/system_prompts.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/explorer/tools/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/explorer/tools/create_nexus.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/explorer/tools/expand_nexus.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/explorer/tools/generate_synthesis.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/explorer/tools/present_exploration.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/orchestrator/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/orchestrator/tools/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/orchestrator/tools/add_input.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/orchestrator/tools/digest_input.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/orchestrator/tools/discard.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/orchestrator/tools/get_schema.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/orchestrator/tools/present_analysis.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/orchestrator/tools/query_graph.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/orchestrator/tools/read_digest.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/orchestrator/tools/read_input.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/reasonable_concern.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/agents/stream_events.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/ac_re_taxonomy.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/action_extraction.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/add_input.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/ai_dto/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/ai_dto/statement_dto.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/ai_dto/statements_deck_dto.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/antithesis_classification.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/antithesis_extraction.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/aspect_classification.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/aspect_generation.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/causality/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/causality/causality_normalizer.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/causality/estimator_resolver.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/control_statements_check.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/create_dx_input.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/create_nexus.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/diagonal_oppositions_check.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/dialectical_context.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/discard.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/display_text_edit.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/expand_nexus.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/perspective_combination.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/perspective_validation.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/positive_ac_re_apex_derivation.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/scoring_scales.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/source_digest.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/statement_classification.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/statement_deduplication.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/statement_headline.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/statement_placement.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/thesis_extraction.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/concerns/transformation_audit.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/dialectical_reasoning.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/enums/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/enums/causality_preset.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/enums/di.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/events/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/events/graph_event.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/events/graph_event_bus.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/exceptions/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/exceptions/node_errors.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/exceptions/resolver_errors.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/composite_input_resolver.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/dialexity_input_resolver.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/estimation_manager.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/mixins/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/mixins/incremental_build_mixin.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/mixins/intent_mixin.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/mixins/persistable_mixin.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/assessable_entity.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/base_node.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/case.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/cycle.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/estimation.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/ideas.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/input.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/nexus.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/perspective.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/polarity.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/rationale.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/statement.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/synthesis.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/transformation.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/transition.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/nodes/wheel.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationship_manager.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/action_reflection_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/belongs_to_cycle_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/belongs_to_nexus_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/changed_to_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/contradiction_of_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/critiques_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/distilled_to_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/estimates_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/explains_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/has_input_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/has_statement_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/has_wheel_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/immutable_structure.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/is_source_of_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/is_target_of_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/negative_side_of_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/opposite_direction_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/opposite_of_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/polarity_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/positive_side_of_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/provides_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/relationships/synthesis_of_relationship.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/rendering.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/repositories/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/repositories/case_repository.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/repositories/cycle_repository.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/repositories/input_repository.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/repositories/nexus_repository.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/repositories/perspective_repository.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/repositories/polarity_repository.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/repositories/schema_repository.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/repositories/statement_repository.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/repositories/transformation_repository.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/repositories/wheel_repository.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/scope_context.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/verbatim_input_resolver.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/wheel_segment.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/graph/wheel_segment_polar_pair.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/protocols/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/protocols/has_config.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/protocols/input_resolver.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/settings.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/utils/__init__.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/utils/bedrock_provider.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/utils/concurrency.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/utils/decompose_probability_uniformly.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/utils/edge_context.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/utils/effect_logger.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/utils/input_context.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/utils/order_transitions.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/utils/sequence_generation.py +0 -0
- {dialectical_framework-1.6.1 → dialectical_framework-1.6.2}/src/dialectical_framework/utils/use_brain.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: dialectical-framework
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.2
|
|
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,perspectives,polarity-reasoning
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "dialectical-framework"
|
|
3
|
-
version = "1.6.
|
|
3
|
+
version = "1.6.2"
|
|
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"
|
|
@@ -431,6 +431,17 @@ def _inspect_wheel(wheel: Wheel) -> str:
|
|
|
431
431
|
spiral_seq = format_spiral(wheel, pp_index)
|
|
432
432
|
if spiral_seq:
|
|
433
433
|
lines.append(f"Spiral: {spiral_seq}")
|
|
434
|
+
|
|
435
|
+
# Per-edge causation (rationales attached to edge Transitions)
|
|
436
|
+
edge_causations = []
|
|
437
|
+
for edge in wheel.edges:
|
|
438
|
+
for rationale, _ in edge.rationales.all():
|
|
439
|
+
if rationale.text:
|
|
440
|
+
label = format_edge_label(edge, pp_index)
|
|
441
|
+
edge_causations.append(f" {label}: {rationale.text}")
|
|
442
|
+
if edge_causations:
|
|
443
|
+
lines.append("Step causation:")
|
|
444
|
+
lines.extend(edge_causations)
|
|
434
445
|
lines.append("")
|
|
435
446
|
|
|
436
447
|
# Parent cycle
|
|
@@ -11,7 +11,7 @@ The CausalityEstimation concern handles normalization and database persistence.
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
13
|
from abc import ABC, abstractmethod
|
|
14
|
-
from dataclasses import dataclass
|
|
14
|
+
from dataclasses import dataclass, field
|
|
15
15
|
from typing import TYPE_CHECKING, Union
|
|
16
16
|
|
|
17
17
|
if TYPE_CHECKING:
|
|
@@ -19,6 +19,17 @@ if TYPE_CHECKING:
|
|
|
19
19
|
from dialectical_framework.graph.nodes.wheel import Wheel
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
@dataclass
|
|
23
|
+
class StepCausation:
|
|
24
|
+
"""Per-step causal justification within a sequence (aliases resolved)."""
|
|
25
|
+
|
|
26
|
+
source_hash: str
|
|
27
|
+
target_hash: str
|
|
28
|
+
source_text: str
|
|
29
|
+
target_text: str
|
|
30
|
+
causation: str # Why source naturally leads to target
|
|
31
|
+
|
|
32
|
+
|
|
22
33
|
@dataclass
|
|
23
34
|
class EstimationStructured:
|
|
24
35
|
"""Raw AI estimation result for a single structure (Cycle or Wheel)."""
|
|
@@ -26,6 +37,7 @@ class EstimationStructured:
|
|
|
26
37
|
probability: float # Raw AI probability (0-1), NOT normalized
|
|
27
38
|
reasoning: str # Why this sequence might occur
|
|
28
39
|
argumentation: str # Circumstances where applicable
|
|
40
|
+
steps: list[StepCausation] = field(default_factory=list) # Per-step causation
|
|
29
41
|
|
|
30
42
|
|
|
31
43
|
class CausalityEstimator(ABC):
|
|
@@ -17,6 +17,7 @@ from dialectical_framework.graph.nodes.wheel import Wheel
|
|
|
17
17
|
from dialectical_framework.concerns.causality.causality_estimator import (
|
|
18
18
|
CausalityEstimator,
|
|
19
19
|
EstimationStructured,
|
|
20
|
+
StepCausation,
|
|
20
21
|
)
|
|
21
22
|
from dialectical_framework.protocols.input_resolver import InputResolver
|
|
22
23
|
|
|
@@ -24,7 +25,34 @@ from dialectical_framework.utils.dc_replace import dc_replace
|
|
|
24
25
|
from dialectical_framework.utils.use_brain import use_brain
|
|
25
26
|
|
|
26
27
|
|
|
28
|
+
class StepCausationDto(BaseModel):
|
|
29
|
+
from_alias: str = Field(
|
|
30
|
+
default="",
|
|
31
|
+
description="Technical alias of the step's source, exactly as given in the sequence (e.g. C1_1).",
|
|
32
|
+
)
|
|
33
|
+
to_alias: str = Field(
|
|
34
|
+
default="",
|
|
35
|
+
description="Technical alias of the step's target, exactly as given in the sequence (e.g. C1_2).",
|
|
36
|
+
)
|
|
37
|
+
causation: str = Field(
|
|
38
|
+
default="",
|
|
39
|
+
description=(
|
|
40
|
+
"One sentence: the causal mechanism why the source naturally leads to "
|
|
41
|
+
"the target. Use the actual statement wording, never aliases."
|
|
42
|
+
),
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
27
46
|
class CausalCycleAssessmentDto(BaseModel):
|
|
47
|
+
# steps comes FIRST: justifying each step before scoring is deliberate
|
|
48
|
+
# chain-of-thought — the holistic probability must be informed by them
|
|
49
|
+
steps: list[StepCausationDto] = Field(
|
|
50
|
+
default_factory=list,
|
|
51
|
+
description=(
|
|
52
|
+
"One entry per consecutive step of the sequence, in order, "
|
|
53
|
+
"including the final wrap-around step back to the first element."
|
|
54
|
+
),
|
|
55
|
+
)
|
|
28
56
|
probability: float = Field(
|
|
29
57
|
default=0,
|
|
30
58
|
description="The probability 0 to 1 of the arranged cycle to exist in reality.",
|
|
@@ -45,6 +73,61 @@ class CausalCycleDto(CausalCycleAssessmentDto):
|
|
|
45
73
|
)
|
|
46
74
|
|
|
47
75
|
|
|
76
|
+
def _resolve_steps(
|
|
77
|
+
step_dtos: list[StepCausationDto],
|
|
78
|
+
sequence: list[Statement],
|
|
79
|
+
seq_idx: int,
|
|
80
|
+
alias_translations: dict[str, str],
|
|
81
|
+
) -> list[StepCausation]:
|
|
82
|
+
"""
|
|
83
|
+
Resolve step DTOs (alias-identified) to StepCausation (hash/text-identified).
|
|
84
|
+
|
|
85
|
+
Primary path: parse C{seq}_{comp} aliases against the sequence.
|
|
86
|
+
Fallback: if aliases are garbled but the step count matches the sequence
|
|
87
|
+
length, map positionally (step i = statements[i] → statements[i+1 mod n]).
|
|
88
|
+
Otherwise drop the steps — per-step causation is best-effort enrichment.
|
|
89
|
+
"""
|
|
90
|
+
n = len(sequence)
|
|
91
|
+
if not step_dtos or n == 0:
|
|
92
|
+
return []
|
|
93
|
+
|
|
94
|
+
def parse(alias: str) -> Optional[Statement]:
|
|
95
|
+
parts = alias.strip().split("_")
|
|
96
|
+
if len(parts) != 2 or not parts[0].startswith("C"):
|
|
97
|
+
return None
|
|
98
|
+
try:
|
|
99
|
+
s, c = int(parts[0][1:]), int(parts[1])
|
|
100
|
+
except ValueError:
|
|
101
|
+
return None
|
|
102
|
+
if s != seq_idx or not (1 <= c <= n):
|
|
103
|
+
return None
|
|
104
|
+
return sequence[c - 1]
|
|
105
|
+
|
|
106
|
+
resolved: list[StepCausation] = []
|
|
107
|
+
for i, dto in enumerate(step_dtos):
|
|
108
|
+
source = parse(dto.from_alias)
|
|
109
|
+
target = parse(dto.to_alias)
|
|
110
|
+
if source is None or target is None:
|
|
111
|
+
if len(step_dtos) != n:
|
|
112
|
+
return [] # aliases garbled and counts don't line up — drop all
|
|
113
|
+
source = sequence[i]
|
|
114
|
+
target = sequence[(i + 1) % n]
|
|
115
|
+
causation = dto.causation
|
|
116
|
+
for technical_alias, text in alias_translations.items():
|
|
117
|
+
causation = dc_replace(causation, technical_alias, text)
|
|
118
|
+
assert source.hash is not None and target.hash is not None
|
|
119
|
+
resolved.append(
|
|
120
|
+
StepCausation(
|
|
121
|
+
source_hash=source.hash,
|
|
122
|
+
target_hash=target.hash,
|
|
123
|
+
source_text=source.text,
|
|
124
|
+
target_text=target.text,
|
|
125
|
+
causation=causation,
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
return resolved
|
|
129
|
+
|
|
130
|
+
|
|
48
131
|
class CausalCyclesDeckDto(BaseModel):
|
|
49
132
|
causal_cycles: list[CausalCycleDto] = Field(
|
|
50
133
|
...,
|
|
@@ -121,41 +204,37 @@ class CausalityEstimatorBalanced(CausalityEstimator):
|
|
|
121
204
|
def input_resolver(self) -> InputResolver:
|
|
122
205
|
return self._input_resolver
|
|
123
206
|
|
|
124
|
-
def
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
f"For each sequence:\n"
|
|
135
|
-
f"1) Estimate the numeric probability (0 to 1) considering realistic existence, optimal outcomes, and (implementation) feasibility — weigh these together holistically into a single plausibility score\n"
|
|
136
|
-
f"2) Explain why this sequence might occur (or already occurs) in reality\n"
|
|
137
|
-
f"3) Describe circumstances or contexts where this sequence would be most applicable or useful\n\n"
|
|
138
|
-
f"- Only use the sequences **exactly as provided**, do not shorten, skip, collapse, or reorder steps.\n"
|
|
139
|
-
f"</instructions>\n\n"
|
|
140
|
-
f"<formatting>\n"
|
|
141
|
-
f"- Output each circular causality sequence (cycle) as ordered aliases (technical placeholders) of statements as provided e.g. C1_1, C1_2, C1_3, ...\n"
|
|
142
|
-
f"- In the explanations, for fluency, use explicit wording instead of aliases.\n"
|
|
143
|
-
f"- Probability is a float between 0 and 1.\n"
|
|
144
|
-
f"</formatting>"
|
|
145
|
-
)]
|
|
207
|
+
def _lens_phrase(self) -> str:
|
|
208
|
+
"""Assessment lens inserted after 'Assess the following circular causality sequence'."""
|
|
209
|
+
return "considering realism, desirability, and feasibility"
|
|
210
|
+
|
|
211
|
+
def _probability_instruction(self) -> str:
|
|
212
|
+
"""Qualifier inserted after 'Estimate the numeric probability (0 to 1)'."""
|
|
213
|
+
return (
|
|
214
|
+
"considering realistic existence, optimal outcomes, and (implementation) "
|
|
215
|
+
"feasibility — weigh these together holistically into a single plausibility score"
|
|
216
|
+
)
|
|
146
217
|
|
|
147
218
|
def prompt_assess_single_sequence(self, *, sequence: str) -> list:
|
|
219
|
+
"""
|
|
220
|
+
Single prompt template shared by all estimator variants.
|
|
221
|
+
|
|
222
|
+
Subclasses customize only _lens_phrase() and _probability_instruction();
|
|
223
|
+
the sequence handling, instructions, and formatting rules stay identical.
|
|
224
|
+
"""
|
|
148
225
|
return [llm.messages.user(
|
|
149
|
-
f"Assess the following circular causality sequence
|
|
226
|
+
f"Assess the following circular causality sequence {self._lens_phrase()}\n"
|
|
150
227
|
f"(given that the final step cycles back to the first step):\n"
|
|
151
228
|
f"{sequence}\n\n"
|
|
152
229
|
f"<instructions>\n"
|
|
153
|
-
f"1)
|
|
154
|
-
f"2)
|
|
155
|
-
f"3)
|
|
230
|
+
f"1) For each consecutive step of the sequence (including the final wrap-around step back to the first element), state in one sentence the causal mechanism: why does the source naturally lead to the target?\n"
|
|
231
|
+
f"2) Only then, informed by the step-by-step causation, estimate the numeric probability (0 to 1) {self._probability_instruction()}\n"
|
|
232
|
+
f"3) Explain why this sequence might occur (or already occurs) in reality\n"
|
|
233
|
+
f"4) Describe circumstances or contexts where this sequence would be most applicable or useful\n\n"
|
|
156
234
|
f"- Only use the sequence **exactly as provided**, do not shorten, skip, collapse, or reorder steps.\n"
|
|
157
235
|
f"</instructions>\n\n"
|
|
158
236
|
f"<formatting>\n"
|
|
237
|
+
f"- In each step, identify source and target by their technical aliases exactly as given in the sequence; write the causation sentence itself using the actual statement wording, never aliases.\n"
|
|
159
238
|
f"- In the explanations and argumentation, for fluency, try to use explicit wording instead of technical aliases.\n"
|
|
160
239
|
f"- Probability is a float between 0 and 1.\n"
|
|
161
240
|
f"</formatting>"
|
|
@@ -289,6 +368,7 @@ class CausalityEstimatorBalanced(CausalityEstimator):
|
|
|
289
368
|
assessment: CausalCycleAssessmentDto = await _estimate_single_call()
|
|
290
369
|
return CausalCycleDto(
|
|
291
370
|
aliases=aliases,
|
|
371
|
+
steps=assessment.steps,
|
|
292
372
|
probability=assessment.probability,
|
|
293
373
|
reasoning_explanation=assessment.reasoning_explanation,
|
|
294
374
|
argumentation=assessment.argumentation,
|
|
@@ -364,33 +444,14 @@ class CausalityEstimatorBalanced(CausalityEstimator):
|
|
|
364
444
|
i: structure for i, structure in enumerate(structures)
|
|
365
445
|
}
|
|
366
446
|
|
|
367
|
-
#
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
for comp in sequence:
|
|
371
|
-
assert comp.hash is not None
|
|
372
|
-
alias = None
|
|
373
|
-
for existing_comp, existing_alias in components_with_aliases:
|
|
374
|
-
if existing_comp.hash == comp.hash:
|
|
375
|
-
alias = existing_alias
|
|
376
|
-
break
|
|
377
|
-
if alias is None:
|
|
378
|
-
alias = f"C{len(components_with_aliases) + 1}"
|
|
379
|
-
components_with_aliases.append((comp, alias))
|
|
380
|
-
|
|
381
|
-
# Build alias translation map
|
|
382
|
-
id_to_original_alias: dict[str, str] = {}
|
|
383
|
-
for comp, original_alias in components_with_aliases:
|
|
384
|
-
assert comp.hash is not None
|
|
385
|
-
id_to_original_alias[comp.hash] = original_alias
|
|
447
|
+
# Translate technical aliases to statement text. Aliases are
|
|
448
|
+
# batch-relative and must never survive into persisted rationale
|
|
449
|
+
# prose — statement text is the only durable identifier.
|
|
386
450
|
alias_translations: dict[str, str] = {}
|
|
387
451
|
for seq_idx, sequence in enumerate(sequences, 1):
|
|
388
452
|
for comp_idx, component in enumerate(sequence, 1):
|
|
389
453
|
technical_alias = f"C{seq_idx}_{comp_idx}"
|
|
390
|
-
|
|
391
|
-
original_alias = id_to_original_alias.get(component.hash)
|
|
392
|
-
if original_alias:
|
|
393
|
-
alias_translations[technical_alias] = original_alias
|
|
454
|
+
alias_translations[technical_alias] = component.text
|
|
394
455
|
|
|
395
456
|
# Map results
|
|
396
457
|
results: dict[str, EstimationStructured] = {}
|
|
@@ -417,18 +478,22 @@ class CausalityEstimatorBalanced(CausalityEstimator):
|
|
|
417
478
|
# Translate aliases in text
|
|
418
479
|
reasoning_text = causal_cycle.reasoning_explanation
|
|
419
480
|
argumentation_text = causal_cycle.argumentation
|
|
420
|
-
for technical_alias,
|
|
421
|
-
reasoning_text = dc_replace(
|
|
422
|
-
reasoning_text, technical_alias, original_alias
|
|
423
|
-
)
|
|
481
|
+
for technical_alias, text in alias_translations.items():
|
|
482
|
+
reasoning_text = dc_replace(reasoning_text, technical_alias, text)
|
|
424
483
|
argumentation_text = dc_replace(
|
|
425
|
-
argumentation_text, technical_alias,
|
|
484
|
+
argumentation_text, technical_alias, text
|
|
426
485
|
)
|
|
427
486
|
|
|
428
487
|
results[matched_structure.hash] = EstimationStructured(
|
|
429
488
|
probability=causal_cycle.probability,
|
|
430
489
|
reasoning=reasoning_text,
|
|
431
490
|
argumentation=argumentation_text,
|
|
491
|
+
steps=_resolve_steps(
|
|
492
|
+
causal_cycle.steps,
|
|
493
|
+
sequences[seq_idx],
|
|
494
|
+
seq_idx + 1,
|
|
495
|
+
alias_translations,
|
|
496
|
+
),
|
|
432
497
|
)
|
|
433
498
|
|
|
434
499
|
return results
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dependency_injector.wiring import Provide, inject
|
|
4
|
+
|
|
5
|
+
from dialectical_framework.enums.di import DI
|
|
6
|
+
from dialectical_framework.concerns.causality.causality_estimator_balanced import \
|
|
7
|
+
CausalityEstimatorBalanced
|
|
8
|
+
from dialectical_framework.protocols.input_resolver import InputResolver
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class CausalityEstimatorCriteria(CausalityEstimatorBalanced):
|
|
12
|
+
"""
|
|
13
|
+
Causality estimator that uses custom assessment criteria.
|
|
14
|
+
|
|
15
|
+
Instead of the balanced/realistic/desirable/feasible perspective,
|
|
16
|
+
this estimator evaluates sequences against pre-formulated criteria
|
|
17
|
+
derived from a free-form exploration intent.
|
|
18
|
+
|
|
19
|
+
Criteria formulation happens upstream (in BuildWheels).
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
@inject
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
criteria: str,
|
|
26
|
+
input_resolver: InputResolver = Provide[DI.input_resolver],
|
|
27
|
+
):
|
|
28
|
+
super().__init__(input_resolver=input_resolver)
|
|
29
|
+
self._criteria = criteria
|
|
30
|
+
|
|
31
|
+
def _lens_phrase(self) -> str:
|
|
32
|
+
return f"with focus on the following assessment criteria: {self._criteria}"
|
|
33
|
+
|
|
34
|
+
def _probability_instruction(self) -> str:
|
|
35
|
+
return "with emphasis on the assessment criteria above"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dialectical_framework.concerns.causality.causality_estimator_balanced import \
|
|
4
|
+
CausalityEstimatorBalanced
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CausalityEstimatorDesirable(CausalityEstimatorBalanced):
|
|
8
|
+
|
|
9
|
+
def _lens_phrase(self) -> str:
|
|
10
|
+
return "considering desirability, i.e. producing optimal outcomes and maximum results"
|
|
11
|
+
|
|
12
|
+
def _probability_instruction(self) -> str:
|
|
13
|
+
return "regarding how beneficial/optimal this sequence would be if implemented"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dialectical_framework.concerns.causality.causality_estimator_balanced import \
|
|
4
|
+
CausalityEstimatorBalanced
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CausalityEstimatorFeasible(CausalityEstimatorBalanced):
|
|
8
|
+
|
|
9
|
+
def _lens_phrase(self) -> str:
|
|
10
|
+
return "considering feasibility, i.e. best achievable with minimum resistance"
|
|
11
|
+
|
|
12
|
+
def _probability_instruction(self) -> str:
|
|
13
|
+
return "regarding how easily this sequence could be implemented given current constraints"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dialectical_framework.concerns.causality.causality_estimator_balanced import \
|
|
4
|
+
CausalityEstimatorBalanced
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CausalityEstimatorRealistic(CausalityEstimatorBalanced):
|
|
8
|
+
|
|
9
|
+
def _lens_phrase(self) -> str:
|
|
10
|
+
return "for realism, i.e. what typically happens in natural systems"
|
|
11
|
+
|
|
12
|
+
def _probability_instruction(self) -> str:
|
|
13
|
+
return "regarding its realistic existence in natural/existing systems"
|
|
@@ -3,8 +3,7 @@ CausalityEstimation: Concern for estimating causality on Cycles and Wheels.
|
|
|
3
3
|
|
|
4
4
|
This is the "smart" orchestrator that:
|
|
5
5
|
- Groups structures by type and size for parallel estimation
|
|
6
|
-
-
|
|
7
|
-
re-estimates everything; if DB has more, only estimates what was requested
|
|
6
|
+
- (Re-)estimates exactly the structures requested
|
|
8
7
|
- Normalizes probabilities across ALL structures of same type+size in the DB
|
|
9
8
|
|
|
10
9
|
Usage:
|
|
@@ -61,9 +60,8 @@ class CausalityEstimation(ReasonableConcern[EstimationResult], SettingsAware):
|
|
|
61
60
|
of same type+size in the DB
|
|
62
61
|
|
|
63
62
|
Estimation logic per group:
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
- Either way, normalization covers everything in the DB
|
|
63
|
+
- (Re-)estimates exactly the structures requested
|
|
64
|
+
- Normalization covers everything of same type+size in the DB
|
|
67
65
|
"""
|
|
68
66
|
|
|
69
67
|
def __init__(self) -> None:
|
|
@@ -164,25 +162,17 @@ class CausalityEstimation(ReasonableConcern[EstimationResult], SettingsAware):
|
|
|
164
162
|
Estimate a group of same-type, same-size structures.
|
|
165
163
|
|
|
166
164
|
Logic:
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
- If DB has more → only estimate the requested ones
|
|
170
|
-
- Normalize probabilities across all DB structures
|
|
165
|
+
- (Re-)estimate exactly the requested structures
|
|
166
|
+
- Normalize probabilities across all structures of same type+size in DB
|
|
171
167
|
|
|
172
168
|
Returns list of structures that were estimated.
|
|
173
169
|
"""
|
|
174
170
|
# Find all structures of same type+size in DB
|
|
175
171
|
all_in_db = self._find_all_in_layer(requested)
|
|
176
|
-
requested_hashes = {s.hash for s in requested}
|
|
177
|
-
db_hashes = {s.hash for s in all_in_db}
|
|
178
172
|
|
|
179
|
-
#
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
to_estimate = requested
|
|
183
|
-
else:
|
|
184
|
-
# DB has more → only estimate what was requested
|
|
185
|
-
to_estimate = requested
|
|
173
|
+
# Always (re-)estimate exactly what was requested; normalization
|
|
174
|
+
# below covers everything in the DB layer.
|
|
175
|
+
to_estimate = requested
|
|
186
176
|
|
|
187
177
|
# Run AI estimation (returns raw, non-normalized results)
|
|
188
178
|
raw_estimations = await estimator.estimate(to_estimate)
|
|
@@ -258,7 +248,11 @@ class CausalityEstimation(ReasonableConcern[EstimationResult], SettingsAware):
|
|
|
258
248
|
"""
|
|
259
249
|
Persist raw estimations to the database.
|
|
260
250
|
|
|
261
|
-
|
|
251
|
+
Per structure: replaces prior causality rationales (holistic and
|
|
252
|
+
per-step), then creates Rationale + CausalityProbabilityEstimation
|
|
253
|
+
plus one per-step causation Rationale per sequence step (wheel steps
|
|
254
|
+
target their edge Transition; cycle steps target the Cycle itself,
|
|
255
|
+
self-identified by statement-text headers).
|
|
262
256
|
"""
|
|
263
257
|
estimation_manager = EstimationManager()
|
|
264
258
|
|
|
@@ -268,15 +262,82 @@ class CausalityEstimation(ReasonableConcern[EstimationResult], SettingsAware):
|
|
|
268
262
|
|
|
269
263
|
est = raw_estimations[structure.hash]
|
|
270
264
|
|
|
271
|
-
#
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
265
|
+
# Replace: re-estimation supersedes prior explanations, on the
|
|
266
|
+
# structure itself and (for wheels) on its edge Transitions
|
|
267
|
+
self._delete_prior_rationales(structure)
|
|
268
|
+
|
|
269
|
+
# Create Rationale (argumentation folded into text — it used to be
|
|
270
|
+
# stored as an undeclared, write-only `summary` field)
|
|
271
|
+
rationale_text = est.reasoning
|
|
272
|
+
if est.argumentation:
|
|
273
|
+
rationale_text = (
|
|
274
|
+
f"{est.reasoning}\n\n**Applicable contexts:** {est.argumentation}"
|
|
275
|
+
)
|
|
276
|
+
rationale = Rationale(text=rationale_text)
|
|
276
277
|
rationale.set_explanation_target(structure)
|
|
277
278
|
rationale.commit()
|
|
279
|
+
self._report.node_created(rationale)
|
|
278
280
|
|
|
279
281
|
# Store raw AI score as CausalityProbabilityEstimation
|
|
280
282
|
estimation_manager.upsert_estimation(
|
|
281
283
|
structure, CausalityProbabilityEstimation, est.probability, provider=rationale
|
|
282
284
|
)
|
|
285
|
+
|
|
286
|
+
self._persist_step_causations(structure, est)
|
|
287
|
+
|
|
288
|
+
def _delete_prior_rationales(self, structure: Union[Cycle, Wheel]) -> None:
|
|
289
|
+
"""Delete rationales explaining the structure (and its wheel edges)."""
|
|
290
|
+
from dialectical_framework.graph.repositories.node_repository import (
|
|
291
|
+
NodeRepository,
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
node_repo = NodeRepository()
|
|
295
|
+
targets: list = [structure]
|
|
296
|
+
if isinstance(structure, Wheel):
|
|
297
|
+
targets.extend(structure.edges)
|
|
298
|
+
|
|
299
|
+
for target in targets:
|
|
300
|
+
for old_rationale, _ in target.rationales.all():
|
|
301
|
+
self._report.node_deleted(old_rationale)
|
|
302
|
+
node_repo.delete_explanation_rationales(target)
|
|
303
|
+
|
|
304
|
+
def _persist_step_causations(
|
|
305
|
+
self, structure: Union[Cycle, Wheel], est: EstimationStructured
|
|
306
|
+
) -> None:
|
|
307
|
+
"""
|
|
308
|
+
Persist per-step causation rationales.
|
|
309
|
+
|
|
310
|
+
Wheel: each step attaches to the edge Transition matched by
|
|
311
|
+
(source hash, target hash) — never by index, since edge ordering
|
|
312
|
+
starts at an arbitrary edge. Cycle has no edge nodes, so steps
|
|
313
|
+
attach to the Cycle itself with a statement-text header; the same
|
|
314
|
+
header fallback applies to wheel steps that match no edge.
|
|
315
|
+
"""
|
|
316
|
+
if not est.steps:
|
|
317
|
+
return
|
|
318
|
+
|
|
319
|
+
edge_by_hashes: dict[tuple[str, str], object] = {}
|
|
320
|
+
if isinstance(structure, Wheel):
|
|
321
|
+
for edge in structure.edges:
|
|
322
|
+
source_result = edge.source.get()
|
|
323
|
+
target_result = edge.target.get()
|
|
324
|
+
if source_result and target_result:
|
|
325
|
+
key = (source_result[0].hash, target_result[0].hash)
|
|
326
|
+
edge_by_hashes[key] = edge
|
|
327
|
+
|
|
328
|
+
for step in est.steps:
|
|
329
|
+
if not step.causation:
|
|
330
|
+
continue
|
|
331
|
+
edge = edge_by_hashes.get((step.source_hash, step.target_hash))
|
|
332
|
+
if edge is not None:
|
|
333
|
+
# The edge Transition itself identifies source/target
|
|
334
|
+
rationale = Rationale(text=step.causation)
|
|
335
|
+
rationale.set_explanation_target(edge)
|
|
336
|
+
else:
|
|
337
|
+
# No anchor node — the header makes the step self-describing
|
|
338
|
+
rationale = Rationale(
|
|
339
|
+
text=f"**{step.source_text} → {step.target_text}**\n{step.causation}"
|
|
340
|
+
)
|
|
341
|
+
rationale.set_explanation_target(structure)
|
|
342
|
+
rationale.commit()
|
|
343
|
+
self._report.node_created(rationale)
|
|
@@ -261,17 +261,21 @@ class SynthesisGeneration(ReasonableConcern[Optional[SynthesisResult]], Settings
|
|
|
261
261
|
source_label = "?"
|
|
262
262
|
target_label = "?"
|
|
263
263
|
|
|
264
|
+
# Alias + statement text: aliases alone are wheel-relative and would be
|
|
265
|
+
# the LLM's only grounding — self-describing labels prevent alias leaks
|
|
264
266
|
if source_segment:
|
|
265
267
|
core = source_segment.t.get()
|
|
266
268
|
if core:
|
|
267
269
|
stmt, rel = core
|
|
268
|
-
|
|
270
|
+
alias = getattr(rel, "alias", None)
|
|
271
|
+
source_label = f"{alias} ({stmt.text})" if alias else stmt.text
|
|
269
272
|
|
|
270
273
|
if target_segment:
|
|
271
274
|
core = target_segment.t.get()
|
|
272
275
|
if core:
|
|
273
276
|
stmt, rel = core
|
|
274
|
-
|
|
277
|
+
alias = getattr(rel, "alias", None)
|
|
278
|
+
target_label = f"{alias} ({stmt.text})" if alias else stmt.text
|
|
275
279
|
|
|
276
280
|
return f"### Step {index}: {source_label} → {target_label}"
|
|
277
281
|
|
|
@@ -158,6 +158,7 @@ APEX
|
|
|
158
158
|
5. **Ac+ must contradict Re-** (positive action opposes regression toward T-)
|
|
159
159
|
6. Re- and Ac- typically have lower insight than the "+" aspects
|
|
160
160
|
7. Statements are a fuller actionable form, longer than the headline
|
|
161
|
+
8. In headline/statement/explanation prose, refer to concepts by their actual statement wording — never by T/A/T+/A-/Ac+/Re- notation. The notation is context-relative and meaningless to anyone reading the stored text later.
|
|
161
162
|
|
|
162
163
|
## Example (1-PP: T = Love, A = Indifference)
|
|
163
164
|
|
|
@@ -134,3 +134,44 @@ class NodeRepository:
|
|
|
134
134
|
if node_type is not None and not isinstance(node, node_type):
|
|
135
135
|
raise TypeError(f"Expected {node_type.__name__}, got {type(node).__name__}")
|
|
136
136
|
return node
|
|
137
|
+
|
|
138
|
+
@inject
|
|
139
|
+
def delete_explanation_rationales(
|
|
140
|
+
self,
|
|
141
|
+
node: BaseNode,
|
|
142
|
+
sid: Optional[str] = Provide[DI.sid],
|
|
143
|
+
graph_db: Union[Memgraph, Neo4j] = Provide[DI.graph_db],
|
|
144
|
+
) -> list[str]:
|
|
145
|
+
"""
|
|
146
|
+
Delete all Rationales that EXPLAIN the given node (with their critiques).
|
|
147
|
+
|
|
148
|
+
Used to replace prior analytical explanations before persisting fresh
|
|
149
|
+
ones (e.g. re-estimation of causality). Critique rationales attached
|
|
150
|
+
to the deleted rationales are removed as well.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
node: The explained node (must be saved and in current scope)
|
|
154
|
+
sid: Case ID (injected from DI context)
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
Hashes of the deleted Rationale nodes (for event emission)
|
|
158
|
+
"""
|
|
159
|
+
if node._id is None:
|
|
160
|
+
return []
|
|
161
|
+
|
|
162
|
+
# Validate node belongs to current scope
|
|
163
|
+
if sid and node.sid != sid:
|
|
164
|
+
return []
|
|
165
|
+
|
|
166
|
+
query = """
|
|
167
|
+
MATCH (rat:Rationale)-[:EXPLAINS]->(n)
|
|
168
|
+
WHERE id(n) = $node_id
|
|
169
|
+
OPTIONAL MATCH (crit:Rationale)-[:CRITIQUES]->(rat)
|
|
170
|
+
WITH collect(DISTINCT rat) + collect(DISTINCT crit) AS to_delete
|
|
171
|
+
UNWIND to_delete AS r
|
|
172
|
+
WITH DISTINCT r, r.hash AS rat_hash
|
|
173
|
+
DETACH DELETE r
|
|
174
|
+
RETURN rat_hash
|
|
175
|
+
"""
|
|
176
|
+
results = list(graph_db.execute_and_fetch(query, {"node_id": node._id}))
|
|
177
|
+
return [r["rat_hash"] for r in results if r["rat_hash"] is not None]
|
|
@@ -24,14 +24,15 @@ def dc_replace(text: str, alias: str, replace_to: str) -> str:
|
|
|
24
24
|
- `(?<!\\w)`: Not preceded by word character (prevents "AT-" matching)
|
|
25
25
|
- `(["'([{]?)`: Optional opening bracket/quote (captured)
|
|
26
26
|
- `<alias>`: The literal alias (escaped)
|
|
27
|
-
- `(\\s|[]'"})
|
|
27
|
+
- `(\\s|[]'"});,.!?:/—-]|$)`: Followed by space, punctuation, or end (captured)
|
|
28
28
|
"""
|
|
29
29
|
return re.sub(
|
|
30
30
|
r'(?<!\w)(["\'\(\[\{]?)'
|
|
31
31
|
rf"{re.escape(alias)}"
|
|
32
|
-
r"(\s|[\]\'\"\)\}
|
|
33
|
-
#
|
|
34
|
-
|
|
32
|
+
r"(\s|[\]\'\"\)\};,.!?:/—-]|$)",
|
|
33
|
+
# Function replacement: replace_to is arbitrary prose and must not be
|
|
34
|
+
# interpreted as a regex replacement template (backslashes, \1, etc.)
|
|
35
|
+
lambda m: m.group(1) + replace_to + m.group(2),
|
|
35
36
|
text,
|
|
36
37
|
flags=re.VERBOSE,
|
|
37
38
|
)
|