dialectical-framework 1.6.6__tar.gz → 1.6.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/PKG-INFO +1 -1
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/pyproject.toml +1 -1
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/advisor/advisor.py +38 -9
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/advisor/system_prompts.py +91 -19
- dialectical_framework-1.6.8/src/dialectical_framework/agents/advisor/tools/sync.py +32 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/analyst/analyst.py +17 -2
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/analyst/system_prompts.py +10 -0
- dialectical_framework-1.6.8/src/dialectical_framework/agents/app_spec.py +119 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/apps.py +6 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/explorer/explorer.py +15 -1
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/orchestrator/tools/inspect_node.py +14 -2
- dialectical_framework-1.6.8/src/dialectical_framework/agents/toolsets.py +33 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/action_extraction.py +3 -2
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/control_statements_check.py +74 -11
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/dialectical_context.py +167 -15
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/positive_ac_re_apex_derivation.py +1 -1
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/scoring_scales.py +10 -5
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/statement_classification.py +138 -53
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/synthesis_generation.py +5 -1
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/transformation_generation.py +4 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/assessable_entity.py +1 -1
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/estimation.py +26 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/perspective.py +11 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/settings.py +10 -2
- dialectical_framework-1.6.6/src/dialectical_framework/agents/advisor/tools/sync.py +0 -20
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/LICENSE +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/PATENTS +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/README.md +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/advisor/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/advisor/tools/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/advisor/tools/anchor.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/advisor/tools/deepen.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/advisor/tools/explore.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/advisor/tools/ingest.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/advisor/tools/scoped.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/agent_context.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/analyst/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/analyst/skills/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/analyst/skills/anchor_theses.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/analyst/skills/edit_perspective.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/analyst/skills/expand_polarities.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/analyst/skills/find_polarities.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/analyst/skills/introduce_polarity.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/analyst/skills/surface_theses.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/analyst/tools/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/analyst/tools/place_statement.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/conversation_facilitator.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/execution_report.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/explorer/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/explorer/skills/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/explorer/skills/build_wheels.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/explorer/skills/explore_transformations.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/explorer/skills/generate_synthesis.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/explorer/system_prompts.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/explorer/tools/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/explorer/tools/create_nexus.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/explorer/tools/expand_nexus.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/explorer/tools/generate_synthesis.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/explorer/tools/present_exploration.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/orchestrator/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/orchestrator/tools/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/orchestrator/tools/add_input.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/orchestrator/tools/create_dx_input.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/orchestrator/tools/digest_input.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/orchestrator/tools/discard.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/orchestrator/tools/get_schema.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/orchestrator/tools/present_analysis.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/orchestrator/tools/query_graph.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/orchestrator/tools/read_digest.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/orchestrator/tools/read_input.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/reasonable_concern.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/stream_events.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/ac_re_taxonomy.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/add_input.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/ai_dto/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/ai_dto/statement_dto.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/ai_dto/statements_deck_dto.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/antithesis_classification.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/antithesis_extraction.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/antithetical_thesis_detection.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/aspect_classification.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/aspect_generation.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/causality/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/causality/causality_estimator.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/causality/causality_estimator_balanced.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/causality/causality_estimator_criteria.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/causality/causality_estimator_desirable.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/causality/causality_estimator_feasible.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/causality/causality_estimator_realistic.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/causality/causality_normalizer.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/causality/estimator_resolver.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/causality_estimation.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/create_dx_input.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/create_nexus.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/diagonal_oppositions_check.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/discard.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/display_text_edit.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/expand_nexus.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/perspective_combination.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/perspective_validation.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/source_digest.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/statement_deduplication.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/statement_headline.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/statement_placement.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/thesis_extraction.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/concerns/transformation_audit.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/dialectical_reasoning.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/enums/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/enums/causality_preset.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/enums/di.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/events/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/events/graph_event.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/events/graph_event_bus.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/exceptions/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/exceptions/node_errors.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/exceptions/resolver_errors.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/composite_input_resolver.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/dialexity_input_resolver.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/estimation_manager.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/mixins/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/mixins/incremental_build_mixin.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/mixins/intent_mixin.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/mixins/persistable_mixin.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/base_node.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/case.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/cycle.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/ideas.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/input.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/nexus.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/polarity.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/rationale.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/statement.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/synthesis.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/transformation.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/transition.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/nodes/wheel.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationship_manager.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/action_reflection_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/belongs_to_cycle_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/belongs_to_nexus_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/changed_to_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/contradiction_of_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/critiques_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/distilled_to_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/estimates_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/explains_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/has_input_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/has_statement_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/has_wheel_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/immutable_structure.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/is_source_of_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/is_target_of_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/negative_side_of_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/opposite_direction_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/opposite_of_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/polarity_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/positive_side_of_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/provides_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/relationships/synthesis_of_relationship.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/rendering.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/repositories/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/repositories/case_repository.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/repositories/cycle_repository.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/repositories/input_repository.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/repositories/nexus_repository.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/repositories/node_repository.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/repositories/perspective_repository.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/repositories/polarity_repository.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/repositories/schema_repository.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/repositories/statement_repository.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/repositories/transformation_repository.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/repositories/wheel_repository.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/scope_context.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/verbatim_input_resolver.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/wheel_segment.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/graph/wheel_segment_polar_pair.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/protocols/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/protocols/has_config.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/protocols/input_resolver.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/utils/__init__.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/utils/bedrock_provider.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/utils/concurrency.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/utils/dc_replace.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/utils/decompose_probability_uniformly.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/utils/edge_context.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/utils/effect_logger.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/utils/input_context.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/utils/order_transitions.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/utils/sequence_generation.py +0 -0
- {dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/utils/use_brain.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: dialectical-framework
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.8
|
|
4
4
|
Summary: A dialectical framework for augmented intelligence. AI reasoning powered with dialectics supports humans in: system optimization (psychology, engineering, business, politics, etc.); dispute resolution (mediation, conflicts, negotiations, etc.); decision-making (dilemmas, challenging situations, win-win, etc.).
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: dialectics,dialectical-reasoning,synthesis,thesis-antithesis,ai,artificial-intelligence,llm,reasoning-framework,philosophy,logic,argumentation,conflict-resolution,decision-making,critical-thinking,semantic-graph,mirascope,pydantic,perspectives,polarity-reasoning
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "dialectical-framework"
|
|
3
|
-
version = "1.6.
|
|
3
|
+
version = "1.6.8"
|
|
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"
|
|
@@ -17,12 +17,14 @@ from typing import AsyncGenerator, Optional
|
|
|
17
17
|
|
|
18
18
|
from pydantic import BaseModel, Field
|
|
19
19
|
|
|
20
|
-
from dialectical_framework.agents.advisor.system_prompts import
|
|
21
|
-
|
|
20
|
+
from dialectical_framework.agents.advisor.system_prompts import \
|
|
21
|
+
system_prompt
|
|
22
22
|
from dialectical_framework.agents.agent_context import agent_scope
|
|
23
23
|
from dialectical_framework.agents.conversation_facilitator import \
|
|
24
24
|
ConversationFacilitator
|
|
25
|
+
from dialectical_framework.agents.app_spec import AppSpec, resolve_app_layer
|
|
25
26
|
from dialectical_framework.agents.stream_events import StreamEvent
|
|
27
|
+
from dialectical_framework.agents.toolsets import merge_app_tools
|
|
26
28
|
|
|
27
29
|
logger = logging.getLogger(__name__)
|
|
28
30
|
|
|
@@ -69,6 +71,18 @@ class Advisor:
|
|
|
69
71
|
advisor = Advisor(app_preamble=COUNSELOR_APP, messages=saved_messages)
|
|
70
72
|
response = await advisor.chat("What about the other angle?")
|
|
71
73
|
|
|
74
|
+
Usage (app-provided domain tools):
|
|
75
|
+
# The app brings field knowledge two ways: prose in the preamble,
|
|
76
|
+
# and callable resources as app @llm.tool functions. The engine
|
|
77
|
+
# prompt carries no docs for app tools (their tool-schema docstrings
|
|
78
|
+
# travel to the LLM automatically) — introduce them and their usage
|
|
79
|
+
# rules in the app preamble, where domain vocabulary lives.
|
|
80
|
+
with scope(case.sid):
|
|
81
|
+
advisor = Advisor(
|
|
82
|
+
app_preamble=ASTRO_COUNSELOR_APP, # explains when to consult the chart
|
|
83
|
+
app_tools=[lookup_natal_chart], # @llm.tool from the app
|
|
84
|
+
)
|
|
85
|
+
|
|
72
86
|
Usage (Advisor mode of an exploration session — Explorer handover):
|
|
73
87
|
# User was chatting in Explorer (operator mode) and asks "what does
|
|
74
88
|
# this all mean for me?" — the host toggles to counsel mode by
|
|
@@ -104,13 +118,28 @@ class Advisor:
|
|
|
104
118
|
dialectical_context: Optional[str] = None,
|
|
105
119
|
messages: Optional[list] = None,
|
|
106
120
|
nexus_hash: Optional[str] = None,
|
|
121
|
+
app_tools: Optional[list] = None,
|
|
122
|
+
app: Optional[AppSpec] = None,
|
|
107
123
|
) -> None:
|
|
108
124
|
self._nexus_hash = nexus_hash
|
|
125
|
+
# app: declarative app definition — composition depends on the mode:
|
|
126
|
+
# counsel toggle (nexus_hash set) keeps the Navigator contract
|
|
127
|
+
# (EXPLORATION_ADVISOR_APP + voicing + tool_guide); standalone uses
|
|
128
|
+
# the spec's advisor_persona (machinery hidden). See AppSpec.
|
|
129
|
+
app_preamble, app_tools = resolve_app_layer(
|
|
130
|
+
app,
|
|
131
|
+
app_preamble,
|
|
132
|
+
app_tools,
|
|
133
|
+
preamble_for="advisor_scoped" if nexus_hash else "advisor_unscoped",
|
|
134
|
+
)
|
|
109
135
|
if nexus_hash:
|
|
110
136
|
self._validate_nexus(nexus_hash)
|
|
111
137
|
self._tools = _build_scoped_tools(nexus_hash)
|
|
112
138
|
else:
|
|
113
139
|
self._tools = _build_tools()
|
|
140
|
+
# App-provided @llm.tool functions (domain resources: chart lookups,
|
|
141
|
+
# methodology references, ...) — see toolsets.merge_app_tools.
|
|
142
|
+
self._tools = merge_app_tools(self._tools, app_tools)
|
|
114
143
|
self._conversation = ConversationFacilitator(tools=self._tools)
|
|
115
144
|
if messages:
|
|
116
145
|
self._conversation._messages = list(messages)
|
|
@@ -144,13 +173,13 @@ class Advisor:
|
|
|
144
173
|
dialectical_context
|
|
145
174
|
or "No prior understanding — this is a fresh conversation."
|
|
146
175
|
)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
176
|
+
# Rendered at construction (not the import-time SYSTEM_PROMPT
|
|
177
|
+
# constant) so settings-derived prompt values (max_wheel_layer)
|
|
178
|
+
# reflect the live DI configuration.
|
|
179
|
+
engine = system_prompt(
|
|
180
|
+
tool_names=[t.__name__ for t in self._tools],
|
|
181
|
+
scoped_nexus_hash=self._nexus_hash,
|
|
182
|
+
)
|
|
154
183
|
parts.append(engine.replace("{dialectical_context}", context_text))
|
|
155
184
|
|
|
156
185
|
return "\n\n".join(parts)
|
|
@@ -34,6 +34,51 @@ def _ladder_lines(scale: dict[str, float], annotations: dict[float, str]) -> str
|
|
|
34
34
|
return "\n".join(lines)
|
|
35
35
|
|
|
36
36
|
|
|
37
|
+
def _resolve_max_wheel_layer() -> int:
|
|
38
|
+
"""The live settings.max_wheel_layer, falling back to the Pydantic field
|
|
39
|
+
default when DI isn't wired (e.g. the import-time SYSTEM_PROMPT render).
|
|
40
|
+
"""
|
|
41
|
+
from dialectical_framework.settings import Settings
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
from dialectical_framework.protocols.has_config import SettingsAware
|
|
45
|
+
|
|
46
|
+
value = SettingsAware().settings.max_wheel_layer
|
|
47
|
+
if isinstance(value, int) and value >= 1:
|
|
48
|
+
return value
|
|
49
|
+
except Exception:
|
|
50
|
+
pass
|
|
51
|
+
return Settings.model_fields["max_wheel_layer"].default
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _nexus_evolution(cap: int) -> str:
|
|
55
|
+
"""Render the explore doc's 'How a nexus evolves' ladder from the live
|
|
56
|
+
wheel-layer cap (settings.max_wheel_layer), so the prompt's nexus-size
|
|
57
|
+
guidance never drifts from what PerspectiveCombination actually builds.
|
|
58
|
+
"""
|
|
59
|
+
lines = [
|
|
60
|
+
" How a nexus evolves:",
|
|
61
|
+
" - 1 perspective: a single self-referential wheel. Already generates",
|
|
62
|
+
" transformations and synthesis — useful even alone.",
|
|
63
|
+
]
|
|
64
|
+
if cap >= 2:
|
|
65
|
+
lines += [
|
|
66
|
+
" - 2 perspectives: the causal question emerges (which thesis enables which?).",
|
|
67
|
+
" Produces multiple wheels (arrangements), each with its own pathways.",
|
|
68
|
+
]
|
|
69
|
+
if cap >= 3:
|
|
70
|
+
span = f"3-{cap}" if cap > 3 else "3"
|
|
71
|
+
lines += [
|
|
72
|
+
f" - {span} perspectives: richer causal chains, more transformation variety,",
|
|
73
|
+
" deeper synthesis. The sweet spot for insight.",
|
|
74
|
+
]
|
|
75
|
+
lines.append(
|
|
76
|
+
f" - >{cap}: combinatorial explosion — arrangements aren't built beyond"
|
|
77
|
+
f" {cap} perspectives; start a new nexus for more tensions."
|
|
78
|
+
)
|
|
79
|
+
return "\n".join(lines)
|
|
80
|
+
|
|
81
|
+
|
|
37
82
|
_ROLE = """## Role
|
|
38
83
|
|
|
39
84
|
You are in conversation with someone navigating a decision, tension, or
|
|
@@ -277,14 +322,7 @@ _TOOL_DOCS: dict[str, str] = {
|
|
|
277
322
|
and sibling nexuses on one theme fragment the pathways. Create separate
|
|
278
323
|
nexuses only for genuinely distinct themes.
|
|
279
324
|
|
|
280
|
-
|
|
281
|
-
- 1 perspective: a single self-referential wheel. Already generates
|
|
282
|
-
transformations and synthesis — useful even alone.
|
|
283
|
-
- 2 perspectives: the causal question emerges (which thesis enables which?).
|
|
284
|
-
Produces multiple wheels (arrangements), each with its own pathways.
|
|
285
|
-
- 3-4 perspectives: richer causal chains, more transformation variety,
|
|
286
|
-
deeper synthesis. The sweet spot for insight.
|
|
287
|
-
- >4: combinatorial explosion — cap at 4, start a new nexus for more tensions.
|
|
325
|
+
{nexus_evolution}
|
|
288
326
|
|
|
289
327
|
Grouping principle: prefer perspectives from different polarities (different
|
|
290
328
|
T-A oppositions) — transformations between them represent genuine synthesis
|
|
@@ -314,11 +352,15 @@ _TOOL_DOCS: dict[str, str] = {
|
|
|
314
352
|
them. Deepening only adds analytical depth to existing structure — it
|
|
315
353
|
never changes what the exploration contains, so no consent ceremony is
|
|
316
354
|
needed. Harmless on already-developed wheels.""",
|
|
317
|
-
"sync": """- `sync` — Re-reads the
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
355
|
+
"sync": """- `sync` — Re-reads the graph state. Without arguments: the full picture —
|
|
356
|
+
e.g., after multiple ingest/anchor calls, to see all perspectives with
|
|
357
|
+
scores before deciding what to group for explore. With a `nexus_hash`:
|
|
358
|
+
zooms into that one exploration in full depth — the overview caps wheels
|
|
359
|
+
per cycle for compactness, the zoom does not. Zoom when counsel settles on
|
|
360
|
+
one exploration and you need arrangements the overview truncated. NOT
|
|
361
|
+
needed after every tool call (ingest/anchor/explore return their results
|
|
362
|
+
directly), and NOT needed at conversation start — the full state is
|
|
363
|
+
already in your context.""",
|
|
322
364
|
"sync_scoped": """- `sync` — Re-reads this exploration's state. Use when you need a fresh
|
|
323
365
|
picture after changes. NOT needed at conversation start — the exploration
|
|
324
366
|
is already in your context.""",
|
|
@@ -485,6 +527,22 @@ Use `inspect_node` when you want to understand the reasoning behind a score,
|
|
|
485
527
|
explain WHY a specific blindspot exists, or ground a pathway recommendation
|
|
486
528
|
in the actual analytical logic rather than restating the dump.
|
|
487
529
|
|
|
530
|
+
**Cross-exploration correspondences.** When several explorations coexist,
|
|
531
|
+
some perspectives carry correspondence lines — machine-stated facts, not
|
|
532
|
+
suggestions: "Also woven into Nexus [[x]]" (literally the same tension in
|
|
533
|
+
both explorations) and "Same opposition family (...) as perspective N in
|
|
534
|
+
[[x]]" (both tensions anchored to the same deep-structure category). These
|
|
535
|
+
are your invitation to draw parallels across the person's situations —
|
|
536
|
+
often the most powerful counsel move available: the same structural dynamic
|
|
537
|
+
playing out in two arenas of their life means an insight earned in one
|
|
538
|
+
transfers to the other. But family-level correspondence is coarse (few
|
|
539
|
+
families exist, collisions are common) — before drawing the parallel, check
|
|
540
|
+
it holds in substance: read both tetrads and confirm the dynamics actually
|
|
541
|
+
mirror each other, not just the category. The family name itself (Integrity,
|
|
542
|
+
Fire, ...) is framework vocabulary — the How You Speak rules above govern
|
|
543
|
+
it like any other; by default, name what the two tensions share in the
|
|
544
|
+
person's own terms, not the category label.
|
|
545
|
+
|
|
488
546
|
**Sequences are circular causality.** Both Cycle and Wheel sequences are
|
|
489
547
|
closed loops — they start and end with the same element (e.g., "T1 → T2 → T1..."
|
|
490
548
|
or "T1 → A2 → A1 → T2 → T1..."). The "..." indicates the circle continues.
|
|
@@ -520,6 +578,13 @@ Use these scores to prioritize what you draw on:
|
|
|
520
578
|
- `rectangularity`: Tetrad balance (lower = better).
|
|
521
579
|
<0.01 = well-balanced. 0.01–0.09 = mild imbalance, acceptable.
|
|
522
580
|
>0.09 = one side overdeveloped — note the imbalance.
|
|
581
|
+
- `DV`: Dialectical validity — how NATURAL the tension's dynamics are
|
|
582
|
+
(higher = the poles genuinely complement each other and the pathologies
|
|
583
|
+
arise organically; lower = the framing is forced, one-sided, or held
|
|
584
|
+
together by coercion/ideology rather than natural dynamics). Comparative
|
|
585
|
+
signal, no fixed cutoff: prefer high-DV tensions when choosing what to
|
|
586
|
+
build counsel on, and treat a low-DV tension as a hint the framing itself
|
|
587
|
+
may be distorted — consider re-anchoring rather than polishing aspects.
|
|
523
588
|
- `Ks` on aspects: Complementarity toward synthesis.
|
|
524
589
|
T+/A+ should be >0.4 (constructive poles complement the whole).
|
|
525
590
|
T-/A- should be <0.6 (destructive poles don't overpower).
|
|
@@ -549,12 +614,13 @@ Use these scores to prioritize what you draw on:
|
|
|
549
614
|
|
|
550
615
|
**Prioritization rules:**
|
|
551
616
|
|
|
552
|
-
The dump is pre-pruned: tensions below the quality
|
|
553
|
-
blurred structure, failed validation) and
|
|
554
|
-
suppressed — count lines note what was
|
|
555
|
-
the
|
|
617
|
+
The dump is pre-pruned: tensions below the quality floors (weak opposition,
|
|
618
|
+
blurred structure, unnatural/distorted framing, failed validation) and
|
|
619
|
+
low-probability wheels are already suppressed — count lines note what was
|
|
620
|
+
filtered. Everything you see passed the floors; you rank within them, you
|
|
621
|
+
don't re-filter.
|
|
556
622
|
|
|
557
|
-
1. Lead with the strongest tensions (highest HS on A, best area). Softer
|
|
623
|
+
1. Lead with the strongest tensions (highest HS on A, best area, best DV). Softer
|
|
558
624
|
ones are still visible by design — usable, and they may resonate with
|
|
559
625
|
the person's lived experience, but don't build your primary counsel
|
|
560
626
|
around them.
|
|
@@ -635,7 +701,13 @@ def system_prompt(
|
|
|
635
701
|
# Scoped variants of sync/explore have their own doc text.
|
|
636
702
|
key = f"{name}_scoped" if scoped and f"{name}_scoped" in _TOOL_DOCS else name
|
|
637
703
|
if key in _TOOL_DOCS:
|
|
638
|
-
|
|
704
|
+
doc = _TOOL_DOCS[key]
|
|
705
|
+
if "{nexus_evolution}" in doc:
|
|
706
|
+
doc = doc.replace(
|
|
707
|
+
"{nexus_evolution}",
|
|
708
|
+
_nexus_evolution(_resolve_max_wheel_layer()),
|
|
709
|
+
)
|
|
710
|
+
tool_docs.append(doc)
|
|
639
711
|
|
|
640
712
|
conversation_use = _CONVERSATION_USE
|
|
641
713
|
if scoped and "ingest" not in names:
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
sync tool: Re-read the dialectical graph state.
|
|
3
|
+
|
|
4
|
+
Returns a structured dump of tensions, pathways, and synthesis for the
|
|
5
|
+
current case scope. With `nexus_hash`, zooms into one exploration and
|
|
6
|
+
renders it in full depth (the unscoped dump caps wheels per cycle for
|
|
7
|
+
compactness; the zoomed render is exempt, same as counsel-mode dumps).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import Annotated
|
|
13
|
+
|
|
14
|
+
from mirascope import llm
|
|
15
|
+
from pydantic import Field
|
|
16
|
+
|
|
17
|
+
from dialectical_framework.concerns.dialectical_context import \
|
|
18
|
+
DialecticalContext
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@llm.tool
|
|
22
|
+
async def sync(
|
|
23
|
+
nexus_hash: Annotated[
|
|
24
|
+
str | None,
|
|
25
|
+
Field(
|
|
26
|
+
description="Zoom into one exploration: render only this nexus, in full depth (no wheel cap). Omit for the full-case overview."
|
|
27
|
+
),
|
|
28
|
+
] = None,
|
|
29
|
+
) -> str:
|
|
30
|
+
"""Re-read the graph state. Without arguments: the full picture across all explorations (compact — wheels capped per cycle). With a nexus_hash: one exploration in full depth. Use the zoom when counsel centers on one exploration and the overview's capped view isn't enough."""
|
|
31
|
+
concern = DialecticalContext(nexus_hash=nexus_hash)
|
|
32
|
+
return await concern.resolve()
|
|
@@ -20,7 +20,9 @@ from dialectical_framework.agents.analyst.system_prompts import SYSTEM_PROMPT
|
|
|
20
20
|
from dialectical_framework.agents.conversation_facilitator import \
|
|
21
21
|
ConversationFacilitator
|
|
22
22
|
from dialectical_framework.agents.reasonable_concern import ReasonableConcern
|
|
23
|
+
from dialectical_framework.agents.app_spec import AppSpec, resolve_app_layer
|
|
23
24
|
from dialectical_framework.agents.stream_events import StreamEvent
|
|
25
|
+
from dialectical_framework.agents.toolsets import merge_app_tools
|
|
24
26
|
|
|
25
27
|
if TYPE_CHECKING:
|
|
26
28
|
pass
|
|
@@ -48,13 +50,17 @@ class Analyst:
|
|
|
48
50
|
|
|
49
51
|
Usage:
|
|
50
52
|
with scope(case.sid):
|
|
51
|
-
analyst = Analyst(
|
|
53
|
+
analyst = Analyst(app=MY_APP_SPEC) # declarative (see AppSpec)
|
|
52
54
|
response = await analyst.chat("I'm struggling with work-life balance")
|
|
53
55
|
|
|
54
56
|
# Resuming with history:
|
|
55
57
|
with scope(case.sid):
|
|
56
58
|
analyst = Analyst(messages=loaded_messages)
|
|
57
59
|
response = await analyst.chat("What about the second tension?")
|
|
60
|
+
|
|
61
|
+
# Manual preamble control (app_preamble replaces AppSpec composition):
|
|
62
|
+
with scope(case.sid):
|
|
63
|
+
analyst = Analyst(app_preamble="You are a counselor...")
|
|
58
64
|
"""
|
|
59
65
|
|
|
60
66
|
AGENT_NAME = "analyst"
|
|
@@ -63,8 +69,17 @@ class Analyst:
|
|
|
63
69
|
self,
|
|
64
70
|
app_preamble: Optional[str] = None,
|
|
65
71
|
messages: Optional[list] = None,
|
|
72
|
+
app_tools: Optional[list] = None,
|
|
73
|
+
app: Optional[AppSpec] = None,
|
|
66
74
|
) -> None:
|
|
67
|
-
|
|
75
|
+
# app: declarative app definition — the framework composes the
|
|
76
|
+
# Navigator preamble (NAVIGATOR_APP + voicing + tool_guide) and tool
|
|
77
|
+
# set from it. app_preamble/app_tools remain for manual control;
|
|
78
|
+
# mixing them with app= raises (see app_spec.resolve_app_layer).
|
|
79
|
+
app_preamble, app_tools = resolve_app_layer(
|
|
80
|
+
app, app_preamble, app_tools, preamble_for="navigator"
|
|
81
|
+
)
|
|
82
|
+
self._tools = merge_app_tools(_build_tools(), app_tools)
|
|
68
83
|
self._conversation = ConversationFacilitator(tools=self._tools)
|
|
69
84
|
if messages:
|
|
70
85
|
self._conversation._messages = list(messages)
|
|
@@ -130,6 +130,16 @@ the user wants it fixed; absent = not validated (neutral). Communicate the
|
|
|
130
130
|
verdict as meaning ("this one held up under the coherence check"), not as a
|
|
131
131
|
flag name.
|
|
132
132
|
|
|
133
|
+
Validation also scores `DV` (dialectical validity) — how NATURAL the
|
|
134
|
+
tension's dynamics are, separate from coherence: high DV means the poles
|
|
135
|
+
genuinely complement each other and the pathologies arise organically; low
|
|
136
|
+
DV means the framing itself is forced or one-sided even if it reads
|
|
137
|
+
coherently. A low-DV tension is better re-framed (`edit_perspective` or
|
|
138
|
+
discard-and-re-anchor) than polished aspect-by-aspect — the distortion sits
|
|
139
|
+
in the T/A framing, not the aspects. Note: counsel mode prunes very-low-DV
|
|
140
|
+
tensions from its working view, so a framing you keep here may be absent
|
|
141
|
+
there — re-framing it fixes both.
|
|
142
|
+
|
|
133
143
|
## Exploration Setup (Nexus)
|
|
134
144
|
|
|
135
145
|
"Nexus" is the internal name for what the user calls an **Exploration** — same
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AppSpec: declarative app definition — the host describes WHAT its app is,
|
|
3
|
+
each agent head composes the right preamble from it.
|
|
4
|
+
|
|
5
|
+
Without this, an app developer must know framework lore to preamble an app:
|
|
6
|
+
which base constant belongs to which head (NAVIGATOR_APP for Analyst/Explorer,
|
|
7
|
+
EXPLORATION_ADVISOR_APP for the counsel toggle, bare persona for a standalone
|
|
8
|
+
Advisor), that later preamble sections override earlier ones, and that the
|
|
9
|
+
same tool guide must be repeated into every head's preamble. AppSpec owns
|
|
10
|
+
that lore: the app supplies only its custom pieces, the framework supplies
|
|
11
|
+
the generic contract.
|
|
12
|
+
|
|
13
|
+
Usage:
|
|
14
|
+
ASTRO_APP = AppSpec(
|
|
15
|
+
voicing=\"\"\"## Astrological Voicing
|
|
16
|
+
Phrase oppositions in elemental and zodiacal terms where natural...\"\"\",
|
|
17
|
+
advisor_persona=\"\"\"## Persona
|
|
18
|
+
You are a wise astrologer. The person seeks counsel through their chart...\"\"\",
|
|
19
|
+
tool_guide=\"\"\"## Chart Resources
|
|
20
|
+
- lookup_natal_chart(person): fetch a natal chart. Use when...\"\"\",
|
|
21
|
+
tools=[lookup_natal_chart],
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
Analyst(app=ASTRO_APP)
|
|
25
|
+
Explorer(nexus_hash=nx, messages=msgs, app=ASTRO_APP)
|
|
26
|
+
Advisor(nexus_hash=nx, messages=msgs, app=ASTRO_APP) # counsel toggle
|
|
27
|
+
Advisor(app=ASTRO_APP) # standalone advisor
|
|
28
|
+
|
|
29
|
+
Every field is optional — an AppSpec with only `voicing` is a pure
|
|
30
|
+
re-skinning of the Navigator; one with only `tools` + `tool_guide` adds
|
|
31
|
+
domain resources without touching voice. The low-level `app_preamble` /
|
|
32
|
+
`app_tools` constructor params remain for full manual control; passing
|
|
33
|
+
both `app` and either of them raises (ambiguous composition).
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
from __future__ import annotations
|
|
37
|
+
|
|
38
|
+
from dataclasses import dataclass, field
|
|
39
|
+
from typing import Optional
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass(frozen=True)
|
|
43
|
+
class AppSpec:
|
|
44
|
+
"""Declarative definition of a host app, composed per agent head.
|
|
45
|
+
|
|
46
|
+
voicing: Domain flavor layered on the Navigator user contract
|
|
47
|
+
(Analyst/Explorer and the counsel toggle). Vocabulary direction,
|
|
48
|
+
framing, domain emphasis — NOT tool docs, NOT persona for the
|
|
49
|
+
standalone Advisor.
|
|
50
|
+
advisor_persona: Persona for the STANDALONE (unscoped) Advisor, where
|
|
51
|
+
the machinery is hidden and the preamble is the entire user-facing
|
|
52
|
+
identity (like COUNSELOR_APP). Ignored in counsel-toggle mode,
|
|
53
|
+
which keeps the Navigator contract.
|
|
54
|
+
tool_guide: Shared documentation for the app's tools — what each does,
|
|
55
|
+
when to reach for it. Included verbatim in EVERY head's preamble
|
|
56
|
+
so the usage rules cannot drift between heads. How tool use
|
|
57
|
+
SURFACES to the user still follows each head's disclosure rules.
|
|
58
|
+
tools: App-provided @llm.tool functions, passed to every head
|
|
59
|
+
(see toolsets.merge_app_tools).
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
voicing: Optional[str] = None
|
|
63
|
+
advisor_persona: Optional[str] = None
|
|
64
|
+
tool_guide: Optional[str] = None
|
|
65
|
+
tools: list = field(default_factory=list)
|
|
66
|
+
|
|
67
|
+
def navigator_preamble(self, advanced: bool = False) -> str:
|
|
68
|
+
"""Preamble for Analyst/Explorer heads: Navigator contract + app pieces."""
|
|
69
|
+
from dialectical_framework.agents.apps import (
|
|
70
|
+
NAVIGATOR_ADVANCED_MODE_APP, NAVIGATOR_APP)
|
|
71
|
+
|
|
72
|
+
base = NAVIGATOR_ADVANCED_MODE_APP if advanced else NAVIGATOR_APP
|
|
73
|
+
return _join(base, self.voicing, self.tool_guide)
|
|
74
|
+
|
|
75
|
+
def advisor_preamble(self, scoped: bool) -> str:
|
|
76
|
+
"""Preamble for the Advisor head.
|
|
77
|
+
|
|
78
|
+
scoped=True (counsel toggle of a Navigator session): the Navigator
|
|
79
|
+
contract survives the toggle — EXPLORATION_ADVISOR_APP + app pieces.
|
|
80
|
+
scoped=False (standalone Advisor): the persona IS the identity —
|
|
81
|
+
no Navigator base, machinery stays hidden.
|
|
82
|
+
"""
|
|
83
|
+
from dialectical_framework.agents.apps import EXPLORATION_ADVISOR_APP
|
|
84
|
+
|
|
85
|
+
if scoped:
|
|
86
|
+
return _join(EXPLORATION_ADVISOR_APP, self.voicing, self.tool_guide)
|
|
87
|
+
return _join(self.advisor_persona, self.tool_guide)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _join(*parts: Optional[str]) -> str:
|
|
91
|
+
return "\n\n".join(p.strip() for p in parts if p and p.strip())
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def resolve_app_layer(
|
|
95
|
+
app: Optional[AppSpec],
|
|
96
|
+
app_preamble: Optional[str],
|
|
97
|
+
app_tools: Optional[list],
|
|
98
|
+
preamble_for: str, # "navigator" | "advisor_scoped" | "advisor_unscoped"
|
|
99
|
+
) -> tuple[Optional[str], Optional[list]]:
|
|
100
|
+
"""Resolve the (preamble, tools) pair from either an AppSpec or the
|
|
101
|
+
low-level params. Mixing both raises — composition would be ambiguous
|
|
102
|
+
(does app_preamble replace the spec's derived preamble or stack on it?).
|
|
103
|
+
"""
|
|
104
|
+
if app is None:
|
|
105
|
+
return app_preamble, app_tools
|
|
106
|
+
if app_preamble is not None or app_tools is not None:
|
|
107
|
+
raise ValueError(
|
|
108
|
+
"Pass either app= (declarative) or app_preamble=/app_tools= "
|
|
109
|
+
"(manual), not both."
|
|
110
|
+
)
|
|
111
|
+
if preamble_for == "navigator":
|
|
112
|
+
preamble = app.navigator_preamble()
|
|
113
|
+
elif preamble_for == "advisor_scoped":
|
|
114
|
+
preamble = app.advisor_preamble(scoped=True)
|
|
115
|
+
elif preamble_for == "advisor_unscoped":
|
|
116
|
+
preamble = app.advisor_preamble(scoped=False)
|
|
117
|
+
else:
|
|
118
|
+
raise ValueError(f"Unknown preamble_for: {preamble_for}")
|
|
119
|
+
return preamble or None, app.tools or None
|
{dialectical_framework-1.6.6 → dialectical_framework-1.6.8}/src/dialectical_framework/agents/apps.py
RENAMED
|
@@ -19,6 +19,12 @@ There are two territories:
|
|
|
19
19
|
Apps define HOW the agents communicate — vocabulary, depth, framing, persona.
|
|
20
20
|
They are injected by the host application at agent construction time.
|
|
21
21
|
|
|
22
|
+
The recommended host interface is `AppSpec` (agents/app_spec.py): the app
|
|
23
|
+
declares its custom pieces (voicing, advisor_persona, tool_guide, tools) and
|
|
24
|
+
each agent head composes the right base from THIS module itself — hosts never
|
|
25
|
+
concatenate these constants by hand. Direct `app_preamble=` passing remains
|
|
26
|
+
for full manual control.
|
|
27
|
+
|
|
22
28
|
Prompt Revision Methodology
|
|
23
29
|
===========================
|
|
24
30
|
When fixing LLM output bugs in these prompts, use /df-review-reasoning-layer for the
|
|
@@ -20,7 +20,9 @@ from dialectical_framework.agents.conversation_facilitator import \
|
|
|
20
20
|
ConversationFacilitator
|
|
21
21
|
from dialectical_framework.agents.explorer.system_prompts import system_prompt
|
|
22
22
|
from dialectical_framework.agents.reasonable_concern import ReasonableConcern
|
|
23
|
+
from dialectical_framework.agents.app_spec import AppSpec, resolve_app_layer
|
|
23
24
|
from dialectical_framework.agents.stream_events import StreamEvent
|
|
25
|
+
from dialectical_framework.agents.toolsets import merge_app_tools
|
|
24
26
|
from dialectical_framework.graph.repositories.nexus_repository import \
|
|
25
27
|
NexusRepository
|
|
26
28
|
|
|
@@ -66,9 +68,21 @@ class Explorer:
|
|
|
66
68
|
nexus_hash: str,
|
|
67
69
|
app_preamble: Optional[str] = None,
|
|
68
70
|
messages: Optional[list] = None,
|
|
71
|
+
app_tools: Optional[list] = None,
|
|
72
|
+
app: Optional[AppSpec] = None,
|
|
69
73
|
) -> None:
|
|
70
74
|
self._nexus_hash = nexus_hash
|
|
71
|
-
|
|
75
|
+
# app: declarative app definition (Navigator base + voicing +
|
|
76
|
+
# tool_guide + tools) — see AppSpec. Pass the SAME AppSpec to every
|
|
77
|
+
# head (Analyst, Explorer, Advisor): the Explorer<->Advisor toggle
|
|
78
|
+
# shares literal history (a missing tool breaks capability
|
|
79
|
+
# mid-conversation), and the Analyst thread owes the user the same
|
|
80
|
+
# domain resources by parity. For advanced-mode preambles compose
|
|
81
|
+
# manually: app_preamble=my_app.navigator_preamble(advanced=True).
|
|
82
|
+
app_preamble, app_tools = resolve_app_layer(
|
|
83
|
+
app, app_preamble, app_tools, preamble_for="navigator"
|
|
84
|
+
)
|
|
85
|
+
self._tools = merge_app_tools(_build_tools(), app_tools)
|
|
72
86
|
self._conversation = ConversationFacilitator(tools=self._tools)
|
|
73
87
|
|
|
74
88
|
if messages:
|
|
@@ -149,6 +149,8 @@ from pydantic import Field
|
|
|
149
149
|
|
|
150
150
|
from dialectical_framework.agents.reasonable_concern import ReasonableConcern
|
|
151
151
|
from dialectical_framework.enums.di import DI
|
|
152
|
+
from dialectical_framework.graph.nodes.estimation import \
|
|
153
|
+
DialecticalValidityEstimation
|
|
152
154
|
from dialectical_framework.graph.rendering import (
|
|
153
155
|
build_pp_index,
|
|
154
156
|
component_alias,
|
|
@@ -215,7 +217,11 @@ def _inspect_perspective(pp: Perspective) -> str:
|
|
|
215
217
|
# Tetrad quality metrics
|
|
216
218
|
diff_t = pp.diff_t
|
|
217
219
|
diff_a = pp.diff_a
|
|
218
|
-
area =
|
|
220
|
+
# Raw area (= theory's SP, -2..2) — the scale every band/gate/prompt in the
|
|
221
|
+
# system speaks (settings min_sp, advisor bands, dialectical_context).
|
|
222
|
+
# area_normalized (area/2) is a UI-only hint; showing it here under a
|
|
223
|
+
# different scale than the Advisor's dump confused cross-surface reads.
|
|
224
|
+
area = pp.area
|
|
219
225
|
rect = pp.rectangularity
|
|
220
226
|
metrics: list[str] = []
|
|
221
227
|
if diff_t is not None:
|
|
@@ -223,9 +229,15 @@ def _inspect_perspective(pp: Perspective) -> str:
|
|
|
223
229
|
if diff_a is not None:
|
|
224
230
|
metrics.append(f"diff_a={diff_a:.3f}")
|
|
225
231
|
if area is not None:
|
|
226
|
-
metrics.append(f"
|
|
232
|
+
metrics.append(f"area={area:.3f}")
|
|
227
233
|
if rect is not None:
|
|
228
234
|
metrics.append(f"rect={rect:.4f}")
|
|
235
|
+
# DV (Dialectical Validity, paper's naturalness companion to SP) — read
|
|
236
|
+
# from the persisted estimation, annotation only.
|
|
237
|
+
for est, _ in pp.estimations.all():
|
|
238
|
+
if isinstance(est, DialecticalValidityEstimation):
|
|
239
|
+
metrics.append(f"DV={est.value:.3f}")
|
|
240
|
+
break
|
|
229
241
|
if metrics:
|
|
230
242
|
lines.append(f"Quality: {', '.join(metrics)}")
|
|
231
243
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Shared helper for merging app-provided tools into an agent's built-in set.
|
|
3
|
+
|
|
4
|
+
All three conversational agents (Analyst, Explorer, Advisor) expose an
|
|
5
|
+
`app_tools` constructor parameter — the app-side seam for domain
|
|
6
|
+
resources (chart lookups, methodology references, knowledge-base fetches).
|
|
7
|
+
The merge rules are identical across agents, so they live here.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import Optional
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def merge_app_tools(builtin: list, app_tools: Optional[list]) -> list:
|
|
16
|
+
"""Append app-provided @llm.tool functions to an agent's built-in set.
|
|
17
|
+
|
|
18
|
+
The agent's system prompt has no docs for app tools and skips unknown
|
|
19
|
+
names — apps describe them in the app preamble, where domain vocabulary
|
|
20
|
+
lives; the tool schemas (name, params, docstring) reach the LLM through
|
|
21
|
+
the tool protocol itself.
|
|
22
|
+
|
|
23
|
+
Raises:
|
|
24
|
+
ValueError: If an app tool shadows a built-in tool name — the app
|
|
25
|
+
tool would silently hijack framework machinery.
|
|
26
|
+
"""
|
|
27
|
+
if not app_tools:
|
|
28
|
+
return builtin
|
|
29
|
+
builtin_names = {t.__name__ for t in builtin}
|
|
30
|
+
collisions = [t.__name__ for t in app_tools if t.__name__ in builtin_names]
|
|
31
|
+
if collisions:
|
|
32
|
+
raise ValueError(f"app_tools shadow built-in tools: {collisions}")
|
|
33
|
+
return builtin + list(app_tools)
|
|
@@ -111,8 +111,9 @@ APEX
|
|
|
111
111
|
2. Must help transition FROM T- (problem) TOWARD A+ (benefit)
|
|
112
112
|
3. Must NOT simply restate A+ - it's the PATH, not the destination
|
|
113
113
|
4. Should be generative: enable discovery rather than prescribe specific outcomes
|
|
114
|
-
5.
|
|
115
|
-
6.
|
|
114
|
+
5. Must stay subtle, not forceful: an action that imposes, coerces, or overpowers reverses its polarity from Ac+ to Ac-. Prefer enabling over forcing
|
|
115
|
+
6. Length: a fuller actionable form, longer than the headline
|
|
116
|
+
7. Choose the insight level that best matches the nature of the action
|
|
116
117
|
"""
|
|
117
118
|
|
|
118
119
|
|