dialectical-framework 1.1.2__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/PKG-INFO +1 -1
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/pyproject.toml +1 -1
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/analyst/analyst.py +3 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/analyst/system_prompts.py +26 -2
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/conversation_facilitator.py +20 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/explorer/explorer.py +6 -0
- dialectical_framework-1.2.0/src/dialectical_framework/agents/explorer/skills/generate_synthesis.py +207 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/explorer/system_prompts.py +2 -0
- dialectical_framework-1.2.0/src/dialectical_framework/agents/explorer/tools/create_nexus.py +41 -0
- dialectical_framework-1.2.0/src/dialectical_framework/agents/explorer/tools/expand_nexus.py +27 -0
- dialectical_framework-1.2.0/src/dialectical_framework/agents/explorer/tools/generate_synthesis.py +27 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/explorer/tools/present_exploration.py +2 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/orchestrator/tools/get_schema.py +1 -1
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/orchestrator/tools/inspect_node.py +2 -1
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/orchestrator/tools/present_analysis.py +4 -1
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/reasonable_concern.py +31 -0
- {dialectical_framework-1.1.2/src/dialectical_framework/agents/explorer/tools → dialectical_framework-1.2.0/src/dialectical_framework/concerns}/create_nexus.py +10 -21
- dialectical_framework-1.2.0/src/dialectical_framework/concerns/expand_nexus.py +79 -0
- dialectical_framework-1.2.0/src/dialectical_framework/concerns/synthesis_generation.py +347 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/nexus.py +14 -7
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/synthesis.py +3 -3
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/utils/use_brain.py +5 -4
- dialectical_framework-1.1.2/src/dialectical_framework/concerns/synthesis_generation.py +0 -227
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/LICENSE +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/README.md +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/agent_context.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/analyst/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/analyst/skills/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/analyst/skills/anchor_theses.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/analyst/skills/edit_perspective.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/analyst/skills/expand_polarities.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/analyst/skills/find_polarities.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/analyst/skills/introduce_polarity.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/analyst/skills/surface_theses.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/analyst/tools/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/analyst/tools/create_dx_input.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/analyst/tools/place_statement.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/apps.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/execution_report.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/explorer/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/explorer/skills/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/explorer/skills/build_wheels.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/explorer/skills/explore_transformations.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/explorer/tools/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/orchestrator/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/orchestrator/tools/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/orchestrator/tools/add_input.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/orchestrator/tools/discard.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/orchestrator/tools/query_graph.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/agents/stream_events.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/ac_re_taxonomy.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/action_extraction.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/ai_dto/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/ai_dto/statement_dto.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/ai_dto/statements_deck_dto.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/antithesis_classification.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/antithesis_extraction.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/aspect_classification.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/aspect_generation.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/causality/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/causality/causality_estimator.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/causality/causality_estimator_balanced.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/causality/causality_estimator_criteria.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/causality/causality_estimator_desirable.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/causality/causality_estimator_feasible.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/causality/causality_estimator_realistic.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/causality/causality_normalizer.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/causality/estimator_resolver.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/causality_estimation.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/control_statements_check.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/diagonal_oppositions_check.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/display_text_edit.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/perspective_combination.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/perspective_validation.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/positive_ac_re_apex_derivation.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/statement_classification.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/statement_deduplication.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/statement_placement.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/thesis_extraction.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/transformation_audit.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/concerns/transformation_generation.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/dialectical_reasoning.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/enums/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/enums/causality_preset.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/enums/di.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/events/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/events/graph_event.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/events/graph_event_bus.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/exceptions/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/exceptions/node_errors.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/exceptions/resolver_errors.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/composite_input_resolver.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/dialexity_input_resolver.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/estimation_manager.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/mixins/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/mixins/incremental_build_mixin.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/mixins/intent_mixin.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/mixins/persistable_mixin.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/assessable_entity.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/base_node.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/case.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/cycle.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/estimation.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/ideas.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/input.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/perspective.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/polarity.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/rationale.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/statement.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/transformation.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/transition.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/nodes/wheel.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationship_manager.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/action_reflection_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/belongs_to_cycle_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/belongs_to_nexus_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/changed_to_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/contradiction_of_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/critiques_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/distilled_to_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/estimates_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/explains_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/has_input_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/has_statement_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/has_wheel_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/immutable_structure.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/is_source_of_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/is_target_of_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/negative_side_of_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/opposite_direction_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/opposite_of_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/polarity_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/positive_side_of_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/provides_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/relationships/synthesis_of_relationship.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/repositories/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/repositories/case_repository.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/repositories/cycle_repository.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/repositories/input_repository.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/repositories/nexus_repository.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/repositories/node_repository.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/repositories/perspective_repository.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/repositories/polarity_repository.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/repositories/schema_repository.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/repositories/statement_repository.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/repositories/transformation_repository.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/repositories/wheel_repository.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/scope_context.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/verbatim_input_resolver.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/wheel_segment.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/graph/wheel_segment_polar_pair.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/protocols/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/protocols/has_config.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/protocols/input_resolver.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/settings.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/utils/__init__.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/utils/bedrock_provider.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/utils/dc_replace.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/utils/decompose_probability_uniformly.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/utils/edge_context.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/utils/effect_logger.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/utils/order_transitions.py +0 -0
- {dialectical_framework-1.1.2 → dialectical_framework-1.2.0}/src/dialectical_framework/utils/sequence_generation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: dialectical-framework
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: A dialectical framework for augmented intelligence. AI reasoning powered with dialectics supports humans in: system optimization (psychology, engineering, business, politics, etc.); dispute resolution (mediation, conflicts, negotiations, etc.); decision-making (dilemmas, challenging situations, win-win, etc.).
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: dialectics,dialectical-reasoning,synthesis,thesis-antithesis,ai,artificial-intelligence,llm,reasoning-framework,philosophy,logic,argumentation,conflict-resolution,decision-making,critical-thinking,semantic-graph,mirascope,pydantic,perspectives,polarity-reasoning
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "dialectical-framework"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.2.0"
|
|
4
4
|
description = "A dialectical framework for augmented intelligence. AI reasoning powered with dialectics supports humans in: system optimization (psychology, engineering, business, politics, etc.); dispute resolution (mediation, conflicts, negotiations, etc.); decision-making (dilemmas, challenging situations, win-win, etc.)."
|
|
5
5
|
authors = ["Evaldas Taroza <evaldas@dialexity.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -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,
|
|
@@ -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.
|
|
@@ -152,6 +152,7 @@ class ConversationFacilitator(SettingsAware):
|
|
|
152
152
|
|
|
153
153
|
# Sync full conversation history from the response chain
|
|
154
154
|
self._messages = list(response.messages)
|
|
155
|
+
self._strip_unsupported_input_fields()
|
|
155
156
|
|
|
156
157
|
# Extract structured response
|
|
157
158
|
return await self._call_with_response_model(response_model)
|
|
@@ -209,11 +210,30 @@ class ConversationFacilitator(SettingsAware):
|
|
|
209
210
|
stream = await stream.resume(tool_outputs)
|
|
210
211
|
|
|
211
212
|
self._messages = list(stream.messages)
|
|
213
|
+
self._strip_unsupported_input_fields()
|
|
212
214
|
result = await self._call_with_response_model(response_model)
|
|
213
215
|
yield ResponseComplete(result=result)
|
|
214
216
|
|
|
215
217
|
# --- Internal helpers ---
|
|
216
218
|
|
|
219
|
+
def _strip_unsupported_input_fields(self) -> None:
|
|
220
|
+
"""Strip output-only fields from raw_message before replaying to API.
|
|
221
|
+
|
|
222
|
+
Mirascope passes raw_message dicts back verbatim as input. If the API
|
|
223
|
+
added output-only fields (like 'caller' on tool_use blocks), they cause
|
|
224
|
+
400 errors on the next call. This strips them.
|
|
225
|
+
"""
|
|
226
|
+
for msg in self._messages:
|
|
227
|
+
raw = getattr(msg, "raw_message", None)
|
|
228
|
+
if not isinstance(raw, dict):
|
|
229
|
+
continue
|
|
230
|
+
content = raw.get("content")
|
|
231
|
+
if not isinstance(content, list):
|
|
232
|
+
continue
|
|
233
|
+
for block in content:
|
|
234
|
+
if isinstance(block, dict) and block.get("type") == "tool_use":
|
|
235
|
+
block.pop("caller", None)
|
|
236
|
+
|
|
217
237
|
@staticmethod
|
|
218
238
|
def _log_tool_calls(tool_calls: list) -> None:
|
|
219
239
|
"""Log tool invocations to the effect logger if configured."""
|
|
@@ -119,6 +119,10 @@ 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.expand_nexus import \
|
|
123
|
+
expand_nexus
|
|
124
|
+
from dialectical_framework.agents.explorer.tools.generate_synthesis import \
|
|
125
|
+
generate_synthesis
|
|
122
126
|
from dialectical_framework.agents.explorer.tools.present_exploration import \
|
|
123
127
|
present_exploration
|
|
124
128
|
from dialectical_framework.agents.orchestrator.tools.get_schema import \
|
|
@@ -131,6 +135,8 @@ def _build_tools() -> list:
|
|
|
131
135
|
return [
|
|
132
136
|
build_wheels,
|
|
133
137
|
explore_transformations,
|
|
138
|
+
generate_synthesis,
|
|
139
|
+
expand_nexus,
|
|
134
140
|
present_exploration,
|
|
135
141
|
inspect_node,
|
|
136
142
|
query_graph,
|
dialectical_framework-1.2.0/src/dialectical_framework/agents/explorer/skills/generate_synthesis.py
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"""
|
|
2
|
+
GenerateSynthesis: Skill for generating S+/S- synthesis from a Wheel.
|
|
3
|
+
|
|
4
|
+
Orchestrates: resolve wheel → verify transformations → gather lower-layer
|
|
5
|
+
context → call SynthesisGeneration concern → create Synthesis node → commit.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from itertools import combinations
|
|
12
|
+
from typing import Optional, TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
from dependency_injector.wiring import Provide, inject
|
|
15
|
+
|
|
16
|
+
from dialectical_framework.agents.reasonable_concern import ReasonableConcern
|
|
17
|
+
from dialectical_framework.concerns.synthesis_generation import (
|
|
18
|
+
SynthesisGeneration,
|
|
19
|
+
SynthesisResult,
|
|
20
|
+
)
|
|
21
|
+
from dialectical_framework.enums.di import DI
|
|
22
|
+
from dialectical_framework.graph.nodes.statement import Statement
|
|
23
|
+
from dialectical_framework.graph.nodes.synthesis import (
|
|
24
|
+
POSITION_S_MINUS,
|
|
25
|
+
POSITION_S_PLUS,
|
|
26
|
+
Synthesis,
|
|
27
|
+
)
|
|
28
|
+
from dialectical_framework.graph.relationships.polarity_relationship import (
|
|
29
|
+
SMinusRelationship,
|
|
30
|
+
SPlusRelationship,
|
|
31
|
+
)
|
|
32
|
+
from dialectical_framework.graph.relationships.synthesis_of_relationship import (
|
|
33
|
+
SynthesisOfRelationship,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
if TYPE_CHECKING:
|
|
37
|
+
from dialectical_framework.graph.nodes.nexus import Nexus
|
|
38
|
+
from dialectical_framework.graph.nodes.perspective import Perspective
|
|
39
|
+
from dialectical_framework.graph.nodes.wheel import Wheel
|
|
40
|
+
from dialectical_framework.protocols.input_resolver import InputResolver
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass
|
|
44
|
+
class GenerateSynthesisResult:
|
|
45
|
+
"""Result from GenerateSynthesis skill."""
|
|
46
|
+
|
|
47
|
+
synthesis: Synthesis
|
|
48
|
+
is_new: bool = True
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class GenerateSynthesis(ReasonableConcern[GenerateSynthesisResult]):
|
|
52
|
+
"""
|
|
53
|
+
Skill for generating S+/S- synthesis from a Wheel's Transformations.
|
|
54
|
+
|
|
55
|
+
Idempotent: returns existing Synthesis if one already exists for the Wheel.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
def __init__(self, wheel_hash: str) -> None:
|
|
59
|
+
self.wheel_hash = wheel_hash
|
|
60
|
+
|
|
61
|
+
async def resolve(self) -> GenerateSynthesisResult:
|
|
62
|
+
"""
|
|
63
|
+
Generate synthesis for a Wheel.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
GenerateSynthesisResult with the Synthesis node
|
|
67
|
+
|
|
68
|
+
Raises:
|
|
69
|
+
ValueError: If wheel not found or has no Transformations
|
|
70
|
+
"""
|
|
71
|
+
wheel = self._resolve_wheel()
|
|
72
|
+
|
|
73
|
+
# Check transformations exist
|
|
74
|
+
transformations = wheel.transformations
|
|
75
|
+
if not transformations:
|
|
76
|
+
raise ValueError(
|
|
77
|
+
f"Wheel {wheel.short_hash} has no Transformations — "
|
|
78
|
+
f"run explore_transformations first"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Idempotent: return existing synthesis
|
|
82
|
+
existing = self._find_existing_synthesis(wheel)
|
|
83
|
+
if existing:
|
|
84
|
+
self._report.summary = (
|
|
85
|
+
f"Synthesis already exists for Wheel {wheel.short_hash}"
|
|
86
|
+
)
|
|
87
|
+
self._report.artifacts["wheel"] = wheel.short_hash
|
|
88
|
+
self._report.artifacts["existing"] = True
|
|
89
|
+
return GenerateSynthesisResult(synthesis=existing, is_new=False)
|
|
90
|
+
|
|
91
|
+
# Gather context
|
|
92
|
+
input_text = await self._get_input_text()
|
|
93
|
+
lower_layer_context = self._build_lower_layer_context(wheel)
|
|
94
|
+
|
|
95
|
+
# Call the concern
|
|
96
|
+
concern = SynthesisGeneration()
|
|
97
|
+
result = await concern.resolve(
|
|
98
|
+
wheel=wheel,
|
|
99
|
+
input_text=input_text,
|
|
100
|
+
lower_layer_context=lower_layer_context,
|
|
101
|
+
)
|
|
102
|
+
self._report = self._report.merge(concern.report)
|
|
103
|
+
|
|
104
|
+
if result is None:
|
|
105
|
+
raise ValueError(
|
|
106
|
+
f"Synthesis generation failed for Wheel {wheel.short_hash}"
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
# Create Synthesis node and wire up
|
|
110
|
+
synthesis = Synthesis()
|
|
111
|
+
synthesis.save()
|
|
112
|
+
|
|
113
|
+
synthesis.s_plus.connect(
|
|
114
|
+
result.s_plus_statement,
|
|
115
|
+
relationship=SPlusRelationship(
|
|
116
|
+
alias=POSITION_S_PLUS, heuristic_similarity=None
|
|
117
|
+
),
|
|
118
|
+
)
|
|
119
|
+
synthesis.s_minus.connect(
|
|
120
|
+
result.s_minus_statement,
|
|
121
|
+
relationship=SMinusRelationship(
|
|
122
|
+
alias=POSITION_S_MINUS, heuristic_similarity=None
|
|
123
|
+
),
|
|
124
|
+
)
|
|
125
|
+
synthesis.target.connect(wheel, relationship=SynthesisOfRelationship())
|
|
126
|
+
synthesis.commit()
|
|
127
|
+
|
|
128
|
+
# Report
|
|
129
|
+
self._report.node_created(synthesis)
|
|
130
|
+
self._report.artifacts["wheel"] = wheel.short_hash
|
|
131
|
+
self._report.artifacts["s_plus"] = result.s_plus_statement.text
|
|
132
|
+
self._report.artifacts["s_minus"] = result.s_minus_statement.text
|
|
133
|
+
self._report.summary = (
|
|
134
|
+
f"Generated synthesis for Wheel {wheel.short_hash}: "
|
|
135
|
+
f"S+ = \"{result.s_plus_statement.text}\", "
|
|
136
|
+
f"S- = \"{result.s_minus_statement.text}\""
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
return GenerateSynthesisResult(synthesis=synthesis)
|
|
140
|
+
|
|
141
|
+
def _resolve_wheel(self) -> Wheel:
|
|
142
|
+
"""Resolve Wheel from hash or prefix."""
|
|
143
|
+
from dialectical_framework.graph.nodes.wheel import Wheel
|
|
144
|
+
from dialectical_framework.graph.repositories.node_repository import (
|
|
145
|
+
NodeRepository,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
repo = NodeRepository()
|
|
149
|
+
node = repo.find_by_hash(self.wheel_hash, node_type=Wheel)
|
|
150
|
+
if node is None:
|
|
151
|
+
raise ValueError(f"Wheel not found: {self.wheel_hash}")
|
|
152
|
+
return node
|
|
153
|
+
|
|
154
|
+
@staticmethod
|
|
155
|
+
def _find_existing_synthesis(wheel: Wheel) -> Optional[Synthesis]:
|
|
156
|
+
"""Check if the wheel already has a synthesis."""
|
|
157
|
+
existing = list(wheel.synthesis.all())
|
|
158
|
+
if existing:
|
|
159
|
+
return existing[0][0]
|
|
160
|
+
return None
|
|
161
|
+
|
|
162
|
+
@inject
|
|
163
|
+
async def _get_input_text(
|
|
164
|
+
self,
|
|
165
|
+
input_resolver: InputResolver = Provide[DI.input_resolver],
|
|
166
|
+
) -> str:
|
|
167
|
+
"""Get concatenated text from all inputs in scope."""
|
|
168
|
+
from dialectical_framework.graph.repositories.input_repository import (
|
|
169
|
+
InputRepository,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
repo = InputRepository()
|
|
173
|
+
inputs = repo.get_all()
|
|
174
|
+
|
|
175
|
+
if not inputs:
|
|
176
|
+
return ""
|
|
177
|
+
|
|
178
|
+
texts = []
|
|
179
|
+
for input_node in inputs:
|
|
180
|
+
resolved = await input_resolver.resolve(input_node)
|
|
181
|
+
texts.append(resolved)
|
|
182
|
+
|
|
183
|
+
return "\n\n---\n\n".join(texts)
|
|
184
|
+
|
|
185
|
+
def _build_lower_layer_context(self, wheel: Wheel) -> str:
|
|
186
|
+
"""Find synthesis from sub-wheels (lower PP layers) sharing perspectives."""
|
|
187
|
+
from dialectical_framework.graph.repositories.wheel_repository import (
|
|
188
|
+
WheelRepository,
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
pps = wheel._perspectives
|
|
192
|
+
if len(pps) < 2:
|
|
193
|
+
return ""
|
|
194
|
+
|
|
195
|
+
wheel_repo = WheelRepository()
|
|
196
|
+
parts: list[str] = []
|
|
197
|
+
|
|
198
|
+
# Look one layer down (N-1 perspectives)
|
|
199
|
+
for combo in combinations(pps, len(pps) - 1):
|
|
200
|
+
sub_wheels = wheel_repo.find_by_layer(list(combo))
|
|
201
|
+
for sub_wheel in sub_wheels:
|
|
202
|
+
for synth, _ in sub_wheel.synthesis.all():
|
|
203
|
+
parts.append(
|
|
204
|
+
f"Sub-wheel [{sub_wheel.short_hash}]: {synth:positions:0}"
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
return "\n".join(parts)
|
|
@@ -25,6 +25,7 @@ On first message (or when resuming):
|
|
|
25
25
|
- If wheels don't exist yet, call `build_wheels` to create them.
|
|
26
26
|
- If build_wheels yields no wheels (e.g., only one position), explain that exploration needs at least two positions interacting — suggest the user adds more via the analysis thread.
|
|
27
27
|
- If transformations don't exist yet, call `explore_transformations` for each wheel.
|
|
28
|
+
- After transformations exist, call `generate_synthesis` to derive S+/S- for each wheel.
|
|
28
29
|
|
|
29
30
|
When presenting transformations:
|
|
30
31
|
- Focus on the Ac+ (constructive action: T- -> A+) and Re+ (constructive reflection: A- -> T+).
|
|
@@ -48,6 +49,7 @@ When the user wants to go deeper on a specific transformation:
|
|
|
48
49
|
|
|
49
50
|
- `build_wheels` -- Generate causal structures (Cycles + Wheels) from this Nexus. Use nexus_hash: "{nexus_hash}".
|
|
50
51
|
- `explore_transformations` -- Generate Action-Reflection transformations for a Wheel.
|
|
52
|
+
- `generate_synthesis` -- Generate S+/S- synthesis for a Wheel. Requires transformations first.
|
|
51
53
|
- `present_exploration` -- Show current state of this Nexus: perspectives, wheels, transformations.
|
|
52
54
|
- `inspect_node` -- Deep-dive any node by hash.
|
|
53
55
|
- `query_graph` -- Raw Cypher for custom queries. Call `get_schema` first.
|
|
@@ -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)
|
dialectical_framework-1.2.0/src/dialectical_framework/agents/explorer/tools/generate_synthesis.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
generate_synthesis tool: thin LLM-facing wrapper around the GenerateSynthesis skill.
|
|
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.agents.explorer.skills.generate_synthesis import (
|
|
13
|
+
GenerateSynthesis,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@llm.tool
|
|
18
|
+
async def generate_synthesis(
|
|
19
|
+
wheel_hash: Annotated[
|
|
20
|
+
str,
|
|
21
|
+
Field(description="Hash of the Wheel to generate synthesis for"),
|
|
22
|
+
],
|
|
23
|
+
) -> str:
|
|
24
|
+
"""Generate S+/S- synthesis for a Wheel — the emergent properties arising from circular causality. S+ represents complementary harmony (1+1>2), S- represents reinforcing uniformity (1+1<2). The wheel must have transformations computed first."""
|
|
25
|
+
skill = GenerateSynthesis(wheel_hash=wheel_hash)
|
|
26
|
+
await skill.resolve()
|
|
27
|
+
return str(skill.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}")
|
|
@@ -10,15 +10,40 @@ All three levels inherit from ReasonableConcern — same interface (resolve + re
|
|
|
10
10
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
|
+
import asyncio
|
|
14
|
+
import inspect
|
|
13
15
|
from abc import ABC, abstractmethod
|
|
16
|
+
from functools import wraps
|
|
14
17
|
from typing import TYPE_CHECKING, Any, Generic, TypeVar
|
|
15
18
|
|
|
19
|
+
from langfuse import get_client, observe
|
|
20
|
+
|
|
16
21
|
if TYPE_CHECKING:
|
|
17
22
|
from dialectical_framework.agents.execution_report import ExecutionReport
|
|
18
23
|
|
|
19
24
|
R_co = TypeVar("R_co", covariant=True)
|
|
20
25
|
|
|
21
26
|
|
|
27
|
+
def _conditional_observe(name: str, fn: Any) -> Any:
|
|
28
|
+
"""Wrap fn with @observe only when an active Langfuse trace exists."""
|
|
29
|
+
observed = observe(name=name)(fn)
|
|
30
|
+
|
|
31
|
+
if asyncio.iscoroutinefunction(fn):
|
|
32
|
+
@wraps(fn)
|
|
33
|
+
async def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
34
|
+
if get_client().get_current_trace_id():
|
|
35
|
+
return await observed(*args, **kwargs)
|
|
36
|
+
return await fn(*args, **kwargs)
|
|
37
|
+
else:
|
|
38
|
+
@wraps(fn)
|
|
39
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
40
|
+
if get_client().get_current_trace_id():
|
|
41
|
+
return observed(*args, **kwargs)
|
|
42
|
+
return fn(*args, **kwargs)
|
|
43
|
+
|
|
44
|
+
return wrapper
|
|
45
|
+
|
|
46
|
+
|
|
22
47
|
class ReasonableConcern(ABC, Generic[R_co]):
|
|
23
48
|
"""
|
|
24
49
|
Base class for concerns, skills, and tools.
|
|
@@ -34,6 +59,12 @@ class ReasonableConcern(ABC, Generic[R_co]):
|
|
|
34
59
|
|
|
35
60
|
_report: ExecutionReport
|
|
36
61
|
|
|
62
|
+
def __init_subclass__(cls, **kwargs: Any) -> None:
|
|
63
|
+
super().__init_subclass__(**kwargs)
|
|
64
|
+
if "resolve" in cls.__dict__:
|
|
65
|
+
original = cls.__dict__["resolve"]
|
|
66
|
+
cls.resolve = _conditional_observe(cls.__name__, original) # type: ignore[assignment]
|
|
67
|
+
|
|
37
68
|
def __getattr__(self, name: str) -> Any:
|
|
38
69
|
if name == "_report":
|
|
39
70
|
from dialectical_framework.agents.execution_report import ExecutionReport
|
|
@@ -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)
|