Apps are tools that do one thing well.
What's an app?
An app takes input, does something, and returns output.
Examples:
stable-diffusion— prompt in, image outwhisper— audio in, text outsummarize— long text in, short text outrouter(decision) — state plus typed questions in, probability per answer out
Inputs and outputs
Every app has a schema:
1stable-diffusion2├── Input3│ ├── prompt (text, required)4│ ├── style (text, optional)5│ └── size (choice, optional)6└── Output7 └── image (file)The schema tells you what to provide and what you'll get back.
Decision apps
Decision apps answer structured questions about a piece of state (and optionally images or videos) and return a probability distribution over each answer — not generated media. Set category: decision in inf.yml (Configuration — Categories).
The wire contract matches the generated SDK types DecisionInput / DecisionOutput (and DecisionVisionInput when images are included, or DecisionVideoInput when videos are included as well; the Python helper ships in inferencesh ≥ v0.23.0). Question kinds:
| Kind | Input field | What you ask | Output field |
|---|---|---|---|
| Choice | choices[] | Which one of a fixed set of named options applies | choices — map keyed by question id |
| Score | scores[] | Where the state sits on ordered levels (low → high) | scores — map keyed by question id |
| Noul | nouls[] | Probability that something is true (yes/no) | nouls — map keyed by question id |
Each question has an id (your key), instructions (what the model should consider), and kind-specific fields (options for choices, levels for scores, optional criteria for nouls). state is arbitrary JSON the model reads alongside the questions. Vision models add images — file URIs every question can see.
Example input:
1{2 "state": { "ticket": "Payment failed after card update", "channel": "email" },3 "choices": [4 {5 "id": "intent",6 "instructions": "What is the customer trying to do?",7 "options": [8 { "name": "refund", "description": "Get money back" },9 { "name": "retry", "description": "Retry the charge" }10 ]11 }12 ],13 "nouls": [14 {15 "id": "urgent",16 "instructions": "Does this need same-day handling?",17 "criteria": { "true": "Same-day SLA applies", "false": "Standard queue" }18 }19 ]20}Example output (shape every decision app returns):
1{2 "choices": {3 "intent": {4 "choice": "retry",5 "confidence": 0.72,6 "probabilities": { "refund": 0.28, "retry": 0.72 }7 }8 },9 "nouls": {10 "urgent": { "noul": 0.41 }11 },12 "scores": {},13 "model": "myteam/support-router",14 "input_tokens": 184215}- Choice answers include the highest-probability
choice,confidence, andprobabilitiesfor every option name. - Score answers include
score(0 through the top level index),normalized(0–1),confidence, per-levelprobabilities, and alegendmapping level numbers to descriptions. - Noul answers expose
noulas the probability the statement is true.
Run decision apps like any other app (client.tasks.create, Flows, or the workspace UI). TypeScript types: JavaScript SDK — Decision app types.
Where apps come from
| Source | Description |
|---|---|
| The Grid | 100+ pre-built apps from inference shell (image, audio, text, and more) |
| Community | Public apps from other users |
| You | Apps you create and deploy |
Each app has a category (for example image, chat, or decision for the shared decision contract) and optional tags — lowercase slugs such as text-to-image or open-weights that describe what it does and how it behaves. Tags feed search and store listings. → Configuration — App tags · Apps API
Apps vs connector tools: The Grid is the library of runnable apps (each with typed inputs and outputs). Agents can also call external integrations (Gmail, Slack, Linear, and more) as connector tools — see Tool Orchestration and Connectors.
How to use apps
- Directly — Run from the workspace UI
- In Flows — Chain with other apps
- As Agent Tools — Let agents call them
- Via API — Run programmatically
Creating Apps
You can create your own apps using Python. An app consists of:
inference.py— The codeinf.yml— Configuration
Code Structure
1class AppSetup(BaseAppInput):2 """Static configuration (restart required)"""3 model_name: str45class AppInput(BaseAppInput):6 """Request arguments (per run)"""7 prompt: str89class App(BaseApp):10 async def setup(self, config: AppSetup):11 # Load heavy resources12 pass1314 async def run(self, input: AppInput):15 # Process request16 passNext
→ Tasks