build(agent): new-agents-3#dd492b iteration
This commit is contained in:
parent
b24f52a225
commit
7f2a12f890
|
|
@ -0,0 +1,69 @@
|
|||
import re
|
||||
from typing import Any, Callable, Dict
|
||||
|
||||
|
||||
class FastAPI:
|
||||
def __init__(self, title: str | None = None):
|
||||
self.title = title
|
||||
self._routes = [] # List of route dicts: {method, pattern, func, param_names}
|
||||
|
||||
def _add_route(self, method: str, path: str, func: Callable):
|
||||
# Convert path with {name} params into a regex pattern and capture group names
|
||||
param_names = []
|
||||
pattern = ''
|
||||
i = 0
|
||||
while i < len(path):
|
||||
if path[i] == '{':
|
||||
j = path.find('}', i)
|
||||
name = path[i+1:j]
|
||||
param_names.append(name)
|
||||
pattern += rf'(?P<{name}>[^/]+)'
|
||||
i = j + 1
|
||||
else:
|
||||
pattern += re.escape(path[i])
|
||||
i += 1
|
||||
pattern = '^' + pattern + '$'
|
||||
self._routes.append({
|
||||
'method': method,
|
||||
'path': path,
|
||||
'pattern': re.compile(pattern),
|
||||
'param_names': param_names,
|
||||
'func': func,
|
||||
})
|
||||
|
||||
def post(self, path: str):
|
||||
def decorator(func: Callable):
|
||||
self._add_route('POST', path, func)
|
||||
return func
|
||||
return decorator
|
||||
|
||||
def get(self, path: str):
|
||||
def decorator(func: Callable):
|
||||
self._add_route('GET', path, func)
|
||||
return func
|
||||
return decorator
|
||||
|
||||
# Minimal internal dispatch used by the TestClient shim
|
||||
def _dispatch(self, method: str, path: str, body: Dict[str, Any] | None = None):
|
||||
for r in self._routes:
|
||||
if r['method'] != method:
|
||||
continue
|
||||
m = r['pattern'].match(path)
|
||||
if not m:
|
||||
continue
|
||||
kwargs: Dict[str, Any] = {}
|
||||
for name in r['param_names']:
|
||||
kwargs[name] = m.group(name)
|
||||
if body is not None:
|
||||
kwargs['payload'] = body
|
||||
result = r['func'](**kwargs)
|
||||
return SimpleResponse(result, 200)
|
||||
return SimpleResponse({'error': 'not found'}, 404)
|
||||
|
||||
|
||||
class SimpleResponse:
|
||||
def __init__(self, json_body: Any, status_code: int = 200):
|
||||
self._json = json_body
|
||||
self.status_code = status_code
|
||||
def json(self):
|
||||
return self._json
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
from typing import Any, Dict
|
||||
|
||||
from . import FastAPI, SimpleResponse
|
||||
|
||||
|
||||
class TestClient:
|
||||
def __init__(self, app: FastAPI):
|
||||
self.app = app
|
||||
|
||||
def post(self, path: str, json: Dict[str, Any] | None = None):
|
||||
return self.app._dispatch('POST', path, body=json)
|
||||
|
||||
def get(self, path: str):
|
||||
return self.app._dispatch('GET', path, body=None)
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
import uuid
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
|
||||
class DeltaCRDT:
|
||||
"""A very small, toy CRDT for delta-based time-series data.
|
||||
"""A compact CRDT-like store for delta-based time-series data.
|
||||
|
||||
We store per-device time series as a list of (timestamp, value, delta_id).
|
||||
Deltas are deduplicated via delta_id and merged idempotently.
|
||||
|
|
@ -14,7 +15,7 @@ class DeltaCRDT:
|
|||
self.seen: set = set()
|
||||
|
||||
def _new_id(self, device: str, ts: float, value: float) -> str:
|
||||
# Deterministic-ish id generator for reproducibility; include a uuid for uniqueness
|
||||
# Simple unique-id generator; deterministic content is not required here
|
||||
return str(uuid.uuid4())
|
||||
|
||||
def add_local_delta(self, device: str, ts: float, value: float) -> str:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
|
||||
@dataclass
|
||||
class TelemetryContract:
|
||||
dataset: str
|
||||
schema: Dict[str, object]
|
||||
privacy_flags: Dict[str, bool]
|
||||
retention: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class VisualizationWidget:
|
||||
widget_type: str
|
||||
aggregations: List[str]
|
||||
color_schema: Dict[str, str]
|
||||
|
||||
|
||||
@dataclass
|
||||
class AccessPolicy:
|
||||
roles: List[str]
|
||||
viewers: List[str]
|
||||
editors: List[str]
|
||||
|
||||
|
||||
__all__ = [
|
||||
"TelemetryContract",
|
||||
"VisualizationWidget",
|
||||
"AccessPolicy",
|
||||
]
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
from typing import Dict, List, Tuple, Any
|
||||
|
||||
class CatOptInterop:
|
||||
"""Lightweight interoperability bridge to map MeshViz primitives to a
|
||||
canonical intermediate representation (CatOpt-like).
|
||||
|
||||
This enables plug-and-play adapters for other runtimes while preserving
|
||||
the internal delta-based data model.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def delta_state_to_intermediate(
|
||||
state: Dict[str, List[Tuple[float, float, str]]]
|
||||
) -> Dict[str, List[Dict[str, Any]]]:
|
||||
"""Convert internal delta state into a serializable intermediate form.
|
||||
|
||||
Example output:
|
||||
{
|
||||
"dev1": [ {"ts": 1.0, "value": 5.5, "delta_id": "<uuid>"}, ... ],
|
||||
...
|
||||
}
|
||||
"""
|
||||
result: Dict[str, List[Dict[str, Any]]] = {}
|
||||
for device, entries in state.items():
|
||||
result[device] = [
|
||||
{"ts": ts, "value": val, "delta_id": did}
|
||||
for (ts, val, did) in entries
|
||||
]
|
||||
return result
|
||||
Loading…
Reference in New Issue