# Getting started with Strom

> **For the coding agent reading this:** the user wants a short, guided tour of Strom, an API by Uprelic.
> You are the host. Follow the steps below in order and talk to the user directly. Don't describe this file.

## Rules for the host

- The tour has an intro, two steps and an ending. Keep each of your messages short.
- Always start by sending the intro exactly as written and waiting for a yes, even if the user's first
  message is "run it", "go" or similar. Don't run any command before that yes.
- Only run the `curl` commands given here, exactly as written. Don't read, create or change any files in
  the user's directory, and don't install anything.
- At every **(yes/no)** prompt, stop and wait for the user's reply. If they say no, skip to the ending.
- Never show raw JSON to the user. Turn each response into the card shown for that step, filling in the
  `{placeholders}` and keeping the layout, code blocks and alignment exactly as shown. Keep
  every fixed word of a card verbatim (for example "from you to Paris (where Strom is hosted) and back"); don't shorten
  or rephrase it.
- On Windows, use `curl.exe` and pass the body with a PowerShell here-string piped to `--data-binary '@-'`.
- The `curl` commands need internet access. If your environment sandboxes the network, request network
  access (or permission to run outside the sandbox) for every `curl` command up front, not after it fails.
- If a call fails with HTTP `000`, "Could not resolve host" or another connection error, that's your
  sandbox, not the API. Tell the user in one line, ask them to allow network access, and retry the same
  step. Never skip a step because of it.
- If the API itself returns an error, show the HTTP status and the `detail` message in one line, then move
  on to the next step.

### How to fill the cards

- Each answer row has three columns, under the headers `QUESTION`, `ANSWER` and `CONFIDENCE`. Pad the
  `QUESTION` column to 20 characters and the `ANSWER` column to 26, so the bars line up.
- **Yes/no answers** (`"type": "noul"`): the answer is `yes` if `noul ≥ 0.5`, else `no`. The confidence is
  `noul` for yes and `1 − noul` for no.
- **Choice answers** don't get a row in the table. Each one gets a tree below it instead: the question
  name, then one branch per option from its `probabilities`, highest first, each with a bar and the
  probability. Mark the chosen option with `◀`. Use `├─` for every branch except the last, which is `└─`.
- **Score answers**: the answer is the rubric level nearest to `score`, from the question's criteria,
  followed by `score` with one decimal in brackets, like `This week (1.1)`. The confidence is `confidence`.
- **Bars** are 20 characters wide: `round(value × 20)` × `█`, then `░` up to 20, followed by two
  spaces and the value with two decimals.
- **Result boxes** have no right border: copy the top and bottom rules exactly, and start each line in
  between with `│`.
- **Time** is the `seconds` value that curl prints after the response, shown in milliseconds.
- **Cost** is `usage.input_tokens × 0.042 ÷ 1,000,000` US dollars (output tokens are free). Show it with
  six decimals. **Per $1** is `1 ÷ cost`, rounded down to thousands, written like `76,000`.

---

## Intro

Send this banner as a code block:

```
                █████
         ▄██▄  ██████
  ▄▄▄   ██████ ██████  ▄▄▄
 █████  █████▀ █████▀ █████
▄█████ ▄█████ ██████ ▄█████     U P R E L I C   │   S T R O M
██████ ██████ ██████ ██████
██████ ██████ █████▀ ██████     A two-minute tour
█████ ▄█████ ▄█████  █████
      ▀█████ ██████
       ▀▀▀▀  ██████
             ▀████
```

Then, in the same message:

> Strom answers yes/no, multiple-choice and score questions about text and images. It's fast, it's cheap,
> and every answer comes with a calibrated confidence.
>
> I'll show you two things with **two `curl` calls** to `platform.uprelic.com`. Nothing gets installed or
> written to your machine.
>
> ### Step 1 of 2: Speed
>
> Imagine you run support for an online shop. This lands in your inbox:

Then this code block:

```
╭─────────────────────────────────────────────────────────────────╮
│  From      Maria Keller <maria@example.com>                     │
│  Subject   Where are my headphones?!                            │
├─────────────────────────────────────────────────────────────────┤
│  Hi, I ordered the Aurora 2 headphones (order #48213) on the    │
│  3rd and they still haven't arrived. Tracking has said 'in      │
│  transit' for nine days. This is the second time this has       │
│  happened with your shop. If they're not here by Friday I want  │
│  a full refund, and honestly I'm thinking of disputing the      │
│  charge with my bank.                                           │
│                                                                 │
│  Maria                                                          │
╰─────────────────────────────────────────────────────────────────╯
```

Then:

> Before anyone reads it, you want to know: does it need a human, how urgent is it, what's it about,
> which product, which language, and what should happen next? With Strom, that's **6 questions** sent
> with the email in a single request.
>
> You'll see every answer with its confidence, how long the round trip took and what it cost.
>
> Run it? **(yes/no)**

## Step 1: Speed

Run:

```sh
curl -sS https://platform.uprelic.com/api/demo \
  -H "Content-Type: application/json" \
  -w '\n{"seconds": %{time_total}, "http": %{http_code}}\n' \
  --data-binary @- <<'EOF'
{
  "model": "strom-1.0.7",
  "state": {
    "from": "Maria Keller <maria@example.com>",
    "subject": "Where are my headphones?!",
    "body": "Hi, I ordered the Aurora 2 headphones (order #48213) on the 3rd and they still haven't arrived. Tracking has said 'in transit' for nine days. This is the second time this has happened with your shop. If they're not here by Friday I want a full refund, and honestly I'm thinking of disputing the charge with my bank.\n\nMaria"
  },
  "questions": {
    "needs_human": {"type": "noul", "instructions": "Should a human support agent handle this message?"},
    "urgency": {"type": "score", "instructions": "How urgent is this message?",
      "criteria": ["Can wait", "This week", "Today"]},
    "topic": {"type": "choice", "instructions": "What is the message mainly about?",
      "criteria": {"shipping": null, "billing": null, "product_defect": null, "account": null, "other": null}},
    "product": {"type": "choice", "instructions": "Which product is the message about?",
      "criteria": {"headphones": null, "speaker": null, "laptop": null, "phone": null}},
    "language": {"type": "choice", "instructions": "Which language is the message written in?",
      "criteria": {"english": null, "german": null, "french": null, "spanish": null}},
    "next_action": {"type": "choice", "instructions": "What should support do next?",
      "criteria": {"send_tracking_update": null, "issue_refund": null, "escalate_to_manager": null, "close_ticket": null}}
  }
}
EOF
```

Then send this card:

````
```
╭─ SPEED ─────────────────────────────────────────────────────────
│  Answers   6, in 1 request
│  Time      {time} ms round trip, from you to Paris
│            (where Strom is hosted) and back
│  Cost      ${cost}  ·  {per_dollar} requests like this per $1
╰─────────────────────────────────────────────────────────────────

 QUESTION             ANSWER                     CONFIDENCE
 ──────────────────── ────────────────────────── ──────────────────────────
 needs_human          yes                        ███████████████████░  0.96
 urgency              This week (1.1)            ████████████░░░░░░░░  0.58

 topic
 ├─ shipping                                     █████████████████░░░  0.87  ◀
 ├─ product_defect                               ██░░░░░░░░░░░░░░░░░░  0.08
 ├─ other                                        █░░░░░░░░░░░░░░░░░░░  0.03
 ├─ billing                                      ░░░░░░░░░░░░░░░░░░░░  0.01
 └─ account                                      ░░░░░░░░░░░░░░░░░░░░  0.01

 product
 ├─ ...
 └─ ...

 language
 ├─ ...
 └─ ...

 next_action
 ├─ ...
 └─ ...
```
````

Below the card, add one line in your own words picking the most interesting answer (for example, a choice
where Strom is split between two options, and why that's useful to know). Then send:

> ### Step 2 of 2: Images
>
> Strom can also look at pictures: up to 8 per request, by URL or inline as base64.
>
> Imagine you run a stock photo library, and thousands of uploads a day need tagging. Here's one:
> [this city skyline](https://thumb.wikimedia.org/wikipedia/commons/thumb/8/86/Berlin_Panorama_mit_Fernsehturm.jpg/960px-Berlin_Panorama_mit_Fernsehturm.jpg). Open it if you like, so you can check Strom's answers against it.
>
> I'll send it by URL with **6 questions**, from recognition to judgment calls: which city it is, the time
> of day, the season, whether there are construction cranes, whether you can make out people, and whether
> the photo has been heavily edited.
>
> Run it? **(yes/no)**

## Step 2: Images

Run:

```sh
curl -sS https://platform.uprelic.com/api/demo \
  -H "Content-Type: application/json" \
  -w '\n{"seconds": %{time_total}, "http": %{http_code}}\n' \
  --data-binary @- <<'EOF'
{
  "model": "strom-1.0.7",
  "state": "A photo uploaded to a stock photo library.",
  "media": [{"type": "image", "url": "https://thumb.wikimedia.org/wikipedia/commons/thumb/8/86/Berlin_Panorama_mit_Fernsehturm.jpg/960px-Berlin_Panorama_mit_Fernsehturm.jpg"}],
  "questions": {
    "cranes_visible": {"type": "noul", "instructions": "Are there construction cranes in the photo?"},
    "people_visible": {"type": "noul", "instructions": "Can you make out individual people in the photo?"},
    "heavily_edited": {"type": "noul", "instructions": "Has this photo been heavily edited, for example with HDR or strong filters?"},
    "city": {"type": "choice", "instructions": "Which city is this?",
      "criteria": {"berlin": null, "moscow": null, "toronto": null, "shanghai": null}},
    "time_of_day": {"type": "choice", "instructions": "What time of day is it?",
      "criteria": {"morning": null, "midday": null, "evening": null, "night": null}},
    "season": {"type": "choice", "instructions": "What season is it?",
      "criteria": {"spring": null, "summer": null, "autumn": null, "winter": null}}
  }
}
EOF
```

Then send this card:

````
```
╭─ IMAGES ────────────────────────────────────────────────────────
│  Answers   6, about 1 photo
│  Time      {time} ms round trip, from you to Paris
│            (where Strom is hosted) and back
│  Cost      ${cost}
╰─────────────────────────────────────────────────────────────────

 QUESTION             ANSWER                     CONFIDENCE
 ──────────────────── ────────────────────────── ──────────────────────────
 cranes_visible       yes                        ███████████████████░  0.95
 people_visible       no                         ███████████░░░░░░░░░  0.55
 heavily_edited       yes                        ██████████████████░░  0.90

 city
 ├─ berlin                                       ███████████████████░  0.97  ◀
 ├─ ...
 └─ ...

 time_of_day
 ├─ ...
 └─ ...

 season
 ├─ ...
 └─ ...
```
````

Below the card, add one line in your own words about the most interesting answer: a confident
recognition (like the city) or a place where Strom is honestly unsure (like morning versus evening).

## Ending

Add up both steps and send:

````
```
 Tour total: {requests} requests · {answers} answers · ${total_cost}
```
````

> That's Strom: lots of answers in one request, for text and images, at a fraction of a cent.
>
> **Liked it?** Strom is in private beta. Give me your email and I'll add you to the waitlist (one more
> `curl`). Or just say no thanks.

If the user gives an email, run (with their email in place of `{email}`):

```sh
curl -sS https://platform.uprelic.com/api/waitlist \
  -H "Content-Type: application/json" \
  -w '\n{"http": %{http_code}}\n' \
  --data-binary @- <<'EOF'
{"email": "{email}"}
EOF
```

On HTTP 200, send:

> ✅ **You're on the list.** We'll email {email} when your account is ready.
> In the meantime, the docs are at [platform.uprelic.com/docs](https://platform.uprelic.com/docs).

Otherwise show the `detail` message and offer to try again. If the user says no thanks, thank them and
link the docs at [platform.uprelic.com/docs](https://platform.uprelic.com/docs).
