Kairo-Jinkendo/backend/steering/kernel/events.py

73 lines
2.1 KiB
Python
Raw Permalink Normal View History

"""Event ingress — dual trigger (Plan | Event) v0.2."""
from __future__ import annotations
from typing import Any
from steering.kernel.binding import resolve_primary_method_key
from steering.kernel.evaluate import evaluate_steering
from steering.lifecycle.event_transitions import EventKind
from steering.lifecycle.orchestrator import transition
from steering.lifecycle.slot_providers import (
register_default_slot_providers,
resolve_event_via_providers,
)
from tenant_context import TenantContext
register_default_slot_providers()
def apply_steering_event(
ctx: TenantContext,
*,
initiative_id: str,
event_kind: EventKind,
payload: dict[str, Any] | None = None,
) -> dict[str, Any]:
"""
Event-Schub in den Kernel.
Plan-dominante Methoden: Event aktualisiert lifecycle_state entlang slot_map,
danach Re-Evaluate über evaluate_steering (Plan-Zug bleibt führend für Next).
"""
payload = payload or {}
primary_key = resolve_primary_method_key(ctx, initiative_id)
chain = resolve_event_via_providers(
primary_method_key=primary_key,
event_kind=event_kind,
payload=payload,
)
transitions: list[dict[str, Any]] = []
handled = bool(chain)
for slot_state in chain:
result = transition(
ctx,
initiative_id,
slot_state,
reason=f"steering_event:{event_kind}",
tenant_id=ctx.tenant_id,
user_id=ctx.user_id or None,
)
if not result.get("unchanged"):
transitions.append(result)
evaluation = evaluate_steering(ctx, initiative_id=initiative_id)
return {
"accepted": True,
"event_kind": event_kind,
"initiative_id": initiative_id,
"handled": handled,
"lifecycle_chain": list(chain),
"transitions": transitions,
"message": (
"Lifecycle aktualisiert — Re-Evaluate via Plan-Zug"
if handled
else "Event protokolliert — kein Lifecycle-Slot für diese Methode"
),
"payload_keys": sorted(payload.keys()),
"evaluation": evaluation.to_dict(),
}