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.
- {flare_kernel-0.1.0 → flare_kernel-0.2.1}/PKG-INFO +37 -8
- {flare_kernel-0.1.0 → flare_kernel-0.2.1}/README.md +30 -6
- {flare_kernel-0.1.0 → flare_kernel-0.2.1}/pyproject.toml +7 -2
- flare_kernel-0.2.1/src/flare_kernel/contracts/__init__.py +23 -0
- flare_kernel-0.2.1/src/flare_kernel/contracts/kernel_contract.py +133 -0
- flare_kernel-0.2.1/src/flare_kernel/router/__init__.py +45 -0
- flare_kernel-0.2.1/src/flare_kernel/router/action_payload.py +148 -0
- flare_kernel-0.2.1/src/flare_kernel/router/canonical/__init__.py +1 -0
- flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_analysis.py +53 -0
- flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_builder.py +82 -0
- flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_checkpoint.py +102 -0
- flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_context.py +88 -0
- flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_context_analysis.py +151 -0
- flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_context_inputs.py +109 -0
- flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_context_session.py +90 -0
- flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_flow.py +149 -0
- flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_payload.py +131 -0
- flare_kernel-0.2.1/src/flare_kernel/router/canonical/canonical_state_projection.py +136 -0
- flare_kernel-0.2.1/src/flare_kernel/router/completion_response_builder.py +129 -0
- flare_kernel-0.2.1/src/flare_kernel/router/completion_selection.py +55 -0
- flare_kernel-0.2.1/src/flare_kernel/router/endpoint_context.py +127 -0
- flare_kernel-0.2.1/src/flare_kernel/router/guided_completion.py +28 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/__init__.py +1 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_amount_quantity.py +163 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_answer.py +42 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_authority.py +81 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_authority_checkpoint.py +58 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_authority_hydration.py +116 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_authority_session.py +70 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_canonicalization.py +119 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_clarification.py +122 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_decision_rules.py +123 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_deployment_delivery.py +120 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_entry_policy.py +142 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_extraction.py +84 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_extraction_extractors.py +164 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_extraction_merge.py +85 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_field_projection.py +78 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_field_projection_entity.py +107 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_field_projection_payload.py +89 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_field_projection_source.py +60 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_field_scope.py +40 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_confirmed_updates.py +21 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_flags.py +40 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_followup.py +154 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_followup_work_item.py +113 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_open_fields.py +25 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_status.py +84 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_guided_summary.py +26 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_inputs.py +109 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_node_state.py +83 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_numeric.py +126 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_payload_updates.py +92 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_readiness.py +63 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_state_persistence.py +45 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_status.py +47 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_status_chooser_stage.py +121 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_status_guided_session.py +20 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_status_projection.py +156 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_status_schema.py +183 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intake/intake_workflow_checkpoint.py +183 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intent/__init__.py +1 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intent/intent_classifier_utils.py +72 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intent/intent_escalation_override.py +82 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intent/intent_escalation_pipeline.py +95 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intent/intent_escalation_signal.py +145 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intent/intent_retrieval.py +101 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intent/intent_routing.py +146 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intent/session_intent.py +133 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intent/session_intent_fields.py +103 -0
- flare_kernel-0.2.1/src/flare_kernel/router/intent/session_intent_small_talk.py +132 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel.py +122 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports.py +18 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/__init__.py +5 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/constants.py +29 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/domain.py +148 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/endpoint.py +50 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/facade.py +21 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/router_flow.py +95 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_compat_exports_parts/runtime.py +30 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_constants.py +55 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_constants_intake.py +34 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_constants_intent.py +176 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_constants_patch.py +32 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_endpoint_handlers.py +29 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_endpoint_handlers_health.py +37 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_endpoint_handlers_knowledge.py +69 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_endpoint_handlers_turn.py +184 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_canonical_state.py +82 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_canonical_wrapper.py +133 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_dependency_resolution.py +272 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_helpers.py +30 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_orchestration.py +119 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_orchestration_wrappers.py +179 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_payload_enrichment.py +75 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_payload_wrapper.py +180 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_turn_context.py +174 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_turn_context_wrapper.py +161 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_facade_utils.py +36 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_intent_query_flow.py +193 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_mode_flow.py +90 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_request_flow.py +754 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_route_action.py +121 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_route_execution.py +115 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_route_run.py +183 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_route_stream.py +149 -0
- flare_kernel-0.2.1/src/flare_kernel/router/kernel_session_intent_flow.py +133 -0
- flare_kernel-0.2.1/src/flare_kernel/router/mode_resolution.py +196 -0
- flare_kernel-0.2.1/src/flare_kernel/router/mode_switch.py +52 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/__init__.py +1 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_checkpoint_state.py +93 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_followup_state.py +77 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_builder.py +113 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_context.py +129 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_context_helpers.py +179 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_decision.py +96 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_projection.py +177 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_result.py +86 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_runtime_state.py +10 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state.py +85 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_context.py +29 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_decision.py +54 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_entry.py +43 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_flow.py +243 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_followup.py +94 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_intent.py +41 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_node.py +60 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_payload.py +91 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_status_state_unpack.py +39 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_trace.py +132 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_trace_projection.py +83 -0
- flare_kernel-0.2.1/src/flare_kernel/router/orchestration/orchestration_trace_steps.py +139 -0
- flare_kernel-0.2.1/src/flare_kernel/router/patch_contract.py +36 -0
- flare_kernel-0.2.1/src/flare_kernel/router/payload_enrichment.py +161 -0
- flare_kernel-0.2.1/src/flare_kernel/router/prompting.py +96 -0
- flare_kernel-0.2.1/src/flare_kernel/router/request_identity.py +23 -0
- flare_kernel-0.2.1/src/flare_kernel/router/request_intent_resolution.py +68 -0
- flare_kernel-0.2.1/src/flare_kernel/router/retrieval/__init__.py +1 -0
- flare_kernel-0.2.1/src/flare_kernel/router/retrieval/retrieval_aliases.py +99 -0
- flare_kernel-0.2.1/src/flare_kernel/router/retrieval/retrieval_field_queries.py +71 -0
- flare_kernel-0.2.1/src/flare_kernel/router/retrieval/retrieval_projection.py +68 -0
- flare_kernel-0.2.1/src/flare_kernel/router/retrieval/retrieval_query_builder.py +76 -0
- flare_kernel-0.2.1/src/flare_kernel/router/retrieval/retrieval_search.py +45 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/__init__.py +1 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_draft_completion.py +121 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_draft_finalize.py +168 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_draft_phase.py +163 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_draft_phase_timing.py +39 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_draft_post_completion.py +104 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_draft_prologue.py +54 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_event_emitter.py +138 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_intake_phase.py +104 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_mode_event_payload.py +78 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_mode_events.py +89 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_response_bootstrap.py +111 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_response_builder.py +155 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_response_builder_transport.py +44 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_response_phases.py +453 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_response_runtime.py +90 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_retrieval_phase.py +105 -0
- flare_kernel-0.2.1/src/flare_kernel/router/streaming/streaming_runtime_steps.py +63 -0
- flare_kernel-0.2.1/src/flare_kernel/router/text_safety.py +94 -0
- flare_kernel-0.2.1/src/flare_kernel/router/turn_context_builder.py +166 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/__init__.py +152 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/domain/__init__.py +1 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/domain/domain_pack_loader.py +696 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/domain/profile_resolution.py +126 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/execution/__init__.py +1 -0
- {flare_kernel-0.1.0/src/flare_kernel/runtime → flare_kernel-0.2.1/src/flare_kernel/runtime/execution}/agent_runtime.py +38 -0
- {flare_kernel-0.1.0/src/flare_kernel/runtime → flare_kernel-0.2.1/src/flare_kernel/runtime/execution}/skill_runtime.py +34 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/infrastructure/__init__.py +1 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/infrastructure/infrastructure.py +523 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/intent/__init__.py +1 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/intent/intent_and_escalation/__init__.py +7 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/intent/intent_and_escalation/decision.py +117 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/intent/intent_and_escalation/lexicon.py +217 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/intent/intent_and_escalation/preprocessing.py +47 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/intent/intent_and_escalation/signals.py +172 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/intent/intent_and_escalation_classifier.py +81 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/llm/__init__.py +1 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/llm/llm_provider.py +410 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/llm/model_router.py +443 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/orchestration/__init__.py +1 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/orchestration/decision_engine.py +447 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/orchestration/mode_orchestration.py +1193 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/orchestration/mode_runtime.py +462 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/__init__.py +1 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/intake_reasoning.py +273 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/intake_reasoning_context.py +215 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/intake_reasoning_hypothesis.py +211 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/intake_reasoning_planning.py +495 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/intake_reasoning_readiness.py +372 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/reasoning/intake_reasoning_shared.py +105 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/session/__init__.py +25 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/session/checkpoint_manager.py +360 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/session/intake_session_store.py +363 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/session/models.py +40 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/tests/test_checkpoint_manager.py +118 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/tests/test_intake_reasoning.py +361 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/tests/test_intake_reasoning_split.py +87 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/tests/test_intake_session_store.py +98 -0
- flare_kernel-0.2.1/src/flare_kernel/runtime/tests/test_kernel_runtime.py +483 -0
- {flare_kernel-0.1.0 → flare_kernel-0.2.1}/src/flare_kernel.egg-info/PKG-INFO +37 -8
- flare_kernel-0.2.1/src/flare_kernel.egg-info/SOURCES.txt +330 -0
- flare_kernel-0.2.1/src/flare_kernel.egg-info/requires.txt +9 -0
- flare_kernel-0.2.1/tests/test_action_payload.py +70 -0
- flare_kernel-0.2.1/tests/test_basics.py +64 -0
- flare_kernel-0.2.1/tests/test_builder_split_modules.py +309 -0
- flare_kernel-0.2.1/tests/test_canonical_state_context_analysis.py +54 -0
- flare_kernel-0.2.1/tests/test_canonical_state_context_inputs.py +27 -0
- flare_kernel-0.2.1/tests/test_canonical_state_context_session.py +49 -0
- flare_kernel-0.2.1/tests/test_canonical_state_flow.py +62 -0
- flare_kernel-0.2.1/tests/test_canonical_state_projection.py +100 -0
- flare_kernel-0.2.1/tests/test_completion_response_builder.py +95 -0
- flare_kernel-0.2.1/tests/test_completion_selection.py +107 -0
- flare_kernel-0.2.1/tests/test_decision_engine.py +204 -0
- flare_kernel-0.2.1/tests/test_domain_pack_loader.py +168 -0
- flare_kernel-0.2.1/tests/test_endpoint_context.py +81 -0
- flare_kernel-0.2.1/tests/test_flare_v1_patch_contract.py +605 -0
- flare_kernel-0.2.1/tests/test_infrastructure_helpers.py +23 -0
- flare_kernel-0.2.1/tests/test_intake_amount_quantity.py +23 -0
- flare_kernel-0.2.1/tests/test_intake_answer.py +25 -0
- flare_kernel-0.2.1/tests/test_intake_authority.py +159 -0
- flare_kernel-0.2.1/tests/test_intake_authority_checkpoint.py +36 -0
- flare_kernel-0.2.1/tests/test_intake_authority_hydration.py +71 -0
- flare_kernel-0.2.1/tests/test_intake_authority_session.py +58 -0
- flare_kernel-0.2.1/tests/test_intake_canonicalization.py +44 -0
- flare_kernel-0.2.1/tests/test_intake_clarification.py +77 -0
- flare_kernel-0.2.1/tests/test_intake_decision_rules.py +81 -0
- flare_kernel-0.2.1/tests/test_intake_deployment_delivery.py +29 -0
- flare_kernel-0.2.1/tests/test_intake_entry_policy.py +56 -0
- flare_kernel-0.2.1/tests/test_intake_extraction.py +54 -0
- flare_kernel-0.2.1/tests/test_intake_extraction_extractors.py +29 -0
- flare_kernel-0.2.1/tests/test_intake_extraction_merge.py +36 -0
- flare_kernel-0.2.1/tests/test_intake_field_projection.py +69 -0
- flare_kernel-0.2.1/tests/test_intake_field_projection_entity.py +28 -0
- flare_kernel-0.2.1/tests/test_intake_field_projection_payload.py +18 -0
- flare_kernel-0.2.1/tests/test_intake_field_projection_source.py +29 -0
- flare_kernel-0.2.1/tests/test_intake_field_scope.py +20 -0
- flare_kernel-0.2.1/tests/test_intake_guided_confirmed_updates.py +18 -0
- flare_kernel-0.2.1/tests/test_intake_guided_flags.py +14 -0
- flare_kernel-0.2.1/tests/test_intake_guided_followup.py +185 -0
- flare_kernel-0.2.1/tests/test_intake_guided_followup_work_item.py +60 -0
- flare_kernel-0.2.1/tests/test_intake_guided_open_fields.py +14 -0
- flare_kernel-0.2.1/tests/test_intake_guided_status.py +23 -0
- flare_kernel-0.2.1/tests/test_intake_guided_summary.py +11 -0
- flare_kernel-0.2.1/tests/test_intake_inputs.py +56 -0
- flare_kernel-0.2.1/tests/test_intake_node_state.py +73 -0
- flare_kernel-0.2.1/tests/test_intake_numeric.py +26 -0
- flare_kernel-0.2.1/tests/test_intake_payload_updates.py +51 -0
- flare_kernel-0.2.1/tests/test_intake_readiness.py +58 -0
- flare_kernel-0.2.1/tests/test_intake_state_persistence.py +36 -0
- flare_kernel-0.2.1/tests/test_intake_status.py +303 -0
- flare_kernel-0.2.1/tests/test_intake_status_guided_session.py +95 -0
- flare_kernel-0.2.1/tests/test_intake_status_projection.py +143 -0
- flare_kernel-0.2.1/tests/test_intake_status_schema.py +160 -0
- flare_kernel-0.2.1/tests/test_intake_status_stage.py +64 -0
- flare_kernel-0.2.1/tests/test_intake_workflow_checkpoint.py +23 -0
- flare_kernel-0.2.1/tests/test_intent_classifier_utils.py +44 -0
- flare_kernel-0.2.1/tests/test_intent_escalation_classifier.py +444 -0
- flare_kernel-0.2.1/tests/test_intent_escalation_override.py +66 -0
- flare_kernel-0.2.1/tests/test_intent_escalation_pipeline.py +83 -0
- flare_kernel-0.2.1/tests/test_intent_escalation_signal.py +68 -0
- flare_kernel-0.2.1/tests/test_intent_resolution.py +1747 -0
- flare_kernel-0.2.1/tests/test_intent_retrieval.py +110 -0
- flare_kernel-0.2.1/tests/test_intent_routing.py +106 -0
- flare_kernel-0.2.1/tests/test_kernel_alias_delegation.py +22 -0
- flare_kernel-0.2.1/tests/test_kernel_endpoint_handlers.py +195 -0
- flare_kernel-0.2.1/tests/test_kernel_facade_helpers.py +20 -0
- flare_kernel-0.2.1/tests/test_kernel_intent_query_flow.py +60 -0
- flare_kernel-0.2.1/tests/test_kernel_mode_flow.py +63 -0
- flare_kernel-0.2.1/tests/test_kernel_route_execution_wrappers.py +97 -0
- flare_kernel-0.2.1/tests/test_kernel_session_intent_flow.py +40 -0
- flare_kernel-0.2.1/tests/test_llm_provider.py +227 -0
- flare_kernel-0.2.1/tests/test_mode_resolution.py +169 -0
- flare_kernel-0.2.1/tests/test_mode_switch.py +40 -0
- flare_kernel-0.2.1/tests/test_model_router.py +261 -0
- flare_kernel-0.2.1/tests/test_orchestration_checkpoint_state.py +30 -0
- flare_kernel-0.2.1/tests/test_orchestration_followup_state.py +26 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_context.py +65 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_context_helpers.py +39 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_decision.py +71 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_projection.py +240 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_result.py +53 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_runtime_state.py +53 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_state_context.py +25 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_state_decision.py +43 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_state_entry.py +42 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_state_followup.py +64 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_state_intent.py +38 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_state_node.py +53 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_state_payload.py +54 -0
- flare_kernel-0.2.1/tests/test_orchestration_status_state_unpack.py +38 -0
- flare_kernel-0.2.1/tests/test_orchestration_trace.py +146 -0
- flare_kernel-0.2.1/tests/test_orchestration_trace_projection.py +17 -0
- flare_kernel-0.2.1/tests/test_orchestration_trace_steps.py +28 -0
- flare_kernel-0.2.1/tests/test_patch_contract.py +52 -0
- flare_kernel-0.2.1/tests/test_payload_enrichment.py +128 -0
- flare_kernel-0.2.1/tests/test_request_identity.py +24 -0
- flare_kernel-0.2.1/tests/test_request_intent_resolution.py +41 -0
- flare_kernel-0.2.1/tests/test_retrieval_aliases.py +71 -0
- flare_kernel-0.2.1/tests/test_retrieval_field_queries.py +25 -0
- flare_kernel-0.2.1/tests/test_retrieval_projection.py +61 -0
- flare_kernel-0.2.1/tests/test_retrieval_query_builder.py +48 -0
- flare_kernel-0.2.1/tests/test_retrieval_search.py +29 -0
- flare_kernel-0.2.1/tests/test_session_intent.py +98 -0
- flare_kernel-0.2.1/tests/test_session_intent_fields.py +67 -0
- flare_kernel-0.2.1/tests/test_session_intent_small_talk.py +31 -0
- flare_kernel-0.2.1/tests/test_streaming_draft_completion.py +101 -0
- flare_kernel-0.2.1/tests/test_streaming_draft_finalize.py +100 -0
- flare_kernel-0.2.1/tests/test_streaming_draft_phase.py +186 -0
- flare_kernel-0.2.1/tests/test_streaming_draft_post_completion.py +97 -0
- flare_kernel-0.2.1/tests/test_streaming_draft_prologue.py +45 -0
- flare_kernel-0.2.1/tests/test_streaming_event_emitter.py +72 -0
- flare_kernel-0.2.1/tests/test_streaming_intake_phase.py +83 -0
- flare_kernel-0.2.1/tests/test_streaming_mode_event_payload.py +85 -0
- flare_kernel-0.2.1/tests/test_streaming_mode_events.py +63 -0
- flare_kernel-0.2.1/tests/test_streaming_response_bootstrap.py +82 -0
- flare_kernel-0.2.1/tests/test_streaming_response_phases.py +168 -0
- flare_kernel-0.2.1/tests/test_streaming_response_runtime.py +83 -0
- flare_kernel-0.2.1/tests/test_streaming_retrieval_phase.py +69 -0
- flare_kernel-0.2.1/tests/test_streaming_runtime_steps.py +61 -0
- flare_kernel-0.2.1/tests/test_text_safety.py +34 -0
- flare_kernel-0.2.1/tests/test_turn_context_builder.py +55 -0
- flare_kernel-0.1.0/src/flare_kernel/contracts/__init__.py +0 -5
- flare_kernel-0.1.0/src/flare_kernel/contracts/kernel_contract.py +0 -36
- flare_kernel-0.1.0/src/flare_kernel/router/__init__.py +0 -5
- flare_kernel-0.1.0/src/flare_kernel/router/kernel.py +0 -342
- flare_kernel-0.1.0/src/flare_kernel/runtime/__init__.py +0 -26
- flare_kernel-0.1.0/src/flare_kernel/runtime/domain_pack_loader.py +0 -240
- flare_kernel-0.1.0/src/flare_kernel/runtime/llm_provider.py +0 -204
- flare_kernel-0.1.0/src/flare_kernel/runtime/mode_orchestration.py +0 -330
- flare_kernel-0.1.0/src/flare_kernel/runtime/mode_runtime.py +0 -262
- flare_kernel-0.1.0/src/flare_kernel/runtime/tests/test_kernel_runtime.py +0 -114
- flare_kernel-0.1.0/src/flare_kernel.egg-info/SOURCES.txt +0 -25
- flare_kernel-0.1.0/src/flare_kernel.egg-info/requires.txt +0 -4
- flare_kernel-0.1.0/tests/test_basics.py +0 -25
- {flare_kernel-0.1.0 → flare_kernel-0.2.1}/setup.cfg +0 -0
- {flare_kernel-0.1.0 → flare_kernel-0.2.1}/src/flare_kernel/__init__.py +0 -0
- {flare_kernel-0.1.0 → flare_kernel-0.2.1}/src/flare_kernel/app.py +0 -0
- {flare_kernel-0.1.0 → flare_kernel-0.2.1}/src/flare_kernel/main.py +0 -0
- {flare_kernel-0.1.0/src/flare_kernel/runtime → flare_kernel-0.2.1/src/flare_kernel/runtime/infrastructure}/logging.py +0 -0
- {flare_kernel-0.1.0/src/flare_kernel/runtime → flare_kernel-0.2.1/src/flare_kernel/runtime/infrastructure}/trace.py +0 -0
- {flare_kernel-0.1.0 → flare_kernel-0.2.1}/src/flare_kernel.egg-info/dependency_links.txt +0 -0
- {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
|
|
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.
|
|
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
|
-
##
|
|
50
|
+
## 品牌注入(可选)
|
|
44
51
|
|
|
45
|
-
1. kernel 支持从
|
|
52
|
+
1. kernel 支持从 domain-pack 读取品牌配置:
|
|
46
53
|
`branding/instance-branding.json`
|
|
47
|
-
2.
|
|
48
|
-
-
|
|
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
|
-
|
|
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
|
-
##
|
|
30
|
+
## 品牌注入(可选)
|
|
29
31
|
|
|
30
|
-
1. kernel 支持从
|
|
32
|
+
1. kernel 支持从 domain-pack 读取品牌配置:
|
|
31
33
|
`branding/instance-branding.json`
|
|
32
|
-
2.
|
|
33
|
-
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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
|