snapshot: NODE1 production state 2026-02-09
Complete snapshot of /opt/microdao-daarion/ from NODE1 (144.76.224.179).
This represents the actual running production code that has diverged
significantly from the previous main branch.
Key changes from old main:
- Gateway (http_api.py): expanded from ~40KB to 164KB with full agent support
- Router: new /v1/agents/{id}/infer endpoint with vision + DeepSeek routing
- Behavior Policy: SOWA v2.2 (3-level: FULL/ACK/SILENT)
- Agent Registry: config/agent_registry.yml as single source of truth
- 13 agents configured (was 3)
- Memory service integration
- CrewAI teams and roles
Excluded from snapshot: venv/, .env, data/, backups, .tgz archives
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
51
packages/agromatrix-tools/agromatrix_tools/normalize.py
Normal file
51
packages/agromatrix-tools/agromatrix_tools/normalize.py
Normal file
@@ -0,0 +1,51 @@
|
||||
import re
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def parse_quantity(text: str) -> Tuple[float, str]:
|
||||
# supports "2,5 т" and "2.5 t"
|
||||
m = re.search(r"([0-9]+(?:[\.,][0-9]+)?)\s*([a-zA-Zа-яА-Я/]+)", text)
|
||||
if not m:
|
||||
raise ValueError("quantity_not_found")
|
||||
value = float(m.group(1).replace(',', '.'))
|
||||
unit = m.group(2).lower()
|
||||
return value, unit
|
||||
|
||||
|
||||
def parse_rate(text: str) -> Tuple[float, str]:
|
||||
# "150 кг/га"
|
||||
m = re.search(r"([0-9]+(?:[\.,][0-9]+)?)\s*([a-zA-Zа-яА-Я/]+)", text)
|
||||
if not m:
|
||||
raise ValueError("rate_not_found")
|
||||
value = float(m.group(1).replace(',', '.'))
|
||||
unit = m.group(2).lower()
|
||||
return value, unit
|
||||
|
||||
|
||||
def normalize_unit(unit: str, unit_map: dict):
|
||||
unit_cf = unit.casefold().strip()
|
||||
for u in unit_map:
|
||||
if u['id'] == unit_cf:
|
||||
return u['id']
|
||||
if unit_cf == u.get('name','').casefold():
|
||||
return u['id']
|
||||
for s in u.get('synonyms', []):
|
||||
if unit_cf == s.casefold():
|
||||
return u['id']
|
||||
return None
|
||||
|
||||
|
||||
def convert(value: float, from_unit: str, to_unit: str, unit_map: dict) -> float:
|
||||
if from_unit == to_unit:
|
||||
return value
|
||||
units = {u['id']: u for u in unit_map}
|
||||
f = units.get(from_unit)
|
||||
t = units.get(to_unit)
|
||||
if not f or not t:
|
||||
raise ValueError("unit_not_found")
|
||||
# only support to_base conversion for now
|
||||
if f.get('to_base') and f['to_base']['base'] == to_unit:
|
||||
return value * float(f['to_base']['factor'])
|
||||
if t.get('to_base') and t['to_base']['base'] == from_unit:
|
||||
return value / float(t['to_base']['factor'])
|
||||
raise ValueError("conversion_not_supported")
|
||||
Reference in New Issue
Block a user