Metadata-Version: 2.4
Name: bowerbot-skill-kit
Version: 0.2.0
Summary: BowerBot skill that drives a live NVIDIA Omniverse Kit app over HTTP
Keywords: bowerbot,bowerbot-skill,omniverse,kit,nvidia,usd,openusd,3d
Author: Arturo Morales Rangel
Author-email: Arturo Morales Rangel <arangel@binarycore.us>
License-Expression: Apache-2.0
Requires-Dist: bowerbot>=1.5,<2
Requires-Dist: requests>=2.32,<3
Requires-Dist: pydantic>=2.0,<3
Requires-Dist: pytest>=8.0,<10 ; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23,<2 ; extra == 'dev'
Requires-Dist: ruff>=0.4,<1 ; extra == 'dev'
Requires-Python: >=3.12
Project-URL: Homepage, https://github.com/binary-core-llc/bowerbot-skill-kit
Project-URL: Issues, https://github.com/binary-core-llc/bowerbot-skill-kit/issues
Project-URL: BowerBot core, https://github.com/binary-core-llc/bowerbot
Project-URL: Kit extension, https://github.com/binary-core-llc/bowerbot-kit
Provides-Extra: dev
Description-Content-Type: text/markdown

<div align="center">

# bowerbot-skill-kit

**NVIDIA Omniverse Kit provider skill for [BowerBot](https://github.com/binary-core-llc/bowerbot).**

Drives a live Kit app (Isaac Sim, USD Composer, custom Kit apps) over HTTP through the
[bowerbot.kit](https://github.com/binary-core-llc/bowerbot-kit) extension.

[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![Python](https://img.shields.io/badge/Python-3.12+-blue)](https://www.python.org/)
[![Built by Binary Core LLC](https://img.shields.io/badge/Built%20by-Binary%20Core%20LLC-black)](https://binarycore.us)

</div>

---

## What it does

This skill is the BowerBot half of a two-part integration. The other half is the
[`bowerbot.kit`](https://github.com/binary-core-llc/bowerbot-kit) Kit extension, which runs
inside a live Omniverse Kit app and exposes generic Kit operations over HTTP on port 8900.
This skill calls those endpoints.

It exposes eight LLM-callable tools — one per Kit operation:

| Tool | Description |
|------|-------------|
| `get_kit_info` | Confirm a live Kit app is reachable; read its instance and companions |
| `play_timeline` | Start the timeline (drives PhysX if loaded) |
| `pause_timeline` | Pause the timeline |
| `step_timeline` | Advance the timeline a fixed number of frames |
| `read_transform` | Read a prim's runtime transform from Kit's live memory |
| `capture_viewport` | Render the active viewport to a PNG on the Kit machine |
| `get_selection` | Read the current Kit UI selection |
| `set_selection` | Set the Kit UI selection (empty list clears it) |

These cover only operations that **require a running Kit app** and cannot be done by reading
USD off disk. Anything BowerBot can do alone (listing prims, reading authored transforms)
stays in BowerBot core. Zero duplication.

## Install

Match the install method you used for BowerBot itself.

If you installed BowerBot with `uv tool install`, add the skill to the same tool environment:

```bash
uv tool install bowerbot --with bowerbot-skill-kit --reinstall
```

If you installed BowerBot with `pip` (in a venv or system-wide), install the skill into the
same Python environment:

```bash
pip install bowerbot-skill-kit
```

BowerBot discovers the skill automatically via Python entry points (`bowerbot.skills`). No
code changes required in BowerBot.

You must also install and enable the [`bowerbot.kit`](https://github.com/binary-core-llc/bowerbot-kit)
extension in your Kit app — this skill is only the client half.

## Configure

The skill requires `base_url` pointing at the host Kit app's HTTP transport. Add a `kit`
block to `~/.bowerbot/config.json` (the bundled `bowerbot.kit` extension binds
`http://127.0.0.1:8900` by default):

```json
{
  "skills": {
    "kit": {
      "enabled": true,
      "config": { "base_url": "http://127.0.0.1:8900" }
    }
  }
}
```

## Usage

Once installed and configured, the skill is just available to BowerBot. Talk to the agent
normally:

```
You: is my Kit app connected?
BowerBot: Yes — bowerbot.kit (instance "default") is reachable.

You: run the simulation for 60 frames and tell me where the ball ended up
BowerBot: Stepped 60 frames. /World/Ball is now at (3.2, 0.0, -1.8).

You: grab a screenshot of the viewport
BowerBot: Captured to C:/captures/viewport_capture.png
```

## Architecture

This skill follows BowerBot's required FastAPI-style internal layout:

```
src/bowerbot_skill_kit/
  skill.py          # Skill subclass. Tool registration + execute() dispatch only.
  SKILL.md          # Natural-language instructions injected into the LLM prompt.
  schemas/          # Pydantic request + response models, one module per domain
  services/         # Orchestrators, one function per tool, grouped by domain
  tools/            # Tool definitions surfaced to the LLM
  utils/            # Pure-function primitives (HTTP transport + parsing)
```

Each tool maps to one service function that calls exactly one kit endpoint — no action
multiplexing. Caller params are validated by constructing the domain's pydantic request
schema; only `utils/` touches the HTTP library, so services stay transport-agnostic. This
mirrors the `bowerbot.kit` extension's own `endpoint -> service -> utils` rule and its
pydantic-validated request bodies.

The skill is **hyper-isolated**: it imports only from `bowerbot.skills` (the public SDK) and
its own submodules.

## Development

Default flow uses BowerBot from PyPI:

```bash
git clone https://github.com/binary-core-llc/bowerbot-skill-kit.git
cd bowerbot-skill-kit
uv sync --extra dev
uv run pytest
```

If you are also working on BowerBot itself and want an editable install of the core against
your local checkout, run this **after** `uv sync`:

```bash
uv pip install -e ../bowerbot
```

The live integration tests automatically skip unless a `bowerbot.kit` extension is answering
on `http://127.0.0.1:8900`.

## License

Apache 2.0. See [LICENSE](LICENSE).

---

Built with 🐦 by [Binary Core LLC](https://binarycore.us)
