lingot 0.0.1__py3-none-any.whl

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/__init__.py ADDED
@@ -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__"]
lingot/cli.py ADDED
@@ -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())
lingot/pipeline.py ADDED
@@ -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)
lingot/workers.py ADDED
@@ -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,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.
@@ -0,0 +1,8 @@
1
+ lingot/__init__.py,sha256=YgYcS0UeYA0oIXEfcmdvI4IOCn0A1uaiqEFKhhdfMOw,609
2
+ lingot/cli.py,sha256=TFpnfCZ6xR8SsXfzlC409RgKTsLWoiUzTEH68_85rLo,1270
3
+ lingot/pipeline.py,sha256=Z-ucovz9JrEE2jMjwKsG5EFljbNi-edBKV3v1L_jnro,1586
4
+ lingot/workers.py,sha256=_wDO1BSTTN5MACYFtIOJrnFwwnO_PPFZT3n29bR2uDs,2494
5
+ lingot-0.0.1.dist-info/METADATA,sha256=X8xPXX68GoFXCX9C6_weJDoCnJy9uVKPBygH6C_-Avo,2896
6
+ lingot-0.0.1.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
7
+ lingot-0.0.1.dist-info/entry_points.txt,sha256=pyFF4AyR825yM-Q1eya3fgVYdMpNUpnk0VmkrVey92U,43
8
+ lingot-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ lingot = lingot.cli:main