lingot 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lingot-0.0.1/.github/workflows/ci.yml +18 -0
- lingot-0.0.1/.github/workflows/release.yml +36 -0
- lingot-0.0.1/.gitignore +18 -0
- lingot-0.0.1/PKG-INFO +77 -0
- lingot-0.0.1/README.md +51 -0
- lingot-0.0.1/justfile +25 -0
- lingot-0.0.1/pyproject.toml +57 -0
- lingot-0.0.1/src/lingot/__init__.py +14 -0
- lingot-0.0.1/src/lingot/cli.py +42 -0
- lingot-0.0.1/src/lingot/pipeline.py +49 -0
- lingot-0.0.1/src/lingot/workers.py +78 -0
- lingot-0.0.1/tests/test_smoke.py +14 -0
- lingot-0.0.1/ts/package.json +15 -0
- lingot-0.0.1/ts/src/index.ts +33 -0
- lingot-0.0.1/ts/tsconfig.json +14 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on: [push, pull_request]
|
|
3
|
+
jobs:
|
|
4
|
+
test:
|
|
5
|
+
strategy:
|
|
6
|
+
matrix:
|
|
7
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
8
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
9
|
+
fail-fast: false
|
|
10
|
+
runs-on: ${{ matrix.os }}
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: ${{ matrix.python-version }}
|
|
16
|
+
- run: pip install -e ".[dev]"
|
|
17
|
+
- run: pytest -q
|
|
18
|
+
- run: ruff check src/
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
tags: ["v*"]
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
id-token: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
quality:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
- run: pip install -e ".[dev]"
|
|
19
|
+
- run: pytest -q
|
|
20
|
+
- run: ruff check src/
|
|
21
|
+
- name: Smoke import
|
|
22
|
+
run: python -c "import lingot; print(lingot.__version__)"
|
|
23
|
+
|
|
24
|
+
publish:
|
|
25
|
+
needs: quality
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
environment: release
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v4
|
|
30
|
+
- uses: actions/setup-python@v5
|
|
31
|
+
with:
|
|
32
|
+
python-version: "3.12"
|
|
33
|
+
- run: pip install build twine
|
|
34
|
+
- run: python -m build
|
|
35
|
+
- run: twine check dist/*
|
|
36
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
lingot-0.0.1/.gitignore
ADDED
lingot-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lingot
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Umbrella orchestrator for the Autarkis spatial stack — the mint for embodied-AI ground truth.
|
|
5
|
+
Project-URL: Homepage, https://github.com/Autarkis/lingot
|
|
6
|
+
Project-URL: Repository, https://github.com/Autarkis/lingot
|
|
7
|
+
Project-URL: Issues, https://github.com/Autarkis/lingot/issues
|
|
8
|
+
Author-email: Boris Blosse <borisblosse@gmail.com>
|
|
9
|
+
Keywords: embodied-ai,ground-truth,robotics,simulation,spatial,synthetic-data
|
|
10
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: Other/Proprietary License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: build; extra == 'dev'
|
|
22
|
+
Requires-Dist: pyright>=1.1; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
24
|
+
Requires-Dist: ruff>=0.1; extra == 'dev'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# Lingot
|
|
28
|
+
|
|
29
|
+
**The mint for the reserve currency of embodied AI.** Lingot is the umbrella
|
|
30
|
+
orchestrator of the Autarkis spatial stack — the thin layer that depends on the
|
|
31
|
+
worker services and conducts them through one pipeline:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
spec -> cadastre (registry + solve) -> chitin (physics .phys) -> oneiros (render) -> StagedScene
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Lingot is intentionally thin. It owns the *order* and the *data hand-off*; the
|
|
38
|
+
work lives in the workers, each an independently published package.
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install lingot # Python orchestrator + CLI (PyPI: lingot)
|
|
44
|
+
npm install @autarkis/lingot # JS orchestrator / client (npm bare `lingot` is taken -> scoped)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
> The Rust force-directed solver is **not** vendored here — it ships as its own
|
|
48
|
+
> worker package and is pulled in as a dependency. Lingot orchestrates; it does
|
|
49
|
+
> not implement.
|
|
50
|
+
|
|
51
|
+
## Local development
|
|
52
|
+
|
|
53
|
+
The worker repos are siblings (`../cadastre`, `../chitin`, `../oneiros`). Wire
|
|
54
|
+
them in editable mode, then run the pipeline on a spec:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
just dev-install
|
|
58
|
+
just run path/to/spec.json
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Every pipeline stage delegates to a worker adapter in `src/lingot/workers.py`.
|
|
62
|
+
Stages with no wired worker raise a clear error naming what to connect — the
|
|
63
|
+
skeleton runs end-to-end the moment the seams are filled.
|
|
64
|
+
|
|
65
|
+
## Layout
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
lingot/
|
|
69
|
+
|- src/lingot/ # Python orchestrator
|
|
70
|
+
| |- pipeline.py # stage order + data hand-off
|
|
71
|
+
| |- workers.py # one adapter seam per worker service
|
|
72
|
+
| \- cli.py # `lingot run spec.json`
|
|
73
|
+
|- ts/ # @autarkis/lingot — JS orchestrator / client
|
|
74
|
+
\- justfile # dev / test / build across py + ts
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
See [`../LINGOT.md`](../LINGOT.md) for the full thesis.
|
lingot-0.0.1/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Lingot
|
|
2
|
+
|
|
3
|
+
**The mint for the reserve currency of embodied AI.** Lingot is the umbrella
|
|
4
|
+
orchestrator of the Autarkis spatial stack — the thin layer that depends on the
|
|
5
|
+
worker services and conducts them through one pipeline:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
spec -> cadastre (registry + solve) -> chitin (physics .phys) -> oneiros (render) -> StagedScene
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Lingot is intentionally thin. It owns the *order* and the *data hand-off*; the
|
|
12
|
+
work lives in the workers, each an independently published package.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install lingot # Python orchestrator + CLI (PyPI: lingot)
|
|
18
|
+
npm install @autarkis/lingot # JS orchestrator / client (npm bare `lingot` is taken -> scoped)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
> The Rust force-directed solver is **not** vendored here — it ships as its own
|
|
22
|
+
> worker package and is pulled in as a dependency. Lingot orchestrates; it does
|
|
23
|
+
> not implement.
|
|
24
|
+
|
|
25
|
+
## Local development
|
|
26
|
+
|
|
27
|
+
The worker repos are siblings (`../cadastre`, `../chitin`, `../oneiros`). Wire
|
|
28
|
+
them in editable mode, then run the pipeline on a spec:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
just dev-install
|
|
32
|
+
just run path/to/spec.json
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Every pipeline stage delegates to a worker adapter in `src/lingot/workers.py`.
|
|
36
|
+
Stages with no wired worker raise a clear error naming what to connect — the
|
|
37
|
+
skeleton runs end-to-end the moment the seams are filled.
|
|
38
|
+
|
|
39
|
+
## Layout
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
lingot/
|
|
43
|
+
|- src/lingot/ # Python orchestrator
|
|
44
|
+
| |- pipeline.py # stage order + data hand-off
|
|
45
|
+
| |- workers.py # one adapter seam per worker service
|
|
46
|
+
| \- cli.py # `lingot run spec.json`
|
|
47
|
+
|- ts/ # @autarkis/lingot — JS orchestrator / client
|
|
48
|
+
\- justfile # dev / test / build across py + ts
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
See [`../LINGOT.md`](../LINGOT.md) for the full thesis.
|
lingot-0.0.1/justfile
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Lingot — umbrella orchestrator. Conducts the worker services (cadastre, chitin,
|
|
2
|
+
# oneiros, solver) into a labeled StagedScene. See ../LINGOT.md for the thesis.
|
|
3
|
+
|
|
4
|
+
# Editable-install Lingot + the sibling worker repos for local dev.
|
|
5
|
+
dev-install:
|
|
6
|
+
pip install -e ".[dev]"
|
|
7
|
+
pip install -e ../cadastre || echo "skip cadastre (not pip-installable yet)"
|
|
8
|
+
pip install -e ../chitin || echo "skip chitin"
|
|
9
|
+
pip install -e ../oneiros || echo "skip oneiros"
|
|
10
|
+
|
|
11
|
+
# Run the Python test suite.
|
|
12
|
+
test:
|
|
13
|
+
pytest
|
|
14
|
+
|
|
15
|
+
# Run the pipeline on a spec file.
|
|
16
|
+
run spec:
|
|
17
|
+
lingot run {{spec}}
|
|
18
|
+
|
|
19
|
+
# Build the JS orchestrator (@autarkis/lingot).
|
|
20
|
+
ts-build:
|
|
21
|
+
cd ts && npm install && npm run build
|
|
22
|
+
|
|
23
|
+
# Build the Python wheel.
|
|
24
|
+
build:
|
|
25
|
+
python -m build
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "lingot"
|
|
7
|
+
version = "0.0.1"
|
|
8
|
+
description = "Umbrella orchestrator for the Autarkis spatial stack — the mint for embodied-AI ground truth."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
authors = [{ name = "Boris Blosse", email = "borisblosse@gmail.com" }]
|
|
12
|
+
keywords = ["robotics", "synthetic-data", "simulation", "spatial", "ground-truth", "embodied-ai"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 2 - Pre-Alpha",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Intended Audience :: Science/Research",
|
|
17
|
+
"License :: Other/Proprietary License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
# Worker services Lingot conducts. Commented until published; `just dev-install`
|
|
26
|
+
# editable-installs the sibling repos from ../ for local dev.
|
|
27
|
+
dependencies = [
|
|
28
|
+
# "cadastre",
|
|
29
|
+
# "chitin",
|
|
30
|
+
# "oneiros",
|
|
31
|
+
# "lingot-solver",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.optional-dependencies]
|
|
35
|
+
dev = ["pytest>=7.0", "ruff>=0.1", "pyright>=1.1", "build"]
|
|
36
|
+
|
|
37
|
+
[project.scripts]
|
|
38
|
+
lingot = "lingot.cli:main"
|
|
39
|
+
|
|
40
|
+
[project.urls]
|
|
41
|
+
Homepage = "https://github.com/Autarkis/lingot"
|
|
42
|
+
Repository = "https://github.com/Autarkis/lingot"
|
|
43
|
+
Issues = "https://github.com/Autarkis/lingot/issues"
|
|
44
|
+
|
|
45
|
+
[tool.hatch.build.targets.wheel]
|
|
46
|
+
packages = ["src/lingot"]
|
|
47
|
+
|
|
48
|
+
[tool.ruff]
|
|
49
|
+
target-version = "py310"
|
|
50
|
+
line-length = 100
|
|
51
|
+
|
|
52
|
+
[tool.pyright]
|
|
53
|
+
include = ["src"]
|
|
54
|
+
typeCheckingMode = "standard"
|
|
55
|
+
|
|
56
|
+
[tool.pytest.ini_options]
|
|
57
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Lingot — umbrella orchestrator for the Autarkis spatial stack.
|
|
2
|
+
|
|
3
|
+
Lingot is thin. It depends on the worker services — cadastre (registry + solve),
|
|
4
|
+
chitin (physics compile), oneiros (render) — and conducts them through the
|
|
5
|
+
pipeline that turns a constraint spec into an exported, labeled StagedScene.
|
|
6
|
+
|
|
7
|
+
It is the mint: spec in, certified unit of ground truth out. The workers are the
|
|
8
|
+
machinery; Lingot owns the order and the hand-off. See ../LINGOT.md for the thesis.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from lingot.pipeline import Pipeline, PipelineResult
|
|
12
|
+
|
|
13
|
+
__version__ = "0.0.1"
|
|
14
|
+
__all__ = ["Pipeline", "PipelineResult", "__version__"]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""`lingot` command-line entrypoint."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import json
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from lingot import __version__
|
|
11
|
+
from lingot.pipeline import Pipeline
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main(argv: list[str] | None = None) -> int:
|
|
15
|
+
parser = argparse.ArgumentParser(
|
|
16
|
+
prog="lingot",
|
|
17
|
+
description="Mint a StagedScene from a constraint spec by conducting the worker services.",
|
|
18
|
+
)
|
|
19
|
+
parser.add_argument("--version", action="version", version=f"lingot {__version__}")
|
|
20
|
+
sub = parser.add_subparsers(dest="command", required=True)
|
|
21
|
+
|
|
22
|
+
run = sub.add_parser("run", help="Run the full pipeline on a spec file.")
|
|
23
|
+
run.add_argument("spec", help="Path to a constraint spec (JSON).")
|
|
24
|
+
run.add_argument("-o", "--out", help="Write the StagedScene JSON here (default: stdout).")
|
|
25
|
+
|
|
26
|
+
args = parser.parse_args(argv)
|
|
27
|
+
|
|
28
|
+
if args.command == "run":
|
|
29
|
+
result = Pipeline().run_file(args.spec)
|
|
30
|
+
payload = json.dumps(result.staged_scene, indent=2)
|
|
31
|
+
if args.out:
|
|
32
|
+
Path(args.out).write_text(payload, encoding="utf-8")
|
|
33
|
+
print(f"wrote {args.out}", file=sys.stderr)
|
|
34
|
+
else:
|
|
35
|
+
print(payload)
|
|
36
|
+
return 0
|
|
37
|
+
|
|
38
|
+
return 1
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
if __name__ == "__main__":
|
|
42
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""The Lingot pipeline: constraint spec -> exported, labeled StagedScene.
|
|
2
|
+
|
|
3
|
+
Stage order mirrors the stack architecture:
|
|
4
|
+
|
|
5
|
+
spec --> registry(build) --> solver(resolve) --> chitin(compile physics)
|
|
6
|
+
--> oneiros(render) --> export(StagedScene)
|
|
7
|
+
|
|
8
|
+
Lingot owns the order and the data hand-off; each stage is delegated to a worker
|
|
9
|
+
adapter (see workers.py). A stage with no wired worker raises a clear
|
|
10
|
+
NotImplementedError naming what to wire — the skeleton runs end-to-end the moment
|
|
11
|
+
the seams are filled.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import json
|
|
17
|
+
from dataclasses import dataclass, field
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
from lingot.workers import Workers, load_default_workers
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class PipelineResult:
|
|
26
|
+
staged_scene: dict[str, Any]
|
|
27
|
+
artifacts: dict[str, Any] = field(default_factory=dict)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class Pipeline:
|
|
32
|
+
"""Conducts the worker services through the scene-minting pipeline."""
|
|
33
|
+
|
|
34
|
+
workers: Workers = field(default_factory=load_default_workers)
|
|
35
|
+
|
|
36
|
+
def run(self, spec: dict[str, Any]) -> PipelineResult:
|
|
37
|
+
w = self.workers
|
|
38
|
+
|
|
39
|
+
scene = w.require("registry").build_scene(spec)
|
|
40
|
+
scene = w.require("solver").resolve(scene)
|
|
41
|
+
scene = w.require("compiler").compile_physics(scene)
|
|
42
|
+
scene = w.require("renderer").render(scene)
|
|
43
|
+
staged = w.require("exporter").export(scene)
|
|
44
|
+
|
|
45
|
+
return PipelineResult(staged_scene=staged)
|
|
46
|
+
|
|
47
|
+
def run_file(self, spec_path: str | Path) -> PipelineResult:
|
|
48
|
+
spec = json.loads(Path(spec_path).read_text(encoding="utf-8"))
|
|
49
|
+
return self.run(spec)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""Adapters to the worker services Lingot orchestrates.
|
|
2
|
+
|
|
3
|
+
Each Protocol below is the seam between Lingot (the conductor) and one worker
|
|
4
|
+
package (the instrument). Wiring a real tool means implementing one adapter and
|
|
5
|
+
pointing it at that worker's real entrypoint — nothing else in the pipeline moves.
|
|
6
|
+
|
|
7
|
+
Status: seams defined, real wiring TODO. We deliberately do NOT guess the workers'
|
|
8
|
+
public APIs here (verify before calling); each adapter names the tool and the
|
|
9
|
+
stage it owns so wiring is a localized, one-file job.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from dataclasses import dataclass
|
|
15
|
+
from typing import Any, Protocol
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# --- Worker seams (one per stage of the mint) ------------------------------
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Registry(Protocol):
|
|
22
|
+
"""cadastre — the spatial identity tree the scene is struck against."""
|
|
23
|
+
|
|
24
|
+
def build_scene(self, spec: dict[str, Any]) -> Any: ...
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Solver(Protocol):
|
|
28
|
+
"""force-directed constraint solver — resolves typed intent into geometry."""
|
|
29
|
+
|
|
30
|
+
def resolve(self, scene: Any) -> Any: ...
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class Compiler(Protocol):
|
|
34
|
+
"""chitin — bakes physics, emitting .phys collider sidecars."""
|
|
35
|
+
|
|
36
|
+
def compile_physics(self, scene: Any) -> Any: ...
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class Renderer(Protocol):
|
|
40
|
+
"""oneiros — casts the photoreal surface (Cosmos bridge) over the structure."""
|
|
41
|
+
|
|
42
|
+
def render(self, scene: Any) -> Any: ...
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class Exporter(Protocol):
|
|
46
|
+
"""scene_to_dict / StagedScene — JSON interchange Atrium and FiftyOne consume."""
|
|
47
|
+
|
|
48
|
+
def export(self, scene: Any) -> dict[str, Any]: ...
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass
|
|
52
|
+
class Workers:
|
|
53
|
+
"""Container of wired worker adapters. Unwired seams raise a clear error."""
|
|
54
|
+
|
|
55
|
+
registry: Registry | None = None
|
|
56
|
+
solver: Solver | None = None
|
|
57
|
+
compiler: Compiler | None = None
|
|
58
|
+
renderer: Renderer | None = None
|
|
59
|
+
exporter: Exporter | None = None
|
|
60
|
+
|
|
61
|
+
def require(self, name: str) -> Any:
|
|
62
|
+
worker = getattr(self, name)
|
|
63
|
+
if worker is None:
|
|
64
|
+
raise NotImplementedError(
|
|
65
|
+
f"Lingot worker '{name}' is not wired yet. Implement the {name!r} "
|
|
66
|
+
f"adapter against the real package and pass it into "
|
|
67
|
+
f"Pipeline(workers=Workers({name}=...))."
|
|
68
|
+
)
|
|
69
|
+
return worker
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def load_default_workers() -> Workers:
|
|
73
|
+
"""Best-effort discovery of installed worker packages.
|
|
74
|
+
|
|
75
|
+
Returns an empty Workers() for now — real adapters land here as each tool's
|
|
76
|
+
public API is verified (`just dev-install` makes the sibling repos importable).
|
|
77
|
+
"""
|
|
78
|
+
return Workers()
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from lingot import Pipeline, __version__
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_version():
|
|
7
|
+
assert __version__ == "0.0.1"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_unwired_stage_raises_clear_error():
|
|
11
|
+
# Every stage delegates to a worker adapter; with none wired, the first stage
|
|
12
|
+
# must fail loudly and name what to wire.
|
|
13
|
+
with pytest.raises(NotImplementedError, match="registry"):
|
|
14
|
+
Pipeline().run({})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@autarkis/lingot",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "The mint for the reserve currency of embodied AI — JS-side orchestrator/client for the Autarkis spatial stack.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": ["dist"],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"test": "node --test"
|
|
12
|
+
},
|
|
13
|
+
"license": "UNLICENSED",
|
|
14
|
+
"private": true
|
|
15
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @autarkis/lingot — JS-side orchestrator / client for the Autarkis spatial stack.
|
|
3
|
+
*
|
|
4
|
+
* The bare npm name `lingot` is taken by an unrelated package, so the JS package
|
|
5
|
+
* is scoped under the org: `@autarkis/lingot`. (PyPI keeps the bare `lingot`.)
|
|
6
|
+
*
|
|
7
|
+
* Lingot is thin: it conducts the worker services and surfaces the StagedScene —
|
|
8
|
+
* the JSON interchange Atrium and FiftyOne consume — to JS/TS consumers.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export interface StagedScene {
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface PipelineResult {
|
|
16
|
+
stagedScene: StagedScene;
|
|
17
|
+
artifacts: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Conducts the worker services. Real transport — HTTP/IPC to the Python
|
|
22
|
+
* pipeline, or the solver wasm binding — lands behind this seam.
|
|
23
|
+
*/
|
|
24
|
+
export class Lingot {
|
|
25
|
+
async run(_spec: Record<string, unknown>): Promise<PipelineResult> {
|
|
26
|
+
throw new Error(
|
|
27
|
+
"Lingot JS orchestrator is not wired yet: connect run() to the Python " +
|
|
28
|
+
"pipeline (HTTP/IPC) or the solver wasm binding.",
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const VERSION = "0.0.1";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ES2022",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"rootDir": "src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src"]
|
|
14
|
+
}
|