dialectical-framework 2.0.2__tar.gz → 2.0.4__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.2 → dialectical_framework-2.0.4}/PKG-INFO +1 -1
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/pyproject.toml +1 -1
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/consultant/consultant.py +17 -25
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/control_statements_check.py +16 -145
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/synthesis_generation.py +14 -3
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/tetrad_candidates.py +54 -63
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/transformation_generation.py +13 -2
- dialectical_framework-2.0.4/src/dialectical_framework/concerns/transformation_sketch.py +366 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/view_sketch.py +8 -38
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/edge_context.py +33 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/LICENSE +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/PATENTS +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/README.md +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/advisor.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/build_policy.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/migration.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/reply_hygiene.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/system_prompts.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/anchor.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/deepen.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/explore.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/ingest.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/note.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/record_decision.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/scoped.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/sync.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/agent_context.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/analyst.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/anchor_theses.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/edit_perspective.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/expand_polarities.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/find_polarities.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/introduce_polarity.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/sketch_tetrad.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/surface_theses.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/system_prompts.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/tools/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/tools/place_statement.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/app_spec.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/apps.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/consultant/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/conversation_facilitator.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/execution_report.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/explorer.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/skills/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/skills/build_wheels.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/skills/explore_transformations.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/skills/generate_synthesis.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/system_prompts.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/tools/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/tools/create_nexus.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/tools/expand_nexus.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/tools/generate_synthesis.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/tools/present_exploration.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/add_input.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/audit_feasibility.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/create_dx_input.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/digest_input.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/discard.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/get_schema.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/inspect_node.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/present_analysis.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/query_graph.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/read_digest.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/read_input.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/reasonable_concern.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/stream_events.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/toolsets.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/turn_timing.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/ac_re_taxonomy.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/action_extraction.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/add_input.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/ai_dto/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/ai_dto/statement_dto.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/ai_dto/statements_deck_dto.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/antithesis_classification.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/antithesis_extraction.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/antithetical_thesis_detection.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/aspect_classification.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/aspect_generation.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/build_status.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_estimator.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_estimator_balanced.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_estimator_criteria.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_estimator_desirable.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_estimator_feasible.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_estimator_realistic.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_normalizer.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/estimator_resolver.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality_estimation.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/create_dx_input.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/create_nexus.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/decision_coherence_check.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/decision_confirmation_check.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/diagonal_oppositions_check.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/dialectical_context.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/discard.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/display_text_edit.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/expand_nexus.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/perspective_combination.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/perspective_validation.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/positive_ac_re_apex_derivation.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/record_decision.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/scoring_scales.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/source_digest.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/statement_classification.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/statement_deduplication.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/statement_headline.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/statement_placement.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/tetrad_grounding.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/tetrad_sketch.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/thesis_extraction.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/transformation_audit.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/dialectical_reasoning.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/enums/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/enums/causality_preset.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/enums/di.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/events/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/events/graph_event.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/events/graph_event_bus.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/events/progress_event.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/exceptions/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/exceptions/node_errors.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/exceptions/resolver_errors.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/composite_input_resolver.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/dialexity_input_resolver.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/estimation_manager.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/mixins/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/mixins/incremental_build_mixin.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/mixins/intent_mixin.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/mixins/persistable_mixin.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/assessable_entity.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/base_node.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/case.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/cycle.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/decision.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/estimation.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/ideas.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/input.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/nexus.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/note.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/perspective.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/polarity.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/rationale.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/statement.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/synthesis.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/transformation.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/transition.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/wheel.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationship_manager.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/action_reflection_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/belongs_to_cycle_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/belongs_to_nexus_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/changed_to_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/contradiction_of_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/critiques_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/distilled_to_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/estimates_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/explains_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/grounded_in_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/has_input_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/has_statement_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/has_wheel_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/immutable_structure.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/is_source_of_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/is_target_of_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/negative_side_of_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/opposite_direction_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/opposite_of_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/polarity_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/positive_side_of_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/provides_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/synthesis_of_relationship.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/rendering.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/case_repository.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/cycle_repository.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/decision_repository.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/input_repository.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/nexus_repository.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/node_repository.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/note_repository.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/perspective_repository.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/polarity_repository.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/schema_repository.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/statement_repository.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/transformation_repository.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/wheel_repository.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/scope_context.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/verbatim_input_resolver.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/views.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/wheel_segment.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/wheel_segment_polar_pair.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/protocols/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/protocols/has_config.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/protocols/input_resolver.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/py.typed +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/settings.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/__init__.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/async_drain.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/bedrock_provider.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/call_census.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/chunking.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/concurrency.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/dc_replace.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/decompose_probability_uniformly.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/effect_logger.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/input_context.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/order_transitions.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/progress.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/retry_accounting.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/sequence_generation.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/thinking_compat.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/use_brain.py +0 -0
- {dialectical_framework-2.0.2 → dialectical_framework-2.0.4}/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.4
|
|
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.4"
|
|
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"
|
|
@@ -324,12 +324,7 @@ 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
|
-
|
|
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)
|
|
327
|
+
self._conversation.set_system_prompt("\n\n".join(parts))
|
|
333
328
|
|
|
334
329
|
async def chat(self, user_message: str) -> str:
|
|
335
330
|
result = await self._conversation.submit(ChatResponse, user_message)
|
|
@@ -367,8 +362,7 @@ class Consultant:
|
|
|
367
362
|
view shows what has been ESTABLISHED, and where `focus` asks for
|
|
368
363
|
structure not yet worked out ("a perspective for the thesis you
|
|
369
364
|
named") the turn builds it by the method first
|
|
370
|
-
(`concerns/view_sketch.py
|
|
371
|
-
prompt, the focus is the turn). What it built is
|
|
365
|
+
(`concerns/view_sketch.py::view_sketch_prompt`). What it built is
|
|
372
366
|
kept in `messages` as the consultant's own words, so the next turn can
|
|
373
367
|
be asked about a corner it just drew.
|
|
374
368
|
|
|
@@ -386,8 +380,7 @@ class Consultant:
|
|
|
386
380
|
"""
|
|
387
381
|
from dialectical_framework.concerns.view_sketch import (
|
|
388
382
|
ViewSketchDto, exploration_view_from_sketch, history_ask,
|
|
389
|
-
history_text, perspective_from_sketch,
|
|
390
|
-
view_sketch_instructions)
|
|
383
|
+
history_text, perspective_from_sketch, view_sketch_prompt)
|
|
391
384
|
|
|
392
385
|
import asyncio
|
|
393
386
|
import dataclasses
|
|
@@ -397,19 +390,19 @@ class Consultant:
|
|
|
397
390
|
|
|
398
391
|
level = self._conversation._thinking_kwargs().get("thinking")
|
|
399
392
|
history = self._conversation._messages
|
|
400
|
-
# The request
|
|
401
|
-
#
|
|
402
|
-
#
|
|
403
|
-
#
|
|
404
|
-
#
|
|
405
|
-
#
|
|
406
|
-
#
|
|
407
|
-
#
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
393
|
+
# The WHOLE request is the turn's user message, its "Answer with ONE
|
|
394
|
+
# JSON object" included — by measurement, not habit. For one day
|
|
395
|
+
# (2026-10-06) the static instructions rode on the system prompt so the
|
|
396
|
+
# cache would cover them (~$0.007 a card) and only "What to show: ..."
|
|
397
|
+
# was the turn. First cards did not notice; a RETRY did: its history
|
|
398
|
+
# already holds "Show me: ..." and the previous drawing in PROSE, and with
|
|
399
|
+
# a bare focus as the last user turn the model answered in prose too —
|
|
400
|
+
# 1.75 parse retries a retry card, 4.75 view-turn calls instead of 3,
|
|
401
|
+
# 33 s instead of 20 (`tests/e2e/probe_view_turn_retry_calls.py`, 8
|
|
402
|
+
# utterances; the first app had measured the same 4.6 calls and +17 s).
|
|
403
|
+
# The request->prose pair `history_ask` keeps OUT of the history is the
|
|
404
|
+
# same trap; the long request as the last turn is what holds the format.
|
|
405
|
+
request = view_sketch_prompt(focus, self._conversation.settings.component_length)
|
|
413
406
|
|
|
414
407
|
async def draw() -> ViewSketchDto:
|
|
415
408
|
# Each draw works on a COPY of the history: the turns run in
|
|
@@ -417,8 +410,7 @@ class Consultant:
|
|
|
417
410
|
# read. What the view leaves behind is appended once, below.
|
|
418
411
|
sketch_turn = ConversationFacilitator(format_mode="json", thinking=level)
|
|
419
412
|
sketch_turn._messages = list(history)
|
|
420
|
-
sketch_turn.
|
|
421
|
-
return await sketch_turn.submit(ViewSketchDto, ask)
|
|
413
|
+
return await sketch_turn.submit(ViewSketchDto, request)
|
|
422
414
|
|
|
423
415
|
n = clamp_attempts(attempts)
|
|
424
416
|
# Fully parallel, deliberately. On a COLD cache all N draws write the
|
|
@@ -32,7 +32,7 @@ from __future__ import annotations
|
|
|
32
32
|
|
|
33
33
|
import asyncio
|
|
34
34
|
from dataclasses import dataclass
|
|
35
|
-
from typing import TYPE_CHECKING
|
|
35
|
+
from typing import TYPE_CHECKING
|
|
36
36
|
|
|
37
37
|
from pydantic import BaseModel, Field
|
|
38
38
|
|
|
@@ -97,74 +97,15 @@ class CoherenceEvaluationDto(BaseModel):
|
|
|
97
97
|
)
|
|
98
98
|
|
|
99
99
|
|
|
100
|
-
class TetradCoherenceDto(BaseModel):
|
|
101
|
-
"""One tetrad's two control statements, from the JOINT call.
|
|
102
|
-
|
|
103
|
-
No DV field, deliberately. DV is an annotation that only `resolve`
|
|
104
|
-
persists (`DialecticalValidityEstimation`) and nothing reads it when
|
|
105
|
-
choosing among drafts — `SketchVerdict` has no DV term — so asking for it
|
|
106
|
-
here would buy output tokens and nothing else. A draft that goes on to be
|
|
107
|
-
persisted is scored by `resolve` afterwards, DV and all.
|
|
108
|
-
"""
|
|
109
|
-
|
|
110
|
-
tetrad: int = Field(
|
|
111
|
-
description=(
|
|
112
|
-
"The number of the tetrad this verdict scores, exactly as labelled "
|
|
113
|
-
"in the request."
|
|
114
|
-
)
|
|
115
|
-
)
|
|
116
|
-
t_plus_without_a_plus_yields_t_minus: float = Field(
|
|
117
|
-
ge=0.0,
|
|
118
|
-
le=1.0,
|
|
119
|
-
description="Conceptual Coherence (0.0-1.0) of that tetrad's statement (a).",
|
|
120
|
-
)
|
|
121
|
-
a_plus_without_t_plus_yields_a_minus: float = Field(
|
|
122
|
-
ge=0.0,
|
|
123
|
-
le=1.0,
|
|
124
|
-
description="Conceptual Coherence (0.0-1.0) of that tetrad's statement (b).",
|
|
125
|
-
)
|
|
126
|
-
reasoning: str = Field(
|
|
127
|
-
description=(
|
|
128
|
-
"One sentence on the weaker of that tetrad's two statements. A note, "
|
|
129
|
-
"not an essay."
|
|
130
|
-
)
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
class JointCoherenceEvaluationDto(BaseModel):
|
|
135
|
-
"""Every tetrad of one request, scored in one call."""
|
|
136
|
-
|
|
137
|
-
verdicts: list[TetradCoherenceDto] = Field(
|
|
138
|
-
description=(
|
|
139
|
-
"One entry per tetrad in the request, in the request's order. Score "
|
|
140
|
-
"every tetrad; omit none."
|
|
141
|
-
)
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
@dataclass(frozen=True)
|
|
146
|
-
class TetradTexts:
|
|
147
|
-
"""The four aspect texts of one tetrad — all the control statements need.
|
|
148
|
-
|
|
149
|
-
What `score_texts_many` takes, so a caller holding several drafts as text
|
|
150
|
-
cannot mix up the order of four positional strings.
|
|
151
|
-
"""
|
|
152
|
-
|
|
153
|
-
t_plus: str
|
|
154
|
-
t_minus: str
|
|
155
|
-
a_plus: str
|
|
156
|
-
a_minus: str
|
|
157
|
-
|
|
158
|
-
|
|
159
100
|
def control_statements(
|
|
160
101
|
*, t_plus: str, t_minus: str, a_plus: str, a_minus: str
|
|
161
102
|
) -> tuple[str, str]:
|
|
162
103
|
"""The paper's two control statements, built from four texts.
|
|
163
104
|
|
|
164
|
-
One builder for
|
|
165
|
-
`score_texts`
|
|
166
|
-
|
|
167
|
-
|
|
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.
|
|
168
109
|
"""
|
|
169
110
|
return (
|
|
170
111
|
f'"{t_plus}" without "{a_plus}" yields "{t_minus}"',
|
|
@@ -172,13 +113,12 @@ def control_statements(
|
|
|
172
113
|
)
|
|
173
114
|
|
|
174
115
|
|
|
175
|
-
# ---
|
|
116
|
+
# --- Prompt text ---
|
|
176
117
|
#
|
|
177
|
-
#
|
|
178
|
-
#
|
|
179
|
-
#
|
|
180
|
-
#
|
|
181
|
-
# the other (`concerns/tetrad_candidates.py`).
|
|
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).
|
|
182
122
|
|
|
183
123
|
_PATTERN = """The pattern "[Positive] without [Balancing factor] yields [Negative]" tests whether
|
|
184
124
|
the absence of a balancing positive aspect naturally leads to the negative/shadow aspect."""
|
|
@@ -372,14 +312,12 @@ class ControlStatementsCheck(ReasonableConcern[ControlStatementsCheckResult]):
|
|
|
372
312
|
"""The two control statements on bare texts — no Perspective, no graph.
|
|
373
313
|
|
|
374
314
|
What `resolve` does after reading the four aspects off a committed
|
|
375
|
-
node,
|
|
376
|
-
|
|
377
|
-
the same
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
(nothing in selection reads it). Two statements, two calls, both with
|
|
382
|
-
reasoning, is the shape that made judging a third of a card's cost.
|
|
315
|
+
node, offered to callers that hold a tetrad as text: the best-of-N
|
|
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`).
|
|
383
321
|
"""
|
|
384
322
|
stmt_1, stmt_2 = control_statements(
|
|
385
323
|
t_plus=t_plus, t_minus=t_minus, a_plus=a_plus, a_minus=a_minus
|
|
@@ -389,73 +327,6 @@ class ControlStatementsCheck(ReasonableConcern[ControlStatementsCheckResult]):
|
|
|
389
327
|
self._evaluate_control_statement(stmt_2, text),
|
|
390
328
|
)
|
|
391
329
|
|
|
392
|
-
async def score_texts_many(
|
|
393
|
-
self,
|
|
394
|
-
tetrads: Sequence[TetradTexts],
|
|
395
|
-
*,
|
|
396
|
-
text: str = "",
|
|
397
|
-
) -> list[Optional[TetradCoherenceDto]]:
|
|
398
|
-
"""Several tetrads' control statements, all in ONE call.
|
|
399
|
-
|
|
400
|
-
What `score_texts` asks for one draft at a time, asked for a whole
|
|
401
|
-
best-of-N field at once. Measured reason (2026-10-06, the first app's
|
|
402
|
-
real entry points through `utils/call_census.py`): per-statement calls
|
|
403
|
-
made judging 6 of the 11 provider calls behind one card and ~3.3k of
|
|
404
|
-
its ~5.1k output tokens — about a third of the card's cost — because
|
|
405
|
-
each call spent ~550 output tokens of reasoning on one sentence. One
|
|
406
|
-
call with a short note per tetrad replaces six.
|
|
407
|
-
|
|
408
|
-
The question is unchanged and so is its discipline: the judge sees
|
|
409
|
-
only each tetrad's four aspects (never the thesis or antithesis, see
|
|
410
|
-
`concerns/tetrad_candidates.py`), the statements are built by the same
|
|
411
|
-
builder `resolve` uses, and the prompt forbids comparing the drafts —
|
|
412
|
-
selection stays among independent draws. CC only; `TetradCoherenceDto`
|
|
413
|
-
says why DV is not asked for here.
|
|
414
|
-
|
|
415
|
-
Fail-soft per tetrad: a verdict the model omits, or labels with a
|
|
416
|
-
number that is out of range or already filled, comes back `None` for
|
|
417
|
-
that tetrad rather than shifting every later one onto the wrong draft.
|
|
418
|
-
"""
|
|
419
|
-
if not tetrads:
|
|
420
|
-
return []
|
|
421
|
-
|
|
422
|
-
blocks = []
|
|
423
|
-
for n, tetrad in enumerate(tetrads, 1):
|
|
424
|
-
stmt_a, stmt_b = control_statements(
|
|
425
|
-
t_plus=tetrad.t_plus,
|
|
426
|
-
t_minus=tetrad.t_minus,
|
|
427
|
-
a_plus=tetrad.a_plus,
|
|
428
|
-
a_minus=tetrad.a_minus,
|
|
429
|
-
)
|
|
430
|
-
blocks.append(f"Tetrad {n}:\n(a) {stmt_a}\n(b) {stmt_b}")
|
|
431
|
-
|
|
432
|
-
context_section = f"<context>\n{text}\n</context>\n\n" if text else ""
|
|
433
|
-
joined = "\n\n".join(blocks)
|
|
434
|
-
prompt = f"""{context_section}Rate the control statements of {len(tetrads)} tetrads. Each tetrad has two statements, (a) and (b).
|
|
435
|
-
|
|
436
|
-
{joined}
|
|
437
|
-
|
|
438
|
-
{_PATTERN}
|
|
439
|
-
|
|
440
|
-
Rate every statement on one scale:
|
|
441
|
-
|
|
442
|
-
{_CC_SCALE}
|
|
443
|
-
|
|
444
|
-
Score each tetrad on its own, against the pattern above and nothing else. These are independent drafts: do not compare them with each other, do not rank them, do not pick a best, and do not let one tetrad's wording move another's score. The order they appear in carries no information. Return one verdict per tetrad, labelled with that tetrad's number."""
|
|
445
|
-
|
|
446
|
-
conversation = ConversationFacilitator()
|
|
447
|
-
result = await conversation.submit(
|
|
448
|
-
response_model=JointCoherenceEvaluationDto,
|
|
449
|
-
user_content=prompt,
|
|
450
|
-
)
|
|
451
|
-
|
|
452
|
-
placed: list[Optional[TetradCoherenceDto]] = [None] * len(tetrads)
|
|
453
|
-
for verdict in result.verdicts:
|
|
454
|
-
index = verdict.tetrad - 1
|
|
455
|
-
if 0 <= index < len(placed) and placed[index] is None:
|
|
456
|
-
placed[index] = verdict
|
|
457
|
-
return placed
|
|
458
|
-
|
|
459
330
|
async def _evaluate_control_statement(
|
|
460
331
|
self,
|
|
461
332
|
statement: str,
|
|
@@ -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
|
|
|
@@ -31,12 +31,13 @@ holding a text or an object with `.statement` (`TetradDto`'s `AspectDto`).
|
|
|
31
31
|
|
|
32
32
|
from __future__ import annotations
|
|
33
33
|
|
|
34
|
+
import asyncio
|
|
34
35
|
import logging
|
|
35
36
|
from dataclasses import dataclass
|
|
36
37
|
from typing import Any, Optional, Sequence
|
|
37
38
|
|
|
38
|
-
from dialectical_framework.concerns.control_statements_check import
|
|
39
|
-
ControlStatementsCheck
|
|
39
|
+
from dialectical_framework.concerns.control_statements_check import \
|
|
40
|
+
ControlStatementsCheck
|
|
40
41
|
from dialectical_framework.graph.nodes.estimation import \
|
|
41
42
|
CONCEPTUAL_COHERENCE_THRESHOLD
|
|
42
43
|
|
|
@@ -108,78 +109,68 @@ def is_complete(candidate: Any) -> bool:
|
|
|
108
109
|
async def judge_sketches(
|
|
109
110
|
candidates: Sequence[Any], context: str = ""
|
|
110
111
|
) -> list[Optional[SketchVerdict]]:
|
|
111
|
-
"""The validator's two control statements for
|
|
112
|
+
"""The validator's two control statements for every candidate, each draft
|
|
113
|
+
judged on its own, each statement in its own call (gathered).
|
|
112
114
|
|
|
113
115
|
Statement texts are built by the same builder `ControlStatementsCheck.resolve`
|
|
114
|
-
uses,
|
|
115
|
-
question asked of the same words. The
|
|
116
|
-
aspects of each draft
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
own call (`docs/dev-notes/antithesis-selection.md`, "Best-of-N"); the
|
|
138
|
-
joint call's stability, and its position bias (a candidate winning for
|
|
139
|
-
being listed first), are unmeasured — measure both with the same probe,
|
|
140
|
-
and the card quality with the app's paired eval, before reading any
|
|
141
|
-
quality claim into this. If stability falls below ~85%, the rung down is
|
|
142
|
-
one call per candidate with both statements in one DTO, which is still
|
|
143
|
-
half the output of the per-statement shape.
|
|
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
|
+
- THIS prompt with each reasoning field capped at one short sentence
|
|
134
|
+
(the score is written before the reasoning, so the cap looked free):
|
|
135
|
+
output 534 -> 181 tokens a call, but 78% against 90%, scores +0.05, the
|
|
136
|
+
same winner as this judge in 29/40. The reasoning is not dead weight.
|
|
137
|
+
A cheaper judge has to be measured against this one on that probe first;
|
|
138
|
+
the owner closed the cost question at this point (2026-10-06).
|
|
144
139
|
"""
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
reasoning=v.reasoning,
|
|
168
|
-
)
|
|
169
|
-
for v in verdicts
|
|
170
|
-
]
|
|
140
|
+
|
|
141
|
+
async def one(tension: Any) -> Optional[SketchVerdict]:
|
|
142
|
+
# Reading the verdict is inside the `try` too: a malformed response
|
|
143
|
+
# is a failed judging (sorts last), never a failed selection.
|
|
144
|
+
try:
|
|
145
|
+
first, second = await ControlStatementsCheck().score_texts(
|
|
146
|
+
t_plus=aspect_text(tension.t_plus),
|
|
147
|
+
t_minus=aspect_text(tension.t_minus),
|
|
148
|
+
a_plus=aspect_text(tension.a_plus),
|
|
149
|
+
a_minus=aspect_text(tension.a_minus),
|
|
150
|
+
text=context,
|
|
151
|
+
)
|
|
152
|
+
return SketchVerdict(
|
|
153
|
+
t_plus_without_a_plus=first.coherence_score,
|
|
154
|
+
a_plus_without_t_plus=second.coherence_score,
|
|
155
|
+
reasoning=f"{first.reasoning} / {second.reasoning}".strip(" /"),
|
|
156
|
+
)
|
|
157
|
+
except Exception as exc: # noqa: BLE001 — degrade to "unjudged"
|
|
158
|
+
logger.warning("Judging a sketch failed; it sorts last: %s", exc)
|
|
159
|
+
return None
|
|
160
|
+
|
|
161
|
+
return list(await asyncio.gather(*(one(c) for c in candidates)))
|
|
171
162
|
|
|
172
163
|
|
|
173
164
|
async def select_sketch(
|
|
174
165
|
candidates: Sequence[Any], context: str = ""
|
|
175
166
|
) -> tuple[int, list[Optional[SketchVerdict]]]:
|
|
176
|
-
"""Judge every candidate (
|
|
177
|
-
all verdicts (None where
|
|
167
|
+
"""Judge every candidate (gathered) and return the index of the best plus
|
|
168
|
+
all verdicts (None where judging failed).
|
|
178
169
|
|
|
179
170
|
Ranking: the weaker control statement first (the pass rule), then the
|
|
180
171
|
mean, then the earlier draw — a deterministic tie-break, not a preference.
|
|
181
|
-
|
|
182
|
-
draw is kept, which is exactly what `attempts=1` would have done.
|
|
172
|
+
A candidate whose judging failed sorts last; if every judging failed the
|
|
173
|
+
first draw is kept, which is exactly what `attempts=1` would have done.
|
|
183
174
|
|
|
184
175
|
ONE candidate is never judged: there is nothing to select among, so
|
|
185
176
|
`attempts=1` costs no extra call.
|
|
@@ -248,7 +248,17 @@ class ReSideCompletionDto(BaseModel):
|
|
|
248
248
|
description="Proactiveness category for Re+"
|
|
249
249
|
)
|
|
250
250
|
|
|
251
|
-
# Re- fields
|
|
251
|
+
# Re- fields. The weak position of the staged generator, measured
|
|
252
|
+
# 2026-10-06 (`tests/e2e/probe_staged_endpoints.py`, 102 Transformations on
|
|
253
|
+
# 17 one-tension wheels, read with the theory-faithful `TransitionVerdict`):
|
|
254
|
+
# Re- valid 49% against Ac- 70%, and it is the LANDING that fails (59%
|
|
255
|
+
# land in T-; 27% valid on T->A edges). The prompt asked for "the
|
|
256
|
+
# reflection without the action", which the writer read as "keep watching,
|
|
257
|
+
# do nothing" — and wherever A is the passive pole, doing nothing is A's
|
|
258
|
+
# trap, not T's. Two `re_minus_from` / `re_minus_into` fields ahead of these
|
|
259
|
+
# (the one-shot's fix) moved it within noise and were reverted; the
|
|
260
|
+
# landing is now named in `_generate_re_side`'s Re- instruction instead.
|
|
261
|
+
# See docs/dev-notes/one-shot-transformation.md.
|
|
252
262
|
re_minus_headline: str = Field(description="Re- headline (component length)")
|
|
253
263
|
re_minus_statement: str = Field(description="Re- statement (fuller than the headline)")
|
|
254
264
|
re_minus_explanation: str = Field(
|
|
@@ -641,7 +651,8 @@ Given their action, what reflection does it trigger that leads to growth?
|
|
|
641
651
|
|
|
642
652
|
What happens when their action IS taken in, but nothing you do grounds that reflection?
|
|
643
653
|
- What Re+ ITSELF degenerates into when Ac+ is absent — an overextension of the reflection, not the absence of one
|
|
644
|
-
-
|
|
654
|
+
- Where it LANDS is what makes it Re-: it ends in the A- line of <reflection_perspective> — YOUR OWN trap. It starts from that block's T+ line (the other side's strength); you need not name the start, but the landing must be your trap
|
|
655
|
+
- The common miss: "keep watching and do nothing". When the other side is the passive one, doing nothing just leaves THEIR trap in place (the block's T- line) — that is not Re-. Re- is your reflecting, overdone, carrying YOU into your own trap
|
|
645
656
|
- NOT the same failure as Ac-: Ac- is your action left unreflected, Re- is your reflection left unacted
|
|
646
657
|
- Your Ac+ must CONTRADICT Re- (your positive action opposes this regression)
|
|
647
658
|
- Usually lower insight than Re+
|