Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ Pull narrower resources only when needed:
- Prefer the bridge-backed `.mcp.json` entry when you want Codex to start LichtFeld for you. Use the raw HTTP endpoint only if LichtFeld is already running.
- Prefer resources for discovery and current state; use tools for mutations.
- Check tool metadata before invoking: `category`, `kind`, `runtime`, `thread_affinity`, `destructive`, `long_running`, `user_visible`.
- For long-running operations, pair the mutating call with `runtime.job.describe`, `runtime.job.wait`, or `runtime.events.tail` instead of sleeping.
- For long-running operations, pair the mutating call with `runtime_job_describe`, `runtime_job_wait`, or `runtime_events_tail` instead of sleeping.
- Do not guess operator ids, menu paths, panel ids, or UI tool ids. Read `operators/registry`, `ui/tools`, or `ui/menus` first.
- After selection writes, confirm with `selection.get` or `lichtfeld://selection/current`.
- Scene exports are synchronous in the current GUI implementation. `scene.export_status` reports idle semantics and `scene.export_cancel` cannot stop an export once started.
- `editor.run` can wait inline. For longer scripts, use `editor.is_running`, `editor.wait`, and `editor.get_output`.
- After selection writes, confirm with `selection_get` or `lichtfeld://selection/current`.
- Scene exports are synchronous in the current GUI implementation. `scene_export_status` reports idle semantics and `scene_export_cancel` cannot stop an export once started.
- `editor_run` can wait inline. For longer scripts, use `editor_is_running`, `editor_wait`, and `editor_get_output`.

## Important Runtime Job IDs

Expand All @@ -51,23 +51,23 @@ Pull narrower resources only when needed:

### Load Dataset And Train

- `scene.load_dataset` or `scene.load_checkpoint`
- `scene_load_dataset` or `scene_load_checkpoint`
- read `lichtfeld://scene/state`
- `training.start`
- watch `training.main` through `runtime.job.*` or `runtime.events.tail`
- `training_start`
- watch `training.main` through `runtime_job_*` or `runtime_events_tail`

### Manipulate UI Or Operators

- read `lichtfeld://ui/state`
- inspect `lichtfeld://ui/tools`, `lichtfeld://ui/menus`, or `lichtfeld://operators/registry`
- call `ui.*` or `operator.*`
- call `ui_*` or `operator_*`
- if the tool goes modal, watch `operator.modal` and `lichtfeld://operators/modal_state`

### Work On Gaussian Selection

- use `selection.rect`, `selection.click`, `selection.brush`, `selection.lasso`, or `selection.by_description`
- verify via `selection.get` or `lichtfeld://selection/current`
- then call `gaussians.read`, `gaussians.write`, `transform.*`, `scene.*`, or `operator.invoke`
- use `selection_rect`, `selection_click`, `selection_brush`, `selection_lasso`, or `selection_by_description`
- verify via `selection_get` or `lichtfeld://selection/current`
- then call `gaussians_read`, `gaussians_write`, `transform_*`, `scene_*`, or `operator_invoke`

## Docs

Expand Down
14 changes: 7 additions & 7 deletions docs/docs/development/mcp/bootstrap.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ For most tasks, resources answer the first two questions an agent needs:

## How To Pick The Next Namespace

- Need dataset import, training, or export progress: start with `runtime.*`
- Need toolbar, menu, or panel actions: start with `ui.*`
- Need operator ids or schemas: start with `operator.*` or `lichtfeld://operators/registry`
- Need visible Gaussians or scene nodes: start with `selection.*`, `gaussians.*`, or `scene.*`
- Need Python execution inside the app: start with `editor.*`
- Need dataset import, training, or export progress: start with `runtime_*`
- Need toolbar, menu, or panel actions: start with `ui_*`
- Need operator ids or schemas: start with `operator_*` or `lichtfeld://operators/registry`
- Need visible Gaussians or scene nodes: start with `selection_*`, `gaussians_*`, or `scene_*`
- Need Python execution inside the app: start with `editor_*`

## Minimal Mutation Pattern

Expand All @@ -44,7 +44,7 @@ Use the same pattern for most tasks:
1. Read the relevant resource.
2. Invoke the tool with explicit arguments.
3. Read back the narrowest state resource.
4. If the action is long-running, switch to `runtime.job.wait` or `runtime.events.tail`.
4. If the action is long-running, switch to `runtime_job_wait` or `runtime_events_tail`.

## Long-Running Jobs

Expand All @@ -61,7 +61,7 @@ Example wait loop:

```json
{
"tool": "runtime.job.wait",
"tool": "runtime_job_wait",
"arguments": {
"job_id": "training.main",
"until": "changed",
Expand Down
34 changes: 17 additions & 17 deletions docs/docs/development/mcp/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ Then narrow further:

| Namespace | Use |
| --- | --- |
| `scene.*` | Load datasets, checkpoints, scene nodes, exports |
| `training.*` | Training state, loss, and training control |
| `runtime.*` | Normalized job and event tracking |
| `ui.tool.*`, `ui.menu.*`, `ui.panel.*`, `ui.operator.*` | Drive the registered GUI surface |
| `operator.*` | Introspect and invoke registered GUI operators, including modal flows |
| `selection.*` | Screen-space Gaussian selection |
| `transform.*` | Node transform inspection and edits |
| `gaussians.*` | Raw Gaussian tensor reads and writes |
| `history.*` | Shared undo/redo inspection, playback, and grouped transactions |
| `editor.*` | Integrated Python console execution |
| `camera.*`, `render.*`, `sequencer.*` | View state, captures, and timeline workflows |
| `scene_*` | Load datasets, checkpoints, scene nodes, exports |
| `training_*` | Training state, loss, and training control |
| `runtime_*` | Normalized job and event tracking |
| `ui_tool_*`, `ui_menu_*`, `ui_panel_*`, `ui_operator_*` | Drive the registered GUI surface |
| `operator_*` | Introspect and invoke registered GUI operators, including modal flows |
| `selection_*` | Screen-space Gaussian selection |
| `transform_*` | Node transform inspection and edits |
| `gaussians_*` | Raw Gaussian tensor reads and writes |
| `history_*` | Shared undo/redo inspection, playback, and grouped transactions |
| `editor_*` | Integrated Python console execution |
| `camera_*`, `render_*`, `sequencer_*` | View state, captures, and timeline workflows |

## Runtime Model

Expand All @@ -64,11 +64,11 @@ Then narrow further:

When a tool can block or keep running, use the runtime APIs instead of sleeping:

- `runtime.job.list`
- `runtime.job.describe`
- `runtime.job.wait`
- `runtime.job.control`
- `runtime.events.tail`
- `runtime_job_list`
- `runtime_job_describe`
- `runtime_job_wait`
- `runtime_job_control`
- `runtime_events_tail`

## Recommended Reading Order

Expand All @@ -79,5 +79,5 @@ When a tool can block or keep running, use the runtime APIs instead of sleeping:

- Do not guess operator ids or modal event shapes.
- Do not scan the entire source tree before checking `resources/list`, `tools/list`, and the bootstrap resources.
- Do not poll blindly when `runtime.job.wait` or `runtime.events.tail` can tell you what changed.
- Do not poll blindly when `runtime_job_wait` or `runtime_events_tail` can tell you what changed.
- Do not assume exports are asynchronous in the current GUI implementation.
24 changes: 12 additions & 12 deletions docs/docs/development/mcp/recipes/editor-and-runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ Use this flow when the task is to execute Python inside the integrated editor an

## Sequence

1. Optionally call `editor.set_code`.
2. Call `editor.run`.
3. If the script is still running, watch `editor.python` through `runtime.job.wait`.
4. Read output with `editor.get_output` or `lichtfeld://editor/output`.
1. Optionally call `editor_set_code`.
2. Call `editor_run`.
3. If the script is still running, watch `editor.python` through `runtime_job_wait`.
4. Read output with `editor_get_output` or `lichtfeld://editor/output`.

## Set Code

```json
{
"tool": "editor.set_code",
"tool": "editor_set_code",
"arguments": {
"code": "print('hello from MCP')",
"show_console": true
Expand All @@ -29,7 +29,7 @@ Use this flow when the task is to execute Python inside the integrated editor an

```json
{
"tool": "editor.run",
"tool": "editor_run",
"arguments": {
"wait_for_completion": true,
"wait_for_output": true,
Expand All @@ -42,7 +42,7 @@ Or set and run in one call:

```json
{
"tool": "editor.run",
"tool": "editor_run",
"arguments": {
"code": "print('hello from MCP')",
"wait_for_completion": true,
Expand All @@ -56,7 +56,7 @@ Or set and run in one call:

```json
{
"tool": "runtime.job.wait",
"tool": "runtime_job_wait",
"arguments": {
"job_id": "editor.python",
"until": "inactive",
Expand All @@ -69,7 +69,7 @@ Or set and run in one call:

```json
{
"tool": "editor.get_output",
"tool": "editor_get_output",
"arguments": {
"max_chars": 20000,
"tail": true
Expand All @@ -79,6 +79,6 @@ Or set and run in one call:

## Notes

- `editor.run` can place code into the editor and execute it in one step
- use `editor.is_running` for a cheap status check
- use `editor.interrupt` if the script must be stopped
- `editor_run` can place code into the editor and execute it in one step
- use `editor_is_running` for a cheap status check
- use `editor_interrupt` if the script must be stopped
22 changes: 11 additions & 11 deletions docs/docs/development/mcp/recipes/export-scene.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ Use this flow when you need to export one or more scene nodes to `PLY`, `SOG`, `

## Sequence

1. Read `lichtfeld://scene/nodes` or call `scene.list_nodes`.
1. Read `lichtfeld://scene/nodes` or call `scene_list_nodes`.
2. Choose either a single `node` or a list of `nodes`.
3. Call one of the `scene.export_*` tools.
3. Call one of the `scene_export_*` tools.
4. Treat the export as synchronous in the current GUI implementation.

## Export To PLY

```json
{
"tool": "scene.export_ply",
"tool": "scene_export_ply",
"arguments": {
"path": "/tmp/export.ply",
"node": "training_model",
Expand All @@ -28,30 +28,30 @@ Use this flow when you need to export one or more scene nodes to `PLY`, `SOG`, `

Other export entry points:

- `scene.export_sog`
- `scene.export_spz`
- `scene.export_usd`
- `scene.export_html`
- `scene_export_sog`
- `scene_export_spz`
- `scene_export_usd`
- `scene_export_html`

## Status And Cancellation

These tools document the current execution model:

```json
{
"tool": "scene.export_status",
"tool": "scene_export_status",
"arguments": {}
}
```
```json
{
"tool": "scene.export_cancel",
"tool": "scene_export_cancel",
"arguments": {}
}
```

In the current GUI implementation:

- exports complete synchronously
- `scene.export_status` reports idle state
- `scene.export_cancel` returns an error because there is nothing cancellable once export starts
- `scene_export_status` reports idle state
- `scene_export_cancel` returns an error because there is nothing cancellable once export starts
16 changes: 8 additions & 8 deletions docs/docs/development/mcp/recipes/load-dataset-and-train.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ Use this flow when the goal is to load a COLMAP dataset or checkpoint and then m
## Sequence

1. Read `lichtfeld://runtime/catalog` to confirm the runtime job ids.
2. Call `scene.load_dataset` or `scene.load_checkpoint`.
2. Call `scene_load_dataset` or `scene_load_checkpoint`.
3. Read `lichtfeld://scene/state` to confirm the training snapshot.
4. Call `training.start`.
5. Observe `training.main` through `runtime.job.wait`, `runtime.job.describe`, or `runtime.events.tail`.
4. Call `training_start`.
5. Observe `training.main` through `runtime_job_wait`, `runtime_job_describe`, or `runtime_events_tail`.

## Load A Dataset

```json
{
"tool": "scene.load_dataset",
"tool": "scene_load_dataset",
"arguments": {
"path": "/data/colmap/room",
"images_folder": "images",
Expand All @@ -38,7 +38,7 @@ Notes:

```json
{
"tool": "training.start",
"tool": "training_start",
"arguments": {}
}
```
Expand All @@ -49,7 +49,7 @@ Wait for a change in the normalized training job:

```json
{
"tool": "runtime.job.wait",
"tool": "runtime_job_wait",
"arguments": {
"job_id": "training.main",
"until": "changed",
Expand All @@ -62,7 +62,7 @@ Read recent training events without creating a subscription:

```json
{
"tool": "runtime.events.tail",
"tool": "runtime_events_tail",
"arguments": {
"types": [
"training.progress",
Expand All @@ -77,5 +77,5 @@ Read recent training events without creating a subscription:
## State Checks

- `lichtfeld://scene/state` gives the normalized training snapshot
- `training.get_loss_history` or `lichtfeld://training/loss_curve` gives the loss curve
- `training_get_loss_history` or `lichtfeld://training/loss_curve` gives the loss curve
- `lichtfeld://runtime/state` gives a broader runtime summary
26 changes: 13 additions & 13 deletions docs/docs/development/mcp/recipes/operators-and-modal.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ Use this flow when the task depends on registered GUI operators rather than a de

## Sequence

1. Read `lichtfeld://operators/registry` or call `operator.list`.
2. Call `operator.describe` for the chosen id and inspect its schema and poll state.
3. Call `operator.invoke`.
4. If the result is modal, switch to `operator.modal_state`, `operator.modal_event`, `operator.cancel_modal`, and the normalized runtime job `operator.modal`.
1. Read `lichtfeld://operators/registry` or call `operator_list`.
2. Call `operator_describe` for the chosen id and inspect its schema and poll state.
3. Call `operator_invoke`.
4. If the result is modal, switch to `operator_modal_state`, `operator_modal_event`, `operator_cancel_modal`, and the normalized runtime job `operator.modal`.

## Discover Operators

```json
{
"tool": "operator.list",
"tool": "operator_list",
"arguments": {
"include_schema": true,
"include_poll": true
Expand All @@ -29,7 +29,7 @@ Use this flow when the task depends on registered GUI operators rather than a de

```json
{
"tool": "operator.describe",
"tool": "operator_describe",
"arguments": {
"operator_id": "transform.translate",
"include_schema": true,
Expand All @@ -40,11 +40,11 @@ Use this flow when the task depends on registered GUI operators rather than a de

## Invoke The Operator

Use the schema returned by `operator.describe` instead of guessing the payload:
Use the schema returned by `operator_describe` instead of guessing the payload:

```json
{
"tool": "operator.invoke",
"tool": "operator_invoke",
"arguments": {
"operator_id": "transform.translate",
"arguments": {
Expand All @@ -60,7 +60,7 @@ Inspect current modal state:

```json
{
"tool": "operator.modal_state",
"tool": "operator_modal_state",
"arguments": {}
}
```
Expand All @@ -69,7 +69,7 @@ Dispatch a modal event:

```json
{
"tool": "operator.modal_event",
"tool": "operator_modal_event",
"arguments": {
"type": "mouse_move",
"x": 320,
Expand All @@ -85,13 +85,13 @@ Cancel the active modal operator:

```json
{
"tool": "operator.cancel_modal",
"tool": "operator_cancel_modal",
"arguments": {}
}
```

## Notes

- Use `operator.describe` before `operator.invoke`
- `operator.invoke` may finish immediately or return `running_modal`
- Use `operator_describe` before `operator_invoke`
- `operator_invoke` may finish immediately or return `running_modal`
- modal operator state is also normalized as runtime job `operator.modal`
Loading
Loading