dialectical-framework 1.5.4__tar.gz → 1.5.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/PKG-INFO +1 -1
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/pyproject.toml +1 -1
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/analyst/skills/expand_polarities.py +61 -39
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/analyst/system_prompts.py +8 -1
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/apps.py +5 -2
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/create_nexus.py +10 -2
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/perspective_combination.py +54 -41
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/cycle.py +24 -9
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/LICENSE +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/README.md +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/advisor/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/advisor/advisor.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/advisor/system_prompts.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/advisor/tools/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/advisor/tools/anchor.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/advisor/tools/explore.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/advisor/tools/ingest.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/advisor/tools/sync.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/agent_context.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/analyst/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/analyst/analyst.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/analyst/skills/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/analyst/skills/anchor_theses.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/analyst/skills/edit_perspective.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/analyst/skills/find_polarities.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/analyst/skills/introduce_polarity.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/analyst/skills/surface_theses.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/analyst/tools/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/analyst/tools/create_dx_input.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/analyst/tools/place_statement.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/conversation_facilitator.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/execution_report.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/explorer/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/explorer/explorer.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/explorer/skills/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/explorer/skills/build_wheels.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/explorer/skills/explore_transformations.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/explorer/skills/generate_synthesis.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/explorer/system_prompts.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/explorer/tools/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/explorer/tools/create_nexus.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/explorer/tools/expand_nexus.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/explorer/tools/generate_synthesis.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/explorer/tools/present_exploration.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/orchestrator/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/orchestrator/tools/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/orchestrator/tools/add_input.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/orchestrator/tools/digest_input.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/orchestrator/tools/discard.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/orchestrator/tools/get_schema.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/orchestrator/tools/inspect_node.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/orchestrator/tools/present_analysis.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/orchestrator/tools/query_graph.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/orchestrator/tools/read_digest.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/orchestrator/tools/read_input.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/reasonable_concern.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/stream_events.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/ac_re_taxonomy.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/action_extraction.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/add_input.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/ai_dto/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/ai_dto/statement_dto.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/ai_dto/statements_deck_dto.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/antithesis_classification.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/antithesis_extraction.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/aspect_classification.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/aspect_generation.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/causality/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/causality/causality_estimator.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/causality/causality_estimator_balanced.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/causality/causality_estimator_criteria.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/causality/causality_estimator_desirable.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/causality/causality_estimator_feasible.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/causality/causality_estimator_realistic.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/causality/causality_normalizer.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/causality/estimator_resolver.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/causality_estimation.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/control_statements_check.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/create_dx_input.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/diagonal_oppositions_check.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/dialectical_context.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/discard.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/display_text_edit.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/expand_nexus.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/perspective_validation.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/positive_ac_re_apex_derivation.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/source_digest.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/statement_classification.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/statement_deduplication.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/statement_placement.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/synthesis_generation.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/thesis_extraction.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/transformation_audit.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/concerns/transformation_generation.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/dialectical_reasoning.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/enums/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/enums/causality_preset.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/enums/di.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/events/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/events/graph_event.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/events/graph_event_bus.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/exceptions/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/exceptions/node_errors.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/exceptions/resolver_errors.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/composite_input_resolver.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/dialexity_input_resolver.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/estimation_manager.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/mixins/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/mixins/incremental_build_mixin.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/mixins/intent_mixin.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/mixins/persistable_mixin.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/assessable_entity.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/base_node.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/case.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/estimation.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/ideas.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/input.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/nexus.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/perspective.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/polarity.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/rationale.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/statement.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/synthesis.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/transformation.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/transition.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/nodes/wheel.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationship_manager.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/action_reflection_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/belongs_to_cycle_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/belongs_to_nexus_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/changed_to_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/contradiction_of_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/critiques_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/distilled_to_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/estimates_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/explains_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/has_input_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/has_statement_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/has_wheel_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/immutable_structure.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/is_source_of_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/is_target_of_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/negative_side_of_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/opposite_direction_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/opposite_of_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/polarity_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/positive_side_of_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/provides_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/relationships/synthesis_of_relationship.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/rendering.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/repositories/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/repositories/case_repository.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/repositories/cycle_repository.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/repositories/input_repository.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/repositories/nexus_repository.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/repositories/node_repository.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/repositories/perspective_repository.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/repositories/polarity_repository.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/repositories/schema_repository.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/repositories/statement_repository.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/repositories/transformation_repository.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/repositories/wheel_repository.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/scope_context.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/verbatim_input_resolver.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/wheel_segment.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/graph/wheel_segment_polar_pair.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/protocols/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/protocols/has_config.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/protocols/input_resolver.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/settings.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/utils/__init__.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/utils/bedrock_provider.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/utils/concurrency.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/utils/dc_replace.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/utils/decompose_probability_uniformly.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/utils/edge_context.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/utils/effect_logger.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/utils/input_context.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/utils/order_transitions.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/utils/sequence_generation.py +0 -0
- {dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/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.5.
|
|
3
|
+
Version: 1.5.6
|
|
4
4
|
Summary: A dialectical framework for augmented intelligence. AI reasoning powered with dialectics supports humans in: system optimization (psychology, engineering, business, politics, etc.); dispute resolution (mediation, conflicts, negotiations, etc.); decision-making (dilemmas, challenging situations, win-win, etc.).
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: dialectics,dialectical-reasoning,synthesis,thesis-antithesis,ai,artificial-intelligence,llm,reasoning-framework,philosophy,logic,argumentation,conflict-resolution,decision-making,critical-thinking,semantic-graph,mirascope,pydantic,perspectives,polarity-reasoning
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "dialectical-framework"
|
|
3
|
-
version = "1.5.
|
|
3
|
+
version = "1.5.6"
|
|
4
4
|
description = "A dialectical framework for augmented intelligence. AI reasoning powered with dialectics supports humans in: system optimization (psychology, engineering, business, politics, etc.); dispute resolution (mediation, conflicts, negotiations, etc.); decision-making (dilemmas, challenging situations, win-win, etc.)."
|
|
5
5
|
authors = ["Evaldas Taroza <evaldas@dialexity.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -18,27 +18,36 @@ from pydantic import Field
|
|
|
18
18
|
|
|
19
19
|
from dialectical_framework.agents.reasonable_concern import ReasonableConcern
|
|
20
20
|
from dialectical_framework.enums.di import DI
|
|
21
|
-
from dialectical_framework.concerns.aspect_generation import (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
from dialectical_framework.concerns.aspect_generation import (
|
|
22
|
+
AspectGeneration,
|
|
23
|
+
AspectResult,
|
|
24
|
+
)
|
|
25
|
+
from dialectical_framework.concerns.statement_deduplication import (
|
|
26
|
+
StatementDeduplication,
|
|
27
|
+
)
|
|
25
28
|
from dialectical_framework.graph.nodes.polarity import Polarity
|
|
26
|
-
from dialectical_framework.graph.nodes.perspective import (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
from dialectical_framework.graph.nodes.perspective import (
|
|
30
|
+
POSITION_A_MINUS,
|
|
31
|
+
POSITION_A_PLUS,
|
|
32
|
+
POSITION_T_MINUS,
|
|
33
|
+
POSITION_T_PLUS,
|
|
34
|
+
Perspective,
|
|
35
|
+
)
|
|
31
36
|
from dialectical_framework.graph.relationships.polarity_relationship import (
|
|
32
|
-
AMinusRelationship,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
from dialectical_framework.graph.repositories.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
AMinusRelationship,
|
|
38
|
+
APlusRelationship,
|
|
39
|
+
HasPolarityRelationship,
|
|
40
|
+
TMinusRelationship,
|
|
41
|
+
TPlusRelationship,
|
|
42
|
+
)
|
|
43
|
+
from dialectical_framework.graph.repositories.statement_repository import (
|
|
44
|
+
StatementRepository,
|
|
45
|
+
)
|
|
46
|
+
from dialectical_framework.graph.repositories.input_repository import InputRepository
|
|
47
|
+
from dialectical_framework.graph.repositories.node_repository import NodeRepository
|
|
48
|
+
from dialectical_framework.graph.repositories.perspective_repository import (
|
|
49
|
+
PerspectiveRepository,
|
|
50
|
+
)
|
|
42
51
|
|
|
43
52
|
if TYPE_CHECKING:
|
|
44
53
|
from dialectical_framework.protocols.input_resolver import InputResolver
|
|
@@ -51,20 +60,22 @@ class ExpandPolarity(ReasonableConcern[list[Perspective]]):
|
|
|
51
60
|
Creates Perspectives from a Polarity by generating and connecting aspects
|
|
52
61
|
(T+, T-, A+, A-).
|
|
53
62
|
|
|
54
|
-
Each call produces
|
|
55
|
-
|
|
56
|
-
|
|
63
|
+
Each call produces `count` NEW perspectives (alternative tetrads) for the
|
|
64
|
+
Polarity, generated sequentially so each uses `not_like_these` (existing +
|
|
65
|
+
already-generated-this-call) to ensure diversity. Any pre-existing partial
|
|
66
|
+
Perspective counts toward `count`.
|
|
57
67
|
|
|
58
68
|
Flow:
|
|
59
69
|
1. Resolve Polarity by hash
|
|
60
70
|
2. Look up existing Perspectives for this Polarity
|
|
61
|
-
3.
|
|
62
|
-
4. Complete all partial PPs by generating aspects
|
|
71
|
+
3. Create new partial Perspectives so `count` are generated this call
|
|
72
|
+
4. Complete all partial PPs sequentially by generating aspects
|
|
63
73
|
5. Return list of completed Perspectives (existing + new)
|
|
64
74
|
"""
|
|
65
75
|
|
|
66
|
-
def __init__(self, polarity_hash: str) -> None:
|
|
76
|
+
def __init__(self, polarity_hash: str, count: int = 1) -> None:
|
|
67
77
|
self.polarity_hash = polarity_hash
|
|
78
|
+
self.count = max(1, count)
|
|
68
79
|
|
|
69
80
|
async def resolve(self) -> list[Perspective]:
|
|
70
81
|
"""
|
|
@@ -86,20 +97,17 @@ class ExpandPolarity(ReasonableConcern[list[Perspective]]):
|
|
|
86
97
|
pp_repo = PerspectiveRepository()
|
|
87
98
|
existing_pps = pp_repo.find_by_polarity(polarity)
|
|
88
99
|
|
|
89
|
-
if not existing_pps:
|
|
90
|
-
# No PP exists - create one referencing the Polarity
|
|
91
|
-
pp = self._create_perspective_for_polarity(polarity)
|
|
92
|
-
existing_pps = [pp]
|
|
93
|
-
|
|
94
100
|
complete_pps = [pp for pp in existing_pps if pp.is_complete()]
|
|
95
101
|
partial_pps = [pp for pp in existing_pps if not pp.is_complete()]
|
|
96
102
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
103
|
+
# Complete any existing partials, then create additional new ones so that
|
|
104
|
+
# `count` fresh Perspectives are produced this call (a pre-existing partial
|
|
105
|
+
# counts as one of them).
|
|
106
|
+
additional_needed = self.count - len(partial_pps)
|
|
107
|
+
for _ in range(max(0, additional_needed)):
|
|
108
|
+
partial_pps.append(self._create_perspective_for_polarity(polarity))
|
|
101
109
|
|
|
102
|
-
# Complete all partial PPs
|
|
110
|
+
# Complete all partial PPs sequentially (each sees prior results)
|
|
103
111
|
completed_pps: list[Perspective] = []
|
|
104
112
|
|
|
105
113
|
for pp in partial_pps:
|
|
@@ -209,7 +217,12 @@ class ExpandPolarity(ReasonableConcern[list[Perspective]]):
|
|
|
209
217
|
|
|
210
218
|
def _perspective_final_state(self, pp: Perspective) -> dict[str, str | None]:
|
|
211
219
|
"""Build a dict with the final post-dedup text at each position."""
|
|
212
|
-
positions = [
|
|
220
|
+
positions = [
|
|
221
|
+
POSITION_T_PLUS,
|
|
222
|
+
POSITION_T_MINUS,
|
|
223
|
+
POSITION_A_PLUS,
|
|
224
|
+
POSITION_A_MINUS,
|
|
225
|
+
]
|
|
213
226
|
state: dict[str, str | None] = {"hash": pp.short_hash}
|
|
214
227
|
for pos in positions:
|
|
215
228
|
manager = pp.get_relationship_manager_by_position(pos)
|
|
@@ -299,13 +312,22 @@ class ExpandPolarity(ReasonableConcern[list[Perspective]]):
|
|
|
299
312
|
|
|
300
313
|
@llm.tool
|
|
301
314
|
async def expand_polarities(
|
|
302
|
-
polarity_hashes: Annotated[
|
|
315
|
+
polarity_hashes: Annotated[
|
|
316
|
+
list[str],
|
|
317
|
+
Field(description="Hashes of Polarities to expand into full Perspectives"),
|
|
318
|
+
],
|
|
319
|
+
count: Annotated[
|
|
320
|
+
int,
|
|
321
|
+
Field(
|
|
322
|
+
description="Number of new Perspectives to generate per Polarity (each is diverse from prior ones)"
|
|
323
|
+
),
|
|
324
|
+
] = 1,
|
|
303
325
|
) -> str:
|
|
304
|
-
"""Build complete Perspectives from Polarities by generating evaluative aspects (T+, T-, A+, A-) for each.
|
|
326
|
+
"""Build complete Perspectives from Polarities by generating evaluative aspects (T+, T-, A+, A-) for each. Generates `count` new Perspectives per Polarity sequentially — each sees prior tetrads to ensure diversity. The Polarities must already exist in the graph."""
|
|
305
327
|
import asyncio
|
|
306
328
|
|
|
307
329
|
async def _expand_one(h: str) -> str:
|
|
308
|
-
concern = ExpandPolarity(polarity_hash=h)
|
|
330
|
+
concern = ExpandPolarity(polarity_hash=h, count=count)
|
|
309
331
|
await concern.resolve()
|
|
310
332
|
return str(concern.report)
|
|
311
333
|
|
|
@@ -35,6 +35,13 @@ Choose your approach based on the user's input:
|
|
|
35
35
|
- User is working step-by-step and asks for the next step
|
|
36
36
|
- User refers to specific existing theses and wants tensions found
|
|
37
37
|
- User explicitly asks to expand a polarity into perspectives
|
|
38
|
+
- User asks to "find tetrades", "show aspects", "build T+/T-/A+/A-", or otherwise requests the four-aspect structure
|
|
39
|
+
|
|
40
|
+
**Disambiguating "perspectives", "angles", "points of view":**
|
|
41
|
+
These words map to DIFFERENT tools depending on what's in scope:
|
|
42
|
+
- Polarity in view/referenced → `expand_polarities` (build the tetrad for that polarity)
|
|
43
|
+
- Thesis in view/referenced → `find_polarities` (find opposing angles)
|
|
44
|
+
- No specific node → check what exists: unexpanded polarities → `expand_polarities`; theses without polarities → `find_polarities`
|
|
38
45
|
|
|
39
46
|
**Use `add_input` when:**
|
|
40
47
|
- User provides multi-sentence source material (a paragraph, article, or detailed description) to capture before analysis
|
|
@@ -93,7 +100,7 @@ When the user wants to explore interactions between perspectives:
|
|
|
93
100
|
- `surface_theses` — Extract theses from inputs (requires inputs in scope).
|
|
94
101
|
- `find_polarities` — Find antitheses for existing theses.
|
|
95
102
|
- `introduce_polarity` — Directly introduce a known T-A tension (both sides clear).
|
|
96
|
-
- `expand_polarities` — Expand polarities into full Perspectives (T+/T-/A+/A-).
|
|
103
|
+
- `expand_polarities` — Expand polarities into full Perspectives (T+/T-/A+/A-). Pass `count > 1` to generate several diverse tetrads per polarity in one call.
|
|
97
104
|
- `place_statement` — Check if a statement exists in the graph already.
|
|
98
105
|
|
|
99
106
|
**Steering:**
|
{dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/src/dialectical_framework/agents/apps.py
RENAMED
|
@@ -341,8 +341,11 @@ both sides contribute", "constructive co-existence", "where 1+1 > 2".
|
|
|
341
341
|
|
|
342
342
|
## Viewport Scope
|
|
343
343
|
|
|
344
|
-
Messages may
|
|
344
|
+
Messages may begin with `[User is currently viewing: ...]`. This tells you their active focus — use it to resolve ambiguous requests:
|
|
345
345
|
|
|
346
|
+
- When the user asks for an action without specifying a target (e.g., "find tetrades", "expand", "show aspects", "find perspectives"), apply it to the node in their current view.
|
|
347
|
+
- If a polarity is in view and the user asks for tetrades/aspects/perspectives/angles, expand that polarity into its full structure.
|
|
348
|
+
- If a thesis is in view and the user asks for perspectives/angles/oppositions, find opposing viewpoints for that thesis.
|
|
346
349
|
- Only operate on the node(s) in the user's viewport unless they explicitly reference something else or ask to switch.
|
|
347
350
|
- Never silently pivot to other nodes outside the viewport. If you think working on a different node would help, ask first.
|
|
348
351
|
|
|
@@ -487,5 +490,5 @@ rules. Adjust interaction accordingly:
|
|
|
487
490
|
- Present tetrads structurally with all six positions and scores.
|
|
488
491
|
- Show transformation positions explicitly: Ac, Ac+, Ac-, Re, Re+, Re-.
|
|
489
492
|
- Show control statements, modality alignment, diagonal contradictions.
|
|
490
|
-
- Suggest next steps
|
|
493
|
+
- Suggest exploration-phase next steps (nexus, wheels) rather than auto-executing — the user drives structural expansion. Analysis tools (expand, find) still follow "act on clear intent."
|
|
491
494
|
"""
|
|
@@ -10,8 +10,7 @@ from typing import Optional
|
|
|
10
10
|
from dialectical_framework.agents.reasonable_concern import ReasonableConcern
|
|
11
11
|
from dialectical_framework.graph.nodes.nexus import Nexus
|
|
12
12
|
from dialectical_framework.graph.nodes.perspective import Perspective
|
|
13
|
-
from dialectical_framework.graph.repositories.node_repository import
|
|
14
|
-
NodeRepository
|
|
13
|
+
from dialectical_framework.graph.repositories.node_repository import NodeRepository
|
|
15
14
|
from dialectical_framework.protocols.has_config import SettingsAware
|
|
16
15
|
|
|
17
16
|
|
|
@@ -48,7 +47,16 @@ class CreateNexus(SettingsAware, ReasonableConcern[CreateNexusResult]):
|
|
|
48
47
|
|
|
49
48
|
repo = NodeRepository()
|
|
50
49
|
perspectives: list[Perspective] = []
|
|
50
|
+
# Dedup input hashes, preserving order: BELONGS_TO_NEXUS is a directed
|
|
51
|
+
# relationship, so connect() does NOT deduplicate. A repeated hash here
|
|
52
|
+
# would create duplicate edges, causing nexus.perspectives.all() to
|
|
53
|
+
# yield the same PP twice and poisoning combination generation
|
|
54
|
+
# (degenerate cycles with repeated perspective_hashes).
|
|
55
|
+
seen_hashes: set[str] = set()
|
|
51
56
|
for pp_hash in perspective_hashes:
|
|
57
|
+
if pp_hash in seen_hashes:
|
|
58
|
+
continue
|
|
59
|
+
seen_hashes.add(pp_hash)
|
|
52
60
|
node = repo.find_by_hash(pp_hash, node_type=Perspective)
|
|
53
61
|
if node is None:
|
|
54
62
|
raise ValueError(f"Perspective not found: {pp_hash}")
|
|
@@ -43,7 +43,6 @@ from dialectical_framework.graph.repositories.wheel_repository import WheelRepos
|
|
|
43
43
|
from dialectical_framework.protocols.has_config import SettingsAware
|
|
44
44
|
from dialectical_framework.utils.sequence_generation import (
|
|
45
45
|
generate_compatible_sequences,
|
|
46
|
-
generate_permutation_sequences,
|
|
47
46
|
)
|
|
48
47
|
|
|
49
48
|
if TYPE_CHECKING:
|
|
@@ -123,26 +122,37 @@ class PerspectiveCombination(ReasonableConcern[CombinationResult], SettingsAware
|
|
|
123
122
|
self._report.ok = False
|
|
124
123
|
self._report.summary = "Nexus must be committed before combination"
|
|
125
124
|
return CombinationResult(
|
|
126
|
-
nexus=nexus,
|
|
127
|
-
|
|
125
|
+
nexus=nexus,
|
|
126
|
+
cycles=[],
|
|
127
|
+
wheels=[],
|
|
128
|
+
cycles_by_layer={},
|
|
129
|
+
wheels_by_layer={},
|
|
128
130
|
)
|
|
129
131
|
|
|
130
132
|
if not perspectives:
|
|
131
133
|
self._report.ok = False
|
|
132
134
|
self._report.summary = "No Perspectives provided"
|
|
133
135
|
return CombinationResult(
|
|
134
|
-
nexus=nexus,
|
|
135
|
-
|
|
136
|
+
nexus=nexus,
|
|
137
|
+
cycles=[],
|
|
138
|
+
wheels=[],
|
|
139
|
+
cycles_by_layer={},
|
|
140
|
+
wheels_by_layer={},
|
|
136
141
|
)
|
|
137
142
|
|
|
138
143
|
# Validate all PPs are committed
|
|
139
144
|
for pp in perspectives:
|
|
140
145
|
if not pp.is_committed:
|
|
141
146
|
self._report.ok = False
|
|
142
|
-
self._report.summary =
|
|
147
|
+
self._report.summary = (
|
|
148
|
+
"Perspective must be committed before combination"
|
|
149
|
+
)
|
|
143
150
|
return CombinationResult(
|
|
144
|
-
nexus=nexus,
|
|
145
|
-
|
|
151
|
+
nexus=nexus,
|
|
152
|
+
cycles=[],
|
|
153
|
+
wheels=[],
|
|
154
|
+
cycles_by_layer={},
|
|
155
|
+
wheels_by_layer={},
|
|
146
156
|
)
|
|
147
157
|
|
|
148
158
|
# Add PPs to Nexus (idempotent — skip already connected)
|
|
@@ -151,8 +161,19 @@ class PerspectiveCombination(ReasonableConcern[CombinationResult], SettingsAware
|
|
|
151
161
|
self._report.artifacts["nexus_hash"] = nexus.short_hash
|
|
152
162
|
self._report.artifacts["perspective_count"] = len(perspectives)
|
|
153
163
|
|
|
154
|
-
# Build from all PPs in Nexus (not just the ones passed in)
|
|
155
|
-
|
|
164
|
+
# Build from all PPs in Nexus (not just the ones passed in).
|
|
165
|
+
# Dedup by hash, preserving order: nexus.perspectives.all() can yield
|
|
166
|
+
# the same Perspective twice if a duplicate BELONGS_TO_NEXUS edge exists
|
|
167
|
+
# (BELONGS_TO_NEXUS is a directed relationship — connect() does NOT
|
|
168
|
+
# deduplicate it). combinations() over a list with repeats produces
|
|
169
|
+
# degenerate cycles whose perspective_hashes repeat a PP, corrupting
|
|
170
|
+
# all downstream wheel rendering.
|
|
171
|
+
seen: set[str] = set()
|
|
172
|
+
all_nexus_pps = [
|
|
173
|
+
pp
|
|
174
|
+
for pp, _ in nexus.perspectives.all()
|
|
175
|
+
if pp.hash not in seen and not seen.add(pp.hash)
|
|
176
|
+
]
|
|
156
177
|
total_pps = len(all_nexus_pps)
|
|
157
178
|
|
|
158
179
|
# Build combinations layer by layer, collect only new structures
|
|
@@ -265,8 +286,8 @@ class PerspectiveCombination(ReasonableConcern[CombinationResult], SettingsAware
|
|
|
265
286
|
"""
|
|
266
287
|
Generate T-cycle permutations for a PP combination.
|
|
267
288
|
|
|
268
|
-
|
|
269
|
-
|
|
289
|
+
Fixes the first perspective and permutes the rest to produce all
|
|
290
|
+
(N-1)! unique cycle orderings (circular rotation equivalence eliminated).
|
|
270
291
|
|
|
271
292
|
Returns:
|
|
272
293
|
Tuple of (all_cycles, new_cycles)
|
|
@@ -282,26 +303,17 @@ class PerspectiveCombination(ReasonableConcern[CombinationResult], SettingsAware
|
|
|
282
303
|
new_cycles.append(cycle)
|
|
283
304
|
return all_cycles, new_cycles
|
|
284
305
|
|
|
285
|
-
#
|
|
286
|
-
t_components: list[Statement] = []
|
|
287
|
-
comp_hash_to_pp: dict[str, Perspective] = {}
|
|
306
|
+
# Validate all PPs have T components
|
|
288
307
|
for pp in perspectives:
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
continue
|
|
292
|
-
t_comp = t_result[0]
|
|
293
|
-
t_components.append(t_comp)
|
|
294
|
-
comp_hash_to_pp[t_comp.hash] = pp
|
|
308
|
+
if not pp.t.get():
|
|
309
|
+
return all_cycles, new_cycles
|
|
295
310
|
|
|
296
|
-
|
|
297
|
-
|
|
311
|
+
# Generate all (N-1)! orderings by fixing first PP, permuting rest
|
|
312
|
+
from itertools import permutations as itertools_permutations
|
|
298
313
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
for sequence in sequences:
|
|
303
|
-
# Map component sequence back to PP ordering
|
|
304
|
-
ordered_pps = [comp_hash_to_pp[comp.hash] for comp in sequence]
|
|
314
|
+
first, rest = perspectives[0], perspectives[1:]
|
|
315
|
+
for perm in itertools_permutations(rest):
|
|
316
|
+
ordered_pps = [first, *perm]
|
|
305
317
|
|
|
306
318
|
cycle, is_new = self._find_or_create_cycle(ordered_pps)
|
|
307
319
|
all_cycles.append(cycle)
|
|
@@ -324,13 +336,17 @@ class PerspectiveCombination(ReasonableConcern[CombinationResult], SettingsAware
|
|
|
324
336
|
Returns:
|
|
325
337
|
Tuple of (Cycle, is_new)
|
|
326
338
|
"""
|
|
327
|
-
from dialectical_framework.graph.repositories.cycle_repository import
|
|
339
|
+
from dialectical_framework.graph.repositories.cycle_repository import (
|
|
340
|
+
CycleRepository,
|
|
341
|
+
)
|
|
328
342
|
|
|
329
343
|
# Layer-1 (single PP) Cycles have no causality intent (nothing to order)
|
|
330
344
|
intent = self._preset if len(perspectives) >= 2 else None
|
|
331
345
|
|
|
332
346
|
cycle_repo = CycleRepository()
|
|
333
|
-
existing_cycles = cycle_repo.find_by_perspectives(
|
|
347
|
+
existing_cycles = cycle_repo.find_by_perspectives(
|
|
348
|
+
perspectives, exact_order=True
|
|
349
|
+
)
|
|
334
350
|
|
|
335
351
|
for cycle in existing_cycles:
|
|
336
352
|
if cycle.intent == intent:
|
|
@@ -402,9 +418,7 @@ class PerspectiveCombination(ReasonableConcern[CombinationResult], SettingsAware
|
|
|
402
418
|
transition.commit()
|
|
403
419
|
transition.cycle.connect(wheel)
|
|
404
420
|
self._report.node_created(transition)
|
|
405
|
-
self._report.relationship_created(
|
|
406
|
-
transition.cycle, transition, wheel
|
|
407
|
-
)
|
|
421
|
+
self._report.relationship_created(transition.cycle, transition, wheel)
|
|
408
422
|
|
|
409
423
|
# Connect to cycle
|
|
410
424
|
cycle.wheels.connect(wheel)
|
|
@@ -432,7 +446,9 @@ class PerspectiveCombination(ReasonableConcern[CombinationResult], SettingsAware
|
|
|
432
446
|
Two sequences are opposite-direction if one is a circular reverse of the other.
|
|
433
447
|
Connects pairs via the OPPOSITE_DIRECTION symmetric relationship.
|
|
434
448
|
"""
|
|
435
|
-
from dialectical_framework.graph.repositories.cycle_repository import
|
|
449
|
+
from dialectical_framework.graph.repositories.cycle_repository import (
|
|
450
|
+
CycleRepository,
|
|
451
|
+
)
|
|
436
452
|
|
|
437
453
|
cycle_repo = CycleRepository()
|
|
438
454
|
wheel_repo = WheelRepository()
|
|
@@ -461,7 +477,7 @@ def _connect_opposite_direction_cycles(
|
|
|
461
477
|
|
|
462
478
|
for i, cycle_a in enumerate(cycles):
|
|
463
479
|
seq_a = cycle_a.perspective_hashes
|
|
464
|
-
for cycle_b in cycles[i + 1:]:
|
|
480
|
+
for cycle_b in cycles[i + 1 :]:
|
|
465
481
|
seq_b = cycle_b.perspective_hashes
|
|
466
482
|
if _is_circular_reverse(seq_a, seq_b):
|
|
467
483
|
pair_id = tuple(sorted([cycle_a.hash, cycle_b.hash]))
|
|
@@ -486,7 +502,7 @@ def _connect_opposite_direction_wheels(
|
|
|
486
502
|
wheel_sequences.append((wheel, comp_hashes))
|
|
487
503
|
|
|
488
504
|
for i, (wheel_a, seq_a) in enumerate(wheel_sequences):
|
|
489
|
-
for wheel_b, seq_b in wheel_sequences[i + 1:]:
|
|
505
|
+
for wheel_b, seq_b in wheel_sequences[i + 1 :]:
|
|
490
506
|
if _is_circular_reverse(seq_a, seq_b):
|
|
491
507
|
pair_id = tuple(sorted([wheel_a.hash, wheel_b.hash]))
|
|
492
508
|
if pair_id not in connected:
|
|
@@ -508,7 +524,4 @@ def _is_circular_reverse(seq_a: list[str], seq_b: list[str]) -> bool:
|
|
|
508
524
|
if len(seq_a) <= 2:
|
|
509
525
|
return False
|
|
510
526
|
reversed_a = list(reversed(seq_a))
|
|
511
|
-
return any(
|
|
512
|
-
reversed_a[i:] + reversed_a[:i] == seq_b
|
|
513
|
-
for i in range(len(reversed_a))
|
|
514
|
-
)
|
|
527
|
+
return any(reversed_a[i:] + reversed_a[:i] == seq_b for i in range(len(reversed_a)))
|
|
@@ -14,7 +14,11 @@ from typing import ClassVar, Optional, TYPE_CHECKING
|
|
|
14
14
|
|
|
15
15
|
from dialectical_framework.graph.nodes.assessable_entity import AssessableEntity
|
|
16
16
|
from dialectical_framework.graph.mixins.intent_mixin import IntentMixin
|
|
17
|
-
from dialectical_framework.graph.relationship_manager import
|
|
17
|
+
from dialectical_framework.graph.relationship_manager import (
|
|
18
|
+
RelationshipTo,
|
|
19
|
+
RelationshipBoth,
|
|
20
|
+
RelationshipManager,
|
|
21
|
+
)
|
|
18
22
|
from dialectical_framework.graph.relationships.has_wheel_relationship import (
|
|
19
23
|
HasWheelRelationship,
|
|
20
24
|
)
|
|
@@ -82,7 +86,7 @@ class Cycle(IntentMixin, AssessableEntity, label="Cycle"):
|
|
|
82
86
|
wheels: ClassVar[RelationshipManager[Wheel]] = RelationshipTo(
|
|
83
87
|
"Wheel",
|
|
84
88
|
model=HasWheelRelationship,
|
|
85
|
-
cardinality=(0, None) # Zero or more wheels can implement this cycle
|
|
89
|
+
cardinality=(0, None), # Zero or more wheels can implement this cycle
|
|
86
90
|
)
|
|
87
91
|
|
|
88
92
|
# Opposite-direction counterpart (symmetric)
|
|
@@ -100,22 +104,31 @@ class Cycle(IntentMixin, AssessableEntity, label="Cycle"):
|
|
|
100
104
|
Order determines the T-cycle: T1 → T2 → T3 → T1...
|
|
101
105
|
|
|
102
106
|
Args:
|
|
103
|
-
perspectives: Ordered list of committed Perspectives
|
|
107
|
+
perspectives: Ordered list of committed, distinct Perspectives
|
|
104
108
|
|
|
105
109
|
Returns:
|
|
106
110
|
Self for chaining
|
|
107
111
|
|
|
108
112
|
Raises:
|
|
109
|
-
ValueError: If any PP is not committed
|
|
113
|
+
ValueError: If any PP is not committed, or if any PP is repeated
|
|
110
114
|
"""
|
|
111
115
|
hashes = []
|
|
112
116
|
for pp in perspectives:
|
|
113
117
|
if not pp.is_committed:
|
|
114
|
-
raise ValueError(
|
|
115
|
-
"Perspective must be committed before adding to Cycle"
|
|
116
|
-
)
|
|
118
|
+
raise ValueError("Perspective must be committed before adding to Cycle")
|
|
117
119
|
hashes.append(pp.hash)
|
|
118
120
|
|
|
121
|
+
# Reject duplicate perspectives. A cycle claiming to be "layer N"
|
|
122
|
+
# (N = len(perspective_hashes)) must reference N *distinct* PPs.
|
|
123
|
+
# Duplicates produce degenerate cycles (e.g. combinations() over a
|
|
124
|
+
# PP list poisoned by a transient duplicate BELONGS_TO_NEXUS edge)
|
|
125
|
+
# that render as malformed wheels. Fail loud so corruption is never
|
|
126
|
+
# persisted rather than surfacing later in the consuming app.
|
|
127
|
+
if len(set(hashes)) != len(hashes):
|
|
128
|
+
raise ValueError(
|
|
129
|
+
f"Cycle perspectives must be distinct; got duplicates in {hashes}"
|
|
130
|
+
)
|
|
131
|
+
|
|
119
132
|
self.perspective_hashes = hashes
|
|
120
133
|
self._pp_refs = perspectives # Keep refs for potential use
|
|
121
134
|
return self
|
|
@@ -133,7 +146,10 @@ class Cycle(IntentMixin, AssessableEntity, label="Cycle"):
|
|
|
133
146
|
if not self.perspective_hashes:
|
|
134
147
|
return []
|
|
135
148
|
|
|
136
|
-
from dialectical_framework.graph.repositories.node_repository import
|
|
149
|
+
from dialectical_framework.graph.repositories.node_repository import (
|
|
150
|
+
NodeRepository,
|
|
151
|
+
)
|
|
152
|
+
|
|
137
153
|
repo = NodeRepository()
|
|
138
154
|
|
|
139
155
|
result = []
|
|
@@ -268,4 +284,3 @@ class Cycle(IntentMixin, AssessableEntity, label="Cycle"):
|
|
|
268
284
|
hash_str = self.short_hash if self.is_committed else "uncommitted"
|
|
269
285
|
pp_count = len(self.perspective_hashes)
|
|
270
286
|
return f"Cycle({hash_str}, pp_count={pp_count}, intent={self.intent})"
|
|
271
|
-
|
|
File without changes
|
|
File without changes
|
{dialectical_framework-1.5.4 → dialectical_framework-1.5.6}/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
|
|
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
|