dialectical-framework 2.1.2__tar.gz → 2.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/PKG-INFO +1 -1
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/pyproject.toml +1 -1
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/conversation_facilitator.py +15 -1
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/settings.py +29 -3
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/bedrock_provider.py +17 -18
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/use_brain.py +45 -1
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/LICENSE +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/PATENTS +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/README.md +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/advisor.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/build_policy.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/migration.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/reply_hygiene.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/system_prompts.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/tools/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/tools/anchor.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/tools/deepen.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/tools/explore.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/tools/ingest.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/tools/note.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/tools/record_decision.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/tools/scoped.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/advisor/tools/sync.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/agent_context.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/analyst/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/analyst/analyst.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/analyst/skills/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/analyst/skills/anchor_theses.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/analyst/skills/edit_perspective.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/analyst/skills/expand_polarities.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/analyst/skills/find_polarities.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/analyst/skills/introduce_polarity.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/analyst/skills/sketch_tetrad.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/analyst/skills/surface_theses.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/analyst/system_prompts.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/analyst/tools/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/analyst/tools/place_statement.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/app_spec.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/apps.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/consultant/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/consultant/consultant.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/execution_report.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/explorer/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/explorer/explorer.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/explorer/skills/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/explorer/skills/build_wheels.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/explorer/skills/explore_transformations.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/explorer/skills/generate_synthesis.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/explorer/system_prompts.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/explorer/tools/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/explorer/tools/create_nexus.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/explorer/tools/expand_nexus.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/explorer/tools/generate_synthesis.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/explorer/tools/present_exploration.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/orchestrator/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/orchestrator/tools/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/orchestrator/tools/add_input.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/orchestrator/tools/audit_feasibility.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/orchestrator/tools/create_dx_input.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/orchestrator/tools/digest_input.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/orchestrator/tools/discard.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/orchestrator/tools/get_schema.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/orchestrator/tools/inspect_node.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/orchestrator/tools/present_analysis.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/orchestrator/tools/query_graph.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/orchestrator/tools/read_digest.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/orchestrator/tools/read_input.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/reasonable_concern.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/stream_events.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/toolsets.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/turn_timing.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/ac_re_taxonomy.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/action_extraction.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/add_input.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/ai_dto/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/ai_dto/statement_dto.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/ai_dto/statements_deck_dto.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/antithesis_classification.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/antithesis_extraction.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/antithetical_thesis_detection.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/aspect_classification.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/aspect_generation.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/attribution_check.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/build_status.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/causality/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/causality/causality_estimator.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/causality/causality_estimator_balanced.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/causality/causality_estimator_criteria.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/causality/causality_estimator_desirable.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/causality/causality_estimator_feasible.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/causality/causality_estimator_realistic.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/causality/causality_normalizer.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/causality/estimator_resolver.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/causality_estimation.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/control_statements_check.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/create_dx_input.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/create_nexus.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/decision_coherence_check.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/decision_confirmation_check.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/diagonal_oppositions_check.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/dialectical_context.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/discard.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/display_text_edit.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/expand_nexus.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/perspective_combination.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/perspective_validation.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/positive_ac_re_apex_derivation.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/record_decision.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/scoring_scales.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/source_digest.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/statement_classification.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/statement_deduplication.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/statement_headline.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/statement_placement.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/synthesis_generation.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/tetrad_candidates.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/tetrad_grounding.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/tetrad_sketch.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/thesis_extraction.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/thesis_fit_check.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/transformation_audit.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/transformation_generation.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/transformation_sketch.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/concerns/view_sketch.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/dialectical_reasoning.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/enums/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/enums/causality_preset.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/enums/di.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/events/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/events/graph_event.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/events/graph_event_bus.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/events/progress_event.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/exceptions/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/exceptions/node_errors.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/exceptions/provider_errors.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/exceptions/resolver_errors.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/composite_input_resolver.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/dialexity_input_resolver.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/estimation_manager.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/mixins/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/mixins/incremental_build_mixin.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/mixins/intent_mixin.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/mixins/persistable_mixin.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/assessable_entity.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/base_node.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/case.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/cycle.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/decision.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/estimation.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/ideas.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/input.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/nexus.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/note.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/perspective.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/polarity.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/rationale.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/statement.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/synthesis.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/transformation.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/transition.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/nodes/wheel.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationship_manager.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/action_reflection_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/belongs_to_cycle_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/belongs_to_nexus_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/changed_to_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/contradiction_of_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/critiques_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/distilled_to_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/estimates_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/explains_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/grounded_in_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/has_input_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/has_statement_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/has_wheel_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/immutable_structure.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/is_source_of_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/is_target_of_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/negative_side_of_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/opposite_direction_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/opposite_of_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/polarity_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/positive_side_of_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/provides_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/relationships/synthesis_of_relationship.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/rendering.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/case_repository.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/cycle_repository.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/decision_repository.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/input_repository.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/nexus_repository.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/node_repository.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/note_repository.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/perspective_repository.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/polarity_repository.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/schema_repository.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/statement_repository.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/transformation_repository.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/repositories/wheel_repository.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/scope_context.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/verbatim_input_resolver.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/views.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/wheel_segment.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/graph/wheel_segment_polar_pair.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/protocols/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/protocols/has_config.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/protocols/input_resolver.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/py.typed +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/settings_context.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/__init__.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/async_drain.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/call_census.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/chunking.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/concurrency.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/dc_replace.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/decompose_probability_uniformly.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/edge_context.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/effect_logger.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/format_compat.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/input_context.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/order_transitions.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/progress.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/retry_accounting.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/sequence_generation.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/thinking_compat.py +0 -0
- {dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/utils/utterance.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: dialectical-framework
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.3
|
|
4
4
|
Summary: A dialectical framework for augmented intelligence. AI reasoning powered with dialectics supports humans in: system optimization (psychology, engineering, business, politics, etc.); dispute resolution (mediation, conflicts, negotiations, etc.); decision-making (dilemmas, challenging situations, win-win, etc.).
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: dialectics,dialectical-reasoning,synthesis,thesis-antithesis,ai,artificial-intelligence,llm,reasoning-framework,philosophy,logic,argumentation,conflict-resolution,decision-making,critical-thinking,semantic-graph,mirascope,pydantic,perspectives,polarity-reasoning
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "dialectical-framework"
|
|
3
|
-
version = "2.1.
|
|
3
|
+
version = "2.1.3"
|
|
4
4
|
description = "A dialectical framework for augmented intelligence. AI reasoning powered with dialectics supports humans in: system optimization (psychology, engineering, business, politics, etc.); dispute resolution (mediation, conflicts, negotiations, etc.); decision-making (dilemmas, challenging situations, win-win, etc.)."
|
|
5
5
|
authors = ["Evaldas Taroza <evaldas@dialexity.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -35,7 +35,8 @@ from dialectical_framework.utils.call_census import record_call
|
|
|
35
35
|
from dialectical_framework.utils.thinking_compat import conversational_round
|
|
36
36
|
from dialectical_framework.utils.retry_accounting import (RetryAccount,
|
|
37
37
|
retry_account)
|
|
38
|
-
from dialectical_framework.utils.use_brain import (
|
|
38
|
+
from dialectical_framework.utils.use_brain import (last_structured_reply_text,
|
|
39
|
+
prefill_token_kwargs,
|
|
39
40
|
retry_transient, use_brain)
|
|
40
41
|
|
|
41
42
|
from mirascope.llm import FinishReason, TextChunk, ThoughtChunk, ToolOutput
|
|
@@ -333,6 +334,15 @@ class ConversationFacilitator(SettingsAware):
|
|
|
333
334
|
# prefill-sensitive quantity — the one prompt caching can move — is
|
|
334
335
|
# `CallRecord.first_token_seconds` on the turn's first round, not this.
|
|
335
336
|
self.last_submit_first_delta_s: Optional[float] = None
|
|
337
|
+
# The last STRUCTURED reply of this turn as the model wrote it, before
|
|
338
|
+
# parsing — the JSON text, or the tool call's arguments as text. `None`
|
|
339
|
+
# on a turn that made no structured call (a reused written reply, a
|
|
340
|
+
# mocked one). A DTO that validates can still carry a field the model
|
|
341
|
+
# cut short and continued in the next one (the first app's handoff,
|
|
342
|
+
# 2026-10-27); nothing in a parse can see that, but a host's own check
|
|
343
|
+
# can, and then it needs the bytes to say whether the split was the
|
|
344
|
+
# writing or the wire. See `use_brain.last_structured_reply_text`.
|
|
345
|
+
self.last_structured_reply_text: Optional[str] = None
|
|
336
346
|
# Bumped once per submit, and captured by `submit_stream` so its `finally`
|
|
337
347
|
# can tell "this turn is still the current one" from "a turn the consumer
|
|
338
348
|
# walked away from, being finalised now".
|
|
@@ -522,6 +532,7 @@ class ConversationFacilitator(SettingsAware):
|
|
|
522
532
|
self.last_tool_rounds = []
|
|
523
533
|
self.last_submit_seconds = 0.0
|
|
524
534
|
self.last_submit_retries = RetryAccount()
|
|
535
|
+
self.last_structured_reply_text = None
|
|
525
536
|
# Reset here too although this path can never set it: a facilitator is
|
|
526
537
|
# reused across turns, so without this a non-streaming submit would report
|
|
527
538
|
# the previous STREAMED turn's figure as its own.
|
|
@@ -701,6 +712,7 @@ class ConversationFacilitator(SettingsAware):
|
|
|
701
712
|
self.last_submit_seconds = 0.0
|
|
702
713
|
self.last_submit_retries = RetryAccount()
|
|
703
714
|
self.last_submit_first_delta_s = None
|
|
715
|
+
self.last_structured_reply_text = None
|
|
704
716
|
|
|
705
717
|
# Re-entered per await instead of wrapped around the whole generator, and
|
|
706
718
|
# `retry_account` explains why: a contextvar set across a `yield` installs
|
|
@@ -1442,6 +1454,8 @@ class ConversationFacilitator(SettingsAware):
|
|
|
1442
1454
|
return messages
|
|
1443
1455
|
|
|
1444
1456
|
result = await _llm_call()
|
|
1457
|
+
# Same task as the call, so this is THIS call's text (see use_brain).
|
|
1458
|
+
self.last_structured_reply_text = last_structured_reply_text()
|
|
1445
1459
|
self._messages.append(
|
|
1446
1460
|
llm.messages.assistant(
|
|
1447
1461
|
self._assistant_history_text(result),
|
{dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/settings.py
RENAMED
|
@@ -36,7 +36,9 @@ class Settings(BaseModel):
|
|
|
36
36
|
`dialectical_framework.settings_context` scopes them to one asyncio context):
|
|
37
37
|
`ai_model`, `reasoning_model`, and everything read through
|
|
38
38
|
`SettingsAware.settings` — word limits, the thinking level, the Advisor's
|
|
39
|
-
floors and caps, the audit switches.
|
|
39
|
+
floors and caps, the audit switches. `llm_stream_awaited_calls` and
|
|
40
|
+
`llm_stream_headers_timeout_s` are read at the provider on every call, so
|
|
41
|
+
they scope the same way.
|
|
40
42
|
|
|
41
43
|
Per process (read once, from the base `DialecticalReasoning.setup()` installs;
|
|
42
44
|
a value inside `using_settings` has no effect): `graph_db_*` (the connection is
|
|
@@ -304,7 +306,8 @@ class Settings(BaseModel):
|
|
|
304
306
|
# Every awaited Bedrock call (`BedrockAnthropicProvider._create_async`) is
|
|
305
307
|
# sent as a stream and assembled into the same `Message` before Mirascope
|
|
306
308
|
# decodes it, so a stall is caught where it happens instead of at the whole
|
|
307
|
-
# read timeout: the response must OPEN within
|
|
309
|
+
# read timeout: the response must OPEN within `llm_stream_headers_timeout_s`
|
|
310
|
+
# (5s by default),
|
|
308
311
|
# content must start within `llm_read_timeout_s`, and a gap past 5s once it
|
|
309
312
|
# flows is a stall. Measured on the first app's promise run (2026-10-12,
|
|
310
313
|
# Sonnet 5.5, 59 cases, read timeout 20s): ~5.5% of calls hang, ALL before
|
|
@@ -314,7 +317,29 @@ class Settings(BaseModel):
|
|
|
314
317
|
# exists as an off switch for a model or provider the measurement did not
|
|
315
318
|
# cover (`docs/dev-notes/streaming-latency-and-retry.md`, "Hangs are caught
|
|
316
319
|
# at the opening"). Per request.
|
|
317
|
-
llm_stream_awaited_calls: bool = Field(default=True, description="Send awaited provider calls as streams and assemble the message, so a hung call is caught when the response fails to open (
|
|
320
|
+
llm_stream_awaited_calls: bool = Field(default=True, description="Send awaited provider calls as streams and assemble the message, so a hung call is caught when the response fails to open (`llm_stream_headers_timeout_s`) rather than at the whole read timeout. On by default; off only for a model or provider where streaming misbehaves.")
|
|
321
|
+
|
|
322
|
+
# How long a streamed awaited call may wait for the response to OPEN
|
|
323
|
+
# (headers, `message_start`) before it counts as a stall and is re-asked
|
|
324
|
+
# (`bedrock_provider._stream_to_message`; the re-ask is the stall curve's
|
|
325
|
+
# one, `use_brain._STALL_RETRY_MAX`). The default is the Bedrock
|
|
326
|
+
# measurement: the first app's promise run (2026-10-12, Sonnet 5.5, 890
|
|
327
|
+
# streamed calls) saw every stall (48, 5.4%) hang before the headers while
|
|
328
|
+
# healthy calls opened at a median 1.2s, p99 3.6s, whatever their size (6
|
|
329
|
+
# of 842 past 5s) — streamed, the opening is the one wait that does not
|
|
330
|
+
# grow with the output, so one short budget fits every call size.
|
|
331
|
+
#
|
|
332
|
+
# A setting since 2026-10-27 because the figure is per transport and
|
|
333
|
+
# account, not per model: on the native `anthropic/` transport the same
|
|
334
|
+
# 5s lost six of twelve fresh sessions in the first app (both attempts past
|
|
335
|
+
# the budget, with the SDK's own retry at zero so that is real
|
|
336
|
+
# time-to-first-byte), where on Bedrock the one re-ask had recovered every
|
|
337
|
+
# stall. Whether the native opening is slow (a wider budget lands the call)
|
|
338
|
+
# or hangs more often (only a retry would) is what the setting lets a host
|
|
339
|
+
# find out: widen it where the logged phase says "before headers" at a rate
|
|
340
|
+
# the re-ask does not absorb. Clamped to the read timeout; lowering it below
|
|
341
|
+
# the healthy p99 buys nothing. Per request, read at the call.
|
|
342
|
+
llm_stream_headers_timeout_s: float = Field(default=5.0, description="How long a streamed provider call may wait for the response to open, in seconds, before it counts as a stall and is re-asked once. 5s is the Bedrock measurement; widen it on a transport whose opening tail is longer. Never more than the read timeout.")
|
|
318
343
|
|
|
319
344
|
@classmethod
|
|
320
345
|
def from_partial(cls, partial_settings: Optional[Settings] = None) -> Self:
|
|
@@ -395,5 +420,6 @@ class Settings(BaseModel):
|
|
|
395
420
|
llm_connect_timeout_s=float(os.getenv("DIALEXITY_LLM_CONNECT_TIMEOUT_S", 30.0)),
|
|
396
421
|
llm_read_timeout_s=float(os.getenv("DIALEXITY_LLM_READ_TIMEOUT_S", 120.0)),
|
|
397
422
|
llm_stream_awaited_calls=os.getenv("DIALEXITY_LLM_STREAM_AWAITED_CALLS", "true").lower() == "true",
|
|
423
|
+
llm_stream_headers_timeout_s=float(os.getenv("DIALEXITY_LLM_STREAM_HEADERS_TIMEOUT_S", 5.0)),
|
|
398
424
|
effect_log_dir=os.getenv("DIALEXITY_GRAPH_LOG_DIR"),
|
|
399
425
|
)
|
|
@@ -415,15 +415,6 @@ logger = logging.getLogger(__name__)
|
|
|
415
415
|
#: so it is a backstop; the measured hangs are all caught at the opening.
|
|
416
416
|
_STREAM_GAP_TIMEOUT_S = 5.0
|
|
417
417
|
|
|
418
|
-
#: How long a streamed awaited call may wait for the response to OPEN (headers,
|
|
419
|
-
#: `message_start`) before it counts as a stall. Measured on the first app's
|
|
420
|
-
#: promise run (2026-10-12, Sonnet 5.5, 890 streamed calls): every stall (48,
|
|
421
|
-
#: 5.4%) hung before the headers, while healthy calls opened at a median 1.2s,
|
|
422
|
-
#: p99 3.6s, whatever their size (6 of 842 past 5s). Streamed, the opening is
|
|
423
|
-
#: the one wait that does not grow with the output, so it is where a hang is
|
|
424
|
-
#: caught: here at 5s rather than at the whole read timeout.
|
|
425
|
-
_STREAM_HEADERS_TIMEOUT_S = 5.0
|
|
426
|
-
|
|
427
418
|
#: Deltas that are the answer being written, as opposed to thinking or
|
|
428
419
|
#: bookkeeping. The SDK's stream yields both the raw `content_block_delta` and
|
|
429
420
|
#: a synthesized event per delta kind.
|
|
@@ -450,14 +441,18 @@ def _is_content_event(event: Any) -> bool:
|
|
|
450
441
|
|
|
451
442
|
|
|
452
443
|
async def _stream_to_message(
|
|
453
|
-
manager: _LearningStreamManager,
|
|
444
|
+
manager: _LearningStreamManager,
|
|
445
|
+
model_name: str,
|
|
446
|
+
read_timeout_s: float,
|
|
447
|
+
headers_timeout_s: float,
|
|
454
448
|
) -> AnthropicMessage:
|
|
455
449
|
"""Consume one stream and return the assembled `Message`, policing silence.
|
|
456
450
|
|
|
457
|
-
Three budgets: the response must OPEN within `
|
|
458
|
-
(where the measured hangs are
|
|
459
|
-
|
|
460
|
-
|
|
451
|
+
Three budgets: the response must OPEN within `headers_timeout_s`
|
|
452
|
+
(`Settings.llm_stream_headers_timeout_s` — where the measured hangs are,
|
|
453
|
+
and never more than the read timeout), the first content must follow
|
|
454
|
+
within the read timeout (queueing, prefill, thinking), and once content
|
|
455
|
+
flows a gap longer than `_STREAM_GAP_TIMEOUT_S` is a stall.
|
|
461
456
|
|
|
462
457
|
The provider's `ping`s do not count as progress: a stream that only pings
|
|
463
458
|
is a hang the socket's read timeout would never see. Every stall is logged
|
|
@@ -467,7 +462,7 @@ async def _stream_to_message(
|
|
|
467
462
|
"""
|
|
468
463
|
loop = asyncio.get_running_loop()
|
|
469
464
|
started = time.monotonic()
|
|
470
|
-
headers_budget = min(
|
|
465
|
+
headers_budget = min(headers_timeout_s, read_timeout_s)
|
|
471
466
|
try:
|
|
472
467
|
stream = await asyncio.wait_for(manager.__aenter__(), timeout=headers_budget)
|
|
473
468
|
except asyncio.TimeoutError as e:
|
|
@@ -476,7 +471,7 @@ async def _stream_to_message(
|
|
|
476
471
|
model_name, time.monotonic() - started,
|
|
477
472
|
)
|
|
478
473
|
raise StreamReadTimeout(
|
|
479
|
-
f"stream did not open within {headers_budget
|
|
474
|
+
f"stream did not open within {headers_budget:g}s"
|
|
480
475
|
) from e
|
|
481
476
|
except Exception as e:
|
|
482
477
|
if type(e).__name__.endswith(("TimeoutError", "ReadTimeout")):
|
|
@@ -653,14 +648,18 @@ class _AnthropicTransport(AnthropicProvider):
|
|
|
653
648
|
stream and comes back as the same assembled `Message`, so a stall is
|
|
654
649
|
caught by the gap between chunks (`_stream_to_message`) instead of by a
|
|
655
650
|
ceiling on the whole generation. The stream manager learns the thinking
|
|
656
|
-
shape the same way.
|
|
651
|
+
shape the same way. The opening budget is read here, per request
|
|
652
|
+
(`llm_stream_headers_timeout_s`); the read timeout was read once, when
|
|
653
|
+
the client was built.
|
|
657
654
|
"""
|
|
658
655
|
model_name = kwargs["model"]
|
|
659
|
-
|
|
656
|
+
settings = get_current_settings()
|
|
657
|
+
if settings.llm_stream_awaited_calls:
|
|
660
658
|
return await _stream_to_message(
|
|
661
659
|
_LearningStreamManager(self.async_client, kwargs, params),
|
|
662
660
|
model_name,
|
|
663
661
|
self._read_timeout_s,
|
|
662
|
+
settings.llm_stream_headers_timeout_s,
|
|
664
663
|
)
|
|
665
664
|
try:
|
|
666
665
|
return await self.async_client.messages.create(
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
+
import contextvars
|
|
4
5
|
import json
|
|
5
6
|
import logging
|
|
6
7
|
import time
|
|
@@ -262,7 +263,7 @@ def use_brain(
|
|
|
262
263
|
)
|
|
263
264
|
if has_format:
|
|
264
265
|
try:
|
|
265
|
-
|
|
266
|
+
parsed = response.parse()
|
|
266
267
|
except ParseError as e:
|
|
267
268
|
salvaged = _salvage_envelope(
|
|
268
269
|
response,
|
|
@@ -276,6 +277,7 @@ def use_brain(
|
|
|
276
277
|
e,
|
|
277
278
|
)
|
|
278
279
|
if salvaged is not None:
|
|
280
|
+
_keep_structured_reply(response, format_name)
|
|
279
281
|
return salvaged
|
|
280
282
|
# Nothing fit, so this is about to cost a re-ask and
|
|
281
283
|
# a nap. Say what the model actually sent, ONCE per
|
|
@@ -288,6 +290,8 @@ def use_brain(
|
|
|
288
290
|
if attempt == 0:
|
|
289
291
|
_log_unsalvageable(response, format_name)
|
|
290
292
|
raise
|
|
293
|
+
_keep_structured_reply(response, format_name)
|
|
294
|
+
return parsed
|
|
291
295
|
return response
|
|
292
296
|
except ModelRefusal:
|
|
293
297
|
# Never retried, and never classified: its explanation is
|
|
@@ -481,6 +485,46 @@ def _framing_leak_note(text: str) -> str:
|
|
|
481
485
|
)
|
|
482
486
|
|
|
483
487
|
|
|
488
|
+
#: The text of the last structured reply parsed in this context, exactly as
|
|
489
|
+
#: the model wrote it. A reply that PARSES can still be wrong in a way no
|
|
490
|
+
#: parser sees: a string field cut mid-word with its tail written into the
|
|
491
|
+
#: next field (the first app's handoff of 2026-10-27, one Lithuanian card of
|
|
492
|
+
#: two) is valid JSON, and the DTO carries only the fields. The framework
|
|
493
|
+
#: cannot tell such a field from a whole one — any check would be a reading of
|
|
494
|
+
#: the content, which is the host's judge, not a parse — so what it does is
|
|
495
|
+
#: keep the bytes: a host whose own check fires reads them back through
|
|
496
|
+
#: `ConversationFacilitator.last_structured_reply_text` and can say whether
|
|
497
|
+
#: the split was the model's writing or something on the way. A ContextVar,
|
|
498
|
+
#: set in the caller's own task, so a draw gathered on another task never
|
|
499
|
+
#: overwrites it; `None` until a structured call has returned here.
|
|
500
|
+
_last_structured_reply: contextvars.ContextVar[Optional[str]] = contextvars.ContextVar(
|
|
501
|
+
"last_structured_reply", default=None
|
|
502
|
+
)
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
def last_structured_reply_text() -> Optional[str]:
|
|
506
|
+
"""The raw text of the last structured reply parsed in this context."""
|
|
507
|
+
return _last_structured_reply.get()
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
def _keep_structured_reply(response: Any, format_name: Optional[str]) -> None:
|
|
511
|
+
"""Record a parsed reply as written, and say so at DEBUG, in full.
|
|
512
|
+
|
|
513
|
+
Whole and never clipped, unlike `_log_unsalvageable`: the tail is the part a
|
|
514
|
+
split-field diagnosis needs, and DEBUG is off unless a host turns it on for
|
|
515
|
+
exactly that. Payload text only — no prompt, no system prompt. Never
|
|
516
|
+
raises: this runs on the success path.
|
|
517
|
+
"""
|
|
518
|
+
try:
|
|
519
|
+
text = response.text("") or ""
|
|
520
|
+
except Exception: # noqa: BLE001
|
|
521
|
+
return
|
|
522
|
+
_last_structured_reply.set(text)
|
|
523
|
+
logging.getLogger(__name__).debug(
|
|
524
|
+
"Structured %s reply as written (%d chars): %s", format_name, len(text), text
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
|
|
484
528
|
def _log_unsalvageable(response: Any, format_name: Optional[str]) -> None:
|
|
485
529
|
"""Log what the model actually sent, so the next envelope is a one-line fix.
|
|
486
530
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dialectical_framework-2.1.2 → dialectical_framework-2.1.3}/src/dialectical_framework/agents/apps.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|