Initial SFERA platform baseline

This commit is contained in:
2026-05-16 19:03:49 +03:00
commit 3b845c8fce
282 changed files with 55045 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
# sfera-runtime-overlays
Runtime observations attached to semantic lineage IDs.
+11
View File
@@ -0,0 +1,11 @@
[project]
name = "sfera-runtime-overlays"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"pydantic>=2.0",
"sfera-sir",
]
[tool.uv]
package = true
@@ -0,0 +1,69 @@
from __future__ import annotations
from datetime import datetime, timezone
from enum import Enum
from pydantic import BaseModel, Field
from sir import SemanticNode, SirSnapshot
class RuntimeSignalKind(str, Enum):
EXECUTION = "EXECUTION"
ERROR = "ERROR"
SLOW_QUERY = "SLOW_QUERY"
WRITE = "WRITE"
class RuntimeSignal(BaseModel):
signal_id: str
lineage_id: str
kind: RuntimeSignalKind
observed_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
count: int = 1
duration_ms: float | None = None
message: str | None = None
attributes: dict = Field(default_factory=dict)
class RuntimeOverlay(BaseModel):
project_id: str
signals: list[RuntimeSignal] = Field(default_factory=list)
class NodeRuntimeSummary(BaseModel):
node: SemanticNode
signal_count: int
error_count: int
max_duration_ms: float | None = None
def summarize_runtime(snapshot: SirSnapshot, overlay: RuntimeOverlay) -> list[NodeRuntimeSummary]:
nodes = {node.lineage_id: node for node in snapshot.nodes}
grouped: dict[str, list[RuntimeSignal]] = {}
for signal in overlay.signals:
if signal.lineage_id in nodes:
grouped.setdefault(signal.lineage_id, []).append(signal)
summaries: list[NodeRuntimeSummary] = []
for lineage_id, signals in grouped.items():
durations = [signal.duration_ms for signal in signals if signal.duration_ms is not None]
summaries.append(
NodeRuntimeSummary(
node=nodes[lineage_id],
signal_count=sum(signal.count for signal in signals),
error_count=sum(signal.count for signal in signals if signal.kind == RuntimeSignalKind.ERROR),
max_duration_ms=max(durations) if durations else None,
)
)
summaries.sort(key=lambda item: (-item.error_count, -(item.max_duration_ms or 0), item.node.qualified_name))
return summaries
__all__ = [
"NodeRuntimeSummary",
"RuntimeOverlay",
"RuntimeSignal",
"RuntimeSignalKind",
"summarize_runtime",
]
@@ -0,0 +1,27 @@
from pathlib import Path
from runtime_overlays import RuntimeOverlay, RuntimeSignal, RuntimeSignalKind, summarize_runtime
from semantic_kernel import index_project
def test_summarize_runtime_attaches_signals_to_nodes(tmp_path: Path):
module = tmp_path / "demo_module.bsl"
module.write_text("Процедура Проведение()\nКонецПроцедуры\n", encoding="utf-8")
snapshot = index_project(tmp_path, project_id="demo")
routine = next(node for node in snapshot.nodes if node.name == "Проведение")
overlay = RuntimeOverlay(
project_id="demo",
signals=[
RuntimeSignal(
signal_id="signal.1",
lineage_id=routine.lineage_id,
kind=RuntimeSignalKind.ERROR,
duration_ms=120.0,
)
],
)
summaries = summarize_runtime(snapshot, overlay)
assert summaries[0].node.name == "Проведение"
assert summaries[0].error_count == 1