Move all three skills into skills/; add root README; fix paths
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
312742cfef
commit
d95e5d452d
84 files changed
+97
-31
No files matched your search
@@ -0,0 +1,190 @@
|
||||
---
|
||||
name: rpa-dashboard-ai
|
||||
description: Builds a working dashboard for an RPA bot or service that uses AI (an LLM or OCR extraction call). It has everything from rpa-dashboard-no-ai plus confidence bands, a review split pane (source document beside the extracted fields, band filters, drafts, Verify), an approve gate the backend enforces, and a cost/ROI page (tokens and cost per run, monthly spend, an against-doing-it-by-hand panel). Web: React + Vite + Tailwind with a sample-data server stub; desktop (PyQt): plain-HTML AI sections over the Qt bridge. Use when the user asks for an "AI RPA dashboard", an "extraction dashboard", an "LLM/OCR review dashboard", or any RPA/bot dashboard in a project that calls an LLM or OCR to extract fields. Needs rpa-dashboard-no-ai installed next to it.
|
||||
---
|
||||
|
||||
# RPA dashboard (AI)
|
||||
|
||||
Everything this skill needs is bundled. Never read the original source projects.
|
||||
Shared files live in the no-AI skill, installed next to this one: `<no-ai>` below
|
||||
means `../rpa-dashboard-no-ai/templates/`.
|
||||
|
||||
**Paths:** both skills must be installed side by side (same parent folder). Resolve
|
||||
`templates/...` against this skill's own folder (the one holding this SKILL.md), and
|
||||
`<no-ai>` against it too (`<this skill>/../rpa-dashboard-no-ai/templates/`), never against
|
||||
the user's project. Run the scripts with those absolute paths, from the user's project, for
|
||||
example `python <this skill>/../rpa-dashboard-no-ai/templates/detect_frontend.py <project root>`.
|
||||
|
||||
| File | What it is |
|
||||
|---|---|
|
||||
| `templates/web/` | The React + Vite + Tailwind starter: shell, KPI, donut, run panel, report, **band legend, review split pane, approve gate, cost page**, sample data. |
|
||||
| `templates/web/pricing.py` | The pricing table (with its source and as-of date) and `cost_for_call`. The backend imports it. |
|
||||
| `templates/web/server_stub.py` | Sample-data backend for runs, review rows and the approve gate. Standard library only. |
|
||||
| `templates/web/bands.py` | The band cut points and rules. The one source of truth: the backend imports it. |
|
||||
| `templates/desktop/ai_sections.html` | Desktop, and web projects with a non-React frontend: the Review tab (band legend, review split pane, drafts, Verify, approve gate) and the Cost tab in plain HTML, pasted into `<no-ai>dashboard.html`. Talks over the Qt bridge, or with no Qt, fetches the `templates/contract.md` endpoints. |
|
||||
| `templates/desktop/ai_bridge.py` | Desktop: the no-AI `Bridge` plus the `ai_request` slot that hands every AI request to the Python review backend. |
|
||||
| `templates/contract.md` | The AI contract: runs, review rows, endpoints and the gate, over HTTP or the Qt bridge. Extends `<no-ai>contract.md`. |
|
||||
| `templates/reference/` | Superbill Review extracts, marked EXAMPLE ONLY. Use them to port extra polish, never copy their project names. |
|
||||
| `<no-ai>frontend.md`, `<no-ai>detect_frontend.py` | Existing frontend: detect, report, keep or restyle. |
|
||||
| `<no-ai>themes.md`, `<no-ai>palette.py` | Theme presets and the custom-colour steps. |
|
||||
| `<no-ai>contract.md` | The no-AI contract the AI one extends. |
|
||||
|
||||
The questions are the same as the no-AI skill's, in the same order. Ask one at a
|
||||
time and wait for the answer. If the user's request already answers a question,
|
||||
don't ask it again.
|
||||
|
||||
## 1. Scan the project
|
||||
|
||||
Before asking anything:
|
||||
- **Frontend:** run `python <no-ai>detect_frontend.py <project root>` and read
|
||||
`<no-ai>frontend.md` section 1.
|
||||
- **AI call:** find the LLM or OCR extraction (for example `genai`, `openai`,
|
||||
`anthropic`, Textract or Tesseract calls): which fields it returns, which are
|
||||
mandatory, and whether it returns per-word scores. Note the provider, the model
|
||||
names, and whether the response's token usage (input, output, thinking) is kept.
|
||||
- **Bot or backend:** the entry point, what it prints, and any web framework
|
||||
(FastAPI, Flask, Django).
|
||||
|
||||
If the project has no AI call at all, say so and suggest `rpa-dashboard-no-ai`.
|
||||
|
||||
## 2. Report the frontend, then ask keep or restyle
|
||||
|
||||
Follow `<no-ai>frontend.md` sections 2 to 5.
|
||||
- **No frontend:** say "No existing frontend found." and go to step 3.
|
||||
- **Frontend found:** say "Frontend found at `<path>`, stack `<stack>`, colours
|
||||
`<main tokens>`." Then ask: **keep its look**, or **restyle** it?
|
||||
|
||||
## 3. Ask for colours
|
||||
|
||||
Skip this if the user chose keep. Offer:
|
||||
1. **Tebra Sky**: blue glass cards on a sky gradient.
|
||||
2. **Superbill Ember**: flat surfaces with a red-orange brand gradient.
|
||||
3. **Custom**: the user gives one brand hex colour.
|
||||
|
||||
## 4. Ask desktop or web
|
||||
|
||||
Ask only if there is no frontend. If there is one, use its stack. If the project
|
||||
uses PyQt, choose desktop and say so.
|
||||
- **Web:** the React starter in `templates/web/`, served by the backend. An existing
|
||||
non-React frontend gets the plain-HTML page instead (step 6, web).
|
||||
- **Desktop:** the no-AI PyQt page with `templates/desktop/ai_sections.html` pasted
|
||||
in, hosted by `templates/desktop/ai_bridge.py`. No web server, no npm.
|
||||
|
||||
## 5. Ask which optional sections to build
|
||||
|
||||
Always built: the no-AI shell and sections, plus the band legend, the review split
|
||||
pane, the approve gate and the cost page. Ask which extras to add (choose any, or none):
|
||||
**checkpoint tracker**, **admin/roles screen**, **login page**, **model picker** (choose
|
||||
the model per batch), **retry on another model** (for failed runs). Build only the
|
||||
chosen ones at their `OPTIONAL:` markers, and delete the markers.
|
||||
- **Checkpoint tracker, admin/roles, login:** web: port them from `<no-ai>dashboard.html`'s
|
||||
`OPTIONAL:` blocks to the markers in `RunPanel.tsx` (checkpoints) and `App.tsx` (admin tab
|
||||
and screen, login). Desktop: they're already in the no-AI page; `<no-ai>sections.py` keeps
|
||||
the chosen ones (no-AI step 6), and `<no-ai>sections.md` says what each needs from the host.
|
||||
- **Model picker:** a `<select>` filled from `GET /models` (the pricing table's keys), at
|
||||
the marker in `Cost.tsx` (desktop: `ai_sections.html`) or next to the Run button; the chosen model goes with the
|
||||
batch's start action.
|
||||
- **Retry on another model:** on a `failed` run, at the marker in `Review.tsx` (desktop: `ai_sections.html`): a model
|
||||
`<select>` (from `GET /models`, defaulting to the run's own model) and a Retry button
|
||||
that sends `POST /runs/{job_id}/retry {model}`, then polls the run as usual.
|
||||
Both need the endpoints in `templates/contract.md`; add them to the backend (and the stub).
|
||||
|
||||
## 6. Build (web)
|
||||
|
||||
**Existing plain-HTML, Vue, Angular or Svelte frontend:** don't use the React starter.
|
||||
Build the no-AI page as `../rpa-dashboard-no-ai/SKILL.md` step 6 says (web, with
|
||||
`API_BASE` filled, for example `/api`), paste the whole of `templates/desktop/ai_sections.html`
|
||||
into it just before `</body>`, and put it where `<no-ai>frontend.md` section 3 says. With no
|
||||
Qt bridge, its AI sections fetch `{API_BASE}` + the paths in `templates/contract.md`, so
|
||||
the backend serves those (step 7). Port it into the app's components only if the user asks,
|
||||
with `ai_sections.html` as the reference. Then skip to step 7.
|
||||
|
||||
1. Copy `templates/web/` into the project as `dashboard/` (an existing React app:
|
||||
port the `src/` components into it, see `<no-ai>frontend.md` section 3).
|
||||
Don't copy `node_modules/` or `dist/`.
|
||||
2. Fill every `{{...}}` in `dashboard/index.html`'s CONFIG block:
|
||||
|
||||
| Placeholder | Value |
|
||||
|---|---|
|
||||
| `APP_NAME`, `APP_SUBTITLE` | The project's name and a short tagline. |
|
||||
| `LOGO_SRC` | The logo's path, or empty. |
|
||||
| `STEPS_JSON` | The run steps as a JSON list, for example `["Initializing","Extract","Review","Completed"]`. |
|
||||
| `REPORT_COLUMNS_JSON` | `[{"key":..., "label":...}]`, with a `status` column. |
|
||||
| `API_BASE` | `/api` unless the backend mounts the dashboard API elsewhere. Keep it equal to `API` in `server_stub.py`. |
|
||||
|
||||
3. Apply the theme in `dashboard/src/index.css` only: replace the `body{...}` and
|
||||
`body.dark{...}` token blocks with the preset from `<no-ai>themes.md` (for Ember,
|
||||
add its font `<link>` to `index.html`'s `<head>`), or with
|
||||
`python <no-ai>palette.py "<hex>"` tokens for a custom colour, showing the user
|
||||
its contrast table. For keep, fill them from the project's tokens
|
||||
(`<no-ai>frontend.md` section 4). Never change the band colour block.
|
||||
4. Search the output for `{{`. None may be left.
|
||||
|
||||
## 6. Build (desktop)
|
||||
|
||||
1. Build the no-AI desktop page and host first, exactly as steps 6 and 7 of
|
||||
`../rpa-dashboard-no-ai/SKILL.md` say: `dashboard/dashboard.html` (theme, placeholders,
|
||||
`SAMPLE_DATA = false` once the bot is wired), `bridge.py` and `bot_runner.py`.
|
||||
2. Paste the whole of `templates/desktop/ai_sections.html` (Review and Cost tabs) into `dashboard/dashboard.html`,
|
||||
just before `</body>`. Change nothing in it: it uses the page's theme tokens, and its
|
||||
band colours are fixed.
|
||||
3. Copy `templates/desktop/ai_bridge.py`, `templates/web/server_stub.py`,
|
||||
`templates/web/bands.py` and `templates/web/pricing.py` into `dashboard/`. Fill `{{APP_NAME}}` in `ai_bridge.py`.
|
||||
4. The app now starts with `python dashboard/ai_bridge.py` (not `bridge.py`).
|
||||
5. Search the output for `{{`. None may be left.
|
||||
|
||||
## 7. Wire the data
|
||||
|
||||
The contracts: `<no-ai>contract.md` for the shell, `templates/contract.md` for runs,
|
||||
review rows and the gate.
|
||||
- **Sample data (no backend for these endpoints yet):** keep `SAMPLE_DATA = true` in
|
||||
`src/store.ts` (a plain-HTML page: in `dashboard.html`) and use `server_stub.py`. Replace its `SAMPLE_FIELDS` with the
|
||||
fields the project's extraction really returns (name, a sample value, word scores,
|
||||
mandatory). Tell the user which endpoints their backend must serve later.
|
||||
- **Backend exists:** add the endpoints from `templates/contract.md` to it. Copy
|
||||
`bands.py` next to it and band every field with `field_band(word_scores, value,
|
||||
mandatory)`. The approve endpoint must refuse (409 with `detail`) while any flagged
|
||||
field is unverified: the page never decides that. For the shell, set
|
||||
`SAMPLE_DATA = false` and serve the no-AI endpoints too.
|
||||
- **Cost page:** copy `pricing.py` next to the backend. Fill `PRICING` with the rates of
|
||||
the models the project really calls, from the provider's pricing page, and set
|
||||
`PRICING_SOURCE` and `PRICING_AS_OF`. If you can't read the rates, ask the user for
|
||||
them. The backend stores each run's token usage and serves `GET /roi`, pricing each run
|
||||
with `cost_for_call`. A run with no recorded usage gets `null`, never 0. If the
|
||||
extraction doesn't keep token usage yet, wire it to (for example Gemini's
|
||||
`usage_metadata`, OpenAI's and Anthropic's `usage`). In sample mode, replace the stub's
|
||||
`ROI_RUNS` models with the project's models.
|
||||
- **Desktop:** the same rules, over the bridge (`templates/contract.md`, "Desktop").
|
||||
The shell is wired in `bot_runner.py` as the no-AI skill says. For review data, keep
|
||||
`server_stub.py` (replace its `SAMPLE_FIELDS` with the real fields, as above) until
|
||||
the project stores its extraction results. Then write a module with the same
|
||||
`dispatch(method, path, body)` over the project's store (same routes, bands from
|
||||
`bands.py`, approve refused while flagged fields are unverified) and import it in
|
||||
`ai_bridge.py` instead of `server_stub`. The page never decides approval.
|
||||
- Never invent fields, model names or prices the project doesn't have.
|
||||
|
||||
## 8. Verify
|
||||
|
||||
```
|
||||
cd dashboard
|
||||
npm install
|
||||
npm run build
|
||||
python server_stub.py # page + sample API on http://127.0.0.1:8000
|
||||
```
|
||||
|
||||
Open the page and check, in light, dark (the toggle) and a window 820px wide or less:
|
||||
- the dashboard, the run panel and the Report tab show sample data;
|
||||
- on Review: the band legend counts and the caveat, band filters, a typed edit marked
|
||||
unsaved until Save, a refused Approve while flagged fields are unverified, and
|
||||
"page X of Y" on a running document;
|
||||
- on Cost: the coverage pill, total and this month's spend, the month table, a run
|
||||
marked "not priced", the pricing source and as-of date, and the by-hand figure
|
||||
changing when an assumption is edited;
|
||||
- no `{{` is left and the console shows no script errors.
|
||||
|
||||
Desktop: `python dashboard/bot_runner.py` (dry run: real steps, ending at 100), then
|
||||
`python dashboard/ai_bridge.py`, and check the same list in the window.
|
||||
|
||||
If you can't run npm (or open a window) here, say so and give the user these commands. Finish by
|
||||
telling the user where the files are, which theme and sections were built, and
|
||||
whether the review data is sample data or the backend's.
|
||||
Reference in new issue
Block a user