Skip to content
Merged
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
Binary file added docs/Truffle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
165 changes: 165 additions & 0 deletions docs/ambient-app.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
---
title: Build a Background App
description: "Create a scheduled app that submits context to agent on your Truffle"
---

Background apps run on a schedule and submit context to Truffle's proactive agent.

To put it simply:

- foreground apps are callable tools
- background apps are context producers

The richer and cleaner your background submissions are, the better proactive behavior you should expect, using cool things like metrics for the model to decide importance on, formatting for submission etc matter a lot here!

---

## What We're Building

This walkthrough uses Kalshi app as an example specifcially the background functionality:

- source: [`app-store/kalshi/kalshi_background.py`](https://github.com/deepshard/truffile/blob/main/app-store/kalshi/kalshi_background.py)
- worker: [`app-store/kalshi/bg_worker.py`](https://github.com/deepshard/truffile/blob/main/app-store/kalshi/bg_worker.py)
- config: [`app-store/kalshi/truffile.yaml`](https://github.com/deepshard/truffile/blob/main/app-store/kalshi/truffile.yaml) (`metadata.background`)
- app source repo: [`app-store/kalshi`](https://github.com/deepshard/truffile/tree/main/app-store/kalshi)

Kalshi background generates:

- portfolio summaries
- price movement alerts
- settlement alerts
- order status updates
- feed/event digests

and submits each item with explicit priority. feel free to do your own version!

---

## Step 1: Background Config in `truffile.yaml`

```yaml
metadata:
name: Kalshi
bundle_id: org.deepshard.kalshi
description: |
Have Truffle trade and monitor Kalshi prediction markets for you.
icon_file: ./icon.png

background:
process:
cmd:
- python
- kalshi_background.py
working_directory: /
environment:
PYTHONUNBUFFERED: "1"
KALSHI_API_KEY: "REPLACE_WITH_KALSHI_API_KEY"
KALSHI_PRIVATE_KEY: |
REPLACE_WITH_KALSHI_PRIVATE_KEY_PEM
default_schedule:
type: interval
interval:
duration: 30m
schedule:
daily_window: "00:00-23:59"

steps:
- name: Install dependencies
type: bash
run: |
apk add --no-cache gcc musl-dev libffi-dev openssl-dev
pip install --no-cache-dir "httpx>=0.27.0" "cryptography>=42.0.0"
- name: Copy application files
type: files
files:
- source: ./config.py
destination: ./config.py
- source: ./client.py
destination: ./client.py
- source: ./bg_worker.py
destination: ./bg_worker.py
- source: ./kalshi_background.py
destination: ./kalshi_background.py
```

---

## Step 2: Runtime Pattern

Kalshi background uses the app runtime background loop (coming soon but for now you can use the example apps to see how to use it for your apps!):

```python
from app_runtime.background import BackgroundRunContext, run_background

def kalshi_ambient(ctx: BackgroundRunContext) -> None:
...
ctx.bg.submit_context(content=content, uris=[], priority=priority)

if __name__ == "__main__":
run_background(kalshi_ambient)
```

Core idea:

1. gather external state (APIs, events, account state)
2. create context messages with enough detail to be actionable
3. submit with priority (`LOW`, `DEFAULT`, `HIGH`) based on urgency

---

## Step 3: Submit Rich Context (Not Generic Text)

From Kalshi, stronger context items include concrete fields:

- ticker and title
- absolute and relative price change
- before/after values
- settlement result and revenue impact
- order IDs and status change

Example style:

```text
Price alert: FED-RATE-SEP moved up 12c (was 41c, now 53c)
```

This is much better for proactivity than broad summaries without entity/time/value details.

---

## Step 4: Reliability and Cleanup

Kalshi background explicitly closes resources on shutdown (This is important and needs to be done for your apps! Your apps will fail at runtime otherwise):

- `atexit.register(_cleanup)` in `kalshi_background.py`
- `_cleanup()` closes `KalshiBackgroundWorker` client and event loop
- worker itself exposes `close()` and wraps API failures

Do the same in your app. Leaving connections open at shutdown is a common source of flaky reruns and container instability.

---

## Step 5: Deploy and Verify

```bash
truffile validate ./app-store/kalshi
truffile deploy --dry-run ./app-store/kalshi
truffile deploy ./app-store/kalshi
```

Then verify:

- scheduled runs execute at expected interval/window (Tip: Keep interval small when testing to see results earlier, you can adjust it and redeploy later when you know it works!)
- context submissions are visible in runtime logs, right now there is not a away for you to go and watch runtime logs for your background apps, we will be adding this feature soon to the sdk. Till then please make sure you follow the example app templates!

---

## When to Use Background

Use background apps when you need:

- periodic polling/monitoring
- context emission for proactive behavior, you would like Truffle to take an action! (Do not be restrained in thinking that a background app can only influence actions for that app only, if I get an instagram message regarding an amazon order, Truffle can use that to do an action of adding said item to my cart!)
- domain-specific event digestion over time

If your app also needs callable tools, keep both blocks in one app (`metadata.foreground` + `metadata.background`) as shown in Kalshi.
161 changes: 161 additions & 0 deletions docs/building-apps.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
---
title: What are Truffle Apps?
---

## What Are Truffle Apps?

Truffle apps are containerized programs that run on your Truffle and extend what the agent on your Truffle can do.

There are three app shapes you can build today:

| Type | When It Runs | What It Does |
|------|--------------|--------------|
| **Foreground** | On demand | Exposes MCP tools (served over `streamable-http`) the agent can call during tasks |
| **Background** | On schedule | Submits context to the proactive agent |
| **Both** | On demand + schedule | Combines MCP tools and scheduled context submission |

<CardGroup cols={2}>
<Card title="Kalshi Example (FG + BG)" icon="github" href="https://github.com/deepshard/truffile/tree/main/app-store/kalshi">
Full example app using both foreground tools and background scheduling.
</Card>
<Card title="Reddit Example (BG)" icon="github" href="https://github.com/deepshard/truffile/tree/main/app-store/reddit">
Background-only example that submits periodic context.
</Card>
</CardGroup>

---

## App Config Shape (Current)

The current SDK supports app-specific foreground/background process blocks under `metadata`.
An app can have both or either!

```yaml
metadata:
name: Kalshi
bundle_id: org.deepshard.kalshi
description: |
Have Truffle trade and monitor Kalshi prediction markets for you.
icon_file: ./icon.png

background:
process:
cmd: ["python", "kalshi_background.py"]
working_directory: /
environment:
PYTHONUNBUFFERED: "1"
KALSHI_API_KEY: "REPLACE_WITH_KALSHI_API_KEY"
KALSHI_PRIVATE_KEY: |
REPLACE_WITH_KALSHI_PRIVATE_KEY_PEM
default_schedule:
type: interval
interval:
duration: 30m
schedule:
daily_window: "00:00-23:59"

foreground:
process:
cmd: ["python", "kalshi_foreground.py"]
working_directory: /
environment:
PYTHONUNBUFFERED: "1"
KALSHI_API_KEY: "REPLACE_WITH_KALSHI_API_KEY"
KALSHI_PRIVATE_KEY: |
REPLACE_WITH_KALSHI_PRIVATE_KEY_PEM

steps:
- name: Install dependencies
type: bash
run: |
apk add --no-cache gcc musl-dev libffi-dev openssl-dev
pip install --no-cache-dir "httpx>=0.27.0" "cryptography>=42.0.0"
- name: Copy application files
type: files
files:
- source: ./config.py
destination: ./config.py
- source: ./client.py
destination: ./client.py
- source: ./bg_worker.py
destination: ./bg_worker.py
- source: ./kalshi_foreground.py
destination: ./kalshi_foreground.py
- source: ./kalshi_background.py
destination: ./kalshi_background.py
```

---

## Build and Deploy Flow

Use this flow for all app types:

1. Validate config and source files.
2. Check deploy plan without mutating device.
3. Deploy via builder session.

```bash
truffile validate ./my-app
truffile deploy --dry-run ./my-app
truffile deploy ./my-app
```

Under the hood, deploy uses a build session, uploads declared files, runs `bash` steps, and finalizes app metadata/process config.

---

## Kalshi Walkthrough:

Kalshi is the best reference because it demonstrates both paths in one app:

- `kalshi_foreground.py` exposes MCP tools such as `get_markets`, `get_market`, `create_order`, and `get_positions`.
- `kalshi_background.py` runs on schedule and submits portfolio/market context through `ctx.bg.submit_context(...)`.

This is the intended split:

- **Foreground** is your callable tool surface (MCP spec).
- **Background** is your proactive context pipeline.

The quality of your background context directly affects proactive behavior. Rich, precise submissions perform better than generic text.

---

## Runtime Stability Pattern (Important)

In Kalshi, network clients are explicitly closed on shutdown:

- foreground: `atexit.register(_cleanup)` calls `KalshiClient.close()`
- background: `atexit.register(_cleanup)` closes the worker client and event loop

Do this in your own apps. Closing outbound clients/sessions before process exit prevents flaky shutdown behavior and avoids container-side runtime crashes.

---

## Next Steps

<CardGroup cols={2}>
<Card title="Build a Foreground App" icon="bullseye" href="/sdk/focus-app">
MCP tool server patterns, examples, and deployment details.
</Card>
<Card title="Build a Background App" icon="clock" href="/sdk/ambient-app">
Scheduling, context submission, and proactivity-oriented design.
</Card>
</CardGroup>

---

## Contribute to the Truffle App Store

Contributors are welcome to submit apps to the Truffle App Store.

To submit your app:

1. Open a PR with your app under the `app-store/` folder.
2. Include a screen recording of your app in action.

For accepted apps, the Truffle team will deploy the app to the App Store so others can use it. Your name can be credited as the app author. In some cases, changes may be required for runtime reliability.

<Frame>
<img src="/images/app-store.png" alt="Example app card in Truffle App Store with author attribution" />
</Frame>
Loading
Loading