flare-kernel 0.1.0__tar.gz → 0.2.1__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 (345) hide show
  1. {flare_kernel-0.1.0 → flare_kernel-0.2.1}/PKG-INFO +37 -8
  2. {flare_kernel-0.1.0 → flare_kernel-0.2.1}/README.md +30 -6
  3. {flare_kernel-0.1.0 → flare_kernel-0.2.1}/pyproject.toml +7 -2
  4. flare_kernel-0.2.1/src/flare_kernel/contracts/__init__.py +23 -0
  5. flare_kernel-0.2.1/src/flare_kernel/contracts/kernel_contract.py +133 -0
  6. flare_kernel-0.2.1/src/flare_kernel/router/__init__.py +45 -0
  7. flare_kernel-0.2.1/src/flare_kernel/router/action_payload.py +148 -0
  8. flare_kernel-0.2.1/src/flare_kernel/router/canonical/__init__.py +1 -0
  9. flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_analysis.py +53 -0
  10. flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_builder.py +82 -0
  11. flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_checkpoint.py +102 -0
  12. flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_context.py +88 -0
  13. flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_context_analysis.py +151 -0
  14. flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_context_inputs.py +109 -0
  15. flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_context_session.py +90 -0
  16. flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_flow.py +149 -0
  17. flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_payload.py +131 -0
  18. flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_projection.py +136 -0
  19. flare_kernel-0.2.1/src/flare_kernel/router/completion_response_builder.py +129 -0
  20. flare_kernel-0.2.1/src/flare_kernel/router/completion_selection.py +55 -0
  21. flare_kernel-0.2.1/src/flare_kernel/router/endpoint_context.py +127 -0
  22. flare_kernel-0.2.1/src/flare_kernel/router/guided_completion.py +28 -0
  23. flare_kernel-0.2.1/src/flare_kernel/router/intake/__init__.py +1 -0
  24. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_amount_quantity.py +163 -0
  25. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_answer.py +42 -0
  26. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_authority.py +81 -0
  27. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_authority_checkpoint.py +58 -0
  28. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_authority_hydration.py +116 -0
  29. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_authority_session.py +70 -0
  30. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_canonicalization.py +119 -0
  31. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_clarification.py +122 -0
  32. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_decision_rules.py +123 -0
  33. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_deployment_delivery.py +120 -0
  34. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_entry_policy.py +142 -0
  35. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_extraction.py +84 -0
  36. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_extraction_extractors.py +164 -0
  37. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_extraction_merge.py +85 -0
  38. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_field_projection.py +78 -0
  39. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_field_projection_entity.py +107 -0
  40. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_field_projection_payload.py +89 -0
  41. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_field_projection_source.py +60 -0
  42. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_field_scope.py +40 -0
  43. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_confirmed_updates.py +21 -0
  44. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_flags.py +40 -0
  45. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_followup.py +154 -0
  46. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_followup_work_item.py +113 -0
  47. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_open_fields.py +25 -0
  48. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_status.py +84 -0
  49. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_summary.py +26 -0
  50. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_inputs.py +109 -0
  51. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_node_state.py +83 -0
  52. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_numeric.py +126 -0
  53. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_payload_updates.py +92 -0
  54. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_readiness.py +63 -0
  55. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_state_persistence.py +45 -0
  56. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_status.py +47 -0
  57. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_status_chooser_stage.py +121 -0
  58. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_status_guided_session.py +20 -0
  59. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_status_projection.py +156 -0
  60. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_status_schema.py +183 -0
  61. flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_workflow_checkpoint.py +183 -0
  62. flare_kernel-0.2.1/src/flare_kernel/router/intent/__init__.py +1 -0
  63. flare_kernel-0.2.1/src/flare_kernel/router/intent/intent_classifier_utils.py +72 -0
  64. flare_kernel-0.2.1/src/flare_kernel/router/intent/intent_escalation_override.py +82 -0
  65. flare_kernel-0.2.1/src/flare_kernel/router/intent/intent_escalation_pipeline.py +95 -0
  66. flare_kernel-0.2.1/src/flare_kernel/router/intent/intent_escalation_signal.py +145 -0
  67. flare_kernel-0.2.1/src/flare_kernel/router/intent/intent_retrieval.py +101 -0
  68. flare_kernel-0.2.1/src/flare_kernel/router/intent/intent_routing.py +146 -0
  69. flare_kernel-0.2.1/src/flare_kernel/router/intent/session_intent.py +133 -0
  70. flare_kernel-0.2.1/src/flare_kernel/router/intent/session_intent_fields.py +103 -0
  71. flare_kernel-0.2.1/src/flare_kernel/router/intent/session_intent_small_talk.py +132 -0
  72. flare_kernel-0.2.1/src/flare_kernel/router/kernel.py +122 -0
  73. flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports.py +18 -0
  74. flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/__init__.py +5 -0
  75. flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/constants.py +29 -0
  76. flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/domain.py +148 -0
  77. flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/endpoint.py +50 -0
  78. flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/facade.py +21 -0
  79. flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/router_flow.py +95 -0
  80. flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/runtime.py +30 -0
  81. flare_kernel-0.2.1/src/flare_kernel/router/kernel_constants.py +55 -0
  82. flare_kernel-0.2.1/src/flare_kernel/router/kernel_constants_intake.py +34 -0
  83. flare_kernel-0.2.1/src/flare_kernel/router/kernel_constants_intent.py +176 -0
  84. flare_kernel-0.2.1/src/flare_kernel/router/kernel_constants_patch.py +32 -0
  85. flare_kernel-0.2.1/src/flare_kernel/router/kernel_endpoint_handlers.py +29 -0
  86. flare_kernel-0.2.1/src/flare_kernel/router/kernel_endpoint_handlers_health.py +37 -0
  87. flare_kernel-0.2.1/src/flare_kernel/router/kernel_endpoint_handlers_knowledge.py +69 -0
  88. flare_kernel-0.2.1/src/flare_kernel/router/kernel_endpoint_handlers_turn.py +184 -0
  89. flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_canonical_state.py +82 -0
  90. flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_canonical_wrapper.py +133 -0
  91. flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_dependency_resolution.py +272 -0
  92. flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_helpers.py +30 -0
  93. flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_orchestration.py +119 -0
  94. flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_orchestration_wrappers.py +179 -0
  95. flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_payload_enrichment.py +75 -0
  96. flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_payload_wrapper.py +180 -0
  97. flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_turn_context.py +174 -0
  98. flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_turn_context_wrapper.py +161 -0
  99. flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_utils.py +36 -0
  100. flare_kernel-0.2.1/src/flare_kernel/router/kernel_intent_query_flow.py +193 -0
  101. flare_kernel-0.2.1/src/flare_kernel/router/kernel_mode_flow.py +90 -0
  102. flare_kernel-0.2.1/src/flare_kernel/router/kernel_request_flow.py +754 -0
  103. flare_kernel-0.2.1/src/flare_kernel/router/kernel_route_action.py +121 -0
  104. flare_kernel-0.2.1/src/flare_kernel/router/kernel_route_execution.py +115 -0
  105. flare_kernel-0.2.1/src/flare_kernel/router/kernel_route_run.py +183 -0
  106. flare_kernel-0.2.1/src/flare_kernel/router/kernel_route_stream.py +149 -0
  107. flare_kernel-0.2.1/src/flare_kernel/router/kernel_session_intent_flow.py +133 -0
  108. flare_kernel-0.2.1/src/flare_kernel/router/mode_resolution.py +196 -0
  109. flare_kernel-0.2.1/src/flare_kernel/router/mode_switch.py +52 -0
  110. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/__init__.py +1 -0
  111. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_checkpoint_state.py +93 -0
  112. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_followup_state.py +77 -0
  113. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_builder.py +113 -0
  114. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_context.py +129 -0
  115. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_context_helpers.py +179 -0
  116. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_decision.py +96 -0
  117. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_projection.py +177 -0
  118. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_result.py +86 -0
  119. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_runtime_state.py +10 -0
  120. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state.py +85 -0
  121. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_context.py +29 -0
  122. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_decision.py +54 -0
  123. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_entry.py +43 -0
  124. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_flow.py +243 -0
  125. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_followup.py +94 -0
  126. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_intent.py +41 -0
  127. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_node.py +60 -0
  128. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_payload.py +91 -0
  129. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_unpack.py +39 -0
  130. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_trace.py +132 -0
  131. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_trace_projection.py +83 -0
  132. flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_trace_steps.py +139 -0
  133. flare_kernel-0.2.1/src/flare_kernel/router/patch_contract.py +36 -0
  134. flare_kernel-0.2.1/src/flare_kernel/router/payload_enrichment.py +161 -0
  135. flare_kernel-0.2.1/src/flare_kernel/router/prompting.py +96 -0
  136. flare_kernel-0.2.1/src/flare_kernel/router/request_identity.py +23 -0
  137. flare_kernel-0.2.1/src/flare_kernel/router/request_intent_resolution.py +68 -0
  138. flare_kernel-0.2.1/src/flare_kernel/router/retrieval/__init__.py +1 -0
  139. flare_kernel-0.2.1/src/flare_kernel/router/retrieval/retrieval_aliases.py +99 -0
  140. flare_kernel-0.2.1/src/flare_kernel/router/retrieval/retrieval_field_queries.py +71 -0
  141. flare_kernel-0.2.1/src/flare_kernel/router/retrieval/retrieval_projection.py +68 -0
  142. flare_kernel-0.2.1/src/flare_kernel/router/retrieval/retrieval_query_builder.py +76 -0
  143. flare_kernel-0.2.1/src/flare_kernel/router/retrieval/retrieval_search.py +45 -0
  144. flare_kernel-0.2.1/src/flare_kernel/router/streaming/__init__.py +1 -0
  145. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_draft_completion.py +121 -0
  146. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_draft_finalize.py +168 -0
  147. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_draft_phase.py +163 -0
  148. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_draft_phase_timing.py +39 -0
  149. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_draft_post_completion.py +104 -0
  150. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_draft_prologue.py +54 -0
  151. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_event_emitter.py +138 -0
  152. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_intake_phase.py +104 -0
  153. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_mode_event_payload.py +78 -0
  154. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_mode_events.py +89 -0
  155. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_response_bootstrap.py +111 -0
  156. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_response_builder.py +155 -0
  157. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_response_builder_transport.py +44 -0
  158. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_response_phases.py +453 -0
  159. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_response_runtime.py +90 -0
  160. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_retrieval_phase.py +105 -0
  161. flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_runtime_steps.py +63 -0
  162. flare_kernel-0.2.1/src/flare_kernel/router/text_safety.py +94 -0
  163. flare_kernel-0.2.1/src/flare_kernel/router/turn_context_builder.py +166 -0
  164. flare_kernel-0.2.1/src/flare_kernel/runtime/__init__.py +152 -0
  165. flare_kernel-0.2.1/src/flare_kernel/runtime/domain/__init__.py +1 -0
  166. flare_kernel-0.2.1/src/flare_kernel/runtime/domain/domain_pack_loader.py +696 -0
  167. flare_kernel-0.2.1/src/flare_kernel/runtime/domain/profile_resolution.py +126 -0
  168. flare_kernel-0.2.1/src/flare_kernel/runtime/execution/__init__.py +1 -0
  169. {flare_kernel-0.1.0/src/flare_kernel/runtime → flare_kernel-0.2.1/src/flare_kernel/runtime/execution}/agent_runtime.py +38 -0
  170. {flare_kernel-0.1.0/src/flare_kernel/runtime → flare_kernel-0.2.1/src/flare_kernel/runtime/execution}/skill_runtime.py +34 -0
  171. flare_kernel-0.2.1/src/flare_kernel/runtime/infrastructure/__init__.py +1 -0
  172. flare_kernel-0.2.1/src/flare_kernel/runtime/infrastructure/infrastructure.py +523 -0
  173. flare_kernel-0.2.1/src/flare_kernel/runtime/intent/__init__.py +1 -0
  174. flare_kernel-0.2.1/src/flare_kernel/runtime/intent/intent_and_escalation/__init__.py +7 -0
  175. flare_kernel-0.2.1/src/flare_kernel/runtime/intent/intent_and_escalation/decision.py +117 -0
  176. flare_kernel-0.2.1/src/flare_kernel/runtime/intent/intent_and_escalation/lexicon.py +217 -0
  177. flare_kernel-0.2.1/src/flare_kernel/runtime/intent/intent_and_escalation/preprocessing.py +47 -0
  178. flare_kernel-0.2.1/src/flare_kernel/runtime/intent/intent_and_escalation/signals.py +172 -0
  179. flare_kernel-0.2.1/src/flare_kernel/runtime/intent/intent_and_escalation_classifier.py +81 -0
  180. flare_kernel-0.2.1/src/flare_kernel/runtime/llm/__init__.py +1 -0
  181. flare_kernel-0.2.1/src/flare_kernel/runtime/llm/llm_provider.py +410 -0
  182. flare_kernel-0.2.1/src/flare_kernel/runtime/llm/model_router.py +443 -0
  183. flare_kernel-0.2.1/src/flare_kernel/runtime/orchestration/__init__.py +1 -0
  184. flare_kernel-0.2.1/src/flare_kernel/runtime/orchestration/decision_engine.py +447 -0
  185. flare_kernel-0.2.1/src/flare_kernel/runtime/orchestration/mode_orchestration.py +1193 -0
  186. flare_kernel-0.2.1/src/flare_kernel/runtime/orchestration/mode_runtime.py +462 -0
  187. flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/__init__.py +1 -0
  188. flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/intake_reasoning.py +273 -0
  189. flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/intake_reasoning_context.py +215 -0
  190. flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/intake_reasoning_hypothesis.py +211 -0
  191. flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/intake_reasoning_planning.py +495 -0
  192. flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/intake_reasoning_readiness.py +372 -0
  193. flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/intake_reasoning_shared.py +105 -0
  194. flare_kernel-0.2.1/src/flare_kernel/runtime/session/__init__.py +25 -0
  195. flare_kernel-0.2.1/src/flare_kernel/runtime/session/checkpoint_manager.py +360 -0
  196. flare_kernel-0.2.1/src/flare_kernel/runtime/session/intake_session_store.py +363 -0
  197. flare_kernel-0.2.1/src/flare_kernel/runtime/session/models.py +40 -0
  198. flare_kernel-0.2.1/src/flare_kernel/runtime/tests/test_checkpoint_manager.py +118 -0
  199. flare_kernel-0.2.1/src/flare_kernel/runtime/tests/test_intake_reasoning.py +361 -0
  200. flare_kernel-0.2.1/src/flare_kernel/runtime/tests/test_intake_reasoning_split.py +87 -0
  201. flare_kernel-0.2.1/src/flare_kernel/runtime/tests/test_intake_session_store.py +98 -0
  202. flare_kernel-0.2.1/src/flare_kernel/runtime/tests/test_kernel_runtime.py +483 -0
  203. {flare_kernel-0.1.0 → flare_kernel-0.2.1}/src/flare_kernel.egg-info/PKG-INFO +37 -8
  204. flare_kernel-0.2.1/src/flare_kernel.egg-info/SOURCES.txt +330 -0
  205. flare_kernel-0.2.1/src/flare_kernel.egg-info/requires.txt +9 -0
  206. flare_kernel-0.2.1/tests/test_action_payload.py +70 -0
  207. flare_kernel-0.2.1/tests/test_basics.py +64 -0
  208. flare_kernel-0.2.1/tests/test_builder_split_modules.py +309 -0
  209. flare_kernel-0.2.1/tests/test_canonical_state_context_analysis.py +54 -0
  210. flare_kernel-0.2.1/tests/test_canonical_state_context_inputs.py +27 -0
  211. flare_kernel-0.2.1/tests/test_canonical_state_context_session.py +49 -0
  212. flare_kernel-0.2.1/tests/test_canonical_state_flow.py +62 -0
  213. flare_kernel-0.2.1/tests/test_canonical_state_projection.py +100 -0
  214. flare_kernel-0.2.1/tests/test_completion_response_builder.py +95 -0
  215. flare_kernel-0.2.1/tests/test_completion_selection.py +107 -0
  216. flare_kernel-0.2.1/tests/test_decision_engine.py +204 -0
  217. flare_kernel-0.2.1/tests/test_domain_pack_loader.py +168 -0
  218. flare_kernel-0.2.1/tests/test_endpoint_context.py +81 -0
  219. flare_kernel-0.2.1/tests/test_flare_v1_patch_contract.py +605 -0
  220. flare_kernel-0.2.1/tests/test_infrastructure_helpers.py +23 -0
  221. flare_kernel-0.2.1/tests/test_intake_amount_quantity.py +23 -0
  222. flare_kernel-0.2.1/tests/test_intake_answer.py +25 -0
  223. flare_kernel-0.2.1/tests/test_intake_authority.py +159 -0
  224. flare_kernel-0.2.1/tests/test_intake_authority_checkpoint.py +36 -0
  225. flare_kernel-0.2.1/tests/test_intake_authority_hydration.py +71 -0
  226. flare_kernel-0.2.1/tests/test_intake_authority_session.py +58 -0
  227. flare_kernel-0.2.1/tests/test_intake_canonicalization.py +44 -0
  228. flare_kernel-0.2.1/tests/test_intake_clarification.py +77 -0
  229. flare_kernel-0.2.1/tests/test_intake_decision_rules.py +81 -0
  230. flare_kernel-0.2.1/tests/test_intake_deployment_delivery.py +29 -0
  231. flare_kernel-0.2.1/tests/test_intake_entry_policy.py +56 -0
  232. flare_kernel-0.2.1/tests/test_intake_extraction.py +54 -0
  233. flare_kernel-0.2.1/tests/test_intake_extraction_extractors.py +29 -0
  234. flare_kernel-0.2.1/tests/test_intake_extraction_merge.py +36 -0
  235. flare_kernel-0.2.1/tests/test_intake_field_projection.py +69 -0
  236. flare_kernel-0.2.1/tests/test_intake_field_projection_entity.py +28 -0
  237. flare_kernel-0.2.1/tests/test_intake_field_projection_payload.py +18 -0
  238. flare_kernel-0.2.1/tests/test_intake_field_projection_source.py +29 -0
  239. flare_kernel-0.2.1/tests/test_intake_field_scope.py +20 -0
  240. flare_kernel-0.2.1/tests/test_intake_guided_confirmed_updates.py +18 -0
  241. flare_kernel-0.2.1/tests/test_intake_guided_flags.py +14 -0
  242. flare_kernel-0.2.1/tests/test_intake_guided_followup.py +185 -0
  243. flare_kernel-0.2.1/tests/test_intake_guided_followup_work_item.py +60 -0
  244. flare_kernel-0.2.1/tests/test_intake_guided_open_fields.py +14 -0
  245. flare_kernel-0.2.1/tests/test_intake_guided_status.py +23 -0
  246. flare_kernel-0.2.1/tests/test_intake_guided_summary.py +11 -0
  247. flare_kernel-0.2.1/tests/test_intake_inputs.py +56 -0
  248. flare_kernel-0.2.1/tests/test_intake_node_state.py +73 -0
  249. flare_kernel-0.2.1/tests/test_intake_numeric.py +26 -0
  250. flare_kernel-0.2.1/tests/test_intake_payload_updates.py +51 -0
  251. flare_kernel-0.2.1/tests/test_intake_readiness.py +58 -0
  252. flare_kernel-0.2.1/tests/test_intake_state_persistence.py +36 -0
  253. flare_kernel-0.2.1/tests/test_intake_status.py +303 -0
  254. flare_kernel-0.2.1/tests/test_intake_status_guided_session.py +95 -0
  255. flare_kernel-0.2.1/tests/test_intake_status_projection.py +143 -0
  256. flare_kernel-0.2.1/tests/test_intake_status_schema.py +160 -0
  257. flare_kernel-0.2.1/tests/test_intake_status_stage.py +64 -0
  258. flare_kernel-0.2.1/tests/test_intake_workflow_checkpoint.py +23 -0
  259. flare_kernel-0.2.1/tests/test_intent_classifier_utils.py +44 -0
  260. flare_kernel-0.2.1/tests/test_intent_escalation_classifier.py +444 -0
  261. flare_kernel-0.2.1/tests/test_intent_escalation_override.py +66 -0
  262. flare_kernel-0.2.1/tests/test_intent_escalation_pipeline.py +83 -0
  263. flare_kernel-0.2.1/tests/test_intent_escalation_signal.py +68 -0
  264. flare_kernel-0.2.1/tests/test_intent_resolution.py +1747 -0
  265. flare_kernel-0.2.1/tests/test_intent_retrieval.py +110 -0
  266. flare_kernel-0.2.1/tests/test_intent_routing.py +106 -0
  267. flare_kernel-0.2.1/tests/test_kernel_alias_delegation.py +22 -0
  268. flare_kernel-0.2.1/tests/test_kernel_endpoint_handlers.py +195 -0
  269. flare_kernel-0.2.1/tests/test_kernel_facade_helpers.py +20 -0
  270. flare_kernel-0.2.1/tests/test_kernel_intent_query_flow.py +60 -0
  271. flare_kernel-0.2.1/tests/test_kernel_mode_flow.py +63 -0
  272. flare_kernel-0.2.1/tests/test_kernel_route_execution_wrappers.py +97 -0
  273. flare_kernel-0.2.1/tests/test_kernel_session_intent_flow.py +40 -0
  274. flare_kernel-0.2.1/tests/test_llm_provider.py +227 -0
  275. flare_kernel-0.2.1/tests/test_mode_resolution.py +169 -0
  276. flare_kernel-0.2.1/tests/test_mode_switch.py +40 -0
  277. flare_kernel-0.2.1/tests/test_model_router.py +261 -0
  278. flare_kernel-0.2.1/tests/test_orchestration_checkpoint_state.py +30 -0
  279. flare_kernel-0.2.1/tests/test_orchestration_followup_state.py +26 -0
  280. flare_kernel-0.2.1/tests/test_orchestration_status_context.py +65 -0
  281. flare_kernel-0.2.1/tests/test_orchestration_status_context_helpers.py +39 -0
  282. flare_kernel-0.2.1/tests/test_orchestration_status_decision.py +71 -0
  283. flare_kernel-0.2.1/tests/test_orchestration_status_projection.py +240 -0
  284. flare_kernel-0.2.1/tests/test_orchestration_status_result.py +53 -0
  285. flare_kernel-0.2.1/tests/test_orchestration_status_runtime_state.py +53 -0
  286. flare_kernel-0.2.1/tests/test_orchestration_status_state_context.py +25 -0
  287. flare_kernel-0.2.1/tests/test_orchestration_status_state_decision.py +43 -0
  288. flare_kernel-0.2.1/tests/test_orchestration_status_state_entry.py +42 -0
  289. flare_kernel-0.2.1/tests/test_orchestration_status_state_followup.py +64 -0
  290. flare_kernel-0.2.1/tests/test_orchestration_status_state_intent.py +38 -0
  291. flare_kernel-0.2.1/tests/test_orchestration_status_state_node.py +53 -0
  292. flare_kernel-0.2.1/tests/test_orchestration_status_state_payload.py +54 -0
  293. flare_kernel-0.2.1/tests/test_orchestration_status_state_unpack.py +38 -0
  294. flare_kernel-0.2.1/tests/test_orchestration_trace.py +146 -0
  295. flare_kernel-0.2.1/tests/test_orchestration_trace_projection.py +17 -0
  296. flare_kernel-0.2.1/tests/test_orchestration_trace_steps.py +28 -0
  297. flare_kernel-0.2.1/tests/test_patch_contract.py +52 -0
  298. flare_kernel-0.2.1/tests/test_payload_enrichment.py +128 -0
  299. flare_kernel-0.2.1/tests/test_request_identity.py +24 -0
  300. flare_kernel-0.2.1/tests/test_request_intent_resolution.py +41 -0
  301. flare_kernel-0.2.1/tests/test_retrieval_aliases.py +71 -0
  302. flare_kernel-0.2.1/tests/test_retrieval_field_queries.py +25 -0
  303. flare_kernel-0.2.1/tests/test_retrieval_projection.py +61 -0
  304. flare_kernel-0.2.1/tests/test_retrieval_query_builder.py +48 -0
  305. flare_kernel-0.2.1/tests/test_retrieval_search.py +29 -0
  306. flare_kernel-0.2.1/tests/test_session_intent.py +98 -0
  307. flare_kernel-0.2.1/tests/test_session_intent_fields.py +67 -0
  308. flare_kernel-0.2.1/tests/test_session_intent_small_talk.py +31 -0
  309. flare_kernel-0.2.1/tests/test_streaming_draft_completion.py +101 -0
  310. flare_kernel-0.2.1/tests/test_streaming_draft_finalize.py +100 -0
  311. flare_kernel-0.2.1/tests/test_streaming_draft_phase.py +186 -0
  312. flare_kernel-0.2.1/tests/test_streaming_draft_post_completion.py +97 -0
  313. flare_kernel-0.2.1/tests/test_streaming_draft_prologue.py +45 -0
  314. flare_kernel-0.2.1/tests/test_streaming_event_emitter.py +72 -0
  315. flare_kernel-0.2.1/tests/test_streaming_intake_phase.py +83 -0
  316. flare_kernel-0.2.1/tests/test_streaming_mode_event_payload.py +85 -0
  317. flare_kernel-0.2.1/tests/test_streaming_mode_events.py +63 -0
  318. flare_kernel-0.2.1/tests/test_streaming_response_bootstrap.py +82 -0
  319. flare_kernel-0.2.1/tests/test_streaming_response_phases.py +168 -0
  320. flare_kernel-0.2.1/tests/test_streaming_response_runtime.py +83 -0
  321. flare_kernel-0.2.1/tests/test_streaming_retrieval_phase.py +69 -0
  322. flare_kernel-0.2.1/tests/test_streaming_runtime_steps.py +61 -0
  323. flare_kernel-0.2.1/tests/test_text_safety.py +34 -0
  324. flare_kernel-0.2.1/tests/test_turn_context_builder.py +55 -0
  325. flare_kernel-0.1.0/src/flare_kernel/contracts/__init__.py +0 -5
  326. flare_kernel-0.1.0/src/flare_kernel/contracts/kernel_contract.py +0 -36
  327. flare_kernel-0.1.0/src/flare_kernel/router/__init__.py +0 -5
  328. flare_kernel-0.1.0/src/flare_kernel/router/kernel.py +0 -342
  329. flare_kernel-0.1.0/src/flare_kernel/runtime/__init__.py +0 -26
  330. flare_kernel-0.1.0/src/flare_kernel/runtime/domain_pack_loader.py +0 -240
  331. flare_kernel-0.1.0/src/flare_kernel/runtime/llm_provider.py +0 -204
  332. flare_kernel-0.1.0/src/flare_kernel/runtime/mode_orchestration.py +0 -330
  333. flare_kernel-0.1.0/src/flare_kernel/runtime/mode_runtime.py +0 -262
  334. flare_kernel-0.1.0/src/flare_kernel/runtime/tests/test_kernel_runtime.py +0 -114
  335. flare_kernel-0.1.0/src/flare_kernel.egg-info/SOURCES.txt +0 -25
  336. flare_kernel-0.1.0/src/flare_kernel.egg-info/requires.txt +0 -4
  337. flare_kernel-0.1.0/tests/test_basics.py +0 -25
  338. {flare_kernel-0.1.0 → flare_kernel-0.2.1}/setup.cfg +0 -0
  339. {flare_kernel-0.1.0 → flare_kernel-0.2.1}/src/flare_kernel/__init__.py +0 -0
  340. {flare_kernel-0.1.0 → flare_kernel-0.2.1}/src/flare_kernel/app.py +0 -0
  341. {flare_kernel-0.1.0 → flare_kernel-0.2.1}/src/flare_kernel/main.py +0 -0
  342. {flare_kernel-0.1.0/src/flare_kernel/runtime → flare_kernel-0.2.1/src/flare_kernel/runtime/infrastructure}/logging.py +0 -0
  343. {flare_kernel-0.1.0/src/flare_kernel/runtime → flare_kernel-0.2.1/src/flare_kernel/runtime/infrastructure}/trace.py +0 -0
  344. {flare_kernel-0.1.0 → flare_kernel-0.2.1}/src/flare_kernel.egg-info/dependency_links.txt +0 -0
  345. {flare_kernel-0.1.0 → flare_kernel-0.2.1}/src/flare_kernel.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flare-kernel
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: FLARE kernel runtime package
5
5
  License: Proprietary
6
6
  Classifier: Development Status :: 3 - Alpha
@@ -8,10 +8,15 @@ Classifier: Programming Language :: Python :: 3
8
8
  Classifier: Programming Language :: Python :: 3.11
9
9
  Requires-Python: >=3.11
10
10
  Description-Content-Type: text/markdown
11
- Requires-Dist: flare-engines<0.2.0,>=0.1.0
11
+ Requires-Dist: flare-engines<0.3.0,>=0.2.0
12
12
  Requires-Dist: fastapi<1.0,>=0.115
13
13
  Requires-Dist: pydantic<3,>=2
14
14
  Requires-Dist: uvicorn<1.0,>=0.30
15
+ Requires-Dist: httpx<1.0,>=0.27
16
+ Requires-Dist: sqlalchemy<3,>=2
17
+ Requires-Dist: psycopg2-binary<3,>=2.9
18
+ Requires-Dist: redis<6,>=5
19
+ Requires-Dist: qdrant-client<2,>=1.9
15
20
 
16
21
  # flare-kernel
17
22
 
@@ -37,21 +42,22 @@ Requires-Dist: uvicorn<1.0,>=0.30
37
42
  1. `POST /kernel/run`
38
43
  2. `POST /kernel/stream`
39
44
  3. `GET /kernel/health`
45
+ 4. `POST /kernel/knowledge/ingest`
46
+ 5. `POST /kernel/knowledge/search`
40
47
 
41
48
  kernel 现已输出 mode/context 运行时占位事件与字段。
42
49
 
43
- ## Instance 注入(品牌信息)
50
+ ## 品牌注入(可选)
44
51
 
45
- 1. kernel 支持从 instance 的 domain-pack 读取品牌配置:
52
+ 1. kernel 支持从 domain-pack 读取品牌配置:
46
53
  `branding/instance-branding.json`
47
- 2. 读取优先级:
48
- - 环境变量 `FLARE_DOMAIN_PACK_ROOT`
49
- - 自动探测 `apps/<instance_id>/domain-pack`
54
+ 2. 读取方式:
55
+ - 仅通过环境变量 `FLARE_DOMAIN_PACK_ROOT` 显式指定
50
56
  3. 注入位置:
51
57
  - `POST /kernel/run` 响应 `result.instance_profile`
52
58
  - `POST /kernel/stream` SSE 事件 `instance_profile`
53
59
 
54
- 说明:品牌注入仅在 instance 层配置,core 不写死产品名、logo、标签。
60
+ 说明:品牌注入通过外部 domain-pack 配置,core 不写死产品名、logo、标签。
55
61
 
56
62
  本地启动(示例):
57
63
 
@@ -59,6 +65,29 @@ kernel 现已输出 mode/context 运行时占位事件与字段。
59
65
  uvicorn flare_kernel.main:app --app-dir packages/flare-kernel/src --host 0.0.0.0 --port 8002
60
66
  ```
61
67
 
68
+ 环境变量(真实链路):
69
+
70
+ 1. `DASHSCOPE_API_KEY`(必填,真实百炼调用)
71
+ 2. `LLM_PROVIDER_BACKEND`(默认 `dashscope`)
72
+ 3. `FLARE_POSTGRES_DSN`
73
+ 4. `FLARE_REDIS_URL`
74
+ 5. `FLARE_QDRANT_URL`
75
+
76
+ 健康检查会输出依赖状态:
77
+
78
+ 1. `llm_ready`
79
+ 2. `postgres_ready`
80
+ 3. `redis_ready`
81
+ 4. `qdrant_ready`
82
+
83
+ 模式决策优先级(`/kernel/run` 与 `/kernel/stream`):
84
+
85
+ 1. `intent_override`(外部业务侧注入)
86
+ 2. 消息意图识别(内置关键词)
87
+ 3. `manual_mode`
88
+ 4. `current_mode`
89
+ 5. fallback(`intent/default`)
90
+
62
91
  ## 最小发布说明
63
92
 
64
93
  1. 当前包版本:`0.1.0`
@@ -22,21 +22,22 @@
22
22
  1. `POST /kernel/run`
23
23
  2. `POST /kernel/stream`
24
24
  3. `GET /kernel/health`
25
+ 4. `POST /kernel/knowledge/ingest`
26
+ 5. `POST /kernel/knowledge/search`
25
27
 
26
28
  kernel 现已输出 mode/context 运行时占位事件与字段。
27
29
 
28
- ## Instance 注入(品牌信息)
30
+ ## 品牌注入(可选)
29
31
 
30
- 1. kernel 支持从 instance 的 domain-pack 读取品牌配置:
32
+ 1. kernel 支持从 domain-pack 读取品牌配置:
31
33
  `branding/instance-branding.json`
32
- 2. 读取优先级:
33
- - 环境变量 `FLARE_DOMAIN_PACK_ROOT`
34
- - 自动探测 `apps/<instance_id>/domain-pack`
34
+ 2. 读取方式:
35
+ - 仅通过环境变量 `FLARE_DOMAIN_PACK_ROOT` 显式指定
35
36
  3. 注入位置:
36
37
  - `POST /kernel/run` 响应 `result.instance_profile`
37
38
  - `POST /kernel/stream` SSE 事件 `instance_profile`
38
39
 
39
- 说明:品牌注入仅在 instance 层配置,core 不写死产品名、logo、标签。
40
+ 说明:品牌注入通过外部 domain-pack 配置,core 不写死产品名、logo、标签。
40
41
 
41
42
  本地启动(示例):
42
43
 
@@ -44,6 +45,29 @@ kernel 现已输出 mode/context 运行时占位事件与字段。
44
45
  uvicorn flare_kernel.main:app --app-dir packages/flare-kernel/src --host 0.0.0.0 --port 8002
45
46
  ```
46
47
 
48
+ 环境变量(真实链路):
49
+
50
+ 1. `DASHSCOPE_API_KEY`(必填,真实百炼调用)
51
+ 2. `LLM_PROVIDER_BACKEND`(默认 `dashscope`)
52
+ 3. `FLARE_POSTGRES_DSN`
53
+ 4. `FLARE_REDIS_URL`
54
+ 5. `FLARE_QDRANT_URL`
55
+
56
+ 健康检查会输出依赖状态:
57
+
58
+ 1. `llm_ready`
59
+ 2. `postgres_ready`
60
+ 3. `redis_ready`
61
+ 4. `qdrant_ready`
62
+
63
+ 模式决策优先级(`/kernel/run` 与 `/kernel/stream`):
64
+
65
+ 1. `intent_override`(外部业务侧注入)
66
+ 2. 消息意图识别(内置关键词)
67
+ 3. `manual_mode`
68
+ 4. `current_mode`
69
+ 5. fallback(`intent/default`)
70
+
47
71
  ## 最小发布说明
48
72
 
49
73
  1. 当前包版本:`0.1.0`
@@ -4,15 +4,20 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "flare-kernel"
7
- version = "0.1.0"
7
+ version = "0.2.1"
8
8
  description = "FLARE kernel runtime package"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
11
11
  dependencies = [
12
- "flare-engines>=0.1.0,<0.2.0",
12
+ "flare-engines>=0.2.0,<0.3.0",
13
13
  "fastapi>=0.115,<1.0",
14
14
  "pydantic>=2,<3",
15
15
  "uvicorn>=0.30,<1.0",
16
+ "httpx>=0.27,<1.0",
17
+ "sqlalchemy>=2,<3",
18
+ "psycopg2-binary>=2.9,<3",
19
+ "redis>=5,<6",
20
+ "qdrant-client>=1.9,<2",
16
21
  ]
17
22
  license = { text = "Proprietary" }
18
23
  classifiers = [
@@ -0,0 +1,23 @@
1
+ """Kernel contracts."""
2
+
3
+ from flare_kernel.contracts.kernel_contract import (
4
+ HealthResponse,
5
+ IntentSuggestResponse,
6
+ KernelRequest,
7
+ KernelResponse,
8
+ KnowledgeIngestRequest,
9
+ KnowledgeIngestResponse,
10
+ KnowledgeSearchRequest,
11
+ KnowledgeSearchResponse,
12
+ )
13
+
14
+ __all__ = [
15
+ "KernelRequest",
16
+ "KernelResponse",
17
+ "HealthResponse",
18
+ "IntentSuggestResponse",
19
+ "KnowledgeIngestRequest",
20
+ "KnowledgeIngestResponse",
21
+ "KnowledgeSearchRequest",
22
+ "KnowledgeSearchResponse",
23
+ ]
@@ -0,0 +1,133 @@
1
+ """Kernel API contracts."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Literal
6
+
7
+ from pydantic import BaseModel, Field, model_validator
8
+
9
+
10
+ class IntakeFieldValue(BaseModel):
11
+ kind: Literal["single_choice", "multi_choice", "free_text", "number", "range", "candidate_ref"]
12
+ value: Any = None
13
+ display_value: str | None = None
14
+ values: list[Any] | None = None
15
+ text: str | None = None
16
+ number: float | int | None = None
17
+ min: float | int | None = None
18
+ max: float | int | None = None
19
+ unit: str | None = None
20
+ currency: str | None = None
21
+ candidate_id: str | None = None
22
+
23
+ @model_validator(mode="after")
24
+ def validate_shape(self) -> "IntakeFieldValue":
25
+ if self.kind == "single_choice" and self.value in (None, ""):
26
+ raise ValueError("single_choice requires value")
27
+ if self.kind == "multi_choice" and not isinstance(self.values, list):
28
+ raise ValueError("multi_choice requires values[]")
29
+ if self.kind == "free_text" and not str(self.text or "").strip():
30
+ raise ValueError("free_text requires text")
31
+ if self.kind == "number" and self.number is None:
32
+ raise ValueError("number requires number")
33
+ if self.kind == "range" and (self.min is None or self.max is None):
34
+ raise ValueError("range requires min and max")
35
+ if self.kind == "candidate_ref" and not str(self.candidate_id or "").strip():
36
+ raise ValueError("candidate_ref requires candidate_id")
37
+ return self
38
+
39
+
40
+ class KernelRequest(BaseModel):
41
+ contract_version: str = "flare.v1"
42
+ client_request_id: str | None = None
43
+ tenant_id: str = "default"
44
+ instance_id: str = "default"
45
+ domain_pack_version: str = "v1"
46
+ session_id: str | None = None
47
+ last_turn_id: str | None = None
48
+ command: str | None = None
49
+ intent: str = "default"
50
+ intent_override: str | None = None
51
+ mode: str | None = None
52
+ manual_mode: str | None = None
53
+ current_mode: str | None = None
54
+ project_id: str | None = None
55
+ user_id: str | None = None
56
+ retrieval_config: dict[str, Any] = Field(default_factory=dict)
57
+ canvas_config: dict[str, Any] = Field(default_factory=dict)
58
+ plan_config: dict[str, Any] = Field(default_factory=dict)
59
+ payload: dict[str, Any] = Field(default_factory=dict)
60
+ context_refs: list[Any] = Field(default_factory=list)
61
+ knowledge_refs: list[str] = Field(default_factory=list)
62
+ action_key: str | None = None
63
+ target_mode: str | None = None
64
+ action_status: str | None = None
65
+ action_reason: str | None = None
66
+ trace_id: str | None = None
67
+ question_id: str | None = None
68
+ field_key: str | None = None
69
+ field_value: IntakeFieldValue | None = None
70
+
71
+
72
+ class KernelResponse(BaseModel):
73
+ trace_id: str
74
+ state: Literal["RUNNING", "SUCCEEDED", "FAILED"]
75
+ events: list[dict[str, Any]] = Field(default_factory=list)
76
+ result: dict[str, Any] = Field(default_factory=dict)
77
+ next_actions: list[dict[str, Any]] = Field(default_factory=list)
78
+
79
+
80
+ class HealthResponse(BaseModel):
81
+ status: Literal["healthy"]
82
+ service: str
83
+ trace_id: str
84
+ llm_ready: bool
85
+ postgres_ready: bool
86
+ redis_ready: bool
87
+ qdrant_ready: bool
88
+ canvas_ready: bool
89
+ rag_ready: bool
90
+ plan_ready: bool
91
+
92
+
93
+ class KnowledgeIngestRequest(BaseModel):
94
+ project_id: str = "default"
95
+ user_id: str = "default"
96
+ session_id: str = "default"
97
+ source_id: str | None = None
98
+ title: str | None = None
99
+ content: str
100
+ metadata: dict[str, Any] = Field(default_factory=dict)
101
+
102
+
103
+ class KnowledgeIngestResponse(BaseModel):
104
+ trace_id: str
105
+ project_id: str
106
+ user_id: str
107
+ record_id: str
108
+ chunk_count: int
109
+ status: Literal["stored", "partial", "failed"]
110
+ details: dict[str, Any] = Field(default_factory=dict)
111
+
112
+
113
+ class KnowledgeSearchRequest(BaseModel):
114
+ project_id: str = "default"
115
+ user_id: str = "default"
116
+ query: str
117
+ top_k: int = 5
118
+
119
+
120
+ class KnowledgeSearchResponse(BaseModel):
121
+ trace_id: str
122
+ project_id: str
123
+ user_id: str
124
+ query: str
125
+ results: list[dict[str, Any]] = Field(default_factory=list)
126
+
127
+
128
+ class IntentSuggestResponse(BaseModel):
129
+ trace_id: str
130
+ suggested_mode: str
131
+ confidence: float = 0.0
132
+ reason: str = ""
133
+ source: Literal["intent_override", "manual", "current", "llm", "keywords", "fallback"] = "fallback"
@@ -0,0 +1,45 @@
1
+ """Kernel routers.
2
+
3
+ This package keeps ``kernel_router`` as the public entrypoint and also provides
4
+ legacy module-name compatibility for recently grouped router modules.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import importlib
10
+ import sys
11
+
12
+ from flare_kernel.router.kernel import router as kernel_router
13
+
14
+ __all__ = ["kernel_router"]
15
+
16
+
17
+ def _resolve_legacy_group(module_name: str) -> str | None:
18
+ if module_name.startswith("canonical_state_"):
19
+ return "canonical"
20
+ if module_name.startswith("orchestration_"):
21
+ return "orchestration"
22
+ if module_name.startswith("streaming_"):
23
+ return "streaming"
24
+ if module_name.startswith("intake_"):
25
+ return "intake"
26
+ if module_name == "session_intent" or module_name.startswith("session_intent_"):
27
+ return "intent"
28
+ if module_name.startswith("intent_"):
29
+ return "intent"
30
+ if module_name.startswith("retrieval_"):
31
+ return "retrieval"
32
+ return None
33
+
34
+
35
+ def __getattr__(name: str):
36
+ """Resolve legacy ``flare_kernel.router.<module>`` access to grouped modules."""
37
+ group = _resolve_legacy_group(name)
38
+ if not group:
39
+ raise AttributeError(f"module 'flare_kernel.router' has no attribute {name!r}")
40
+
41
+ target = f"flare_kernel.router.{group}.{name}"
42
+ module = importlib.import_module(target)
43
+ # Register alias so direct imports by the legacy module path also resolve.
44
+ sys.modules.setdefault(f"flare_kernel.router.{name}", module)
45
+ return module
@@ -0,0 +1,148 @@
1
+ """Action target mode and payload shaping helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import Any, Callable
7
+
8
+ from flare_kernel.contracts import KernelRequest
9
+
10
+ _LEGACY_SOURCING_BASE_FIELDS_ENV = "FLARE_COMPAT_ENABLE_LEGACY_SOURCING_BASE_FIELDS"
11
+ _LEGACY_SOURCING_BASE_FIELDS = ("category", "region")
12
+
13
+
14
+ def resolve_action_target_mode(req: KernelRequest) -> str:
15
+ target_mode = req.target_mode
16
+ if isinstance(target_mode, str):
17
+ normalized = target_mode.strip()
18
+ if normalized in {"requirement_canvas", "intelligent_sourcing", "plan_mode"}:
19
+ return normalized
20
+
21
+ action_key = req.action_key if isinstance(req.action_key, str) else ""
22
+ if action_key == "handoff_to_sourcing":
23
+ return "intelligent_sourcing"
24
+ if action_key == "handoff_to_domain_flow":
25
+ return "intelligent_sourcing"
26
+ if action_key == "continue_collection":
27
+ return "requirement_canvas"
28
+ if action_key == "confirm_plan":
29
+ return "plan_mode"
30
+ if action_key == "confirm_sourcing":
31
+ return "intelligent_sourcing"
32
+ if action_key == "confirm_domain_flow":
33
+ return "intelligent_sourcing"
34
+
35
+ return req.intent if isinstance(req.intent, str) and req.intent.strip() else "default"
36
+
37
+
38
+ def _normalize_key(value: Any) -> str:
39
+ if value is None:
40
+ return ""
41
+ return str(value).strip().lower().replace("-", "_").replace(" ", "_")
42
+
43
+
44
+ def _extract_value(raw_value: Any) -> Any:
45
+ if isinstance(raw_value, dict):
46
+ for candidate in ("value", "content", "text"):
47
+ candidate_value = raw_value.get(candidate)
48
+ if candidate_value not in (None, "", [], {}):
49
+ return candidate_value
50
+ return raw_value
51
+
52
+
53
+ def _legacy_sourcing_base_fields_enabled() -> bool:
54
+ raw = os.getenv(_LEGACY_SOURCING_BASE_FIELDS_ENV)
55
+ if raw is None:
56
+ return False
57
+ value = raw.strip().lower()
58
+ return value not in {"0", "false", "off", "no"}
59
+
60
+
61
+ def _resolve_sourcing_base_field_keys(payload: dict[str, Any]) -> tuple[str, ...]:
62
+ explicit = payload.get("sourcing_base_field_keys")
63
+ if isinstance(explicit, list):
64
+ normalized = [str(item).strip() for item in explicit if str(item).strip()]
65
+ if normalized:
66
+ return tuple(dict.fromkeys(normalized))
67
+ if _legacy_sourcing_base_fields_enabled():
68
+ return _LEGACY_SOURCING_BASE_FIELDS
69
+ return ()
70
+
71
+
72
+ def collect_sourcing_base_fields_from_payload(payload: dict[str, Any]) -> dict[str, Any]:
73
+ base_field_keys = _resolve_sourcing_base_field_keys(payload)
74
+ if not base_field_keys:
75
+ return {}
76
+
77
+ raw_base_fields = payload.get("base_fields")
78
+ if isinstance(raw_base_fields, dict):
79
+ return dict(raw_base_fields)
80
+
81
+ base_fields: dict[str, Any] = {}
82
+ raw_fields = payload.get("fields")
83
+
84
+ if isinstance(raw_fields, dict):
85
+ for key in base_field_keys:
86
+ if key not in raw_fields:
87
+ continue
88
+ value = _extract_value(raw_fields.get(key))
89
+ if value not in (None, "", [], {}):
90
+ base_fields[key] = value
91
+ elif isinstance(raw_fields, list):
92
+ for raw_item in raw_fields:
93
+ if not isinstance(raw_item, dict):
94
+ continue
95
+ field_key = ""
96
+ for candidate in ("field_key", "name", "id", "key", "label"):
97
+ candidate_value = raw_item.get(candidate)
98
+ if isinstance(candidate_value, str) and candidate_value.strip():
99
+ field_key = candidate_value.strip()
100
+ break
101
+ normalized_key = _normalize_key(field_key)
102
+ if normalized_key not in set(base_field_keys):
103
+ continue
104
+ value = _extract_value(raw_item.get("value", raw_item.get("content", raw_item.get("text"))))
105
+ if value not in (None, "", [], {}):
106
+ base_fields[normalized_key] = value
107
+
108
+ for key in base_field_keys:
109
+ if key in base_fields:
110
+ continue
111
+ value = payload.get(key)
112
+ if value not in (None, "", [], {}):
113
+ base_fields[key] = value
114
+
115
+ return base_fields
116
+
117
+
118
+ def build_action_payload(
119
+ req: KernelRequest,
120
+ target_mode: str,
121
+ *,
122
+ collect_sourcing_base_fields: Callable[[dict[str, Any]], dict[str, Any]] | None = None,
123
+ ) -> dict[str, Any]:
124
+ payload = dict(req.payload) if isinstance(req.payload, dict) else {}
125
+ payload["function_type"] = target_mode
126
+ payload["target_mode"] = target_mode
127
+ if isinstance(req.action_key, str) and req.action_key.strip():
128
+ payload["action_key"] = req.action_key.strip()
129
+ if isinstance(req.action_status, str) and req.action_status.strip():
130
+ payload["action_status"] = req.action_status.strip()
131
+ if isinstance(req.action_reason, str) and req.action_reason.strip():
132
+ payload["action_reason"] = req.action_reason.strip()
133
+ if isinstance(req.action_key, str) and req.action_key.strip() == "confirm_sourcing":
134
+ payload["sourcing_confirmed"] = True
135
+ if isinstance(req.retrieval_config, dict) and req.retrieval_config:
136
+ payload["retrieval_config"] = dict(req.retrieval_config)
137
+ if isinstance(req.canvas_config, dict) and req.canvas_config:
138
+ payload["canvas_config"] = dict(req.canvas_config)
139
+ if isinstance(req.plan_config, dict) and req.plan_config:
140
+ payload["plan_config"] = dict(req.plan_config)
141
+
142
+ if target_mode == "intelligent_sourcing":
143
+ collect_fn = collect_sourcing_base_fields or collect_sourcing_base_fields_from_payload
144
+ base_fields = collect_fn(payload)
145
+ if base_fields:
146
+ payload["base_fields"] = base_fields
147
+
148
+ return payload
@@ -0,0 +1 @@
1
+ """Router canonical module group."""
@@ -0,0 +1,53 @@
1
+ """Analysis/retrieval projection helpers for canonical state."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+
8
+ def apply_analysis_and_retrieval_projection(
9
+ *,
10
+ canonical: dict[str, Any],
11
+ command: str,
12
+ can_generate: bool,
13
+ assistant_text: str,
14
+ normalized_retrieved_knowledge: list[dict[str, Any]],
15
+ ) -> None:
16
+ if command == "generate_analysis" and can_generate and assistant_text:
17
+ canonical["analysis"]["sections"].append({"id": "analysis", "title": "需求分析", "content": assistant_text})
18
+ if command == "generate_analysis" and normalized_retrieved_knowledge:
19
+ evidence_rows = normalized_retrieved_knowledge[:3]
20
+ evidence_titles = [str(item.get("title") or item.get("candidate_value") or item.get("snippet") or "证据") for item in evidence_rows]
21
+ evidence_summary = f"检索到 {len(normalized_retrieved_knowledge)} 条证据"
22
+ if evidence_titles:
23
+ evidence_summary = f"{evidence_summary},重点参考:{';'.join(evidence_titles[:3])}"
24
+ canonical["analysis"]["sections"].append(
25
+ {
26
+ "id": "evidence",
27
+ "title": "检索证据",
28
+ "content": evidence_summary,
29
+ }
30
+ )
31
+ if not normalized_retrieved_knowledge:
32
+ return
33
+ comparison_rows: list[dict[str, Any]] = []
34
+ for item in normalized_retrieved_knowledge[:3]:
35
+ comparison_rows.append(
36
+ {
37
+ "record_id": item.get("record_id"),
38
+ "chunk_id": item.get("chunk_id"),
39
+ "title": str(item.get("title") or item.get("candidate_value") or "证据条目"),
40
+ "source": str(item.get("source") or item.get("source_type") or "local"),
41
+ "score": item.get("score"),
42
+ "snippet": str(item.get("snippet") or item.get("content") or "")[:220],
43
+ "matched_field": str(item.get("matched_field") or ""),
44
+ "candidate_value": str(item.get("candidate_value") or ""),
45
+ "confidence": item.get("confidence"),
46
+ "why_relevant": str(item.get("why_relevant") or ""),
47
+ }
48
+ )
49
+ canonical["capabilities"]["field_retrieval"]["comparison_rows"] = comparison_rows
50
+ canonical["capabilities"]["field_retrieval"]["recommendation_summary"] = (
51
+ f"已检索到 {len(normalized_retrieved_knowledge)} 条候选证据,优先查看 "
52
+ + ";".join(str(item.get("title") or item.get("candidate_value") or "证据条目") for item in comparison_rows)
53
+ )
@@ -0,0 +1,82 @@
1
+ """Canonical state projection builder for router responses."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Callable
6
+
7
+ from flare_kernel.contracts import KernelRequest
8
+ from flare_kernel.router.canonical.canonical_state_context import (
9
+ resolve_canonical_state_context,
10
+ )
11
+ from flare_kernel.router.canonical.canonical_state_payload import (
12
+ build_canonical_payload,
13
+ )
14
+ from flare_kernel.router.canonical.canonical_state_projection import (
15
+ apply_analysis_and_retrieval_projection,
16
+ normalize_retrieved_knowledge,
17
+ )
18
+
19
+
20
+ def build_canonical_state(
21
+ *,
22
+ req: KernelRequest,
23
+ command: str,
24
+ resolved_intent: str,
25
+ resolved_mode: str,
26
+ mode_source: str,
27
+ orchestration_status: dict[str, Any],
28
+ runtime_snapshot: dict[str, Any],
29
+ assistant_text: str,
30
+ provider_status: str,
31
+ structured_retrieved_knowledge: list[dict[str, Any]] | None = None,
32
+ map_external_mode_fn: Callable[[str], str],
33
+ resolve_session_intent_stage_fn: Callable[..., str],
34
+ coerce_intent_escalation_policy_fn: Callable[[Any], dict[str, Any]],
35
+ normalize_stage_status_fn: Callable[..., tuple[str, str]],
36
+ build_confirmed_fields_schema_fn: Callable[[dict[str, Any], dict[str, Any]], dict[str, Any]],
37
+ build_missing_fields_schema_fn: Callable[[list[str]], dict[str, Any]],
38
+ is_field_entity_confirmed_fn: Callable[[Any], bool],
39
+ extract_user_message_fn: Callable[[dict[str, Any] | None], str],
40
+ normalize_intake_session_id_fn: Callable[[Any], str],
41
+ resolve_trace_id_fn: Callable[[str | None], str],
42
+ safe_session_id_fn: Callable[[Any], str],
43
+ ) -> dict[str, Any]:
44
+ _ = runtime_snapshot
45
+ normalized_retrieved_knowledge = normalize_retrieved_knowledge(structured_retrieved_knowledge)
46
+ canonical_context = resolve_canonical_state_context(
47
+ req=req,
48
+ command=command,
49
+ resolved_intent=resolved_intent,
50
+ resolved_mode=resolved_mode,
51
+ mode_source=mode_source,
52
+ orchestration_status=orchestration_status,
53
+ assistant_text=assistant_text,
54
+ map_external_mode_fn=map_external_mode_fn,
55
+ resolve_session_intent_stage_fn=resolve_session_intent_stage_fn,
56
+ coerce_intent_escalation_policy_fn=coerce_intent_escalation_policy_fn,
57
+ normalize_stage_status_fn=normalize_stage_status_fn,
58
+ is_field_entity_confirmed_fn=is_field_entity_confirmed_fn,
59
+ extract_user_message_fn=extract_user_message_fn,
60
+ normalize_intake_session_id_fn=normalize_intake_session_id_fn,
61
+ )
62
+ canonical = build_canonical_payload(
63
+ req=req,
64
+ command=command,
65
+ mode_source=mode_source,
66
+ orchestration_status=orchestration_status,
67
+ assistant_text=assistant_text,
68
+ provider_status=provider_status,
69
+ canonical_context=canonical_context,
70
+ build_confirmed_fields_schema_fn=build_confirmed_fields_schema_fn,
71
+ build_missing_fields_schema_fn=build_missing_fields_schema_fn,
72
+ resolve_trace_id_fn=resolve_trace_id_fn,
73
+ safe_session_id_fn=safe_session_id_fn,
74
+ )
75
+ apply_analysis_and_retrieval_projection(
76
+ canonical=canonical,
77
+ command=command,
78
+ can_generate=bool(canonical_context.get("can_generate")),
79
+ assistant_text=assistant_text,
80
+ normalized_retrieved_knowledge=normalized_retrieved_knowledge,
81
+ )
82
+ return canonical