dialectical-framework 2.0.9__tar.gz → 2.0.12__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.9 → dialectical_framework-2.0.12}/PKG-INFO +1 -1
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/pyproject.toml +1 -1
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/consultant/consultant.py +42 -4
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/conversation_facilitator.py +12 -1
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/aspect_generation.py +28 -3
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/transformation_sketch.py +32 -1
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/view_sketch.py +72 -11
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/settings.py +26 -2
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/settings_context.py +2 -2
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/bedrock_provider.py +56 -22
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/use_brain.py +98 -6
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/LICENSE +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/PATENTS +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/README.md +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/advisor.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/build_policy.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/migration.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/reply_hygiene.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/system_prompts.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/tools/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/tools/anchor.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/tools/deepen.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/tools/explore.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/tools/ingest.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/tools/note.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/tools/record_decision.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/tools/scoped.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/advisor/tools/sync.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/agent_context.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/analyst/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/analyst/analyst.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/analyst/skills/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/analyst/skills/anchor_theses.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/analyst/skills/edit_perspective.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/analyst/skills/expand_polarities.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/analyst/skills/find_polarities.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/analyst/skills/introduce_polarity.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/analyst/skills/sketch_tetrad.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/analyst/skills/surface_theses.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/analyst/system_prompts.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/analyst/tools/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/analyst/tools/place_statement.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/app_spec.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/apps.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/consultant/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/execution_report.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/explorer/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/explorer/explorer.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/explorer/skills/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/explorer/skills/build_wheels.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/explorer/skills/explore_transformations.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/explorer/skills/generate_synthesis.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/explorer/system_prompts.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/explorer/tools/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/explorer/tools/create_nexus.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/explorer/tools/expand_nexus.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/explorer/tools/generate_synthesis.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/explorer/tools/present_exploration.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/orchestrator/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/orchestrator/tools/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/orchestrator/tools/add_input.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/orchestrator/tools/audit_feasibility.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/orchestrator/tools/create_dx_input.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/orchestrator/tools/digest_input.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/orchestrator/tools/discard.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/orchestrator/tools/get_schema.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/orchestrator/tools/inspect_node.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/orchestrator/tools/present_analysis.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/orchestrator/tools/query_graph.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/orchestrator/tools/read_digest.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/orchestrator/tools/read_input.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/reasonable_concern.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/stream_events.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/toolsets.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/agents/turn_timing.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/ac_re_taxonomy.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/action_extraction.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/add_input.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/ai_dto/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/ai_dto/statement_dto.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/ai_dto/statements_deck_dto.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/antithesis_classification.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/antithesis_extraction.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/antithetical_thesis_detection.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/aspect_classification.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/build_status.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/causality/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/causality/causality_estimator.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/causality/causality_estimator_balanced.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/causality/causality_estimator_criteria.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/causality/causality_estimator_desirable.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/causality/causality_estimator_feasible.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/causality/causality_estimator_realistic.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/causality/causality_normalizer.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/causality/estimator_resolver.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/causality_estimation.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/control_statements_check.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/create_dx_input.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/create_nexus.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/decision_coherence_check.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/decision_confirmation_check.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/diagonal_oppositions_check.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/dialectical_context.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/discard.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/display_text_edit.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/expand_nexus.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/perspective_combination.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/perspective_validation.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/positive_ac_re_apex_derivation.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/record_decision.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/scoring_scales.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/source_digest.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/statement_classification.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/statement_deduplication.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/statement_headline.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/statement_placement.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/synthesis_generation.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/tetrad_candidates.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/tetrad_grounding.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/tetrad_sketch.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/thesis_extraction.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/transformation_audit.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/concerns/transformation_generation.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/dialectical_reasoning.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/enums/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/enums/causality_preset.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/enums/di.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/events/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/events/graph_event.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/events/graph_event_bus.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/events/progress_event.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/exceptions/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/exceptions/node_errors.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/exceptions/provider_errors.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/exceptions/resolver_errors.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/composite_input_resolver.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/dialexity_input_resolver.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/estimation_manager.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/mixins/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/mixins/incremental_build_mixin.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/mixins/intent_mixin.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/mixins/persistable_mixin.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/assessable_entity.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/base_node.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/case.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/cycle.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/decision.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/estimation.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/ideas.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/input.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/nexus.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/note.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/perspective.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/polarity.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/rationale.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/statement.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/synthesis.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/transformation.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/transition.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/nodes/wheel.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationship_manager.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/action_reflection_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/belongs_to_cycle_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/belongs_to_nexus_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/changed_to_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/contradiction_of_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/critiques_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/distilled_to_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/estimates_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/explains_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/grounded_in_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/has_input_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/has_statement_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/has_wheel_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/immutable_structure.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/is_source_of_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/is_target_of_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/negative_side_of_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/opposite_direction_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/opposite_of_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/polarity_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/positive_side_of_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/provides_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/relationships/synthesis_of_relationship.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/rendering.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/case_repository.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/cycle_repository.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/decision_repository.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/input_repository.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/nexus_repository.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/node_repository.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/note_repository.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/perspective_repository.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/polarity_repository.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/schema_repository.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/statement_repository.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/transformation_repository.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/repositories/wheel_repository.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/scope_context.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/verbatim_input_resolver.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/views.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/wheel_segment.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/graph/wheel_segment_polar_pair.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/protocols/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/protocols/has_config.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/protocols/input_resolver.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/py.typed +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/__init__.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/async_drain.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/call_census.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/chunking.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/concurrency.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/dc_replace.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/decompose_probability_uniformly.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/edge_context.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/effect_logger.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/format_compat.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/input_context.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/order_transitions.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/progress.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/retry_accounting.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/sequence_generation.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/utils/thinking_compat.py +0 -0
- {dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/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.12
|
|
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.12"
|
|
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"
|
|
@@ -42,6 +42,7 @@ from contextlib import aclosing
|
|
|
42
42
|
from typing import Any, AsyncGenerator, Optional
|
|
43
43
|
|
|
44
44
|
from mirascope import llm
|
|
45
|
+
from mirascope.llm.exceptions import ProviderError
|
|
45
46
|
|
|
46
47
|
from dialectical_framework.agents.advisor.advisor import ChatResponse
|
|
47
48
|
from dialectical_framework.agents.advisor.system_prompts import (
|
|
@@ -145,9 +146,21 @@ _TOOL_TOKENS = (
|
|
|
145
146
|
|
|
146
147
|
def _failed_draw(error: BaseException) -> FailedDrawView:
|
|
147
148
|
"""A failed draw's record: the exception's type, the provider's refusal
|
|
148
|
-
category when it is a `ModelRefusal` that carries one, and its text.
|
|
149
|
+
category when it is a `ModelRefusal` that carries one, and its text.
|
|
150
|
+
|
|
151
|
+
The type is the PROVIDER's where Mirascope wrapped one: its `ProviderError`
|
|
152
|
+
subclasses carry the SDK exception as `original_exception`, and that is
|
|
153
|
+
the name a host counts by (`APITimeoutError` for a stalled draw, where the
|
|
154
|
+
wrapper says only `TimeoutError` — the builtin's name too). `ParseError`
|
|
155
|
+
is not a `ProviderError` and keeps its own name.
|
|
156
|
+
"""
|
|
157
|
+
original = (
|
|
158
|
+
getattr(error, "original_exception", None)
|
|
159
|
+
if isinstance(error, ProviderError)
|
|
160
|
+
else None
|
|
161
|
+
)
|
|
149
162
|
return FailedDrawView(
|
|
150
|
-
kind=type(error).__name__,
|
|
163
|
+
kind=type(original if isinstance(original, BaseException) else error).__name__,
|
|
151
164
|
category=getattr(error, "category", None) if isinstance(error, ModelRefusal) else None,
|
|
152
165
|
message=str(error) or None,
|
|
153
166
|
)
|
|
@@ -368,7 +381,10 @@ class Consultant:
|
|
|
368
381
|
return self._conversation._messages
|
|
369
382
|
|
|
370
383
|
async def exploration_view(
|
|
371
|
-
self,
|
|
384
|
+
self,
|
|
385
|
+
focus: Optional[str] = None,
|
|
386
|
+
attempts: Optional[int] = None,
|
|
387
|
+
thesis: Optional[str] = None,
|
|
372
388
|
) -> ExplorationView:
|
|
373
389
|
"""The structure of this conversation as a view — drawn by this head.
|
|
374
390
|
|
|
@@ -389,6 +405,17 @@ class Consultant:
|
|
|
389
405
|
think and building a tetrad in one shot is the heaviest reasoning a
|
|
390
406
|
structured call is asked to do here.
|
|
391
407
|
|
|
408
|
+
`thesis` pins T to the host's own text, VERBATIM: the request says so
|
|
409
|
+
(`view_sketch.THESIS_IS_FIXED`) and the given words are then written
|
|
410
|
+
back over whatever each draw wrote, so the guarantee is code and not
|
|
411
|
+
compliance. For a host that shows the person their own sentence as
|
|
412
|
+
their position, a seven-word recomposition of it is a different
|
|
413
|
+
sentence. The rest of the tetrad is still built — and still built
|
|
414
|
+
around the pinned position, which is why the request carries the text
|
|
415
|
+
too rather than relying on the overwrite alone. Not the same contract
|
|
416
|
+
as `SketchTetrad(thesis=)`, which asks for the position condensed to
|
|
417
|
+
`component_length` because the graph stores a headline.
|
|
418
|
+
|
|
392
419
|
Terminology-free by construction (no hash, alias or score exists),
|
|
393
420
|
unchecked by construction (no HS gate, no validation, nothing
|
|
394
421
|
persisted). Not a tool: the model cannot call this, and the prompt's
|
|
@@ -420,7 +447,9 @@ class Consultant:
|
|
|
420
447
|
# utterances; the first app had measured the same 4.6 calls and +17 s).
|
|
421
448
|
# The request->prose pair `history_ask` keeps OUT of the history is the
|
|
422
449
|
# same trap; the long request as the last turn is what holds the format.
|
|
423
|
-
request = view_sketch_prompt(
|
|
450
|
+
request = view_sketch_prompt(
|
|
451
|
+
focus, self._conversation.settings.component_length, thesis=thesis
|
|
452
|
+
)
|
|
424
453
|
|
|
425
454
|
async def draw() -> ViewSketchDto:
|
|
426
455
|
# Each draw works on a COPY of the history: the turns run in
|
|
@@ -459,6 +488,15 @@ class Consultant:
|
|
|
459
488
|
)
|
|
460
489
|
if not sketches:
|
|
461
490
|
raise failures[0]
|
|
491
|
+
# The pin, enforced: every draw's first tension carries the host's own
|
|
492
|
+
# words as T, so the winner and any runner-up a host serves later all
|
|
493
|
+
# show the sentence the person typed. Done before selection, so the
|
|
494
|
+
# coherence check judges the tetrad the host will actually get.
|
|
495
|
+
pinned = (thesis or "").strip()
|
|
496
|
+
if pinned:
|
|
497
|
+
for drawn_sketch in sketches:
|
|
498
|
+
if drawn_sketch.tensions:
|
|
499
|
+
drawn_sketch.tensions[0].thesis = pinned
|
|
462
500
|
# With several draws the framework's own coherence check picks the one
|
|
463
501
|
# whose FIRST tension holds best (`concerns/tetrad_candidates.py`); a
|
|
464
502
|
# draw with no complete first tension sorts last. The card a blindspot
|
|
@@ -567,8 +567,19 @@ class ConversationFacilitator(SettingsAware):
|
|
|
567
567
|
self._strip_caller_from_messages(response.messages)
|
|
568
568
|
# The continuation is a conversational round too (and it is
|
|
569
569
|
# Mirascope's own request, so nothing in `use_brain` marks it).
|
|
570
|
+
# Retried like the streamed resume (`_start_stream_round`):
|
|
571
|
+
# since the Bedrock client's own retry went to 0
|
|
572
|
+
# (`bedrock_provider._SDK_MAX_RETRIES`) this is the one
|
|
573
|
+
# provider request with no other retry layer. Safe to re-ask
|
|
574
|
+
# — `resume_async` is `response.messages + [user(outputs)]`
|
|
575
|
+
# with no mutation of the response — and the tools have
|
|
576
|
+
# already run, so a retry re-sends their outputs, never
|
|
577
|
+
# re-executes them.
|
|
570
578
|
with conversational_round():
|
|
571
|
-
|
|
579
|
+
resuming = response
|
|
580
|
+
response = await retry_transient(
|
|
581
|
+
lambda: resuming.resume(tool_outputs), what="Resume"
|
|
582
|
+
)
|
|
572
583
|
# Mirascope's own request, below `use_brain`: a provider that
|
|
573
584
|
# does not raise on a refusal itself only says so here.
|
|
574
585
|
if getattr(response, "finish_reason", None) == FinishReason.REFUSAL:
|
|
@@ -165,10 +165,35 @@ Generate aspect statements that fit the semantic structure."""
|
|
|
165
165
|
# — small, and not re-measured at the archive's sample size. Do not re-add a
|
|
166
166
|
# worked plus example without measuring BOTH coherence and restatement
|
|
167
167
|
# (`tests/e2e/probe_aspect_variants.py`).
|
|
168
|
+
#
|
|
169
|
+
# Re-aimed on 2026-10-12, by measurement, from "supplies what the other pole is
|
|
170
|
+
# for" to "leaves it possible". The old wording was the take-up half stated a
|
|
171
|
+
# third time, and with a DECIDED thesis ("I'm not inviting my sister — done")
|
|
172
|
+
# "A developed so that it supplies what T is for" IS the middle path: A+ came
|
|
173
|
+
# back as the compromise ("Leave a path back that she must earn"), and the
|
|
174
|
+
# transformation's Ac+, which turns T- into A+, then faithfully handed the
|
|
175
|
+
# person back the thing they had refused (reported by the first app, promise
|
|
176
|
+
# eval v12, 3 of 7 decided cases failing in every rep). On 16 decided stances
|
|
177
|
+
# x 2 reps x 3 arms, Sonnet 5.5 (`tests/e2e/probe_decided_stance.py`,
|
|
178
|
+
# `decided_stance-20261012-090438.json`): A+ a good A ITSELF is for, 39% ->
|
|
179
|
+
# 94% (paired +55, 95% CI +33..+77), compromise pluses gone (plus_relation
|
|
180
|
+
# `distinct` 69% -> 100%), and coherence ROSE, 59% -> 91% (+31, +9..+54) —
|
|
181
|
+
# which is the theory's own reading, since a plus that carries the other pole
|
|
182
|
+
# cannot satisfy "T+ without A+ yields T-". The arm that only reversed the
|
|
183
|
+
# relation reached 75% / +12 CC; what took it to 94% was adding "a position,
|
|
184
|
+
# not a move" (`view_sketch.TETRAD_BUILD_PROCEDURE` step 1), so the two
|
|
185
|
+
# sentences ship together. Not the same lever as the two spent ones: pushing
|
|
186
|
+
# take-up HARDER (the `*_takes_up` fields, 2026-10-02) cost coherence 25/40 ->
|
|
187
|
+
# 15/40, and a hedged-parent CHECK (2026-09-30) moved nothing.
|
|
188
|
+
# `ASPECT_DEFINITIONS` still states the relation the old way and was in both
|
|
189
|
+
# arms' context — unchanged on purpose; editing it is a new measurement.
|
|
168
190
|
PLUS_RESTATEMENT_CHECK = (
|
|
169
|
-
"
|
|
170
|
-
"
|
|
171
|
-
"
|
|
191
|
+
"Blended parent: a plus is its own parent developed, never the two sides "
|
|
192
|
+
"combined into one arrangement — not the parent made conditional on the "
|
|
193
|
+
"other pole, not a partial, scheduled or trial version of it, not the "
|
|
194
|
+
"middle between them. If a plus only names what its own parent already "
|
|
195
|
+
"delivers, rewrite it so the parent stays the generative act and what the "
|
|
196
|
+
"other pole is for is left possible by it."
|
|
172
197
|
)
|
|
173
198
|
|
|
174
199
|
def is_axis_name(axis: Optional[str]) -> bool:
|
|
@@ -116,9 +116,40 @@ from dialectical_framework.protocols.has_config import SettingsAware
|
|
|
116
116
|
#: that writes the way through a tension in its own voice (the first app's
|
|
117
117
|
#: card) — so none of them can restate the theory differently.
|
|
118
118
|
TRANSFORMATION_POSITIONS = """1. The action (Ac): the concrete move that carries T toward A. The reflection (Re): the re-reading that carries A back toward T. These are the two poles of the transformation.
|
|
119
|
-
2. Each developed well — Ac+ turns T's trap (T-) into A's strength (A+); Re+ turns A's trap (A-) into T's strength (T+).
|
|
119
|
+
2. Each developed well — Ac+ turns T's trap (T-) into A's strength (A+); Re+ turns A's trap (A-) into T's strength (T+). Where T is something the person has DECIDED or refused, Ac and Ac+ are that decision carried out: what A is for shapes HOW they carry it out, never whether or how much. This governs the action and the action developed well only — Ac- still ends in A's trap, as point 3 says.
|
|
120
120
|
3. Each overdeveloped one-sidedly — Ac- is the good action without the good reflection (Ac+ without Re+), which carries T's strength (T+) into A's trap (A-); Re- is the good reflection without the good action (Re+ without Ac+), which carries A's strength (A+) into T's trap (T-). They are the ACTION and the REFLECTION gone wrong: they END in the traps but are not the traps restated — a path is not its destination. Ac+ contradicts Re-, and Re+ contradicts Ac-."""
|
|
121
121
|
|
|
122
|
+
#: THE DECIDED POSITION (2026-10-12). Point 2's second sentence, and the only
|
|
123
|
+
#: part of this text that knows anything about the person's state. The first app
|
|
124
|
+
#: reported the framework handing people back exactly what they had refused:
|
|
125
|
+
#: given "Im not inviting my sister to the wedding … done.", Ac+ came back as
|
|
126
|
+
#: "Give her a clear route back: apologise to Marco and she's welcome." Repairing
|
|
127
|
+
#: A+ upstream (the compromise plus, `antithesis-selection.md`, same day) fixed
|
|
128
|
+
#: the CORNER and not the move — `decision_stands` 62% before and after — so this
|
|
129
|
+
#: layer has its own site, and it is not point 1's "carries T toward A":
|
|
130
|
+
#: rewording that moved nothing (-3 paired, `tests/e2e/probe_decided_move.py`).
|
|
131
|
+
#: What moved it is naming the state: 53% -> 88% of actions keeping the decision
|
|
132
|
+
#: (+34, +18..+51, 32 frozen decided tetrads).
|
|
133
|
+
#:
|
|
134
|
+
#: **The scope clause is load-bearing, measured twice.** Whichever minus the rule
|
|
135
|
+
#: is allowed to reach is the one that breaks. Stated unscoped here it kept 32 of
|
|
136
|
+
#: 32 decisions and broke Ac- (-25, resolved): told the action must not dilute
|
|
137
|
+
#: toward A, the writer wrote Ac- as the decision carried out COLDLY, which lands
|
|
138
|
+
#: in T-, not A-. Moved onto the `action` / `ac_plus` field descriptions it scored
|
|
139
|
+
#: the best endpoint of the three (+47) and broke Re- instead (-32, resolved).
|
|
140
|
+
#: Naming what it does not govern is what left both landings alone.
|
|
141
|
+
#:
|
|
142
|
+
#: Price, on this text's own gate (`probe_transformation_sketch.py`, 25 tetrads
|
|
143
|
+
#: x 2 reps, arm `no_decided_rule`): landings intact (Ac- +2, Re- -4, noise),
|
|
144
|
+
#: validity composites within noise (-8, -10), S- third failure +8, and
|
|
145
|
+
#: **`ac_own` 100% -> 90% (-10, -18..-2, resolved)** — the second accepted trade
|
|
146
|
+
#: on that read, after the scaffold fields' 100% -> 93%. Named rather than
|
|
147
|
+
#: swallowed: a third one needs an argument.
|
|
148
|
+
#:
|
|
149
|
+
#: What the sentence deliberately does NOT say is that a diluted action IS Ac-.
|
|
150
|
+
#: That is a theory claim nothing here has checked, and the archive's record is
|
|
151
|
+
#: that a gloss hardened into a rule gets argued with rather than obeyed.
|
|
152
|
+
#:
|
|
122
153
|
#: What the developments produce together. The S- sentences are the measured
|
|
123
154
|
#: fix (`one-shot-transformation.md`: third-trap 4/17 → 12/17 on graph-built
|
|
124
155
|
#: wheels once the synthesis prompt carried them) and are kept word for word,
|
|
@@ -111,9 +111,11 @@ class ViewSketchPerspectiveDto(BaseModel):
|
|
|
111
111
|
)
|
|
112
112
|
t_plus: str = Field(
|
|
113
113
|
description=(
|
|
114
|
-
"T+ — the THESIS developed constructively, so that
|
|
115
|
-
"
|
|
116
|
-
"
|
|
114
|
+
"T+ — the THESIS developed constructively, so that what A is for stays "
|
|
115
|
+
"possible alongside it. T's own side developed — never T blended with A, "
|
|
116
|
+
"made conditional on it, or the middle between the two. Derived from T; "
|
|
117
|
+
"the positive end of the axis above. A position held, not a move to "
|
|
118
|
+
"make. Empty when not drawn."
|
|
117
119
|
)
|
|
118
120
|
)
|
|
119
121
|
a_minus: str = Field(
|
|
@@ -131,9 +133,11 @@ class ViewSketchPerspectiveDto(BaseModel):
|
|
|
131
133
|
)
|
|
132
134
|
a_plus: str = Field(
|
|
133
135
|
description=(
|
|
134
|
-
"A+ — the ANTITHESIS developed constructively, so that
|
|
135
|
-
"
|
|
136
|
-
"
|
|
136
|
+
"A+ — the ANTITHESIS developed constructively, so that what T is for "
|
|
137
|
+
"stays possible alongside it. A's own side developed — never A blended "
|
|
138
|
+
"with T, made conditional on it, or the middle between the two. Derived "
|
|
139
|
+
"from A; the positive end of the axis above. A position held, not a move "
|
|
140
|
+
"to make. Empty when not drawn."
|
|
137
141
|
)
|
|
138
142
|
)
|
|
139
143
|
t_minus: str = Field(
|
|
@@ -162,6 +166,16 @@ class ViewSketchDto(BaseModel):
|
|
|
162
166
|
#: the graph path gives `AspectGeneration._tetrad_prompt`, stated once here and
|
|
163
167
|
#: shared by the view turn and `concerns/tetrad_sketch.py`, so the two
|
|
164
168
|
#: one-shot builders cannot drift apart.
|
|
169
|
+
#:
|
|
170
|
+
#: Step 1's two measured sentences (2026-10-12, `probe_decided_stance.py`; the
|
|
171
|
+
#: story is on `PLUS_RESTATEMENT_CHECK`, which carries the same rule as the
|
|
172
|
+
#: step-3 check): a plus LEAVES the other pole's good possible rather than
|
|
173
|
+
#: delivering it, and an aspect is a POSITION rather than a move. The second
|
|
174
|
+
#: is what took A+ from 75% to 94% own-strength and coherence from 72% to 91%
|
|
175
|
+
#: on decided stances — the failures it removes are imperatives ("Leave a path
|
|
176
|
+
#: back that she must earn"), and a move that answers both sides at once is a
|
|
177
|
+
#: compromise by construction. It is also where the layering is stated to the
|
|
178
|
+
#: writer: positions live in the tetrad, moves in the Transformation.
|
|
165
179
|
#: What the thesis IS, for a writer that finds it in free words. Measured
|
|
166
180
|
#: without it (`tests/e2e/probe_question_entry.py`, 2026-10-04, 20 questions
|
|
167
181
|
#: through the view turn): the tetrad was statement-grade (CC 17/20, a genuine
|
|
@@ -181,12 +195,29 @@ THESIS_IS_A_STANCE = """The thesis (T) is a STANCE: something the person holds,
|
|
|
181
195
|
TETRAD_BUILD_PROCEDURE = f"""Building a tetrad, when you build one — as its two diagonal contradiction pairs (T+ vs A-, A+ vs T-).
|
|
182
196
|
Each aspect has one fixed parent: T+ and T- develop T; A+ and A- develop A.
|
|
183
197
|
For each pair:
|
|
184
|
-
1. Derive each aspect from ITS OWN parent — a plus develops that parent so
|
|
198
|
+
1. Derive each aspect from ITS OWN parent — a plus develops that parent so that what the other pole is for stays POSSIBLE alongside it, not so that it delivers it; a minus overdevelops that parent one-sidedly, with the other pole absent. Each aspect is a POSITION held or a good someone values, never a move to make: the moves come later, from the way through the tension.
|
|
185
199
|
2. Then name the **axis** — the single dimension on which the two aspects are opposite ends, so they cannot both hold at once.
|
|
186
200
|
3. Re-read both aspects against step 1 for two distinct failures. (a) Wrong parent: if one is really the OTHER parent developed, rewrite it from its own parent. (b) {PLUS_RESTATEMENT_CHECK}"""
|
|
187
201
|
|
|
188
202
|
|
|
189
|
-
|
|
203
|
+
#: What the thesis is when the HOST already has it and wants it kept word for
|
|
204
|
+
#: word. Distinct from `tetrad_sketch_prompt`'s given-thesis line, which asks
|
|
205
|
+
#: for the position "worded in the person's own terms, {max_words} words or
|
|
206
|
+
#: fewer" — a condensation, which is right for `anchor` (the model named the
|
|
207
|
+
#: position, the graph stores a headline) and wrong for a host that shows the
|
|
208
|
+
#: person their OWN sentence as their position (the first app, 2026-10-12: the
|
|
209
|
+
#: card displays the typed words while T was a seven-word recomposition of
|
|
210
|
+
#: them). So this one forbids the rewording the other one invites, and the
|
|
211
|
+
#: framework does not rely on it being obeyed: `Consultant.exploration_view`
|
|
212
|
+
#: writes the given text back over the drawn one (the pin is in code; this
|
|
213
|
+
#: text only stops the writer building the rest of the tetrad around a position
|
|
214
|
+
#: it has quietly reworded).
|
|
215
|
+
THESIS_IS_FIXED = """The thesis (T) is GIVEN, in the person's own words, and it is FIXED: carry it into the view exactly as it stands — do not reword, shorten, sharpen or generalise it, and do not put a different position in its place. Everything else in the tetrad is built around it as given."""
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def view_sketch_prompt(
|
|
219
|
+
focus: Optional[str], max_words: int, thesis: Optional[str] = None
|
|
220
|
+
) -> str:
|
|
190
221
|
"""The structured turn's request, over the consultant's own conversation.
|
|
191
222
|
|
|
192
223
|
Two instructions in one, because the ask is one or the other and the model
|
|
@@ -203,12 +234,42 @@ def view_sketch_prompt(focus: Optional[str], max_words: int) -> str:
|
|
|
203
234
|
(docs/dev-notes/antithesis-selection.md, 2026-10-02). The thesis is asked
|
|
204
235
|
for as a STANCE (`THESIS_IS_A_STANCE`): on 20 questions the turn echoed the
|
|
205
236
|
question as T in 6 before the ask was here (the alsotrue app repo, docs/lab-notes-entry.md).
|
|
237
|
+
|
|
238
|
+
With `thesis` the host has the position already and wants it kept verbatim
|
|
239
|
+
(`THESIS_IS_FIXED`): the stance ask comes OFF — there is nothing to find —
|
|
240
|
+
and the view is asked for the ONE tension that position stands in, because
|
|
241
|
+
a pinned T says nothing about any other tension and a card shows one.
|
|
206
242
|
"""
|
|
243
|
+
pinned = (thesis or "").strip()
|
|
207
244
|
focus_line = (
|
|
208
245
|
f"What to show: {focus}\n\n"
|
|
209
246
|
if focus and focus.strip()
|
|
210
247
|
else "What to show: the tensions this conversation has worked out so far.\n\n"
|
|
211
248
|
)
|
|
249
|
+
scope_line = (
|
|
250
|
+
"- ONE tension: the one the given position below stands in. How much of "
|
|
251
|
+
"it is drawn is still the ask's to say, by the rule above."
|
|
252
|
+
if pinned
|
|
253
|
+
else f"- At most {VIEW_SKETCH_MAX_PERSPECTIVES} tensions, most central "
|
|
254
|
+
"first. Nothing at all rather than a tension the conversation does not "
|
|
255
|
+
"support — a turn that carries no stance (a request for information) "
|
|
256
|
+
"supports none."
|
|
257
|
+
)
|
|
258
|
+
thesis_section = (
|
|
259
|
+
f'{THESIS_IS_FIXED}\n\nThe position: "{pinned}"'
|
|
260
|
+
if pinned
|
|
261
|
+
else THESIS_IS_A_STANCE
|
|
262
|
+
)
|
|
263
|
+
# The exception rides on the line that states the limit, not as a
|
|
264
|
+
# cross-reference from the section above it: a rule and its exception in
|
|
265
|
+
# two places is the competing-signal shape, and the limit is the last line
|
|
266
|
+
# the model reads.
|
|
267
|
+
length_exception = (
|
|
268
|
+
" The given position is the one exception: it stays exactly as it is, "
|
|
269
|
+
"whatever its length."
|
|
270
|
+
if pinned
|
|
271
|
+
else ""
|
|
272
|
+
)
|
|
212
273
|
return f"""Draw the structure of this conversation as dialectical tetrads. Answer with ONE JSON object in the requested schema and nothing else — no prose. Earlier drawings in this conversation are recorded in prose; that is their record, not the format of this answer.
|
|
213
274
|
|
|
214
275
|
{focus_line}{ASPECT_DEFINITIONS}
|
|
@@ -217,15 +278,15 @@ Rules for what goes in the view:
|
|
|
217
278
|
- Show what this conversation has ESTABLISHED: a tension you named and the person took up is drawn as you both have it, in their terms. Do not re-derive what is already on the table.
|
|
218
279
|
- Where the ask needs structure not yet worked out — a perspective for a thesis so far only stated, the antithesis of a position, the corners of a tension you only named — build it now, by the method below, and then draw it.
|
|
219
280
|
- Where the ask stops short of a full tetrad (only the two poles, only the antitheses), leave the positions not asked for EMPTY. An empty corner is honest; an invented one is not.
|
|
220
|
-
|
|
281
|
+
{scope_line}
|
|
221
282
|
|
|
222
|
-
{
|
|
283
|
+
{thesis_section}
|
|
223
284
|
|
|
224
285
|
{_OPPOSING_POSITION_ASK}
|
|
225
286
|
|
|
226
287
|
{TETRAD_BUILD_PROCEDURE}
|
|
227
288
|
|
|
228
|
-
Write every position in the person's own terms, {max_words} words or fewer each."""
|
|
289
|
+
Write every position in the person's own terms, {max_words} words or fewer each.{length_exception}"""
|
|
229
290
|
|
|
230
291
|
|
|
231
292
|
# --- The view shaping (pure) ----------------------------------------------
|
{dialectical_framework-2.0.9 → dialectical_framework-2.0.12}/src/dialectical_framework/settings.py
RENAMED
|
@@ -40,8 +40,8 @@ class Settings(BaseModel):
|
|
|
40
40
|
|
|
41
41
|
Per process (read once, from the base `DialecticalReasoning.setup()` installs;
|
|
42
42
|
a value inside `using_settings` has no effect): `graph_db_*` (the connection is
|
|
43
|
-
a Singleton), `llm_connect_timeout_s` (the provider
|
|
44
|
-
`effect_log_dir` (installed in `setup`). `DIALEXITY_MAX_CONCURRENT_LLM_CALLS`
|
|
43
|
+
a Singleton), `llm_connect_timeout_s` and `llm_read_timeout_s` (the provider
|
|
44
|
+
is registered once), `effect_log_dir` (installed in `setup`). `DIALEXITY_MAX_CONCURRENT_LLM_CALLS`
|
|
45
45
|
is not a field at all: an env var behind one process-wide semaphore.
|
|
46
46
|
"""
|
|
47
47
|
|
|
@@ -276,6 +276,29 @@ class Settings(BaseModel):
|
|
|
276
276
|
# slow generation is not the problem being solved here.
|
|
277
277
|
llm_connect_timeout_s: float = Field(default=30.0, description="TCP/TLS connect timeout for LLM calls, in seconds. Raise on slow or high-latency links.")
|
|
278
278
|
|
|
279
|
+
# Read timeout for the Bedrock client, in seconds: how long one provider
|
|
280
|
+
# call may go without a byte arriving before it raises (`APITimeoutError`,
|
|
281
|
+
# which the ladder retries ONCE — `use_brain._STALL_RETRY_MAX`).
|
|
282
|
+
#
|
|
283
|
+
# The SDK's default is 600s, and the client used to keep it, so a stalled
|
|
284
|
+
# call held whatever was waiting on it for ten minutes with no error and no
|
|
285
|
+
# retry on record (a 610s turn, `prompt-vs-machinery`; the handoff that set
|
|
286
|
+
# this field: one of three gathered draws hung a 20-31s card for 300s,
|
|
287
|
+
# 2026-10-09, Sonnet 5.5). On a NON-streamed call the body arrives whole,
|
|
288
|
+
# so this is a ceiling on one generation; on a streamed round it is the gap
|
|
289
|
+
# between two chunks, and a thinking turn streams its deltas (the
|
|
290
|
+
# facilitator asks for `include_thoughts`), so the long silence is the
|
|
291
|
+
# non-streamed case only. 120s clears every unstalled generation in the
|
|
292
|
+
# archive (the longest measured conversational rounds sit under a minute on
|
|
293
|
+
# Sonnet 5 with thinking) while cutting a stall from 600s to two minutes. A
|
|
294
|
+
# host whose calls are short sets it lower: the first app's draws run ~15s,
|
|
295
|
+
# texts ~8s, structured calls ~3s on Sonnet 5.5, and it runs at 30s. Too
|
|
296
|
+
# low, and a legitimately long generation (a digest of a 40k-character
|
|
297
|
+
# part, an Opus round with a large dump) is cut and re-asked — the retry
|
|
298
|
+
# does not help a call that needed the time. Read once, with the connect
|
|
299
|
+
# timeout, when the provider registers.
|
|
300
|
+
llm_read_timeout_s: float = Field(default=120.0, description="Read timeout for LLM calls, in seconds: the longest one call may wait for the provider's next byte. Lower where every call is short; a stall then surfaces as a timeout instead of holding the caller.")
|
|
301
|
+
|
|
279
302
|
@classmethod
|
|
280
303
|
def from_partial(cls, partial_settings: Optional[Settings] = None) -> Self:
|
|
281
304
|
"""
|
|
@@ -353,5 +376,6 @@ class Settings(BaseModel):
|
|
|
353
376
|
# something. `**` on an empty dict sends nothing.
|
|
354
377
|
**_env_thinking_level(),
|
|
355
378
|
llm_connect_timeout_s=float(os.getenv("DIALEXITY_LLM_CONNECT_TIMEOUT_S", 30.0)),
|
|
379
|
+
llm_read_timeout_s=float(os.getenv("DIALEXITY_LLM_READ_TIMEOUT_S", 120.0)),
|
|
356
380
|
effect_log_dir=os.getenv("DIALEXITY_GRAPH_LOG_DIR"),
|
|
357
381
|
)
|
|
@@ -31,8 +31,8 @@ TWO TIERS, as the code already treats them (see `Settings`):
|
|
|
31
31
|
through `SettingsAware.settings` (word limits, thinking level, the Advisor's
|
|
32
32
|
floors and caps, the audit switches);
|
|
33
33
|
- read ONCE per process, from the base only: `graph_db_*` (the connection is a
|
|
34
|
-
Singleton), `llm_connect_timeout_s` (the provider is
|
|
35
|
-
`effect_log_dir` (installed in `setup`). A value for these inside
|
|
34
|
+
Singleton), `llm_connect_timeout_s` and `llm_read_timeout_s` (the provider is
|
|
35
|
+
registered once), `effect_log_dir` (installed in `setup`). A value for these inside
|
|
36
36
|
`using_settings` has no effect, by construction, not by accident.
|
|
37
37
|
|
|
38
38
|
`container.settings.override(...)` RAISES: it would replace this provider with one
|
|
@@ -36,27 +36,51 @@ if TYPE_CHECKING:
|
|
|
36
36
|
from mirascope.llm.tools import AsyncToolkit, Toolkit
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
def
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
def _client_timeout(
|
|
40
|
+
connect_timeout_s: float | None, read_timeout_s: float | None = None
|
|
41
|
+
) -> httpx.Timeout:
|
|
42
|
+
"""SDK default timeouts with the CONNECT and READ phases set by the framework.
|
|
43
|
+
|
|
44
|
+
Connect: the SDK's 5s assumes a warm datacenter link. A cold TLS handshake
|
|
45
|
+
over a tethered/VPN/mobile connection measured 7.7s, so the first call on
|
|
46
|
+
every fresh connection failed — and the parallel stages failed hardest,
|
|
47
|
+
since each concurrent call opens its own cold connection while a sequential
|
|
48
|
+
one reuses a handshaked socket.
|
|
49
|
+
|
|
50
|
+
Read: the SDK's 600s is the length of a stall nobody asked for. A provider
|
|
51
|
+
call that stops sending holds its caller for ten minutes with no error, and
|
|
52
|
+
where callers are gathered (the view turn's best-of-3) one stalled draw
|
|
53
|
+
holds the two that finished (a 300s card where the same case took 20-31s,
|
|
54
|
+
2026-10-09). `Settings.llm_read_timeout_s` sets it; a timeout raises
|
|
55
|
+
`APITimeoutError`, which the ladder classifies as a stall and re-asks once.
|
|
56
|
+
Write and pool keep the SDK defaults: nothing has stalled on either.
|
|
49
57
|
"""
|
|
50
|
-
|
|
58
|
+
connect = connect_timeout_s if connect_timeout_s is not None else 30.0
|
|
59
|
+
read = read_timeout_s if read_timeout_s is not None else 120.0
|
|
51
60
|
default = DEFAULT_TIMEOUT
|
|
52
61
|
return httpx.Timeout(
|
|
53
|
-
connect=
|
|
54
|
-
read=
|
|
62
|
+
connect=connect,
|
|
63
|
+
read=read,
|
|
55
64
|
write=default.write,
|
|
56
65
|
pool=default.pool,
|
|
57
66
|
)
|
|
58
67
|
|
|
59
68
|
|
|
69
|
+
#: The Anthropic SDK's own retry is OFF: every retry the framework makes is one
|
|
70
|
+
#: it can see. The SDK defaults to two retries of a timeout, a connection error
|
|
71
|
+
#: or a 408/409/429/5xx with its own backoff, BELOW `use_brain`'s ladder and
|
|
72
|
+
#: `retry_transient` — so a stalled call cost three read timeouts before the
|
|
73
|
+
#: ladder saw one failure, and `retry_accounting`/`call_census` recorded none of
|
|
74
|
+
#: it (a 610s turn with `retry_count` 0, `prompt-vs-machinery`). With this at 0
|
|
75
|
+
#: the bound on one call is the ladder's: a stall is (`_STALL_RETRY_MAX`) × the
|
|
76
|
+
#: read timeout plus its flat delay, and the retry is on the account. Every
|
|
77
|
+
#: provider request the framework makes passes a retry layer of its own — the
|
|
78
|
+
#: ladder (`use_brain`), the streamed open and resume (`retry_transient` in
|
|
79
|
+
#: `_start_stream_round`) and, since this went to 0, the awaited resume too
|
|
80
|
+
#: (`ConversationFacilitator.submit`), which until then had only the SDK's.
|
|
81
|
+
_SDK_MAX_RETRIES = 0
|
|
82
|
+
|
|
83
|
+
|
|
60
84
|
#: Start of the Advisor's mutable graph dump inside its system prompt.
|
|
61
85
|
#:
|
|
62
86
|
#: `_CONTEXT_SLOT` (`agents/advisor/system_prompts.py`) is the LAST section and the
|
|
@@ -361,11 +385,19 @@ class BedrockAnthropicProvider(AnthropicProvider):
|
|
|
361
385
|
id = "bedrock"
|
|
362
386
|
default_scope = "bedrock/"
|
|
363
387
|
|
|
364
|
-
def __init__(
|
|
388
|
+
def __init__(
|
|
389
|
+
self,
|
|
390
|
+
*,
|
|
391
|
+
connect_timeout_s: float | None = None,
|
|
392
|
+
read_timeout_s: float | None = None,
|
|
393
|
+
**kwargs, # noqa: ARG002
|
|
394
|
+
) -> None:
|
|
365
395
|
# Skip super().__init__() — parent creates Anthropic/AsyncAnthropic clients we don't need
|
|
366
|
-
timeout =
|
|
367
|
-
self.client = AnthropicBedrock(timeout=timeout)
|
|
368
|
-
self.async_client = AsyncAnthropicBedrock(
|
|
396
|
+
timeout = _client_timeout(connect_timeout_s, read_timeout_s)
|
|
397
|
+
self.client = AnthropicBedrock(timeout=timeout, max_retries=_SDK_MAX_RETRIES)
|
|
398
|
+
self.async_client = AsyncAnthropicBedrock(
|
|
399
|
+
timeout=timeout, max_retries=_SDK_MAX_RETRIES
|
|
400
|
+
)
|
|
369
401
|
self._beta_provider = None
|
|
370
402
|
|
|
371
403
|
@staticmethod
|
|
@@ -594,17 +626,19 @@ def ensure_bedrock_provider(
|
|
|
594
626
|
) -> None:
|
|
595
627
|
"""Register the bedrock provider if not already registered. Idempotent.
|
|
596
628
|
|
|
597
|
-
Registration happens on the first call, so `llm_connect_timeout_s`
|
|
598
|
-
from DI here rather than in `__init__`
|
|
599
|
-
no arguments). Consequence of the
|
|
600
|
-
the first LLM call of the
|
|
629
|
+
Registration happens on the first call, so `llm_connect_timeout_s` and
|
|
630
|
+
`llm_read_timeout_s` are read from DI here rather than in `__init__`
|
|
631
|
+
(Mirascope constructs providers with no arguments). Consequence of the
|
|
632
|
+
idempotence: changing either setting after the first LLM call of the
|
|
633
|
+
process has no effect.
|
|
601
634
|
"""
|
|
602
635
|
global _registered
|
|
603
636
|
if _registered:
|
|
604
637
|
return
|
|
605
638
|
llm.register_provider(
|
|
606
639
|
BedrockAnthropicProvider(
|
|
607
|
-
connect_timeout_s=getattr(settings, "llm_connect_timeout_s", None)
|
|
640
|
+
connect_timeout_s=getattr(settings, "llm_connect_timeout_s", None),
|
|
641
|
+
read_timeout_s=getattr(settings, "llm_read_timeout_s", None),
|
|
608
642
|
),
|
|
609
643
|
scope="bedrock/",
|
|
610
644
|
)
|