dialectical-framework 1.1.1__tar.gz → 1.1.3__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.1.1 → dialectical_framework-1.1.3}/PKG-INFO +1 -1
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/pyproject.toml +1 -1
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/analyst/analyst.py +3 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/analyst/skills/expand_polarities.py +6 -16
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/analyst/skills/find_polarities.py +2 -1
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/analyst/system_prompts.py +28 -2
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/apps.py +8 -1
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/conversation_facilitator.py +6 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/explorer/explorer.py +3 -3
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/explorer/system_prompts.py +2 -5
- dialectical_framework-1.1.3/src/dialectical_framework/agents/explorer/tools/create_nexus.py +41 -0
- dialectical_framework-1.1.3/src/dialectical_framework/agents/explorer/tools/expand_nexus.py +27 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/explorer/tools/present_exploration.py +2 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/orchestrator/tools/get_schema.py +1 -1
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/orchestrator/tools/inspect_node.py +2 -1
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/orchestrator/tools/present_analysis.py +4 -1
- {dialectical_framework-1.1.1/src/dialectical_framework/agents/explorer/tools → dialectical_framework-1.1.3/src/dialectical_framework/concerns}/create_nexus.py +10 -21
- dialectical_framework-1.1.3/src/dialectical_framework/concerns/expand_nexus.py +79 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/nexus.py +14 -7
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/LICENSE +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/README.md +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/agent_context.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/analyst/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/analyst/skills/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/analyst/skills/anchor_theses.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/analyst/skills/edit_perspective.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/analyst/skills/introduce_polarity.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/analyst/skills/surface_theses.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/analyst/tools/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/analyst/tools/create_dx_input.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/analyst/tools/place_statement.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/execution_report.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/explorer/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/explorer/skills/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/explorer/skills/build_wheels.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/explorer/skills/explore_transformations.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/explorer/tools/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/orchestrator/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/orchestrator/tools/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/orchestrator/tools/add_input.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/orchestrator/tools/discard.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/orchestrator/tools/query_graph.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/reasonable_concern.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/stream_events.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/ac_re_taxonomy.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/action_extraction.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/ai_dto/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/ai_dto/statement_dto.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/ai_dto/statements_deck_dto.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/antithesis_classification.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/antithesis_extraction.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/aspect_classification.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/aspect_generation.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/causality/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/causality/causality_estimator.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/causality/causality_estimator_balanced.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/causality/causality_estimator_criteria.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/causality/causality_estimator_desirable.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/causality/causality_estimator_feasible.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/causality/causality_estimator_realistic.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/causality/causality_normalizer.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/causality/estimator_resolver.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/causality_estimation.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/control_statements_check.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/diagonal_oppositions_check.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/display_text_edit.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/perspective_combination.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/perspective_validation.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/positive_ac_re_apex_derivation.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/statement_classification.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/statement_deduplication.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/statement_placement.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/synthesis_generation.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/thesis_extraction.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/transformation_audit.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/concerns/transformation_generation.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/dialectical_reasoning.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/enums/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/enums/causality_preset.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/enums/di.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/events/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/events/graph_event.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/events/graph_event_bus.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/exceptions/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/exceptions/node_errors.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/exceptions/resolver_errors.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/composite_input_resolver.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/dialexity_input_resolver.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/estimation_manager.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/mixins/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/mixins/incremental_build_mixin.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/mixins/intent_mixin.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/mixins/persistable_mixin.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/assessable_entity.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/base_node.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/case.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/cycle.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/estimation.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/ideas.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/input.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/perspective.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/polarity.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/rationale.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/statement.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/synthesis.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/transformation.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/transition.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/nodes/wheel.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationship_manager.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/action_reflection_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/belongs_to_cycle_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/belongs_to_nexus_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/changed_to_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/contradiction_of_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/critiques_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/distilled_to_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/estimates_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/explains_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/has_input_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/has_statement_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/has_wheel_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/immutable_structure.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/is_source_of_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/is_target_of_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/negative_side_of_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/opposite_direction_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/opposite_of_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/polarity_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/positive_side_of_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/provides_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/relationships/synthesis_of_relationship.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/repositories/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/repositories/case_repository.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/repositories/cycle_repository.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/repositories/input_repository.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/repositories/nexus_repository.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/repositories/node_repository.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/repositories/perspective_repository.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/repositories/polarity_repository.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/repositories/schema_repository.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/repositories/statement_repository.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/repositories/transformation_repository.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/repositories/wheel_repository.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/scope_context.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/verbatim_input_resolver.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/wheel_segment.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/graph/wheel_segment_polar_pair.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/protocols/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/protocols/has_config.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/protocols/input_resolver.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/settings.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/utils/__init__.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/utils/bedrock_provider.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/utils/dc_replace.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/utils/decompose_probability_uniformly.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/utils/edge_context.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/utils/effect_logger.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/utils/order_transitions.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/utils/sequence_generation.py +0 -0
- {dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/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.1.
|
|
3
|
+
Version: 1.1.3
|
|
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.1.
|
|
3
|
+
version = "1.1.3"
|
|
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"
|
|
@@ -113,6 +113,8 @@ def _build_tools() -> list:
|
|
|
113
113
|
place_statement
|
|
114
114
|
from dialectical_framework.agents.explorer.tools.create_nexus import \
|
|
115
115
|
create_nexus
|
|
116
|
+
from dialectical_framework.agents.explorer.tools.expand_nexus import \
|
|
117
|
+
expand_nexus
|
|
116
118
|
from dialectical_framework.agents.orchestrator.tools.add_input import \
|
|
117
119
|
add_input
|
|
118
120
|
from dialectical_framework.agents.orchestrator.tools.get_schema import \
|
|
@@ -138,6 +140,7 @@ def _build_tools() -> list:
|
|
|
138
140
|
edit_perspective,
|
|
139
141
|
discard,
|
|
140
142
|
create_nexus,
|
|
143
|
+
expand_nexus,
|
|
141
144
|
present_analysis,
|
|
142
145
|
inspect_node,
|
|
143
146
|
query_graph,
|
|
@@ -91,20 +91,9 @@ class ExpandPolarity(ReasonableConcern[list[Perspective]]):
|
|
|
91
91
|
partial_pps = [pp for pp in existing_pps if not pp.is_complete()]
|
|
92
92
|
|
|
93
93
|
if not partial_pps:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
)
|
|
98
|
-
self._report.artifacts["perspective_hashes"] = [
|
|
99
|
-
pp.hash for pp in complete_pps if pp.hash
|
|
100
|
-
]
|
|
101
|
-
self._report.artifacts["total_count"] = len(complete_pps)
|
|
102
|
-
self._report.artifacts["existing_count"] = len(complete_pps)
|
|
103
|
-
self._report.artifacts["new_count"] = 0
|
|
104
|
-
self._report.artifacts["perspectives"] = [
|
|
105
|
-
self._perspective_final_state(pp) for pp in complete_pps
|
|
106
|
-
]
|
|
107
|
-
return complete_pps
|
|
94
|
+
# All existing perspectives are complete — create a new one
|
|
95
|
+
pp = self._create_perspective_for_polarity(polarity)
|
|
96
|
+
partial_pps = [pp]
|
|
108
97
|
|
|
109
98
|
# Complete all partial PPs
|
|
110
99
|
completed_pps: list[Perspective] = []
|
|
@@ -314,7 +303,7 @@ class ExpandPolarity(ReasonableConcern[list[Perspective]]):
|
|
|
314
303
|
async def expand_polarities(
|
|
315
304
|
polarity_hashes: Annotated[list[str], Field(description="Hashes of Polarities to expand into full Perspectives")],
|
|
316
305
|
) -> str:
|
|
317
|
-
"""Build complete Perspectives from Polarities by generating evaluative aspects (T+, T-, A+, A-) for each.
|
|
306
|
+
"""Build complete Perspectives from Polarities by generating evaluative aspects (T+, T-, A+, A-) for each. Each call generates one new Perspective per Polarity — call multiple times for alternative perspectives on the same Polarity (duplicates in a single call are ignored). The Polarities must already exist in the graph."""
|
|
318
307
|
import asyncio
|
|
319
308
|
|
|
320
309
|
async def _expand_one(h: str) -> str:
|
|
@@ -322,5 +311,6 @@ async def expand_polarities(
|
|
|
322
311
|
await concern.resolve()
|
|
323
312
|
return str(concern.report)
|
|
324
313
|
|
|
325
|
-
|
|
314
|
+
unique_hashes = list(dict.fromkeys(polarity_hashes))
|
|
315
|
+
results = await asyncio.gather(*[_expand_one(h) for h in unique_hashes])
|
|
326
316
|
return "\n---\n".join(results)
|
|
@@ -155,8 +155,9 @@ class FindPolarities(ReasonableConcern[Optional[Ideas]]):
|
|
|
155
155
|
result.existing = existing_antitheses
|
|
156
156
|
return result
|
|
157
157
|
|
|
158
|
+
unique_hashes = list(dict.fromkeys(self.thesis_hashes))
|
|
158
159
|
thesis_results = await asyncio.gather(
|
|
159
|
-
*[_process_thesis(h) for h in
|
|
160
|
+
*[_process_thesis(h) for h in unique_hashes]
|
|
160
161
|
)
|
|
161
162
|
|
|
162
163
|
for result in thesis_results:
|
|
@@ -51,7 +51,7 @@ Always check resonance AFTER presenting results — but never before acting.
|
|
|
51
51
|
- If the user gives a single concept: call `anchor_theses` with that concept as a statement.
|
|
52
52
|
- If the user disagrees with a generated aspect: offer `edit_perspective` with their correction, or `discard` if the whole perspective misses the mark.
|
|
53
53
|
- If the user corrects or refines: use `edit_perspective` or `discard` immediately
|
|
54
|
-
- If the user wants to explore interactions:
|
|
54
|
+
- If the user wants to explore interactions: see "Exploration Setup" section below
|
|
55
55
|
- If the user asks "what do we have?": use `present_analysis`
|
|
56
56
|
- If the user works step-by-step: follow their lead with granular tools
|
|
57
57
|
- When resuming with existing data: use `present_analysis` to orient
|
|
@@ -59,6 +59,29 @@ Always check resonance AFTER presenting results — but never before acting.
|
|
|
59
59
|
When new tensions emerge from conversation:
|
|
60
60
|
- Call `analyze` with `thesis_hashes` to develop them without re-processing everything.
|
|
61
61
|
|
|
62
|
+
## Exploration Setup (Nexus)
|
|
63
|
+
|
|
64
|
+
When the user wants to explore interactions between perspectives:
|
|
65
|
+
|
|
66
|
+
**Before creating:**
|
|
67
|
+
1. Check existing nexuses via `present_analysis`.
|
|
68
|
+
2. If a nexus with similar intent exists — suggest `expand_nexus` to add perspectives to it.
|
|
69
|
+
Only create separate if user deliberately wants a different scope.
|
|
70
|
+
3. Confirm the exploration direction with the user before creating.
|
|
71
|
+
|
|
72
|
+
**Intent (internal quality gate — do not surface to user):**
|
|
73
|
+
- Must be specific: what the user wants to understand or navigate.
|
|
74
|
+
- Refine vague requests ("explore this") into purposeful intents internally.
|
|
75
|
+
|
|
76
|
+
**Title:**
|
|
77
|
+
- Derive a concise title (1-3 words) from the intent silently. No confirmation needed.
|
|
78
|
+
|
|
79
|
+
**Deduplication (always communicate to the user):**
|
|
80
|
+
- If a nexus with similar intent exists, tell the user: name the existing nexus, show its intent,
|
|
81
|
+
and ask whether to add perspectives there or create a separate exploration.
|
|
82
|
+
- Never silently redirect to `expand_nexus` — the user must see why and agree.
|
|
83
|
+
- Only skip the prompt if the user explicitly names the existing nexus themselves.
|
|
84
|
+
|
|
62
85
|
## Tools
|
|
63
86
|
|
|
64
87
|
**Full pipeline:**
|
|
@@ -79,7 +102,8 @@ When new tensions emerge from conversation:
|
|
|
79
102
|
- `discard` — Discard statements or perspectives the user doesn't want.
|
|
80
103
|
|
|
81
104
|
**Exploration setup:**
|
|
82
|
-
- `create_nexus` —
|
|
105
|
+
- `create_nexus` — Create a new exploration grouping perspectives.
|
|
106
|
+
- `expand_nexus` — Add perspectives to an existing exploration.
|
|
83
107
|
|
|
84
108
|
**Querying:**
|
|
85
109
|
- `present_analysis` — Overview of what's been built.
|
|
@@ -94,6 +118,8 @@ Adapt depth and presentation to the persona defined in the app preamble.
|
|
|
94
118
|
## Rules
|
|
95
119
|
|
|
96
120
|
- Never dump raw tool output. Synthesize into appropriate presentation.
|
|
121
|
+
- Never rephrase Statement text. Use exact text (or display_text) from the graph — paraphrasing makes it ambiguous which node you're referring to.
|
|
122
|
+
- When referencing structural nodes (Polarity, Perspective, Nexus, Cycle, Wheel, Transformation, Transition, Synthesis), always include the short hash for disambiguation.
|
|
97
123
|
- User corrections take priority — act immediately, don't push back.
|
|
98
124
|
- When resuming a session with existing data, use `present_analysis` to orient before acting.
|
|
99
125
|
- Skill reports may contain truncated text previews. When you need to present exact node text to the user, use `inspect_node` or `present_analysis` by hash — never reconstruct or guess full text from truncated previews.
|
{dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/agents/apps.py
RENAMED
|
@@ -199,6 +199,13 @@ both sides contribute", "constructive co-existence", "where 1+1 > 2".
|
|
|
199
199
|
- Frame pathways as options, not prescriptions. There are many valid recipes.
|
|
200
200
|
- Present tensions as legitimate — both poles have constructive potential.
|
|
201
201
|
|
|
202
|
+
## Viewport Scope
|
|
203
|
+
|
|
204
|
+
Messages may include context about what the user is currently viewing. This tells you their active focus. Respect it:
|
|
205
|
+
|
|
206
|
+
- Only operate on the node(s) in the user's viewport unless they explicitly reference something else or ask to switch.
|
|
207
|
+
- Never silently pivot to other nodes outside the viewport. If you think working on a different node would help, ask first.
|
|
208
|
+
|
|
202
209
|
## Presentation Defaults
|
|
203
210
|
|
|
204
211
|
Example of a correctly labeled position table:
|
|
@@ -213,7 +220,7 @@ Example of a correctly labeled position table:
|
|
|
213
220
|
The "blindspot" label belongs ONLY to A+ and A- (the opposition's territory).
|
|
214
221
|
T+ and T- are the holder's own visible territory — never label them as blindspots.
|
|
215
222
|
|
|
216
|
-
- Never mention tool names, pipelines, graph operations
|
|
223
|
+
- Never mention tool names, pipelines, or graph operations.
|
|
217
224
|
- User-facing structural terms (Wheel, Nexus, Cycle, Transformation, Position,
|
|
218
225
|
Polarity) are fine to use — these are part of the UX vocabulary.
|
|
219
226
|
- Position labels (T+, T-, A+, A-) can be introduced once the user understands
|
|
@@ -293,6 +293,12 @@ class ConversationFacilitator(SettingsAware):
|
|
|
293
293
|
"""Call LLM with format for structured output."""
|
|
294
294
|
messages = self._messages
|
|
295
295
|
|
|
296
|
+
# Bedrock requires conversations to end with a user message.
|
|
297
|
+
# After the agentic tool loop, messages end with assistant — inject a
|
|
298
|
+
# user prompt so the extraction call is valid for all providers.
|
|
299
|
+
if messages and messages[-1].role == "assistant":
|
|
300
|
+
messages = [*messages, llm.messages.user("Provide your structured response.")]
|
|
301
|
+
|
|
296
302
|
@use_brain(format=response_model)
|
|
297
303
|
async def _llm_call():
|
|
298
304
|
return messages
|
|
@@ -119,8 +119,8 @@ def _build_tools() -> list:
|
|
|
119
119
|
build_wheels
|
|
120
120
|
from dialectical_framework.agents.explorer.skills.explore_transformations import \
|
|
121
121
|
explore_transformations
|
|
122
|
-
from dialectical_framework.agents.explorer.tools.
|
|
123
|
-
|
|
122
|
+
from dialectical_framework.agents.explorer.tools.expand_nexus import \
|
|
123
|
+
expand_nexus
|
|
124
124
|
from dialectical_framework.agents.explorer.tools.present_exploration import \
|
|
125
125
|
present_exploration
|
|
126
126
|
from dialectical_framework.agents.orchestrator.tools.get_schema import \
|
|
@@ -133,7 +133,7 @@ def _build_tools() -> list:
|
|
|
133
133
|
return [
|
|
134
134
|
build_wheels,
|
|
135
135
|
explore_transformations,
|
|
136
|
-
|
|
136
|
+
expand_nexus,
|
|
137
137
|
present_exploration,
|
|
138
138
|
inspect_node,
|
|
139
139
|
query_graph,
|
|
@@ -44,14 +44,10 @@ When the user wants to go deeper on a specific transformation:
|
|
|
44
44
|
- Use `inspect_node` to show full detail.
|
|
45
45
|
- Explain the tetrad structure: Ac/Ac+/Ac- and Re/Re+/Re-.
|
|
46
46
|
|
|
47
|
-
When the user wants to create a sub-exploration:
|
|
48
|
-
- Use `create_nexus` to group a subset of perspectives for focused exploration.
|
|
49
|
-
|
|
50
47
|
## Tools
|
|
51
48
|
|
|
52
49
|
- `build_wheels` -- Generate causal structures (Cycles + Wheels) from this Nexus. Use nexus_hash: "{nexus_hash}".
|
|
53
50
|
- `explore_transformations` -- Generate Action-Reflection transformations for a Wheel.
|
|
54
|
-
- `create_nexus` -- Create a sub-nexus for focused exploration of specific perspectives.
|
|
55
51
|
- `present_exploration` -- Show current state of this Nexus: perspectives, wheels, transformations.
|
|
56
52
|
- `inspect_node` -- Deep-dive any node by hash.
|
|
57
53
|
- `query_graph` -- Raw Cypher for custom queries. Call `get_schema` first.
|
|
@@ -64,7 +60,8 @@ Adapt depth and presentation to the persona defined in the app preamble.
|
|
|
64
60
|
## Rules
|
|
65
61
|
|
|
66
62
|
- Never dump raw tool output. Synthesize into appropriate presentation.
|
|
67
|
-
-
|
|
63
|
+
- Never rephrase Statement text. Use exact text (or display_text) from the graph — paraphrasing makes it ambiguous which node you're referring to.
|
|
64
|
+
- When referencing structural nodes (Polarity, Perspective, Nexus, Cycle, Wheel, Transformation, Transition, Synthesis), always include the short hash for disambiguation.
|
|
68
65
|
- If the user wants to analyze new material, suggest they return to the analysis thread.
|
|
69
66
|
- Skill reports may contain truncated text previews. When you need to present exact node text to the user, use `inspect_node` or `present_analysis` by hash — never reconstruct or guess full text from truncated previews.
|
|
70
67
|
"""
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""
|
|
2
|
+
create_nexus tool: thin LLM-facing wrapper around the CreateNexus concern.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Annotated, Optional
|
|
8
|
+
|
|
9
|
+
from mirascope import llm
|
|
10
|
+
from pydantic import Field
|
|
11
|
+
|
|
12
|
+
from dialectical_framework.concerns.create_nexus import CreateNexus
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@llm.tool
|
|
16
|
+
async def create_nexus(
|
|
17
|
+
intent: Annotated[
|
|
18
|
+
str, Field(description="Exploration purpose — what to understand or navigate")
|
|
19
|
+
],
|
|
20
|
+
perspective_hashes: Annotated[
|
|
21
|
+
list[str], Field(description="Hashes of Perspectives to include")
|
|
22
|
+
],
|
|
23
|
+
title: Annotated[
|
|
24
|
+
Optional[str],
|
|
25
|
+
Field(
|
|
26
|
+
description="Short title for UI display (1-3 words, derived from intent)"
|
|
27
|
+
),
|
|
28
|
+
] = None,
|
|
29
|
+
preset: Annotated[
|
|
30
|
+
str,
|
|
31
|
+
Field(
|
|
32
|
+
description="Estimation strategy: 'preset:auto', 'preset:balanced', 'preset:realistic', 'preset:desirable', 'preset:feasible'"
|
|
33
|
+
),
|
|
34
|
+
] = "preset:auto",
|
|
35
|
+
) -> str:
|
|
36
|
+
"""Create a Nexus — an exploration container that groups Perspectives for structural combination into Cycles and Wheels. The intent describes what to explore or navigate."""
|
|
37
|
+
concern = CreateNexus()
|
|
38
|
+
await concern.resolve(
|
|
39
|
+
intent=intent, perspective_hashes=perspective_hashes, preset=preset, title=title
|
|
40
|
+
)
|
|
41
|
+
return str(concern.report)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
expand_nexus tool: thin LLM-facing wrapper around the ExpandNexus concern.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Annotated
|
|
8
|
+
|
|
9
|
+
from mirascope import llm
|
|
10
|
+
from pydantic import Field
|
|
11
|
+
|
|
12
|
+
from dialectical_framework.concerns.expand_nexus import ExpandNexus
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@llm.tool
|
|
16
|
+
async def expand_nexus(
|
|
17
|
+
nexus_hash: Annotated[
|
|
18
|
+
str, Field(description="Hash of the existing Nexus to expand")
|
|
19
|
+
],
|
|
20
|
+
perspective_hashes: Annotated[
|
|
21
|
+
list[str], Field(description="Hashes of Perspectives to add")
|
|
22
|
+
],
|
|
23
|
+
) -> str:
|
|
24
|
+
"""Add Perspectives to an existing Nexus. Skips any already connected. Use when the user wants to include additional perspectives in an existing exploration rather than creating a new one."""
|
|
25
|
+
concern = ExpandNexus()
|
|
26
|
+
await concern.resolve(nexus_hash=nexus_hash, perspective_hashes=perspective_hashes)
|
|
27
|
+
return str(concern.report)
|
|
@@ -82,6 +82,8 @@ class PresentExploration(ReasonableConcern[str]):
|
|
|
82
82
|
@staticmethod
|
|
83
83
|
def _format_nexus_header(nexus: Nexus) -> str:
|
|
84
84
|
lines = [f"## Nexus [{nexus.short_hash}]"]
|
|
85
|
+
if nexus.title:
|
|
86
|
+
lines.append(f"Title: {nexus.title}")
|
|
85
87
|
if nexus.intent:
|
|
86
88
|
lines.append(f"Intent: {nexus.intent}")
|
|
87
89
|
if nexus.preset:
|
|
@@ -25,7 +25,7 @@ GRAPH_SCHEMA = """## Graph Schema
|
|
|
25
25
|
| Statement | A thesis, position, or claim | `text`, `meaning`, `discarded` |
|
|
26
26
|
| Polarity | A tension — structural T-A pair (thesis vs antithesis) | |
|
|
27
27
|
| Perspective | Full interpretation: Polarity + evaluative aspects (T+, T-, A+, A-) | `intent`, `discarded` |
|
|
28
|
-
| Nexus | Exploration container grouping Perspectives for combination | `intent`, `preset` |
|
|
28
|
+
| Nexus | Exploration container grouping Perspectives for combination | `intent`, `preset`, `title` |
|
|
29
29
|
| Cycle | Ordered sequence of Perspectives defining causality | `intent` |
|
|
30
30
|
| Wheel | Concrete T-A arrangement implementing a Cycle | `intent` |
|
|
31
31
|
| Transformation | Action-reflection structure (Ac, Re, Ac+, Ac-, Re+, Re-) on a Wheel edge | `intent` |
|
|
@@ -238,7 +238,8 @@ def _inspect_nexus(nexus: Nexus) -> str:
|
|
|
238
238
|
lines: list[str] = []
|
|
239
239
|
|
|
240
240
|
# Header
|
|
241
|
-
|
|
241
|
+
title_suffix = f" — {nexus.title}" if nexus.title else ""
|
|
242
|
+
lines.append(f"## Nexus [{_node_id(nexus)}]{title_suffix}{_status_tag(nexus)}")
|
|
242
243
|
lines.append(repr(nexus))
|
|
243
244
|
lines.append("")
|
|
244
245
|
|
|
@@ -136,7 +136,10 @@ class PresentAnalysis(ReasonableConcern[str]):
|
|
|
136
136
|
lines = ["## Nexuses"]
|
|
137
137
|
for n in nexuses:
|
|
138
138
|
pp_list = [(pp, _) for pp, _ in n.perspectives.all() if not pp.discarded]
|
|
139
|
-
|
|
139
|
+
display = n.title or n.intent or "(no intent)"
|
|
140
|
+
lines.append(f"\n [{n.short_hash}] {display} ({len(pp_list)} perspectives)")
|
|
141
|
+
if n.title and n.intent:
|
|
142
|
+
lines.append(f" Intent: {n.intent}")
|
|
140
143
|
lines.append(f" Preset: {n.preset or 'default'}")
|
|
141
144
|
for pp, _ in pp_list:
|
|
142
145
|
lines.append(f" - [{pp.short_hash}] {pp:positions:0}")
|
|
@@ -1,23 +1,18 @@
|
|
|
1
1
|
"""
|
|
2
|
-
CreateNexus:
|
|
2
|
+
CreateNexus concern: creates an exploration container and connects Perspectives to it.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
7
|
from dataclasses import dataclass
|
|
8
|
-
from typing import
|
|
9
|
-
|
|
10
|
-
from dependency_injector.wiring import Provide, inject
|
|
11
|
-
from gqlalchemy import Memgraph, Neo4j
|
|
12
|
-
from mirascope import llm
|
|
13
|
-
from pydantic import Field
|
|
8
|
+
from typing import Optional
|
|
14
9
|
|
|
15
10
|
from dialectical_framework.agents.reasonable_concern import ReasonableConcern
|
|
16
11
|
from dialectical_framework.enums.causality_preset import CausalityPreset
|
|
17
|
-
from dialectical_framework.enums.di import DI
|
|
18
12
|
from dialectical_framework.graph.nodes.nexus import Nexus
|
|
19
13
|
from dialectical_framework.graph.nodes.perspective import Perspective
|
|
20
|
-
from dialectical_framework.graph.repositories.node_repository import
|
|
14
|
+
from dialectical_framework.graph.repositories.node_repository import \
|
|
15
|
+
NodeRepository
|
|
21
16
|
|
|
22
17
|
|
|
23
18
|
@dataclass
|
|
@@ -44,6 +39,7 @@ class CreateNexus(ReasonableConcern[CreateNexusResult]):
|
|
|
44
39
|
intent: str,
|
|
45
40
|
perspective_hashes: list[str],
|
|
46
41
|
preset: str = CausalityPreset.AUTO,
|
|
42
|
+
title: Optional[str] = None,
|
|
47
43
|
) -> CreateNexusResult:
|
|
48
44
|
if not perspective_hashes:
|
|
49
45
|
raise ValueError("At least one Perspective hash is required.")
|
|
@@ -58,6 +54,11 @@ class CreateNexus(ReasonableConcern[CreateNexusResult]):
|
|
|
58
54
|
|
|
59
55
|
nexus = Nexus(intent=intent, preset=preset)
|
|
60
56
|
nexus.commit()
|
|
57
|
+
|
|
58
|
+
if title:
|
|
59
|
+
nexus.title = title
|
|
60
|
+
nexus.save()
|
|
61
|
+
|
|
61
62
|
self._report.node_created(nexus)
|
|
62
63
|
|
|
63
64
|
for pp in perspectives:
|
|
@@ -73,15 +74,3 @@ class CreateNexus(ReasonableConcern[CreateNexusResult]):
|
|
|
73
74
|
self._report.artifacts["preset"] = preset
|
|
74
75
|
|
|
75
76
|
return CreateNexusResult(nexus=nexus, perspectives=perspectives)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
@llm.tool
|
|
79
|
-
async def create_nexus(
|
|
80
|
-
intent: Annotated[str, Field(description="Exploration purpose — what to understand or navigate")],
|
|
81
|
-
perspective_hashes: Annotated[list[str], Field(description="Hashes of Perspectives to include")],
|
|
82
|
-
preset: Annotated[str, Field(description="Estimation strategy: 'preset:auto', 'preset:balanced', 'preset:realistic', 'preset:desirable', 'preset:feasible'")] = "preset:auto",
|
|
83
|
-
) -> str:
|
|
84
|
-
"""Create a Nexus — an exploration container that groups Perspectives for structural combination into Cycles and Wheels. The intent describes what to explore or navigate."""
|
|
85
|
-
concern = CreateNexus()
|
|
86
|
-
await concern.resolve(intent=intent, perspective_hashes=perspective_hashes, preset=preset)
|
|
87
|
-
return str(concern.report)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ExpandNexus concern: adds Perspectives to an existing Nexus.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
|
|
9
|
+
from dialectical_framework.agents.reasonable_concern import ReasonableConcern
|
|
10
|
+
from dialectical_framework.graph.nodes.nexus import Nexus
|
|
11
|
+
from dialectical_framework.graph.nodes.perspective import Perspective
|
|
12
|
+
from dialectical_framework.graph.repositories.node_repository import \
|
|
13
|
+
NodeRepository
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class ExpandNexusResult:
|
|
18
|
+
nexus: Nexus
|
|
19
|
+
added: list[Perspective] = field(default_factory=list)
|
|
20
|
+
skipped: list[Perspective] = field(default_factory=list)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ExpandNexus(ReasonableConcern[ExpandNexusResult]):
|
|
24
|
+
"""
|
|
25
|
+
Adds Perspectives to an existing Nexus, skipping already-connected ones.
|
|
26
|
+
|
|
27
|
+
Programmatic usage:
|
|
28
|
+
concern = ExpandNexus()
|
|
29
|
+
result = await concern.resolve(
|
|
30
|
+
nexus_hash="abc123",
|
|
31
|
+
perspective_hashes=["def456", "ghi789"],
|
|
32
|
+
)
|
|
33
|
+
print(f"Added {len(result.added)}, skipped {len(result.skipped)}")
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
async def resolve(
|
|
37
|
+
self,
|
|
38
|
+
nexus_hash: str,
|
|
39
|
+
perspective_hashes: list[str],
|
|
40
|
+
) -> ExpandNexusResult:
|
|
41
|
+
if not perspective_hashes:
|
|
42
|
+
raise ValueError("At least one Perspective hash is required.")
|
|
43
|
+
|
|
44
|
+
repo = NodeRepository()
|
|
45
|
+
|
|
46
|
+
nexus = repo.find_by_hash(nexus_hash, node_type=Nexus)
|
|
47
|
+
if nexus is None:
|
|
48
|
+
raise ValueError(f"Nexus not found: {nexus_hash}")
|
|
49
|
+
|
|
50
|
+
perspectives: list[Perspective] = []
|
|
51
|
+
for pp_hash in perspective_hashes:
|
|
52
|
+
node = repo.find_by_hash(pp_hash, node_type=Perspective)
|
|
53
|
+
if node is None:
|
|
54
|
+
raise ValueError(f"Perspective not found: {pp_hash}")
|
|
55
|
+
perspectives.append(node)
|
|
56
|
+
|
|
57
|
+
existing_hashes = {pp.hash for pp, _ in nexus.perspectives.all()}
|
|
58
|
+
added: list[Perspective] = []
|
|
59
|
+
skipped: list[Perspective] = []
|
|
60
|
+
|
|
61
|
+
for pp in perspectives:
|
|
62
|
+
if pp.hash not in existing_hashes:
|
|
63
|
+
pp.nexus.connect(nexus)
|
|
64
|
+
self._report.relationship_created(pp.nexus, pp, nexus)
|
|
65
|
+
existing_hashes.add(pp.hash)
|
|
66
|
+
added.append(pp)
|
|
67
|
+
else:
|
|
68
|
+
skipped.append(pp)
|
|
69
|
+
|
|
70
|
+
self._report.ok = True
|
|
71
|
+
self._report.summary = (
|
|
72
|
+
f"Expanded Nexus {nexus.short_hash}: added {len(added)} perspectives"
|
|
73
|
+
+ (f", skipped {len(skipped)} already connected" if skipped else "")
|
|
74
|
+
)
|
|
75
|
+
self._report.artifacts["nexus_hash"] = nexus.short_hash
|
|
76
|
+
self._report.artifacts["added_count"] = len(added)
|
|
77
|
+
self._report.artifacts["skipped_count"] = len(skipped)
|
|
78
|
+
|
|
79
|
+
return ExpandNexusResult(nexus=nexus, added=added, skipped=skipped)
|
|
@@ -17,7 +17,10 @@ from dialectical_framework.enums.causality_preset import CausalityPreset
|
|
|
17
17
|
from dialectical_framework.enums.di import DI
|
|
18
18
|
from dialectical_framework.graph.nodes.base_node import BaseNode
|
|
19
19
|
from dialectical_framework.graph.mixins.intent_mixin import IntentMixin
|
|
20
|
-
from dialectical_framework.graph.relationship_manager import
|
|
20
|
+
from dialectical_framework.graph.relationship_manager import (
|
|
21
|
+
RelationshipFrom,
|
|
22
|
+
RelationshipManager,
|
|
23
|
+
)
|
|
21
24
|
from dialectical_framework.graph.relationships.belongs_to_nexus_relationship import (
|
|
22
25
|
BelongsToNexusRelationship,
|
|
23
26
|
)
|
|
@@ -73,12 +76,16 @@ class Nexus(IntentMixin, BaseNode, label="Nexus"):
|
|
|
73
76
|
# Prompt strategy for causality estimation (preset selector)
|
|
74
77
|
preset: str = CausalityPreset.BALANCED
|
|
75
78
|
|
|
79
|
+
# Display title (not part of hash — purely metadata).
|
|
80
|
+
# NOTE: Cannot use Optional[str] here due to GQLAlchemy metaclass + future annotations.
|
|
81
|
+
title: str = None
|
|
82
|
+
|
|
76
83
|
# Perspectives in this exploration
|
|
77
84
|
# PP→Nexus: Perspective belongs to this Nexus
|
|
78
85
|
perspectives: ClassVar[RelationshipManager[Perspective]] = RelationshipFrom(
|
|
79
86
|
"Perspective",
|
|
80
87
|
model=BelongsToNexusRelationship,
|
|
81
|
-
cardinality=(0, None) # Zero or more PPs
|
|
88
|
+
cardinality=(0, None), # Zero or more PPs
|
|
82
89
|
)
|
|
83
90
|
|
|
84
91
|
# NOTE: Cycles are derived from PPs, not stored as relationship.
|
|
@@ -93,10 +100,7 @@ class Nexus(IntentMixin, BaseNode, label="Nexus"):
|
|
|
93
100
|
return [self.preset]
|
|
94
101
|
|
|
95
102
|
@inject
|
|
96
|
-
def commit(
|
|
97
|
-
self,
|
|
98
|
-
graph_db: Union[Memgraph, Neo4j] = Provide[DI.graph_db]
|
|
99
|
-
) -> Self:
|
|
103
|
+
def commit(self, graph_db: Union[Memgraph, Neo4j] = Provide[DI.graph_db]) -> Self:
|
|
100
104
|
"""
|
|
101
105
|
Commit this Nexus to the database.
|
|
102
106
|
|
|
@@ -117,12 +121,15 @@ class Nexus(IntentMixin, BaseNode, label="Nexus"):
|
|
|
117
121
|
"""Debug representation of the Nexus."""
|
|
118
122
|
id_str = self.short_hash or "uncommitted"
|
|
119
123
|
pp_count = self.perspectives.count()
|
|
120
|
-
|
|
124
|
+
title_str = f", title={self.title}" if self.title else ""
|
|
125
|
+
return f"Nexus({id_str}{title_str}, pps={pp_count}, preset={self.preset}, intent={self.intent})"
|
|
121
126
|
|
|
122
127
|
def __str__(self) -> str:
|
|
123
128
|
"""String representation of the Nexus."""
|
|
124
129
|
id_str = self.short_hash or "uncommitted"
|
|
125
130
|
parts = [f"hash={id_str}", f"preset={self.preset}"]
|
|
131
|
+
if self.title:
|
|
132
|
+
parts.append(f"title={self.title}")
|
|
126
133
|
if self.intent:
|
|
127
134
|
parts.append(f"intent={self.intent}")
|
|
128
135
|
return f"Nexus({', '.join(parts)})"
|
|
File without changes
|
|
File without changes
|
{dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/enums/di.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dialectical_framework-1.1.1 → dialectical_framework-1.1.3}/src/dialectical_framework/settings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|