Skip to content
Draft
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
11 changes: 7 additions & 4 deletions sdk/building-apps.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ from truffile.app_runtime import (
)
```

The source lives in `truffile/app_runtime/` in the repo and ships with the installed package. Once you `pip install truffile`, the same runtime is importable from app code running on your device.
The runtime ships in the installed package. Truffile release builds stage it
from Truffle's runtime source before packaging, so released wheels contain the
complete app-authoring API used by generated apps.

There are two other entry points that import the same names:

Expand All @@ -64,15 +66,14 @@ All three forms resolve to the same objects. Pick whichever reads best for you.
The fastest way to start:

```bash
truffile create my-app
truffile create my-app --type foreground
```

```text
✓ Created app scaffold: ./my-app
Files:
→ truffile.yaml
→ my_app_foreground.py
→ my_app_background.py
→ icon.png

Next: truffile validate ./my-app
Expand All @@ -82,9 +83,11 @@ Flags:

- `truffile create <name>` — set the name, prompt for base path
- `truffile create <name> --path <dir>` — set name and base path
- `truffile create <name> --type foreground|background|hybrid` — choose the app shape
- `truffile create` — fully interactive

The generated `my_app_foreground.py` and `my_app_background.py` are stubs using the real SDK classes. Delete whichever you don't need — the app type is inferred from which `foreground` / `background` sections you keep in `truffile.yaml`.
The default remains `hybrid`. When you pass `--type`, Truffile writes only the
matching entrypoints, manifest sections, and copy-file steps.

---

Expand Down
61 changes: 33 additions & 28 deletions sdk/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,18 @@ Most workflows can be driven with explicit arguments, which makes them easy to
test in CI or from another agent:

```bash
truffile connect truffle-6272 --user-id "$TRUFFLE_USER_ID"
truffile list devices
truffile connect truffle-6272 --user-id "$TRUFFLE_USER_ID" --json --non-interactive
truffile list devices --json
truffile list apps --json
truffile load all
truffile create my-app --path ./apps
truffile validate ./apps/my-app
truffile deploy ./apps/my-app --dry-run --json
truffile load all --json
truffile create my-app --type foreground --path ./apps --json --non-interactive
truffile validate ./apps/my-app --json
truffile deploy ./apps/my-app --dry-run --json --non-interactive
# after the user approves deployment and replacing an installed copy
truffile deploy ./apps/my-app --json --non-interactive --replace
truffile delete my-app
truffile delete my-app --dry-run --json --non-interactive
# after the user confirms the exact deletion plan
truffile delete my-app --yes --json --non-interactive
truffile chat "Summarize my installed apps" --json --quiet --timeout 60
truffile infer "Say pong" --json --no-stream --quiet
truffile infer --list-models --json
Expand Down Expand Up @@ -237,7 +240,7 @@ truffile infer
| `--model <name>` | Pre-select a model |
| `--system <text>` | Set an initial system prompt |
| `--no-stream` | Disable streaming (get the full response at once) |
| `--no-tools` | Disable built-in tools (`web_search`, `web_fetch`) |
| `--no-default-tools` | Disable built-in tools (`web_search`, `web_fetch`) |
| `--mcp <url>` | Connect an MCP server at startup (can be repeated) |

```bash
Expand Down Expand Up @@ -393,10 +396,12 @@ truffile create
truffile create my-app

# in a specific directory
truffile create my-app --path ./apps
truffile create my-app --type foreground --path ./apps
```

Creates a scaffold with `truffile.yaml`, foreground/background entry points, and a default icon.
Use `--type foreground`, `--type background`, or `--type hybrid`. The default is
`hybrid` for compatibility. The scaffold contains only the selected entrypoints,
matching manifest sections, and a default icon.

### Validate an app

Expand Down Expand Up @@ -443,25 +448,24 @@ truffile list devices # devices you have saved credentials for

### Delete apps

```bash
# interactive picker
truffile delete

# delete all apps
truffile delete all
For scripts and agents, identify an app by its stable name, slug, or UUID,
preview the exact target, ask the user to confirm that plan, and only then pass
`--yes`:

# delete by index (1-based, as shown in the app list)
truffile delete 1 2 3

# comma-separated works too
truffile delete 1,3,5

# pipe selection
echo "all" | truffile delete
echo "1 2" | truffile delete
```bash
truffile list apps --json
truffile delete my-app --dry-run --json --non-interactive
# after the user confirms the exact app shown above
truffile delete my-app --yes --json --non-interactive
```

If you pass indices that are out of range or invalid, the CLI falls back to the interactive picker (when running in a terminal).
For normal human use, `truffile delete` opens an interactive picker and asks
for confirmation. Numeric indices and `all` remain available interactively,
but automated workflows should use a stable name, slug, or UUID because list
ordering can change.

Non-interactive deletion without a selection or without `--yes` returns a
structured error and does not mutate the device.

### List models

Expand Down Expand Up @@ -499,14 +503,15 @@ Both modes let you talk to models on your Truffle, but they serve different purp
| `truffile scan` | Scan network for Truffle devices |
| `truffile connect <device>` | Connect to a device |
| `truffile disconnect [device\|all]` | Disconnect and clear credentials |
| `truffile create [name] [--path <dir>]` | Scaffold a new app |
| `truffile create [name] [--path <dir>] [--type foreground\|background\|hybrid]` | Scaffold a new app |
| `truffile validate [path]` | Validate app config and sources |
| `truffile deploy [path]` | Deploy app to connected device |
| `truffile deploy --dry-run` | Show deploy plan without changes |
| `truffile deploy --interactive` | Deploy with interactive terminal |
| `truffile list apps` | List installed apps |
| `truffile list devices` | List connected devices |
| `truffile delete [all\|1 2 3]` | Delete apps (interactive, by index, or all) |
| `truffile delete <name-or-uuid> --dry-run --json --non-interactive` | Preview an exact app deletion plan |
| `truffile delete <name-or-uuid> --yes --json --non-interactive` | Delete an app after explicit confirmation |
| `truffile models` | List models on connected device |
| `truffile chat [--resume]` | Agent chat REPL |
| `truffile infer [--model M] [--system S]` | Raw inference REPL |
Expand Down
53 changes: 51 additions & 2 deletions sdk/inference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,27 @@ For the interactive CLI experience (`truffile infer`), see the [CLI guide](/sdk/

---

## Find the device host

Your computer must be able to reach the Truffle on the same network. Run:

```bash
truffile scan --json --non-interactive
```

Use an address returned in `devices[].addresses`, or use the device name as an
mDNS host such as `truffle-1234.local`.

```bash
export TRUFFLE_HOST=truffle-1234.local
```

---

## List Models

```bash
curl -sS http://<device-host>/if2/v1/models | python -m json.tool
curl -sS "http://$TRUFFLE_HOST/if2/v1/models" | python -m json.tool
```

Or via the CLI:
Expand All @@ -28,7 +45,7 @@ truffile models
## Chat Completions

```bash
curl -sS http://<device-host>/if2/v1/chat/completions \
curl -sS "http://$TRUFFLE_HOST/if2/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{
"model": "<model-id-or-uuid>",
Expand All @@ -38,6 +55,38 @@ curl -sS http://<device-host>/if2/v1/chat/completions \
}'
```

### Python client

`httpx` is installed with Truffile. This example lists the available models,
uses the first returned model ID, and sends one non-streaming request:

```python
import os

import httpx

base_url = f"http://{os.environ['TRUFFLE_HOST']}/if2/v1"

models_response = httpx.get(f"{base_url}/models", timeout=15)
models_response.raise_for_status()
models = models_response.json()["data"]
if not models:
raise RuntimeError("No inference models are available on this Truffle")

model = models[0].get("id") or models[0]["uuid"]
response = httpx.post(
f"{base_url}/chat/completions",
json={
"model": model,
"messages": [{"role": "user", "content": "Reply with pong."}],
"stream": False,
},
timeout=120,
)
response.raise_for_status()
print(response.json()["choices"][0]["message"]["content"])
```

### Request body

| Field | Type | Description |
Expand Down
Loading