Skip to main content

usage-patterns-dashboard

Classify a deployment's most expensive conversations by usage pattern (what the user was doing: iterative drafting, browser crawl, batch items, pasted corpus…) and publish or refresh the "Conversation Cost Patterns" dashboard artifact: pattern spend split by cost mechanism, top conversations with console links, a discovery queue for new patterns, the 5-minute cache cliff, tool reliability, models, attachments, compaction health and run-over-run history. Content-free (no message text, titles or user ids). Use when the user asks "what are our most expensive conversations doing", "refresh the cost patterns dashboard", "classify expensive conversations", "usage patterns", "any new usage patterns", or wants to repeat the cost-pattern analysis.

Source facts

Repository
Boise-State-Development/agentcore-public-stack
Last source activity
October 16, 2026 at 19:40
Detected SKILL.md language
English
Stars
22
Forks
32

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
5 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
usage-patterns-dashboard
description
Classify a deployment's most expensive conversations by usage pattern (what the user was doing: iterative drafting, browser crawl, batch items, pasted corpus…) and publish or refresh the "Conversation Cost Patterns" dashboard artifact: pattern spend split by cost mechanism, top conversations with console links, a discovery queue for new patterns, the 5-minute cache cliff, tool reliability, models, attachments, compaction health and run-over-run history. Content-free (no message text, titles or user ids). Use when the user asks "what are our most expensive conversations doing", "refresh the cost patterns dashboard", "classify expensive conversations", "usage patterns", "any new usage patterns", or wants to repeat the cost-pattern analysis.
# Conversation Cost Patterns dashboard Each run pulls the window's per-call cost rows and upload records from the deployment's DynamoDB (read-only, content-free), builds ten datasets locally, and refreshes **one** Dashboard artifact so its link and run history persist. - `scripts/build_datasets.py`: taxonomy rules + every dataset. Stdlib only, run with `python3 -I`. - `assets/index.html`: the dashboard page. Reads datasets only; data-independent. - `references/taxonomy.md`: what each pattern means, its lever, and how to add one. Baseline numbers, findings, parked levers and the data still to collect are in `docs/one-pagers/conversation-usage-patterns.md`. When a run changes the picture, update it. It complements the per-conversation diagnoses in `backend/src/apis/app_api/admin/costs/diagnoses.py`: those say *why* one conversation cost money; this says *what kind* of usage carries the spend. ## 0. Settle the inputs | Input | Default | Where it comes from | |---|---|---| | AWS profile | ask | The deployment's read-only CLI profile (memory may name it) | | Table prefix | ask | e.g. `boisestateai-v2` → `<prefix>-sessions-metadata`, `<prefix>-user-file-uploads` | | Console base URL | ask | The SPA origin; rows link to `<base>/admin/costs/sessions/<id>` | | Window | last 30 days, ending today (UTC) | The user may name another | Work in a fresh scratchpad directory: `RAW=<scratch>/cpd/raw`, `OUT=<scratch>/cpd/out`. Raw scans stay there. Never copy them, or any id from them, into the repo. ## 1. Find or create the dashboard `Artifact` `action: "list"`, `type: "Dashboard"`, and look for the title **Conversation Cost Patterns**. If it exists, keep its `url` for every write below. If not, run `Artifact` `action: "quickstart"` (`intent: "other"`), publish with the Dashboard `type_url` it names, `title: "Conversation Cost Patterns"`, `auto_open: "after_first_write"`, and read the type's instructions it returns. They are the contract for steps 5 and 6. ## 2. Pull the data (read-only) Run each command **on one line**. A prod read-only guard may refuse multi-line commands and any scripting runtime on a line that names the prod profile. Only `scan`/`query` are used. The projections are the privacy boundary: never add `title`, `displayText`, `citations`, `fileName` or any message field. ```bash aws dynamodb scan --profile <PROFILE> --table-name <PREFIX>-sessions-metadata --filter-expression "begins_with(SK, :c) AND #t >= :d" --projection-expression "sessionId,userId,#t,messageId,#c,tokenUsage,modelInfo.modelId,cacheStatus,cacheGapSeconds,wastedUsd,prefixFingerprints,toolCalls,documentsAttached,documentTokens,hasDocuments,turnDurationMs,windowRemovedMessages,compactionEvents,turnAgentId,agentSwitched" --expression-attribute-names '{"#t":"timestamp","#c":"cost"}' --expression-attribute-values '{":c":{"S":"C#"},":d":{"S":"<START>"}}' --output json > $RAW/cost_rows.json ``` ```bash aws dynamodb scan --profile <PROFILE> --table-name <PREFIX>-user-file-uploads --filter-expression "begins_with(GSI1PK, :c) AND createdAt >= :d" --projection-expression "GSI1PK,sizeBytes,mimeType,createdAt" --expression-attribute-values '{":c":{"S":"CONV#"},":d":{"S":"<START>"}}' --output json > $RAW/uploads.json ``` `userId` is read only to count distinct users. No dataset carries it. The cost-row scan grows with traffic (about 200 MB for 64K calls); give it a 10-minute timeout. ## 3. Carry the run history forward The dashboard's `datasets/runs` document holds the history file. `ArtifactData` `get` collection `datasets`, doc `runs`. If it exists, its `source.url` is `/_blob/<asset id>`: `Artifact` `action: "read"`, `url`, `path: "<asset id>"`, and copy the saved file to `$RAW/runs_previous.json`. No document means this is the first run. Skip `--history`. ## 4. Build ```bash python3 -I scripts/build_datasets.py --cost-rows $RAW/cost_rows.json --uploads $RAW/uploads.json --history $RAW/runs_previous.json --window-start <START> --window-end <END> --console-base <BASE> --out $OUT ``` Then add lifetime cost and message counts for the listed conversations (session rows, no title). List the ids in a command that does not name the profile: ```bash python3 -I -c "import json,sys;print('\n'.join(r['session'] for r in json.load(open(sys.argv[1])) if not r['session'].startswith('api-converse')))" $OUT/conversations.json > $RAW/meta_ids.txt ``` ```bash mkdir -p $RAW/meta; while read sid; do aws dynamodb query --profile <PROFILE> --table-name <PREFIX>-sessions-metadata --index-name SessionLookupIndex --key-condition-expression "GSI_PK = :p AND GSI_SK = :m" --projection-expression "sessionId,totalCost,messageCount,deleted,createdAt" --expression-attribute-values "{\":p\":{\"S\":\"SESSION#$sid\"},\":m\":{\"S\":\"META\"}}" --output json > "$RAW/meta/$sid.json"; done < $RAW/meta_ids.txt ``` Re-run the build with `--meta-dir $RAW/meta` added. It prints the run summary and the pattern table. Read them before publishing: a fleet total far from the admin dashboard's figure for the same window means the scan or window is wrong. ## 5. Upload the datasets `$OUT/manifest.json` lists the ten datasets (`id`, `title`, `description`, `file`). Upload each file as an asset, one call per JSON file (the ten calls are independent, so send them together): `Artifact` `action: "publish"`, `url`, `file_path: $OUT/<file>`, `asset: true`. Write the replies' urls to `$OUT/assets.json` as `{"<dataset id>": "/_blob/<id>", …}`. ## 6. Write the dashboard ```bash python3 -I scripts/store_docs.py --manifest $OUT/manifest.json --assets $OUT/assets.json --page assets/index.html --by "<the user's name>" --docs $OUT/docs ``` It writes one JSON file per document (`dash/meta`, every `datasets/<id>`, `files/index.html`) and prints the `writes` list. Pass that list to one `ArtifactData` `action: "batch"` on the dashboard `url`. On a refresh the documents already exist: first `ArtifactData` `action: "list"` the `datasets`, `dash` and `files` collections, and add each document's `version` as `if_version` on its entry, or the batch is refused. Before overwriting, note the `/_blob/<id>` urls the old `datasets/*` documents pointed to. After the batch commits, delete those assets (`Artifact` `action: "delete"`, `url`, `path: <asset id>`), since nothing names them now. Follow the Dashboard type's own rule on verification: re-run nothing beyond what it names. ## 7. Report In chat, from the build summary and the datasets, never from titles: 1. Window, spend, and change since the previous run (`runs`). 2. The three costliest engineerable patterns (not Quick Q&A or Unclassified), their mechanism mix, and lever. 3. Movement: any pattern whose share moved 2+ points since the last run. 4. **Discovery queue**: read `conversations` rows with `queue` containing `discovery`. If five or more share a feature signature (similar tools, uploads, paste size, calls/turn, cadence), propose a new pattern with a rule. Follow `references/taxonomy.md`: add it to `PATTERNS`, bump `RULES_VERSION`, rebuild, and confirm the queue shrank without moving other patterns' spend unexpectedly. 5. Diagnostics worth acting on: a tool over 20% errors, a model with unpriced calls, a jump in idle re-write share. Give the dashboard link. Others can't open it until the user shares it.
View on GitHub