dialectical-framework 2.0.1__tar.gz → 2.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/PKG-INFO +1 -1
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/pyproject.toml +1 -1
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/consultant/consultant.py +47 -11
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/control_statements_check.py +58 -21
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/synthesis_generation.py +14 -3
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/tetrad_candidates.py +58 -27
- dialectical_framework-2.0.3/src/dialectical_framework/concerns/transformation_sketch.py +348 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/view_sketch.py +38 -8
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/views.py +6 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/bedrock_provider.py +80 -5
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/LICENSE +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/PATENTS +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/README.md +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/advisor.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/build_policy.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/migration.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/reply_hygiene.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/system_prompts.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/tools/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/tools/anchor.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/tools/deepen.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/tools/explore.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/tools/ingest.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/tools/note.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/tools/record_decision.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/tools/scoped.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/advisor/tools/sync.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/agent_context.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/analyst/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/analyst/analyst.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/analyst/skills/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/analyst/skills/anchor_theses.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/analyst/skills/edit_perspective.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/analyst/skills/expand_polarities.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/analyst/skills/find_polarities.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/analyst/skills/introduce_polarity.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/analyst/skills/sketch_tetrad.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/analyst/skills/surface_theses.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/analyst/system_prompts.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/analyst/tools/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/analyst/tools/place_statement.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/app_spec.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/apps.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/consultant/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/conversation_facilitator.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/execution_report.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/explorer/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/explorer/explorer.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/explorer/skills/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/explorer/skills/build_wheels.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/explorer/skills/explore_transformations.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/explorer/skills/generate_synthesis.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/explorer/system_prompts.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/explorer/tools/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/explorer/tools/create_nexus.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/explorer/tools/expand_nexus.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/explorer/tools/generate_synthesis.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/explorer/tools/present_exploration.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/orchestrator/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/orchestrator/tools/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/orchestrator/tools/add_input.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/orchestrator/tools/audit_feasibility.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/orchestrator/tools/create_dx_input.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/orchestrator/tools/digest_input.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/orchestrator/tools/discard.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/orchestrator/tools/get_schema.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/orchestrator/tools/inspect_node.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/orchestrator/tools/present_analysis.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/orchestrator/tools/query_graph.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/orchestrator/tools/read_digest.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/orchestrator/tools/read_input.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/reasonable_concern.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/stream_events.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/toolsets.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/agents/turn_timing.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/ac_re_taxonomy.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/action_extraction.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/add_input.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/ai_dto/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/ai_dto/statement_dto.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/ai_dto/statements_deck_dto.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/antithesis_classification.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/antithesis_extraction.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/antithetical_thesis_detection.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/aspect_classification.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/aspect_generation.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/build_status.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/causality/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/causality/causality_estimator.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/causality/causality_estimator_balanced.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/causality/causality_estimator_criteria.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/causality/causality_estimator_desirable.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/causality/causality_estimator_feasible.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/causality/causality_estimator_realistic.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/causality/causality_normalizer.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/causality/estimator_resolver.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/causality_estimation.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/create_dx_input.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/create_nexus.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/decision_coherence_check.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/decision_confirmation_check.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/diagonal_oppositions_check.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/dialectical_context.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/discard.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/display_text_edit.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/expand_nexus.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/perspective_combination.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/perspective_validation.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/positive_ac_re_apex_derivation.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/record_decision.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/scoring_scales.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/source_digest.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/statement_classification.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/statement_deduplication.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/statement_headline.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/statement_placement.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/tetrad_grounding.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/tetrad_sketch.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/thesis_extraction.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/transformation_audit.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/concerns/transformation_generation.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/dialectical_reasoning.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/enums/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/enums/causality_preset.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/enums/di.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/events/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/events/graph_event.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/events/graph_event_bus.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/events/progress_event.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/exceptions/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/exceptions/node_errors.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/exceptions/resolver_errors.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/composite_input_resolver.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/dialexity_input_resolver.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/estimation_manager.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/mixins/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/mixins/incremental_build_mixin.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/mixins/intent_mixin.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/mixins/persistable_mixin.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/assessable_entity.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/base_node.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/case.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/cycle.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/decision.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/estimation.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/ideas.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/input.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/nexus.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/note.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/perspective.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/polarity.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/rationale.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/statement.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/synthesis.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/transformation.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/transition.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/nodes/wheel.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationship_manager.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/action_reflection_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/belongs_to_cycle_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/belongs_to_nexus_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/changed_to_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/contradiction_of_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/critiques_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/distilled_to_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/estimates_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/explains_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/grounded_in_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/has_input_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/has_statement_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/has_wheel_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/immutable_structure.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/is_source_of_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/is_target_of_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/negative_side_of_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/opposite_direction_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/opposite_of_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/polarity_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/positive_side_of_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/provides_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/relationships/synthesis_of_relationship.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/rendering.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/case_repository.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/cycle_repository.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/decision_repository.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/input_repository.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/nexus_repository.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/node_repository.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/note_repository.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/perspective_repository.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/polarity_repository.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/schema_repository.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/statement_repository.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/transformation_repository.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/repositories/wheel_repository.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/scope_context.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/verbatim_input_resolver.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/wheel_segment.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/graph/wheel_segment_polar_pair.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/protocols/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/protocols/has_config.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/protocols/input_resolver.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/py.typed +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/settings.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/__init__.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/async_drain.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/call_census.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/chunking.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/concurrency.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/dc_replace.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/decompose_probability_uniformly.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/edge_context.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/effect_logger.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/input_context.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/order_transitions.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/progress.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/retry_accounting.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/sequence_generation.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/thinking_compat.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/use_brain.py +0 -0
- {dialectical_framework-2.0.1 → dialectical_framework-2.0.3}/src/dialectical_framework/utils/utterance.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: dialectical-framework
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.3
|
|
4
4
|
Summary: A dialectical framework for augmented intelligence. AI reasoning powered with dialectics supports humans in: system optimization (psychology, engineering, business, politics, etc.); dispute resolution (mediation, conflicts, negotiations, etc.); decision-making (dilemmas, challenging situations, win-win, etc.).
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: dialectics,dialectical-reasoning,synthesis,thesis-antithesis,ai,artificial-intelligence,llm,reasoning-framework,philosophy,logic,argumentation,conflict-resolution,decision-making,critical-thinking,semantic-graph,mirascope,pydantic,perspectives,polarity-reasoning
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "dialectical-framework"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.3"
|
|
4
4
|
description = "A dialectical framework for augmented intelligence. AI reasoning powered with dialectics supports humans in: system optimization (psychology, engineering, business, politics, etc.); dispute resolution (mediation, conflicts, negotiations, etc.); decision-making (dilemmas, challenging situations, win-win, etc.)."
|
|
5
5
|
authors = ["Evaldas Taroza <evaldas@dialexity.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -51,7 +51,7 @@ from dialectical_framework.agents.conversation_facilitator import (
|
|
|
51
51
|
FROM_SETTINGS, ConversationFacilitator)
|
|
52
52
|
from dialectical_framework.agents.stream_events import StreamEvent
|
|
53
53
|
from dialectical_framework.agents.turn_timing import TurnTiming
|
|
54
|
-
from dialectical_framework.graph.views import ExplorationView
|
|
54
|
+
from dialectical_framework.graph.views import ExplorationView, PerspectiveView
|
|
55
55
|
|
|
56
56
|
#: Tool verbs → mental acts. These are REWRITES, not drops: dropping every
|
|
57
57
|
#: paragraph that mentions a tool name would also delete the discrimination test
|
|
@@ -324,7 +324,12 @@ class Consultant:
|
|
|
324
324
|
if messages:
|
|
325
325
|
self._conversation.load_messages(messages)
|
|
326
326
|
parts = [p for p in (preamble, method_prompt(include_decision)) if p]
|
|
327
|
-
|
|
327
|
+
# Kept because the view turn's system prompt is this text plus the
|
|
328
|
+
# static half of its request (`exploration_view`): appending keeps the
|
|
329
|
+
# head a PREFIX of it, so the chat turns' cached prefix is readable by
|
|
330
|
+
# the sketch turns instead of each paying for its own.
|
|
331
|
+
self._system_prompt = "\n\n".join(parts)
|
|
332
|
+
self._conversation.set_system_prompt(self._system_prompt)
|
|
328
333
|
|
|
329
334
|
async def chat(self, user_message: str) -> str:
|
|
330
335
|
result = await self._conversation.submit(ChatResponse, user_message)
|
|
@@ -362,7 +367,8 @@ class Consultant:
|
|
|
362
367
|
view shows what has been ESTABLISHED, and where `focus` asks for
|
|
363
368
|
structure not yet worked out ("a perspective for the thesis you
|
|
364
369
|
named") the turn builds it by the method first
|
|
365
|
-
(`concerns/view_sketch.py
|
|
370
|
+
(`concerns/view_sketch.py`: the static instructions ride on the system
|
|
371
|
+
prompt, the focus is the turn). What it built is
|
|
366
372
|
kept in `messages` as the consultant's own words, so the next turn can
|
|
367
373
|
be asked about a corner it just drew.
|
|
368
374
|
|
|
@@ -380,16 +386,30 @@ class Consultant:
|
|
|
380
386
|
"""
|
|
381
387
|
from dialectical_framework.concerns.view_sketch import (
|
|
382
388
|
ViewSketchDto, exploration_view_from_sketch, history_ask,
|
|
383
|
-
history_text,
|
|
389
|
+
history_text, perspective_from_sketch, view_sketch_focus,
|
|
390
|
+
view_sketch_instructions)
|
|
384
391
|
|
|
385
392
|
import asyncio
|
|
393
|
+
import dataclasses
|
|
386
394
|
|
|
387
395
|
from dialectical_framework.concerns.tetrad_candidates import (
|
|
388
|
-
clamp_attempts, select_sketch)
|
|
396
|
+
clamp_attempts, ranking, select_sketch)
|
|
389
397
|
|
|
390
398
|
level = self._conversation._thinking_kwargs().get("thinking")
|
|
391
399
|
history = self._conversation._messages
|
|
392
|
-
request
|
|
400
|
+
# The request travels in two places, not one. Its static half
|
|
401
|
+
# (definitions, rules, the build procedure) goes on the SYSTEM prompt,
|
|
402
|
+
# after this head's own, because that is where the provider's cache
|
|
403
|
+
# breakpoint sits: as part of the user message it followed the history
|
|
404
|
+
# and was re-prefilled at full rate on every draw (~1.2k tokens x N a
|
|
405
|
+
# card, measured 2026-10-06). Only the focus — the person's own ask —
|
|
406
|
+
# is the turn. Same words, and the history record is untouched
|
|
407
|
+
# (`history_ask`, which is why the long request was never kept anyway).
|
|
408
|
+
system = (
|
|
409
|
+
f"{self._system_prompt}\n\n"
|
|
410
|
+
f"{view_sketch_instructions(self._conversation.settings.component_length)}"
|
|
411
|
+
)
|
|
412
|
+
ask = view_sketch_focus(focus)
|
|
393
413
|
|
|
394
414
|
async def draw() -> ViewSketchDto:
|
|
395
415
|
# Each draw works on a COPY of the history: the turns run in
|
|
@@ -397,9 +417,20 @@ class Consultant:
|
|
|
397
417
|
# read. What the view leaves behind is appended once, below.
|
|
398
418
|
sketch_turn = ConversationFacilitator(format_mode="json", thinking=level)
|
|
399
419
|
sketch_turn._messages = list(history)
|
|
400
|
-
|
|
420
|
+
sketch_turn.set_system_prompt(system)
|
|
421
|
+
return await sketch_turn.submit(ViewSketchDto, ask)
|
|
401
422
|
|
|
402
423
|
n = clamp_attempts(attempts)
|
|
424
|
+
# Fully parallel, deliberately. On a COLD cache all N draws write the
|
|
425
|
+
# ~12k system head instead of one writing and the rest reading (~$0.06
|
|
426
|
+
# a card at list prices, 2026-10-06), and the fix would be to await the
|
|
427
|
+
# first draw before firing the rest — but these turns do not stream, so
|
|
428
|
+
# nothing here can tell a cold cache from a warm one, and the stagger
|
|
429
|
+
# would spend a whole draw's latency (~6 s) on EVERY card to save money
|
|
430
|
+
# on the rare one. The 1h breakpoint TTL
|
|
431
|
+
# (`utils/bedrock_provider.py::_CACHE_TTL`) attacks the same cost
|
|
432
|
+
# without the latency, which is the trade taken. Revisit only with a
|
|
433
|
+
# measured cold-start rate.
|
|
403
434
|
drawn = await asyncio.gather(*(draw() for _ in range(n)), return_exceptions=True)
|
|
404
435
|
sketches = [d for d in drawn if not isinstance(d, BaseException)]
|
|
405
436
|
if not sketches:
|
|
@@ -407,19 +438,24 @@ class Consultant:
|
|
|
407
438
|
# With several draws the framework's own coherence check picks the one
|
|
408
439
|
# whose FIRST tension holds best (`concerns/tetrad_candidates.py`); a
|
|
409
440
|
# draw with no complete first tension sorts last. The card a blindspot
|
|
410
|
-
# screen shows is that first tension.
|
|
441
|
+
# screen shows is that first tension. The judged draws that lost come
|
|
442
|
+
# back too, best first, as `runners_up` — a host's "again"/"another"
|
|
443
|
+
# can serve one without a new call (the module's stated intent).
|
|
444
|
+
runners_up: list[PerspectiveView] = []
|
|
411
445
|
if len(sketches) > 1:
|
|
412
446
|
firsts = [s.tensions[0] if s.tensions else None for s in sketches]
|
|
413
447
|
judgeable = [i for i, t in enumerate(firsts) if t is not None and all(
|
|
414
448
|
(getattr(t, k) or "").strip() for k in ("thesis", "antithesis", "t_plus", "t_minus", "a_plus", "a_minus"))]
|
|
415
449
|
if len(judgeable) > 1:
|
|
416
|
-
|
|
417
|
-
|
|
450
|
+
_best, verdicts = await select_sketch([firsts[i] for i in judgeable])
|
|
451
|
+
order = ranking(verdicts)
|
|
452
|
+
sketch = sketches[judgeable[order[0]]]
|
|
453
|
+
runners_up = [perspective_from_sketch(firsts[judgeable[i]]) for i in order[1:]]
|
|
418
454
|
else:
|
|
419
455
|
sketch = sketches[judgeable[0]] if judgeable else sketches[0]
|
|
420
456
|
else:
|
|
421
457
|
sketch = sketches[0]
|
|
422
|
-
view = exploration_view_from_sketch(sketch)
|
|
458
|
+
view = dataclasses.replace(exploration_view_from_sketch(sketch), runners_up=runners_up)
|
|
423
459
|
# What the turn leaves behind is NOT what it sent: the long request and
|
|
424
460
|
# the DTO come off, and the person's ask plus the drawing in words go
|
|
425
461
|
# on. Kept as a request→prose pair, the long request taught the next
|
|
@@ -97,6 +97,47 @@ class CoherenceEvaluationDto(BaseModel):
|
|
|
97
97
|
)
|
|
98
98
|
|
|
99
99
|
|
|
100
|
+
def control_statements(
|
|
101
|
+
*, t_plus: str, t_minus: str, a_plus: str, a_minus: str
|
|
102
|
+
) -> tuple[str, str]:
|
|
103
|
+
"""The paper's two control statements, built from four texts.
|
|
104
|
+
|
|
105
|
+
One builder for both askers (`resolve` off a committed Perspective,
|
|
106
|
+
`score_texts` off bare texts) so the quoting cannot drift: a verdict taken
|
|
107
|
+
before persistence and one taken after must be the same question asked of
|
|
108
|
+
the same words.
|
|
109
|
+
"""
|
|
110
|
+
return (
|
|
111
|
+
f'"{t_plus}" without "{a_plus}" yields "{t_minus}"',
|
|
112
|
+
f'"{a_plus}" without "{t_plus}" yields "{a_minus}"',
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
# --- Prompt text ---
|
|
117
|
+
#
|
|
118
|
+
# The pattern and the two scales of `_evaluate_control_statement`, as constants
|
|
119
|
+
# so a probe can put the SAME scales in front of a candidate judge
|
|
120
|
+
# (`tests/e2e/probe_joint_judge_stability.py` did, 2026-10-06, and rejected two
|
|
121
|
+
# cheaper shapes against this one).
|
|
122
|
+
|
|
123
|
+
_PATTERN = """The pattern "[Positive] without [Balancing factor] yields [Negative]" tests whether
|
|
124
|
+
the absence of a balancing positive aspect naturally leads to the negative/shadow aspect."""
|
|
125
|
+
|
|
126
|
+
_CC_SCALE = """Conceptual Coherence (CC) — is the statement logically meaningful?
|
|
127
|
+
- 0.9-1.0: Highly coherent, clear logical/causal relationship
|
|
128
|
+
- 0.7-0.9: Coherent, reasonable logical connection
|
|
129
|
+
- 0.5-0.7: Somewhat coherent, plausible but weak
|
|
130
|
+
- 0.3-0.5: Weak coherence, tenuous connection
|
|
131
|
+
- 0.0-0.3: Not coherent, no clear logical relationship"""
|
|
132
|
+
|
|
133
|
+
_DV_SCALE = """Dialectical Validity (DV) — is the dialectical relationship natural, judged
|
|
134
|
+
independently of coherence? A statement can be perfectly coherent yet dialectically
|
|
135
|
+
distorted (e.g. one pole arbitrarily privileged, outcomes enforced by coercion or
|
|
136
|
+
ideology rather than natural system dynamics). 1.0 = natural, balanced, generative;
|
|
137
|
+
0.0 = forced, artificial, distorted. Ignore factual correctness; evaluate only the
|
|
138
|
+
quality of the dialectical relationship as a generative principle."""
|
|
139
|
+
|
|
140
|
+
|
|
100
141
|
# --- Result ---
|
|
101
142
|
|
|
102
143
|
|
|
@@ -182,8 +223,12 @@ class ControlStatementsCheck(ReasonableConcern[ControlStatementsCheckResult]):
|
|
|
182
223
|
a_minus = perspective.get_component(POSITION_A_MINUS)
|
|
183
224
|
|
|
184
225
|
# Build control statements
|
|
185
|
-
stmt_1 =
|
|
186
|
-
|
|
226
|
+
stmt_1, stmt_2 = control_statements(
|
|
227
|
+
t_plus=t_plus.prompt_text,
|
|
228
|
+
t_minus=t_minus.prompt_text,
|
|
229
|
+
a_plus=a_plus.prompt_text,
|
|
230
|
+
a_minus=a_minus.prompt_text,
|
|
231
|
+
)
|
|
187
232
|
|
|
188
233
|
# Evaluate both statements in parallel using isolated conversations
|
|
189
234
|
result_1, result_2 = await asyncio.gather(
|
|
@@ -268,12 +313,15 @@ class ControlStatementsCheck(ReasonableConcern[ControlStatementsCheckResult]):
|
|
|
268
313
|
|
|
269
314
|
What `resolve` does after reading the four aspects off a committed
|
|
270
315
|
node, offered to callers that hold a tetrad as text: the best-of-N
|
|
271
|
-
selector (`concerns/tetrad_candidates.py`) and the harness. Built
|
|
272
|
-
the same
|
|
273
|
-
same question as the one asked after
|
|
316
|
+
selector (`concerns/tetrad_candidates.py`) and the harness. Built by
|
|
317
|
+
the same statement builder and asked with the same prompt as `resolve`,
|
|
318
|
+
so a verdict here is the same question as the one asked after
|
|
319
|
+
persistence. Two calls per tetrad is the cost of that: the cheaper
|
|
320
|
+
shapes measured against it disagreed (`tetrad_candidates.judge_sketches`).
|
|
274
321
|
"""
|
|
275
|
-
stmt_1 =
|
|
276
|
-
|
|
322
|
+
stmt_1, stmt_2 = control_statements(
|
|
323
|
+
t_plus=t_plus, t_minus=t_minus, a_plus=a_plus, a_minus=a_minus
|
|
324
|
+
)
|
|
277
325
|
return await asyncio.gather(
|
|
278
326
|
self._evaluate_control_statement(stmt_1, text),
|
|
279
327
|
self._evaluate_control_statement(stmt_2, text),
|
|
@@ -291,22 +339,11 @@ class ControlStatementsCheck(ReasonableConcern[ControlStatementsCheckResult]):
|
|
|
291
339
|
|
|
292
340
|
{statement}
|
|
293
341
|
|
|
294
|
-
|
|
295
|
-
the absence of a balancing positive aspect naturally leads to the negative/shadow aspect.
|
|
342
|
+
{_PATTERN}
|
|
296
343
|
|
|
297
|
-
1.
|
|
298
|
-
- 0.9-1.0: Highly coherent, clear logical/causal relationship
|
|
299
|
-
- 0.7-0.9: Coherent, reasonable logical connection
|
|
300
|
-
- 0.5-0.7: Somewhat coherent, plausible but weak
|
|
301
|
-
- 0.3-0.5: Weak coherence, tenuous connection
|
|
302
|
-
- 0.0-0.3: Not coherent, no clear logical relationship
|
|
344
|
+
1. {_CC_SCALE}
|
|
303
345
|
|
|
304
|
-
2.
|
|
305
|
-
independently of coherence? A statement can be perfectly coherent yet dialectically
|
|
306
|
-
distorted (e.g. one pole arbitrarily privileged, outcomes enforced by coercion or
|
|
307
|
-
ideology rather than natural system dynamics). 1.0 = natural, balanced, generative;
|
|
308
|
-
0.0 = forced, artificial, distorted. Ignore factual correctness; evaluate only the
|
|
309
|
-
quality of the dialectical relationship as a generative principle."""
|
|
346
|
+
2. {_DV_SCALE}"""
|
|
310
347
|
|
|
311
348
|
conversation = ConversationFacilitator()
|
|
312
349
|
return await conversation.submit(
|
|
@@ -30,6 +30,8 @@ from dialectical_framework.agents.conversation_facilitator import (
|
|
|
30
30
|
ConversationFacilitator,
|
|
31
31
|
)
|
|
32
32
|
from dialectical_framework.agents.reasonable_concern import ReasonableConcern
|
|
33
|
+
from dialectical_framework.concerns.transformation_sketch import (
|
|
34
|
+
SYNTHESIS_SHAPE, TRANSFORMATION_POSITIONS)
|
|
33
35
|
from dialectical_framework.graph.nodes.statement import Statement
|
|
34
36
|
from dialectical_framework.protocols.has_config import SettingsAware
|
|
35
37
|
|
|
@@ -39,7 +41,12 @@ if TYPE_CHECKING:
|
|
|
39
41
|
from dialectical_framework.graph.nodes.wheel import Wheel
|
|
40
42
|
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
#: "The shape of the inputs" is the framework's ONE statement of the
|
|
45
|
+
#: Transformation (`transformation_sketch.TRANSFORMATION_POSITIONS`) and of S±
|
|
46
|
+
#: (`SYNTHESIS_SHAPE`), not a copy: this prompt reads graph-built
|
|
47
|
+
#: Transformations and the one-shot writes them, and the two must not define
|
|
48
|
+
#: Ac-/Re- differently (2026-10-06 — this paragraph had dropped where Ac- GOES).
|
|
49
|
+
SYSTEM_PROMPT = f"""You are an expert in dialectical synthesis — the emergent properties arising from circular causality loops.
|
|
43
50
|
|
|
44
51
|
## What Synthesis IS
|
|
45
52
|
|
|
@@ -57,7 +64,7 @@ S+ produces new qualitative dimensions — it increases a system's capacity for
|
|
|
57
64
|
## S- (Negative Synthesis): Collapse Pattern (1+1<2)
|
|
58
65
|
|
|
59
66
|
S- emerges when the failure modes (Ac- and Re-) reinforce each other:
|
|
60
|
-
-
|
|
67
|
+
- Ac+ without Re+ yields Ac- (the action's own drift, which carries T+ into A-); Re+ without Ac+ yields Re- (the reflection's own regression, which carries A+ into T-)
|
|
61
68
|
- Together these create downward spirals — dominance of one pole, or unstable oscillation between them
|
|
62
69
|
- Diversity is reduced and qualitative growth is replaced by quantitative amplification
|
|
63
70
|
|
|
@@ -65,7 +72,11 @@ S- manifests as imitation rather than transformation: external forms, metrics, o
|
|
|
65
72
|
|
|
66
73
|
## The shape of the inputs, exactly
|
|
67
74
|
|
|
68
|
-
Each Transformation is itself a tetrad
|
|
75
|
+
Each Transformation is itself a tetrad, built this way:
|
|
76
|
+
|
|
77
|
+
{TRANSFORMATION_POSITIONS}
|
|
78
|
+
|
|
79
|
+
{SYNTHESIS_SHAPE}
|
|
69
80
|
|
|
70
81
|
## Requirements
|
|
71
82
|
|
|
@@ -106,25 +106,54 @@ def is_complete(candidate: Any) -> bool:
|
|
|
106
106
|
)
|
|
107
107
|
|
|
108
108
|
|
|
109
|
-
async def
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
async def judge_sketches(
|
|
110
|
+
candidates: Sequence[Any], context: str = ""
|
|
111
|
+
) -> list[Optional[SketchVerdict]]:
|
|
112
|
+
"""The validator's two control statements for every candidate, each draft
|
|
113
|
+
judged on its own, each statement in its own call (gathered).
|
|
114
|
+
|
|
115
|
+
Statement texts are built by the same builder `ControlStatementsCheck.resolve`
|
|
116
|
+
uses, and the prompt is the one `resolve` asks, so a verdict here and one
|
|
117
|
+
taken after persistence are the same question asked of the same words. The
|
|
118
|
+
judge sees only the four aspects of each draft, never the thesis or the
|
|
119
|
+
antithesis. Fail-soft per candidate: a judging that fails is `None` for
|
|
120
|
+
that draft alone, which sorts last.
|
|
121
|
+
|
|
122
|
+
Deliberately NOT cheaper, by measurement (2026-10-06,
|
|
123
|
+
`tests/e2e/probe_joint_judge_stability.py`, 40 stored triples). Judging is
|
|
124
|
+
the costliest part of a best-of-3 card (6 of its 11 calls, about a third of
|
|
125
|
+
its cost), and two cheaper shapes were tried and rejected:
|
|
126
|
+
- one call for the whole field: pass/fail agreement with the stored verdict
|
|
127
|
+
70% against this judge's own 92% on the same drafts, the same winner
|
|
128
|
+
across a reversed order in 7/40, the first-listed draft winning 29/40;
|
|
129
|
+
it picked by position and ties;
|
|
130
|
+
- one call per draft with both statements in it (the same lean prompt):
|
|
131
|
+
73% against 90%, the same winner as this judge in 23/40 — stable with
|
|
132
|
+
itself, but measuring something else.
|
|
133
|
+
A cheaper judge has to be measured against this one on that probe first.
|
|
115
134
|
"""
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
135
|
+
|
|
136
|
+
async def one(tension: Any) -> Optional[SketchVerdict]:
|
|
137
|
+
# Reading the verdict is inside the `try` too: a malformed response
|
|
138
|
+
# is a failed judging (sorts last), never a failed selection.
|
|
139
|
+
try:
|
|
140
|
+
first, second = await ControlStatementsCheck().score_texts(
|
|
141
|
+
t_plus=aspect_text(tension.t_plus),
|
|
142
|
+
t_minus=aspect_text(tension.t_minus),
|
|
143
|
+
a_plus=aspect_text(tension.a_plus),
|
|
144
|
+
a_minus=aspect_text(tension.a_minus),
|
|
145
|
+
text=context,
|
|
146
|
+
)
|
|
147
|
+
return SketchVerdict(
|
|
148
|
+
t_plus_without_a_plus=first.coherence_score,
|
|
149
|
+
a_plus_without_t_plus=second.coherence_score,
|
|
150
|
+
reasoning=f"{first.reasoning} / {second.reasoning}".strip(" /"),
|
|
151
|
+
)
|
|
152
|
+
except Exception as exc: # noqa: BLE001 — degrade to "unjudged"
|
|
153
|
+
logger.warning("Judging a sketch failed; it sorts last: %s", exc)
|
|
154
|
+
return None
|
|
155
|
+
|
|
156
|
+
return list(await asyncio.gather(*(one(c) for c in candidates)))
|
|
128
157
|
|
|
129
158
|
|
|
130
159
|
async def select_sketch(
|
|
@@ -137,18 +166,21 @@ async def select_sketch(
|
|
|
137
166
|
mean, then the earlier draw — a deterministic tie-break, not a preference.
|
|
138
167
|
A candidate whose judging failed sorts last; if every judging failed the
|
|
139
168
|
first draw is kept, which is exactly what `attempts=1` would have done.
|
|
169
|
+
|
|
170
|
+
ONE candidate is never judged: there is nothing to select among, so
|
|
171
|
+
`attempts=1` costs no extra call.
|
|
140
172
|
"""
|
|
141
173
|
if len(candidates) == 1:
|
|
142
174
|
return 0, [None]
|
|
143
175
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
except Exception as exc: # noqa: BLE001 — degrade to "unjudged"
|
|
148
|
-
logger.warning("Judging a sketch failed; it sorts last: %s", exc)
|
|
149
|
-
return None
|
|
176
|
+
verdicts = await judge_sketches(candidates, context)
|
|
177
|
+
return ranking(verdicts)[0], verdicts
|
|
178
|
+
|
|
150
179
|
|
|
151
|
-
|
|
180
|
+
def ranking(verdicts: Sequence[Optional[SketchVerdict]]) -> list[int]:
|
|
181
|
+
"""Candidate indices best first, by `select_sketch`'s rule: the weaker
|
|
182
|
+
control statement, then the mean, then the earlier draw; unjudged last.
|
|
183
|
+
`[0]` is the winner; the rest are the runners-up in order."""
|
|
152
184
|
|
|
153
185
|
def key(index: int) -> tuple[int, float, float, int]:
|
|
154
186
|
verdict = verdicts[index]
|
|
@@ -157,5 +189,4 @@ async def select_sketch(
|
|
|
157
189
|
mean = (verdict.t_plus_without_a_plus + verdict.a_plus_without_t_plus) / 2
|
|
158
190
|
return (1, verdict.floor, mean, -index)
|
|
159
191
|
|
|
160
|
-
|
|
161
|
-
return best, verdicts
|
|
192
|
+
return sorted(range(len(verdicts)), key=key, reverse=True)
|