build(agent): new-agents-3#dd492b iteration
This commit is contained in:
parent
3a47b7543b
commit
9bf7ac20d2
|
|
@ -0,0 +1,21 @@
|
|||
node_modules/
|
||||
.npmrc
|
||||
.env
|
||||
.env.*
|
||||
__tests__/
|
||||
coverage/
|
||||
.nyc_output/
|
||||
dist/
|
||||
build/
|
||||
.cache/
|
||||
*.log
|
||||
.DS_Store
|
||||
tmp/
|
||||
.tmp/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
venv/
|
||||
*.egg-info/
|
||||
.pytest_cache/
|
||||
READY_TO_PUBLISH
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# NeuPlan Architecture and Guidelines
|
||||
|
||||
- Purpose
|
||||
- Provide a production-ready scaffold for a neuromorphic planning stack, enabling end-to-end wiring from a lightweight DSL to a neuromorphic backend.
|
||||
- Tech Stack
|
||||
- Language: Python 3.9+
|
||||
- Packaging: pyproject.toml with setuptools
|
||||
- Core modules: neuplan.dsl (LocalProblem, PlanDelta, SharedVariables, to_nir), neuplan.runtime (OnboardRuntime), neuplan.backends.loihi (LoihiBackend)
|
||||
- Testing
|
||||
- test.sh should execute: python -m build, pytest
|
||||
- Testing commands
|
||||
- Build: python3 -m build
|
||||
- Run tests: pytest -q
|
||||
- Contribution
|
||||
- Create a feature branch, implement, run tests, and open a PR. Include README updates and READY_TO_PUBLISH if ready.
|
||||
19
README.md
19
README.md
|
|
@ -1,3 +1,18 @@
|
|||
# neuplan-neuromorphic-compiler-runtime-fo
|
||||
# NeuPlan MVP
|
||||
|
||||
Problem: Space robotics fleets require autonomous planning with strict energy budgets and intermittent connectivity. Conventional CPU-based planners struggle to deliver low-latency, energy-efficient inference for onboard AGI reasoning, while external
|
||||
This repository contains a minimal, production-oriented scaffold for a neuromorphic planning
|
||||
stack intended for onboard autonomous planning in space robotics contexts. The MVP focuses on
|
||||
providing a DSL, a toy neuromorphic intermediate representation (N-IR), a backend shim, and a
|
||||
deterministic onboard runtime that can be extended to real neuromorphic hardware.
|
||||
|
||||
Highlights
|
||||
- DSL for LocalProblem, PlanDelta, and SharedVariables
|
||||
- Toy translation to N-IR suitable for testing and integration
|
||||
- Loihi-like backend shim with deterministic latency/energy model
|
||||
- Onboard runtime to execute planning within strict budgets
|
||||
- Basic tests ensuring end-to-end flow and a minimal demo CLI
|
||||
|
||||
Installation and testing
|
||||
- Run: ./test.sh (requires Python 3.9+ and build tools; creates a virtual environment automatically during build)
|
||||
|
||||
This is an early-stage MVP; expect to see iterative improvements with governance, safety, and HIL features in subsequent iterations.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
"""NeuPlan: toy neuromorphic planning stack scaffold.
|
||||
|
||||
This package provides a minimal, production-oriented scaffold for a
|
||||
NeuPlan MVP: DSL types, a neuromorphic IR translator, a backend shim,
|
||||
and an onboard runtime that can be wired to actual neuromorphic hardware.
|
||||
"""
|
||||
|
||||
from . import dsl
|
||||
from . import runtime
|
||||
from . import backends
|
||||
|
||||
__all__ = ["dsl", "runtime", "backends"]
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
from .loihi import LoihiBackend
|
||||
|
||||
__all__ = ["LoihiBackend"]
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
"""Toy Loihi-like backend for NeuPlan MVP.
|
||||
|
||||
This is a lightweight simulator that pretends to run a neuromorphic graph on
|
||||
Loihi-like hardware. It converts a NeuPlan NIR (toy dict) into a latency/energy
|
||||
estimate and returns a simple executable plan skeleton.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Dict, Any, List
|
||||
|
||||
|
||||
class LoihiBackend:
|
||||
def __init__(self, quantization_bits: int = 8, time_scale: float = 1.0) -> None:
|
||||
self.quantization_bits = quantization_bits
|
||||
self.time_scale = time_scale
|
||||
|
||||
def run(self, nir: Dict[str, Any], time_budget_s: float) -> Dict[str, Any]:
|
||||
nodes: List[Dict[str, Any]] = nir.get("nodes", [])
|
||||
# naive latency model: 5ms per node scaled by time_scale
|
||||
latency = max(0.001, len(nodes) * 0.005 / max(1e-6, self.time_scale))
|
||||
status = "ok" if latency <= time_budget_s else "timeout"
|
||||
energy = max(0.01, len(nodes) * 0.02)
|
||||
plan = {"steps": [{"node": n} for n in nodes]}
|
||||
return {
|
||||
"status": status,
|
||||
"latency_s": latency,
|
||||
"energy_j": energy,
|
||||
"plan": plan,
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
"""Minimal command-line interface to exercise NeuPlan MVP."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import List
|
||||
from neuplan.dsl import LocalProblem, PlanDelta, SharedVariables
|
||||
from neuplan.backends.loihi import LoihiBackend
|
||||
from neuplan.runtime import OnboardRuntime
|
||||
from neuplan.dsl import to_nir
|
||||
|
||||
|
||||
def demo():
|
||||
# Simple demo problem: two assets with a delta depending on energy
|
||||
lp1 = LocalProblem(asset="rover1", constraints={"max_speed": 5}, objective={"energy": 1.0})
|
||||
lp2 = LocalProblem(asset="droneA", constraints={"max_alt": 100}, objective={"energy": 0.8})
|
||||
delta = PlanDelta(delta_id="d1", changes={"requires": ["rover1"]})
|
||||
shared = SharedVariables(variables={"global_time": 0})
|
||||
|
||||
nir = to_nir([lp1, lp2], [delta], shared)
|
||||
backend = LoihiBackend()
|
||||
runtime = OnboardRuntime(backend)
|
||||
res = runtime.plan([lp1, lp2], [delta], shared, time_budget_s=2.0)
|
||||
print("NIR:", json.dumps(nir, indent=2))
|
||||
print("Result:", json.dumps(res, indent=2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo()
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
"""NeuPlan DSL: minimal LocalProblem / PlanDelta / SharedVariables model.
|
||||
|
||||
This is a lightweight, easily testable sketch translating planning problems
|
||||
into a toy neuromorphic intermediate representation (N-IR).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Dict, List, Any
|
||||
import time
|
||||
|
||||
|
||||
@dataclass
|
||||
class LocalProblem:
|
||||
asset: str
|
||||
constraints: Dict[str, Any] = field(default_factory=dict)
|
||||
objective: Dict[str, float] = field(default_factory=dict)
|
||||
|
||||
|
||||
@dataclass
|
||||
class PlanDelta:
|
||||
delta_id: str
|
||||
changes: Dict[str, Any] = field(default_factory=dict)
|
||||
timestamp: float = field(default_factory=lambda: time.time())
|
||||
|
||||
|
||||
@dataclass
|
||||
class SharedVariables:
|
||||
variables: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
|
||||
def to_nir(local_problems: List[LocalProblem], deltas: List[PlanDelta], shared: SharedVariables) -> Dict[str, Any]:
|
||||
"""Translate a set of problems/deltas into a toy neuromorphic IR.
|
||||
|
||||
The real project would generate a graph of spiking neurons with temporal
|
||||
dynamics encoding constraints; here we emit a deterministic, testable
|
||||
toy representation for MVP validation and integration testing.
|
||||
"""
|
||||
nodes: List[Dict[str, Any]] = []
|
||||
edges: List[Dict[str, Any]] = []
|
||||
|
||||
# Create nodes for LocalProblems
|
||||
for idx, lp in enumerate(local_problems):
|
||||
n = {
|
||||
"id": f"LP:{idx}:{lp.asset}",
|
||||
"type": "LocalProblem",
|
||||
"asset": lp.asset,
|
||||
"constraints": lp.constraints,
|
||||
"objective": lp.objective,
|
||||
}
|
||||
nodes.append(n)
|
||||
|
||||
# Create nodes for each PlanDelta
|
||||
for d in deltas:
|
||||
n = {
|
||||
"id": f"DELTA:{d.delta_id}",
|
||||
"type": "PlanDelta",
|
||||
"delta_id": d.delta_id,
|
||||
"changes": d.changes,
|
||||
"timestamp": d.timestamp,
|
||||
}
|
||||
nodes.append(n)
|
||||
|
||||
# Shared variables as a single hub node if present
|
||||
if shared and shared.variables:
|
||||
nodes.append({"id": "SharedVariables:root", "type": "SharedVariables", "payload": shared.variables})
|
||||
|
||||
# Simplified edges: connect LocalProblems to Delta changes if named in constraints
|
||||
for lp in local_problems:
|
||||
for d in deltas:
|
||||
if lp.asset in (d.changes.get("requires", []) or []):
|
||||
edges.append({"src": f"LP:{local_problems.index(lp)}:{lp.asset}", "dst": f"DELTA:{d.delta_id}"})
|
||||
|
||||
return {"nodes": nodes, "edges": edges}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
"""OnboardRuntime: minimal deterministic planner runtime scaffold."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Dict, Any
|
||||
from time import time
|
||||
|
||||
from .dsl import LocalProblem, PlanDelta, SharedVariables, to_nir
|
||||
|
||||
|
||||
class OnboardRuntime:
|
||||
def __init__(self, backend) -> None:
|
||||
# backend expected to implement run(nir: dict, time_budget_s: float) -> dict
|
||||
self.backend = backend
|
||||
|
||||
def plan(self, local_problems: List[LocalProblem], deltas: List[PlanDelta], shared: SharedVariables, time_budget_s: float) -> Dict[str, Any]:
|
||||
nir = to_nir(local_problems, deltas, shared)
|
||||
result = self.backend.run(nir, time_budget_s)
|
||||
# Attach some provenance-like fields for auditing in MVP
|
||||
result["timestamp"] = time()
|
||||
result["nir"] = nir
|
||||
return result
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
[build-system]
|
||||
requires = ["setuptools>=61.0", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "neuplan"
|
||||
version = "0.1.0"
|
||||
description = "Prototype NeuPlan: neuromorphic planning stack (toy)"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.9"
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://example.com/neuplan"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["neuplan"]
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "Running Python build to verify packaging metadata..."
|
||||
python3 -m build
|
||||
|
||||
echo "Running tests..."
|
||||
pytest -q
|
||||
|
||||
echo "Tests completed successfully."
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import json
|
||||
import sys
|
||||
import os
|
||||
# Ensure local package path is discoverable when running from the repo root
|
||||
repo_root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
if repo_root not in sys.path:
|
||||
sys.path.insert(0, repo_root)
|
||||
|
||||
from neuplan.dsl import LocalProblem, PlanDelta, SharedVariables
|
||||
from neuplan.dsl import to_nir
|
||||
from neuplan.backends.loihi import LoihiBackend
|
||||
from neuplan.runtime import OnboardRuntime
|
||||
|
||||
|
||||
def test_nir_generation_and_runtime_plan():
|
||||
lp1 = LocalProblem(asset="rover1", constraints={"max_speed": 5}, objective={"energy": 1.0})
|
||||
lp2 = LocalProblem(asset="droneA", constraints={"max_alt": 100}, objective={"energy": 0.8})
|
||||
delta = PlanDelta(delta_id="d1", changes={"requires": ["rover1"]})
|
||||
shared = SharedVariables(variables={"global_time": 0})
|
||||
|
||||
nir = to_nir([lp1, lp2], [delta], shared)
|
||||
assert isinstance(nir, dict)
|
||||
assert "nodes" in nir and "edges" in nir
|
||||
|
||||
backend = LoihiBackend()
|
||||
runtime = OnboardRuntime(backend)
|
||||
res = runtime.plan([lp1, lp2], [delta], shared, time_budget_s=2.0)
|
||||
assert res["status"] in {"ok", "timeout"}
|
||||
assert "plan" in res
|
||||
Loading…
Reference in New Issue