flare-kernel 0.2.1__tar.gz → 0.2.2__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.
Files changed (359) hide show
  1. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/PKG-INFO +6 -1
  2. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/README.md +5 -0
  3. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/pyproject.toml +1 -1
  4. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/contracts/kernel_contract.py +3 -0
  5. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/canonical/canonical_state_context_analysis.py +10 -2
  6. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/canonical/canonical_state_context_inputs.py +18 -10
  7. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/canonical/canonical_state_flow.py +111 -2
  8. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/canonical/canonical_state_payload.py +68 -9
  9. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/canonical/canonical_state_projection.py +2 -1
  10. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/completion_response_builder.py +13 -3
  11. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/endpoint_context.py +42 -0
  12. flare_kernel-0.2.2/src/flare_kernel/router/guided_completion.py +68 -0
  13. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_authority_hydration.py +14 -4
  14. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_decision_rules.py +27 -2
  15. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_entry_policy.py +100 -0
  16. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_extraction_extractors.py +15 -1
  17. flare_kernel-0.2.2/src/flare_kernel/router/intake/intake_guided_open_fields.py +58 -0
  18. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_inputs.py +16 -6
  19. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_payload_updates.py +33 -16
  20. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_readiness.py +25 -0
  21. flare_kernel-0.2.2/src/flare_kernel/router/intake/intake_state_persistence.py +81 -0
  22. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_status.py +2 -0
  23. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_status_chooser_stage.py +32 -13
  24. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_status_projection.py +87 -1
  25. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_status_schema.py +28 -19
  26. flare_kernel-0.2.2/src/flare_kernel/router/intent/compat_aliases.py +75 -0
  27. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intent/intent_escalation_override.py +11 -10
  28. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intent/intent_escalation_signal.py +29 -9
  29. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intent/session_intent_small_talk.py +6 -7
  30. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_constants_intake.py +0 -4
  31. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_constants_intent.py +2 -25
  32. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_endpoint_handlers_knowledge.py +3 -0
  33. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_facade_turn_context.py +2 -0
  34. flare_kernel-0.2.2/src/flare_kernel/router/next_actions_guard.py +26 -0
  35. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_builder.py +4 -1
  36. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_context.py +18 -0
  37. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_context_helpers.py +13 -2
  38. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_projection.py +16 -5
  39. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_result.py +13 -2
  40. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_state.py +2 -1
  41. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_state_flow.py +10 -5
  42. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_state_intent.py +17 -8
  43. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_state_payload.py +7 -2
  44. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/payload_enrichment.py +74 -0
  45. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/prompting.py +2 -0
  46. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/retrieval/retrieval_projection.py +1 -0
  47. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/retrieval/retrieval_search.py +2 -0
  48. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_draft_post_completion.py +15 -12
  49. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/turn_context_builder.py +5 -0
  50. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/domain/domain_pack_loader.py +1 -49
  51. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/infrastructure/infrastructure.py +108 -36
  52. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/intent/intent_and_escalation/decision.py +10 -11
  53. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/intent/intent_and_escalation/lexicon.py +5 -71
  54. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/intent/intent_and_escalation/signals.py +15 -14
  55. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/intent/intent_and_escalation_classifier.py +9 -8
  56. flare_kernel-0.2.2/src/flare_kernel/runtime/orchestration/canvas_sourcing_contract.py +19 -0
  57. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/orchestration/decision_engine.py +87 -62
  58. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/orchestration/mode_orchestration.py +503 -80
  59. flare_kernel-0.2.2/src/flare_kernel/runtime/orchestration/mode_runtime.py +220 -0
  60. flare_kernel-0.2.2/src/flare_kernel/runtime/orchestration/sourcing_event_payloads.py +186 -0
  61. flare_kernel-0.2.2/src/flare_kernel/runtime/reasoning/intake_reasoning_branching.py +184 -0
  62. flare_kernel-0.2.2/src/flare_kernel/runtime/reasoning/intake_reasoning_branching_policy.py +190 -0
  63. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/reasoning/intake_reasoning_context.py +41 -0
  64. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/reasoning/intake_reasoning_planning.py +224 -11
  65. flare_kernel-0.2.2/src/flare_kernel/runtime/reasoning/intake_reasoning_priority.py +127 -0
  66. flare_kernel-0.2.2/src/flare_kernel/runtime/reasoning/intake_reasoning_question_extraction.py +191 -0
  67. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/reasoning/intake_reasoning_readiness.py +79 -23
  68. flare_kernel-0.2.2/src/flare_kernel/runtime/reasoning/intake_reasoning_shared.py +189 -0
  69. flare_kernel-0.2.2/src/flare_kernel/runtime/tests/test_intake_reasoning.py +747 -0
  70. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/tests/test_kernel_runtime.py +254 -2
  71. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel.egg-info/PKG-INFO +6 -1
  72. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel.egg-info/SOURCES.txt +19 -0
  73. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_builder_split_modules.py +2 -0
  74. flare_kernel-0.2.2/tests/test_business_hardcode_guard.py +68 -0
  75. flare_kernel-0.2.2/tests/test_canonical_state_flow.py +145 -0
  76. flare_kernel-0.2.2/tests/test_canonical_state_payload.py +90 -0
  77. flare_kernel-0.2.2/tests/test_canvas_sourcing_contract_meta.py +36 -0
  78. flare_kernel-0.2.2/tests/test_compat_aliases.py +35 -0
  79. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_completion_response_builder.py +16 -0
  80. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_decision_engine.py +36 -7
  81. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_domain_pack_loader.py +1 -16
  82. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_endpoint_context.py +56 -0
  83. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_flare_v1_patch_contract.py +4 -8
  84. flare_kernel-0.2.2/tests/test_guided_completion.py +37 -0
  85. flare_kernel-0.2.2/tests/test_infrastructure_knowledge.py +181 -0
  86. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_authority_hydration.py +29 -1
  87. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_decision_rules.py +47 -10
  88. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_entry_policy.py +17 -0
  89. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_extraction_extractors.py +6 -0
  90. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_guided_open_fields.py +13 -0
  91. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_inputs.py +29 -0
  92. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_readiness.py +16 -0
  93. flare_kernel-0.2.2/tests/test_intake_reasoning_priority.py +109 -0
  94. flare_kernel-0.2.2/tests/test_intake_state_persistence.py +70 -0
  95. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_status_projection.py +83 -0
  96. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_status_schema.py +44 -13
  97. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intent_escalation_classifier.py +4 -4
  98. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intent_escalation_override.py +0 -1
  99. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intent_escalation_pipeline.py +1 -1
  100. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intent_escalation_signal.py +20 -0
  101. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intent_resolution.py +6 -8
  102. flare_kernel-0.2.2/tests/test_intent_type_compat_aliases.py +19 -0
  103. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_kernel_endpoint_handlers.py +23 -0
  104. flare_kernel-0.2.1/tests/test_turn_context_builder.py → flare_kernel-0.2.2/tests/test_kernel_facade_turn_context.py +21 -16
  105. flare_kernel-0.2.2/tests/test_mode_orchestration_state_bridge.py +83 -0
  106. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_mode_resolution.py +7 -7
  107. flare_kernel-0.2.2/tests/test_new_flow_guard.py +29 -0
  108. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_context.py +29 -0
  109. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_context_helpers.py +18 -0
  110. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_payload_enrichment.py +104 -0
  111. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_retrieval_projection.py +3 -1
  112. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_retrieval_search.py +21 -0
  113. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_session_intent_small_talk.py +12 -0
  114. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_draft_post_completion.py +63 -0
  115. flare_kernel-0.2.2/tests/test_turn_context_builder.py +116 -0
  116. flare_kernel-0.2.1/src/flare_kernel/router/guided_completion.py +0 -28
  117. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_open_fields.py +0 -25
  118. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_state_persistence.py +0 -45
  119. flare_kernel-0.2.1/src/flare_kernel/runtime/orchestration/mode_runtime.py +0 -462
  120. flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/intake_reasoning_shared.py +0 -105
  121. flare_kernel-0.2.1/src/flare_kernel/runtime/tests/test_intake_reasoning.py +0 -361
  122. flare_kernel-0.2.1/tests/test_canonical_state_flow.py +0 -62
  123. flare_kernel-0.2.1/tests/test_intake_state_persistence.py +0 -36
  124. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/setup.cfg +0 -0
  125. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/__init__.py +0 -0
  126. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/app.py +0 -0
  127. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/contracts/__init__.py +0 -0
  128. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/main.py +0 -0
  129. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/__init__.py +0 -0
  130. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/action_payload.py +0 -0
  131. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/canonical/__init__.py +0 -0
  132. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/canonical/canonical_state_analysis.py +0 -0
  133. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/canonical/canonical_state_builder.py +0 -0
  134. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/canonical/canonical_state_checkpoint.py +0 -0
  135. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/canonical/canonical_state_context.py +0 -0
  136. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/canonical/canonical_state_context_session.py +0 -0
  137. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/completion_selection.py +0 -0
  138. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/__init__.py +0 -0
  139. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_amount_quantity.py +0 -0
  140. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_answer.py +0 -0
  141. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_authority.py +0 -0
  142. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_authority_checkpoint.py +0 -0
  143. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_authority_session.py +0 -0
  144. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_canonicalization.py +0 -0
  145. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_clarification.py +0 -0
  146. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_deployment_delivery.py +0 -0
  147. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_extraction.py +0 -0
  148. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_extraction_merge.py +0 -0
  149. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_field_projection.py +0 -0
  150. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_field_projection_entity.py +0 -0
  151. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_field_projection_payload.py +0 -0
  152. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_field_projection_source.py +0 -0
  153. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_field_scope.py +0 -0
  154. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_guided_confirmed_updates.py +0 -0
  155. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_guided_flags.py +0 -0
  156. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_guided_followup.py +0 -0
  157. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_guided_followup_work_item.py +0 -0
  158. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_guided_status.py +0 -0
  159. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_guided_summary.py +0 -0
  160. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_node_state.py +0 -0
  161. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_numeric.py +0 -0
  162. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_status_guided_session.py +0 -0
  163. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intake/intake_workflow_checkpoint.py +0 -0
  164. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intent/__init__.py +0 -0
  165. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intent/intent_classifier_utils.py +0 -0
  166. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intent/intent_escalation_pipeline.py +0 -0
  167. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intent/intent_retrieval.py +0 -0
  168. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intent/intent_routing.py +0 -0
  169. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intent/session_intent.py +0 -0
  170. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/intent/session_intent_fields.py +0 -0
  171. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel.py +0 -0
  172. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_compat_exports.py +0 -0
  173. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_compat_exports_parts/__init__.py +0 -0
  174. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_compat_exports_parts/constants.py +0 -0
  175. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_compat_exports_parts/domain.py +0 -0
  176. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_compat_exports_parts/endpoint.py +0 -0
  177. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_compat_exports_parts/facade.py +0 -0
  178. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_compat_exports_parts/router_flow.py +0 -0
  179. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_compat_exports_parts/runtime.py +0 -0
  180. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_constants.py +0 -0
  181. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_constants_patch.py +0 -0
  182. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_endpoint_handlers.py +0 -0
  183. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_endpoint_handlers_health.py +0 -0
  184. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_endpoint_handlers_turn.py +0 -0
  185. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_facade_canonical_state.py +0 -0
  186. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_facade_canonical_wrapper.py +0 -0
  187. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_facade_dependency_resolution.py +0 -0
  188. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_facade_helpers.py +0 -0
  189. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_facade_orchestration.py +0 -0
  190. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_facade_orchestration_wrappers.py +0 -0
  191. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_facade_payload_enrichment.py +0 -0
  192. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_facade_payload_wrapper.py +0 -0
  193. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_facade_turn_context_wrapper.py +0 -0
  194. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_facade_utils.py +0 -0
  195. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_intent_query_flow.py +0 -0
  196. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_mode_flow.py +0 -0
  197. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_request_flow.py +0 -0
  198. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_route_action.py +0 -0
  199. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_route_execution.py +0 -0
  200. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_route_run.py +0 -0
  201. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_route_stream.py +0 -0
  202. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/kernel_session_intent_flow.py +0 -0
  203. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/mode_resolution.py +4 -4
  204. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/mode_switch.py +0 -0
  205. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/__init__.py +0 -0
  206. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_checkpoint_state.py +0 -0
  207. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_followup_state.py +0 -0
  208. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_decision.py +0 -0
  209. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_runtime_state.py +0 -0
  210. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_state_context.py +0 -0
  211. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_state_decision.py +0 -0
  212. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_state_entry.py +0 -0
  213. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_state_followup.py +0 -0
  214. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_state_node.py +0 -0
  215. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_status_state_unpack.py +0 -0
  216. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_trace.py +0 -0
  217. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_trace_projection.py +0 -0
  218. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/orchestration/orchestration_trace_steps.py +0 -0
  219. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/patch_contract.py +0 -0
  220. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/request_identity.py +0 -0
  221. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/request_intent_resolution.py +0 -0
  222. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/retrieval/__init__.py +0 -0
  223. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/retrieval/retrieval_aliases.py +0 -0
  224. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/retrieval/retrieval_field_queries.py +0 -0
  225. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/retrieval/retrieval_query_builder.py +0 -0
  226. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/__init__.py +0 -0
  227. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_draft_completion.py +0 -0
  228. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_draft_finalize.py +0 -0
  229. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_draft_phase.py +0 -0
  230. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_draft_phase_timing.py +0 -0
  231. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_draft_prologue.py +0 -0
  232. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_event_emitter.py +0 -0
  233. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_intake_phase.py +0 -0
  234. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_mode_event_payload.py +0 -0
  235. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_mode_events.py +0 -0
  236. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_response_bootstrap.py +0 -0
  237. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_response_builder.py +0 -0
  238. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_response_builder_transport.py +0 -0
  239. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_response_phases.py +0 -0
  240. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_response_runtime.py +0 -0
  241. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_retrieval_phase.py +0 -0
  242. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/streaming/streaming_runtime_steps.py +0 -0
  243. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/router/text_safety.py +0 -0
  244. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/__init__.py +0 -0
  245. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/domain/__init__.py +0 -0
  246. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/domain/profile_resolution.py +0 -0
  247. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/execution/__init__.py +0 -0
  248. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/execution/agent_runtime.py +0 -0
  249. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/execution/skill_runtime.py +0 -0
  250. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/infrastructure/__init__.py +0 -0
  251. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/infrastructure/logging.py +0 -0
  252. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/infrastructure/trace.py +0 -0
  253. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/intent/__init__.py +0 -0
  254. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/intent/intent_and_escalation/__init__.py +0 -0
  255. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/intent/intent_and_escalation/preprocessing.py +0 -0
  256. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/llm/__init__.py +0 -0
  257. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/llm/llm_provider.py +0 -0
  258. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/llm/model_router.py +0 -0
  259. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/orchestration/__init__.py +0 -0
  260. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/reasoning/__init__.py +0 -0
  261. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/reasoning/intake_reasoning.py +0 -0
  262. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/reasoning/intake_reasoning_hypothesis.py +0 -0
  263. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/session/__init__.py +0 -0
  264. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/session/checkpoint_manager.py +0 -0
  265. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/session/intake_session_store.py +0 -0
  266. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/session/models.py +0 -0
  267. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/tests/test_checkpoint_manager.py +0 -0
  268. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/tests/test_intake_reasoning_split.py +0 -0
  269. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel/runtime/tests/test_intake_session_store.py +0 -0
  270. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel.egg-info/dependency_links.txt +0 -0
  271. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel.egg-info/requires.txt +0 -0
  272. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/src/flare_kernel.egg-info/top_level.txt +0 -0
  273. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_action_payload.py +0 -0
  274. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_basics.py +0 -0
  275. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_canonical_state_context_analysis.py +0 -0
  276. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_canonical_state_context_inputs.py +0 -0
  277. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_canonical_state_context_session.py +0 -0
  278. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_canonical_state_projection.py +0 -0
  279. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_completion_selection.py +0 -0
  280. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_infrastructure_helpers.py +0 -0
  281. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_amount_quantity.py +0 -0
  282. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_answer.py +0 -0
  283. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_authority.py +0 -0
  284. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_authority_checkpoint.py +0 -0
  285. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_authority_session.py +0 -0
  286. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_canonicalization.py +0 -0
  287. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_clarification.py +0 -0
  288. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_deployment_delivery.py +0 -0
  289. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_extraction.py +0 -0
  290. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_extraction_merge.py +0 -0
  291. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_field_projection.py +0 -0
  292. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_field_projection_entity.py +0 -0
  293. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_field_projection_payload.py +0 -0
  294. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_field_projection_source.py +0 -0
  295. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_field_scope.py +0 -0
  296. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_guided_confirmed_updates.py +0 -0
  297. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_guided_flags.py +0 -0
  298. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_guided_followup.py +0 -0
  299. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_guided_followup_work_item.py +0 -0
  300. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_guided_status.py +0 -0
  301. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_guided_summary.py +0 -0
  302. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_node_state.py +0 -0
  303. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_numeric.py +0 -0
  304. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_payload_updates.py +0 -0
  305. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_status.py +0 -0
  306. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_status_guided_session.py +0 -0
  307. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_status_stage.py +0 -0
  308. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intake_workflow_checkpoint.py +0 -0
  309. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intent_classifier_utils.py +0 -0
  310. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intent_retrieval.py +0 -0
  311. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_intent_routing.py +0 -0
  312. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_kernel_alias_delegation.py +0 -0
  313. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_kernel_facade_helpers.py +0 -0
  314. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_kernel_intent_query_flow.py +0 -0
  315. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_kernel_mode_flow.py +0 -0
  316. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_kernel_route_execution_wrappers.py +0 -0
  317. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_kernel_session_intent_flow.py +0 -0
  318. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_llm_provider.py +0 -0
  319. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_mode_switch.py +0 -0
  320. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_model_router.py +0 -0
  321. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_checkpoint_state.py +0 -0
  322. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_followup_state.py +0 -0
  323. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_decision.py +0 -0
  324. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_projection.py +0 -0
  325. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_result.py +0 -0
  326. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_runtime_state.py +0 -0
  327. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_state_context.py +0 -0
  328. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_state_decision.py +0 -0
  329. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_state_entry.py +0 -0
  330. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_state_followup.py +0 -0
  331. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_state_intent.py +0 -0
  332. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_state_node.py +0 -0
  333. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_state_payload.py +0 -0
  334. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_status_state_unpack.py +0 -0
  335. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_trace.py +0 -0
  336. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_trace_projection.py +0 -0
  337. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_orchestration_trace_steps.py +0 -0
  338. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_patch_contract.py +0 -0
  339. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_request_identity.py +0 -0
  340. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_request_intent_resolution.py +0 -0
  341. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_retrieval_aliases.py +0 -0
  342. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_retrieval_field_queries.py +0 -0
  343. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_retrieval_query_builder.py +0 -0
  344. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_session_intent.py +0 -0
  345. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_session_intent_fields.py +0 -0
  346. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_draft_completion.py +0 -0
  347. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_draft_finalize.py +0 -0
  348. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_draft_phase.py +0 -0
  349. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_draft_prologue.py +0 -0
  350. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_event_emitter.py +0 -0
  351. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_intake_phase.py +0 -0
  352. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_mode_event_payload.py +0 -0
  353. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_mode_events.py +0 -0
  354. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_response_bootstrap.py +0 -0
  355. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_response_phases.py +0 -0
  356. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_response_runtime.py +0 -0
  357. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_retrieval_phase.py +0 -0
  358. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_streaming_runtime_steps.py +0 -0
  359. {flare_kernel-0.2.1 → flare_kernel-0.2.2}/tests/test_text_safety.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flare-kernel
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: FLARE kernel runtime package
5
5
  License: Proprietary
6
6
  Classifier: Development Status :: 3 - Alpha
@@ -22,6 +22,11 @@ Requires-Dist: qdrant-client<2,>=1.9
22
22
 
23
23
  通用编排与执行内核。
24
24
 
25
+ 边界文档:
26
+
27
+ 1. `packages/flare-kernel/docs/KERNEL-BOUNDARY.md`
28
+ 2. `docs/contracts/agent-contract-v1.md`
29
+
25
30
  职责:
26
31
 
27
32
  1. Decision 路由与策略入口。
@@ -2,6 +2,11 @@
2
2
 
3
3
  通用编排与执行内核。
4
4
 
5
+ 边界文档:
6
+
7
+ 1. `packages/flare-kernel/docs/KERNEL-BOUNDARY.md`
8
+ 2. `docs/contracts/agent-contract-v1.md`
9
+
5
10
  职责:
6
11
 
7
12
  1. Decision 路由与策略入口。
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "flare-kernel"
7
- version = "0.2.1"
7
+ version = "0.2.2"
8
8
  description = "FLARE kernel runtime package"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -108,6 +108,9 @@ class KnowledgeIngestResponse(BaseModel):
108
108
  chunk_count: int
109
109
  status: Literal["stored", "partial", "failed"]
110
110
  details: dict[str, Any] = Field(default_factory=dict)
111
+ source_id: str | None = None
112
+ error_code: str | None = None
113
+ error_message: str | None = None
111
114
 
112
115
 
113
116
  class KnowledgeSearchRequest(BaseModel):
@@ -13,6 +13,12 @@ from flare_kernel.router.canonical.canonical_state_projection import (
13
13
  build_next_actions_projection,
14
14
  resolve_analysis_readiness_metrics,
15
15
  )
16
+ from flare_kernel.router.intent.compat_aliases import (
17
+ project_compat_intent_type,
18
+ project_domain_relevance,
19
+ resolve_domain_intent_type,
20
+ resolve_domain_relevance,
21
+ )
16
22
 
17
23
 
18
24
  def build_canonical_state_context_output(
@@ -109,6 +115,8 @@ def build_canonical_state_context_output(
109
115
  if isinstance(context_inputs.get("planner"), dict)
110
116
  else {}
111
117
  )
118
+ domain_relevance = resolve_domain_relevance(context_inputs)
119
+ intent_type_domain = resolve_domain_intent_type(context_inputs, default="qa_only")
112
120
  return {
113
121
  "active_fields": active_fields,
114
122
  "analysis_assumptions": analysis_assumptions,
@@ -131,11 +139,11 @@ def build_canonical_state_context_output(
131
139
  "intake_session_completed": bool(context_session["intake_session_completed"]),
132
140
  "intake_session_id": context_session["intake_session_id"],
133
141
  "intake_session_state": context_session["intake_session_state"],
134
- "intent_type": str(context_inputs["intent_type"] or ""),
142
+ **project_compat_intent_type(intent_type_domain),
135
143
  "missing_key_fields": list(context_inputs["missing_key_fields"]),
136
144
  "next_actions": next_actions,
137
145
  "planner": planner,
138
- "procurement_relevance": bool(context_inputs["procurement_relevance"]),
146
+ **project_domain_relevance(domain_relevance),
139
147
  "recommended_next_step": str(context_inputs["recommended_next_step"] or ""),
140
148
  "required_coverage": required_coverage,
141
149
  "required_missing": list(context_inputs["required_missing"]),
@@ -7,6 +7,12 @@ from typing import Any, Callable
7
7
  from flare_kernel.router.canonical.canonical_state_projection import (
8
8
  collect_confirmed_field_values,
9
9
  )
10
+ from flare_kernel.router.intent.compat_aliases import (
11
+ project_compat_intent_type,
12
+ project_domain_relevance,
13
+ resolve_domain_intent_type,
14
+ resolve_domain_relevance,
15
+ )
10
16
 
11
17
 
12
18
  def resolve_canonical_state_context_inputs(
@@ -38,15 +44,17 @@ def resolve_canonical_state_context_inputs(
38
44
  orchestration_status=orchestration_status,
39
45
  is_field_entity_confirmed_fn=is_field_entity_confirmed_fn,
40
46
  )
41
- procurement_relevance = bool(
42
- orchestration_status.get("procurement_relevance")
43
- or str(resolved_intent or "").strip() in {"requirement_canvas", "intelligent_sourcing"}
44
- or str(resolved_mode or "").strip() in {"requirement_canvas", "intelligent_sourcing"}
47
+ domain_relevance = resolve_domain_relevance(
48
+ orchestration_status,
49
+ default=(
50
+ str(resolved_intent or "").strip() in {"requirement_canvas", "intelligent_sourcing"}
51
+ or str(resolved_mode or "").strip() in {"requirement_canvas", "intelligent_sourcing"}
52
+ ),
53
+ )
54
+ intent_type_domain = resolve_domain_intent_type(
55
+ orchestration_status,
56
+ default=("qa_only" if not domain_relevance else "domain_requirement_intake"),
45
57
  )
46
- intent_type = str(
47
- orchestration_status.get("intent_type")
48
- or ("qa_only" if not procurement_relevance else "procurement_requirement_intake")
49
- ).strip()
50
58
  escalation_target = str(orchestration_status.get("escalation_target") or "").strip()
51
59
  intake_candidate = bool(orchestration_status.get("intake_candidate"))
52
60
  clarification_recommended = bool(orchestration_status.get("clarification_recommended"))
@@ -99,11 +107,11 @@ def resolve_canonical_state_context_inputs(
99
107
  "fields": fields,
100
108
  "inferred_stage": inferred_stage,
101
109
  "intake_candidate": intake_candidate,
102
- "intent_type": intent_type,
110
+ **project_compat_intent_type(intent_type_domain),
103
111
  "hypotheses": hypotheses,
104
112
  "missing_key_fields": missing_key_fields,
105
113
  "planner": planner,
106
- "procurement_relevance": procurement_relevance,
114
+ **project_domain_relevance(domain_relevance),
107
115
  "recommended_next_step": recommended_next_step,
108
116
  "required_missing": required_missing,
109
117
  }
@@ -2,9 +2,82 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import re
5
6
  from typing import Any, Callable
6
7
 
7
8
 
9
+ _OPTION_LINE_PREFIX_RE = re.compile(r"^\s*(?:[-*•]|\d+[\.\))])\s*")
10
+
11
+
12
+ def _normalize_option_text(value: str) -> str:
13
+ text = str(value or "").strip()
14
+ if not text:
15
+ return ""
16
+ text = _OPTION_LINE_PREFIX_RE.sub("", text)
17
+ text = text.lstrip("→> ")
18
+ text = re.sub(r"`+", "", text)
19
+ text = re.sub(r"\*\*|__", "", text)
20
+ text = text.strip(" \t-::,,。!?!?")
21
+ if not text:
22
+ return ""
23
+ parts = re.split(r"[::((\-]", text, maxsplit=1)
24
+ head = str(parts[0] if parts else text).strip()
25
+ if not head:
26
+ return ""
27
+ return head[:30]
28
+
29
+
30
+ def _extract_question_options_from_assistant_text(
31
+ *,
32
+ assistant_text: str,
33
+ field_key: str,
34
+ max_options: int = 3,
35
+ ) -> list[str]:
36
+ raw_text = str(assistant_text or "").strip()
37
+ if not raw_text:
38
+ return []
39
+ normalized_field = str(field_key or "").strip().lower()
40
+ field_hints = {
41
+ "goal": ("目标", "结果", "价值", "成功"),
42
+ "scope": ("范围", "边界", "模块", "系统"),
43
+ "constraints": ("时间", "预算", "合规", "技术", "资源", "限制", "许可", "标准"),
44
+ "parameters": ("数量", "配置", "规格", "性能", "参数", "预算", "许可", "版本", "协议", "兼容"),
45
+ }.get(normalized_field, ())
46
+ lines = [str(item or "").strip() for item in raw_text.splitlines()]
47
+
48
+ def _collect_candidates(*, apply_field_hints: bool) -> list[str]:
49
+ candidates: list[str] = []
50
+ seen: set[str] = set()
51
+ for line in lines:
52
+ if not line:
53
+ continue
54
+ if not (
55
+ _OPTION_LINE_PREFIX_RE.match(line)
56
+ or line.startswith("→")
57
+ or line.startswith("•")
58
+ ):
59
+ continue
60
+ normalized = _normalize_option_text(line)
61
+ if len(normalized) < 2:
62
+ continue
63
+ if any(token in normalized for token in ("例如", "比如", "请", "说明", "描述")):
64
+ continue
65
+ if apply_field_hints and field_hints and not any(hint in normalized for hint in field_hints):
66
+ continue
67
+ if normalized in seen:
68
+ continue
69
+ seen.add(normalized)
70
+ candidates.append(normalized)
71
+ if len(candidates) >= max_options:
72
+ break
73
+ return candidates
74
+
75
+ with_hints = _collect_candidates(apply_field_hints=True)
76
+ if with_hints:
77
+ return with_hints
78
+ return _collect_candidates(apply_field_hints=False)
79
+
80
+
8
81
  def resolve_flow_activation(
9
82
  *,
10
83
  command: str,
@@ -25,7 +98,14 @@ def resolve_flow_activation(
25
98
  "activate_requirement_intake",
26
99
  "submit_intake_answer",
27
100
  "generate_analysis",
28
- } or mode_source in {"intent_override", "active_intake", "intent_and_escalation_classifier"}
101
+ } or mode_source in {
102
+ "intent_override",
103
+ "active_intake",
104
+ "intent_and_escalation_classifier",
105
+ "manual_hint",
106
+ "current_hint",
107
+ "command",
108
+ }
29
109
  should_activate_requirement_flow = bool(
30
110
  (
31
111
  external_mode == "requirement_intake"
@@ -95,11 +175,40 @@ def normalize_stage_status_and_question(
95
175
  resolved_question = None
96
176
  if status_key in {"collecting", "blocked"}:
97
177
  status_key = "idle"
98
- elif isinstance(resolved_question, dict) and intake_session_id:
178
+ elif (
179
+ resolved_question is None
180
+ and required_missing
181
+ and stage_key == "requirement_intake"
182
+ and status_key in {"collecting", "blocked"}
183
+ ):
184
+ primary_field_key = str(required_missing[0] or "").strip()
185
+ if primary_field_key:
186
+ resolved_question = {
187
+ "field_key": primary_field_key,
188
+ "field_label": primary_field_key,
189
+ "question_text": f"请补充「{primary_field_key}」相关信息",
190
+ "options": [],
191
+ "step_index": 1,
192
+ "step_total": len(required_missing),
193
+ }
194
+ if isinstance(resolved_question, dict) and intake_session_id:
99
195
  resolved_question = {
100
196
  **resolved_question,
101
197
  "intake_session_id": intake_session_id,
102
198
  }
199
+ if isinstance(resolved_question, dict):
200
+ existing_options = resolved_question.get("options")
201
+ has_options = isinstance(existing_options, list) and any(str(item).strip() for item in existing_options)
202
+ if not has_options and stage_key == "requirement_intake" and status_key in {"collecting", "blocked"}:
203
+ extracted_options = _extract_question_options_from_assistant_text(
204
+ assistant_text=assistant_text,
205
+ field_key=str(resolved_question.get("field_key") or "").strip(),
206
+ )
207
+ if extracted_options:
208
+ resolved_question = {
209
+ **resolved_question,
210
+ "options": extracted_options,
211
+ }
103
212
  return stage_key, status_key, resolved_question
104
213
 
105
214
 
@@ -5,6 +5,15 @@ from __future__ import annotations
5
5
  from typing import Any, Callable
6
6
 
7
7
  from flare_kernel.contracts import KernelRequest
8
+ from flare_kernel.router.intake.intake_status_projection import (
9
+ build_round_projection,
10
+ )
11
+ from flare_kernel.router.intent.compat_aliases import (
12
+ project_compat_intent_type,
13
+ project_domain_relevance,
14
+ resolve_domain_intent_type,
15
+ resolve_domain_relevance,
16
+ )
8
17
 
9
18
 
10
19
  def build_canonical_payload(
@@ -30,6 +39,56 @@ def build_canonical_payload(
30
39
  can_generate = bool(canonical_context.get("can_generate"))
31
40
  explicit_activation = bool(canonical_context.get("explicit_activation"))
32
41
  activated_mode = str(canonical_context.get("activated_mode") or "auto").strip() or "auto"
42
+ stage_key = str(canonical_context.get("stage_key") or "").strip()
43
+ status_key = str(canonical_context.get("status_key") or "").strip()
44
+ current_question = canonical_context.get("current_question") if isinstance(canonical_context.get("current_question"), dict) else None
45
+ next_actions = canonical_context.get("next_actions") if isinstance(canonical_context.get("next_actions"), list) else []
46
+ question_field_key = str((current_question or {}).get("field_key") or "").strip()
47
+ primary_missing_field = str((required_missing[0] if required_missing else "") or "").strip()
48
+ chooser_kind = "none"
49
+ chooser_visible = False
50
+ if activated_mode != "auto":
51
+ if (
52
+ stage_key == "requirement_intake"
53
+ and isinstance(current_question, dict)
54
+ ):
55
+ chooser_kind = "question"
56
+ chooser_visible = True
57
+ elif stage_key == "requirement_intake" and status_key == "ready_for_submit":
58
+ chooser_kind = "decision_point"
59
+ chooser_visible = True
60
+ elif (
61
+ stage_key == "requirement_intake"
62
+ and status_key in {"collecting", "blocked"}
63
+ and bool(required_missing)
64
+ ):
65
+ chooser_kind = "question"
66
+ chooser_visible = True
67
+ chooser_state = {
68
+ "kind": chooser_kind,
69
+ "visible": chooser_visible,
70
+ "requires_explicit_user_action": chooser_visible,
71
+ "source": "authoritative",
72
+ "current_field_key": question_field_key or primary_missing_field,
73
+ "blocking_fields": [str(item) for item in required_missing if str(item).strip()],
74
+ "next_action_keys": [
75
+ str(item.get("action_key") or item.get("type") or "").strip()
76
+ for item in next_actions
77
+ if isinstance(item, dict)
78
+ and str(item.get("action_key") or item.get("type") or "").strip()
79
+ ],
80
+ }
81
+ round_projection = build_round_projection(
82
+ intake_session_id=intake_session_id,
83
+ stage_key=stage_key,
84
+ status_key=status_key,
85
+ intake_session_state=intake_session_state,
86
+ current_question=current_question,
87
+ checkpoint=canonical_context.get("checkpoint") if isinstance(canonical_context.get("checkpoint"), dict) else {},
88
+ next_actions=next_actions,
89
+ )
90
+ domain_relevance = resolve_domain_relevance(canonical_context)
91
+ intent_type_domain = resolve_domain_intent_type(canonical_context, default="qa_only")
33
92
 
34
93
  return {
35
94
  "contract_version": str(req.contract_version or "flare.v1"),
@@ -51,21 +110,23 @@ def build_canonical_payload(
51
110
  "is_activation_explicit": explicit_activation and activated_mode != "auto",
52
111
  "activation_source": mode_source if explicit_activation else "none",
53
112
  },
54
- "stage": str(canonical_context.get("stage_key") or ""),
55
- "status": str(canonical_context.get("status_key") or ""),
113
+ "stage": stage_key,
114
+ "status": status_key,
115
+ "chooser_state": chooser_state,
56
116
  "intake_session_id": intake_session_id,
57
117
  "intake_session_state": intake_session_state,
58
118
  "intake_session_completed": intake_session_completed,
59
119
  "checkpoint": canonical_context.get("checkpoint"),
120
+ **round_projection,
60
121
  },
61
122
  "checkpoint": canonical_context.get("checkpoint"),
62
123
  "intent_state": {
63
- "intent_type": str(canonical_context.get("intent_type") or ""),
124
+ **project_compat_intent_type(intent_type_domain),
64
125
  "session_intent_stage": str(canonical_context.get("session_intent_stage") or ""),
65
126
  "conversation_intent_state": str(canonical_context.get("conversation_intent_state") or ""),
66
- "procurement_relevance": bool(canonical_context.get("procurement_relevance")),
127
+ **project_domain_relevance(domain_relevance),
67
128
  "escalation_target": str(canonical_context.get("escalation_target") or "")
68
- or ("qa_only" if not bool(canonical_context.get("procurement_relevance")) else "intake_candidate"),
129
+ or ("qa_only" if not domain_relevance else "intake_candidate"),
69
130
  "intake_candidate": bool(canonical_context.get("intake_candidate")),
70
131
  "clarification_recommended": bool(canonical_context.get("clarification_recommended")),
71
132
  "analysis_ready": bool(canonical_context.get("analysis_ready")),
@@ -79,12 +140,10 @@ def build_canonical_payload(
79
140
  canonical_context.get("resolved_intent_escalation_policy_source") or "default"
80
141
  ),
81
142
  },
82
- "question": canonical_context.get("current_question"),
143
+ "question": current_question,
83
144
  "confirmed_fields": build_confirmed_fields_schema_fn(fields, field_entities),
84
145
  "missing_fields": build_missing_fields_schema_fn([str(item) for item in required_missing if str(item).strip()]),
85
- "next_actions": canonical_context.get("next_actions")
86
- if isinstance(canonical_context.get("next_actions"), list)
87
- else [],
146
+ "next_actions": next_actions,
88
147
  "analysis": {
89
148
  "readiness": {
90
149
  "can_generate": can_generate,
@@ -10,6 +10,7 @@ from flare_kernel.router.canonical.canonical_state_analysis import (
10
10
  from flare_kernel.router.canonical.canonical_state_checkpoint import (
11
11
  build_checkpoint_projection,
12
12
  )
13
+ from flare_kernel.router.next_actions_guard import dedupe_next_actions_by_action_key
13
14
 
14
15
 
15
16
  def normalize_retrieved_knowledge(
@@ -72,7 +73,7 @@ def build_next_actions_projection(
72
73
  if isinstance(orchestration_status.get("next_actions"), list)
73
74
  else []
74
75
  )
75
- for action in raw_actions:
76
+ for action in dedupe_next_actions_by_action_key(raw_actions):
76
77
  if not isinstance(action, dict):
77
78
  continue
78
79
  action_key = str(action.get("action_key") or action.get("type") or "").strip()
@@ -5,6 +5,7 @@ from __future__ import annotations
5
5
  from typing import Any, Callable
6
6
 
7
7
  from flare_kernel.contracts import KernelResponse
8
+ from flare_kernel.router.next_actions_guard import dedupe_next_actions_by_action_key
8
9
 
9
10
 
10
11
  def apply_completion_content_policy(
@@ -36,6 +37,9 @@ def build_run_result_payload(
36
37
  mode_switch_reason: dict[str, Any],
37
38
  build_knowledge_citations_fn: Callable[[list[dict[str, Any]]], list[dict[str, Any]]],
38
39
  ) -> dict[str, Any]:
40
+ next_actions = dedupe_next_actions_by_action_key(
41
+ orchestration_status.get("next_actions", runtime_snapshot["next_actions"])
42
+ )
39
43
  return {
40
44
  "message": content_text,
41
45
  "provider": completion_provider,
@@ -59,7 +63,7 @@ def build_run_result_payload(
59
63
  },
60
64
  },
61
65
  "mode_events": runtime_snapshot["mode_events"],
62
- "next_actions": orchestration_status.get("next_actions", runtime_snapshot["next_actions"]),
66
+ "next_actions": next_actions,
63
67
  "retrieved_knowledge": structured_retrieved_knowledge,
64
68
  "knowledge_citation": build_knowledge_citations_fn(structured_retrieved_knowledge),
65
69
  "orchestration_status": orchestration_status,
@@ -80,6 +84,9 @@ def build_action_result_payload(
80
84
  action_status: str | None,
81
85
  action_reason: str | None,
82
86
  ) -> dict[str, Any]:
87
+ next_actions = dedupe_next_actions_by_action_key(
88
+ orchestration_status.get("next_actions", runtime_snapshot["next_actions"])
89
+ )
83
90
  return {
84
91
  "message": content_text,
85
92
  "provider": completion_provider,
@@ -102,7 +109,7 @@ def build_action_result_payload(
102
109
  },
103
110
  },
104
111
  "mode_events": runtime_snapshot["mode_events"],
105
- "next_actions": orchestration_status.get("next_actions", runtime_snapshot["next_actions"]),
112
+ "next_actions": next_actions,
106
113
  "orchestration_status": orchestration_status,
107
114
  "selected_action": {
108
115
  "action_key": action_key,
@@ -120,10 +127,13 @@ def build_kernel_success_response(
120
127
  runtime_snapshot: dict[str, Any],
121
128
  orchestration_status: dict[str, Any],
122
129
  ) -> KernelResponse:
130
+ next_actions = dedupe_next_actions_by_action_key(
131
+ orchestration_status.get("next_actions", runtime_snapshot["next_actions"])
132
+ )
123
133
  return KernelResponse(
124
134
  trace_id=trace_id,
125
135
  state="SUCCEEDED",
126
136
  events=[],
127
137
  result=result,
128
- next_actions=orchestration_status.get("next_actions", runtime_snapshot["next_actions"]),
138
+ next_actions=next_actions,
129
139
  )
@@ -7,6 +7,36 @@ from typing import Any, Callable
7
7
  from flare_kernel.contracts import KernelRequest
8
8
 
9
9
 
10
+ def _normalize_plan_action_command(*, action_command: str, action_key: str | None) -> str:
11
+ if isinstance(action_key, str) and action_key.strip():
12
+ return action_key.strip()
13
+ normalized = str(action_command or "").strip()
14
+ if normalized in {"", "send_message", "apply_field_candidate"}:
15
+ return ""
16
+ return normalized
17
+
18
+
19
+ def _sanitize_plan_mode_action_payload(
20
+ *,
21
+ payload: dict[str, Any],
22
+ target_mode: str,
23
+ action_command: str,
24
+ action_key: str | None,
25
+ ) -> dict[str, Any]:
26
+ if str(target_mode or "").strip() != "plan_mode":
27
+ return dict(payload)
28
+
29
+ normalized = _normalize_plan_action_command(action_command=action_command, action_key=action_key)
30
+ sanitized = dict(payload)
31
+ for key in ("command", "action_key", "selected_action_key", "next_action"):
32
+ sanitized.pop(key, None)
33
+ if normalized:
34
+ sanitized["action_command"] = normalized
35
+ else:
36
+ sanitized.pop("action_command", None)
37
+ return sanitized
38
+
39
+
10
40
  def unpack_kernel_turn_context(turn: dict[str, Any]) -> dict[str, Any]:
11
41
  return {
12
42
  "trace_id": str(turn["trace_id"]),
@@ -61,6 +91,12 @@ def prepare_action_turn_context(
61
91
  action_command = resolve_command_fn(req)
62
92
  action_target_mode = resolve_action_target_mode_fn(req)
63
93
  action_payload = build_action_payload_fn(req, action_target_mode)
94
+ action_payload = _sanitize_plan_mode_action_payload(
95
+ payload=action_payload,
96
+ target_mode=action_target_mode,
97
+ action_command=action_command,
98
+ action_key=req.action_key if isinstance(req.action_key, str) else None,
99
+ )
64
100
  if isinstance(req.project_id, str) and req.project_id.strip():
65
101
  action_payload["project_id"] = req.project_id.strip()
66
102
  if isinstance(req.user_id, str) and req.user_id.strip():
@@ -73,6 +109,12 @@ def prepare_action_turn_context(
73
109
  resolved_mode=action_target_mode,
74
110
  retrieved_knowledge=[],
75
111
  )
112
+ action_payload = _sanitize_plan_mode_action_payload(
113
+ payload=action_payload,
114
+ target_mode=action_target_mode,
115
+ action_command=action_command,
116
+ action_key=req.action_key if isinstance(req.action_key, str) else None,
117
+ )
76
118
  runtime_snapshot = build_kernel_runtime_fn(
77
119
  trace_id=trace_id,
78
120
  tenant_id=req.tenant_id,
@@ -0,0 +1,68 @@
1
+ """Guided-session completion helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from flare_kernel.contracts import KernelRequest
8
+ from flare_kernel.runtime.llm.llm_provider import LLMCompletion
9
+
10
+
11
+ def _is_collecting_question_phase(orchestration_status: dict[str, Any]) -> bool:
12
+ status = orchestration_status if isinstance(orchestration_status, dict) else {}
13
+ current_stage = str(status.get("current_stage") or "").strip().lower()
14
+ if not current_stage.startswith("requirement_intake"):
15
+ return False
16
+ chooser_state = status.get("chooser_state") if isinstance(status.get("chooser_state"), dict) else {}
17
+ chooser_kind = str(chooser_state.get("kind") or "").strip().lower()
18
+ has_current_question = isinstance(status.get("current_question"), dict)
19
+ if has_current_question:
20
+ return True
21
+ if chooser_kind == "question":
22
+ return True
23
+ if bool(status.get("has_active_question")):
24
+ return True
25
+ state = str(status.get("intake_session_state") or "").strip().lower()
26
+ if state in {"collecting", "blocked"}:
27
+ return True
28
+ return False
29
+
30
+
31
+ def resolve_guided_orchestrated_completion(
32
+ *,
33
+ req: KernelRequest,
34
+ command: str,
35
+ resolved_mode: str,
36
+ mode_source: str,
37
+ runtime_snapshot: dict[str, Any],
38
+ orchestration_status: dict[str, Any],
39
+ ) -> LLMCompletion | None:
40
+ _ = (req, mode_source, runtime_snapshot)
41
+ normalized_mode = str(resolved_mode or "").strip()
42
+ normalized_command = str(command or "").strip()
43
+ if normalized_mode != "requirement_canvas":
44
+ return None
45
+ if normalized_command not in {"send_message", "submit_intake_answer", "activate_requirement_intake"}:
46
+ return None
47
+ if not _is_collecting_question_phase(orchestration_status):
48
+ return None
49
+ _ = req
50
+ return LLMCompletion(
51
+ provider="kernel_guardrail",
52
+ model="guided_session",
53
+ content="",
54
+ status="orchestrated",
55
+ details={
56
+ "reason": "guided_session_patch_only",
57
+ "phase": "collecting_question",
58
+ "mode": normalized_mode,
59
+ "command": normalized_command,
60
+ },
61
+ )
62
+
63
+
64
+ def should_persist_memory_record(*, completion: LLMCompletion) -> bool:
65
+ details = completion.details if isinstance(completion.details, dict) else {}
66
+ if str(details.get("reason") or "").strip() == "guided_session_patch_only":
67
+ return False
68
+ return True
@@ -18,10 +18,20 @@ def hydrate_payload_from_authoritative_intake_session(
18
18
  persisted = dict(persisted_payload) if isinstance(persisted_payload, dict) else {}
19
19
  status = dict(persisted_status) if isinstance(persisted_status, dict) else {}
20
20
 
21
- if not merged.get("fields") and isinstance(persisted.get("fields"), dict):
22
- merged["fields"] = dict(persisted.get("fields"))
23
- if not merged.get("field_sources") and isinstance(persisted.get("field_sources"), dict):
24
- merged["field_sources"] = dict(persisted.get("field_sources"))
21
+ persisted_fields = persisted.get("fields") if isinstance(persisted.get("fields"), dict) else {}
22
+ incoming_fields = merged.get("fields") if isinstance(merged.get("fields"), dict) else {}
23
+ if persisted_fields or incoming_fields:
24
+ merged["fields"] = {
25
+ **dict(persisted_fields),
26
+ **dict(incoming_fields),
27
+ }
28
+ persisted_sources = persisted.get("field_sources") if isinstance(persisted.get("field_sources"), dict) else {}
29
+ incoming_sources = merged.get("field_sources") if isinstance(merged.get("field_sources"), dict) else {}
30
+ if persisted_sources or incoming_sources:
31
+ merged["field_sources"] = {
32
+ **dict(persisted_sources),
33
+ **dict(incoming_sources),
34
+ }
25
35
 
26
36
  for key in (
27
37
  "required_fields",