skills/newapi-usage-stats/SKILL.md
Query a NewAPI gateway MySQL database for per-model usage stats (RPM/TPM, total tokens, peak minute) over a given time window, filtered by NewAPI username. Designed for the common case where NewAPI's MySQL is only reachable from inside a backend container running on a Tencent Cloud CVM. Uses Tencent Cloud TAT (Automation Tools) to run a read-only Python script inside that container; the container already holds the MySQL DSN in its environment, so credentials never leave the box. Use when asked to compute RPM/TPM for NewAPI models, audit askmanyai/teamo/upstream-user consumption, size rate-limit quotas from real traffic, or report per-model token volume for any hour/day window.
npx skillsauth add realroc/skills newapi-usage-statsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Read-only audit of NewAPI logs table. Computes per-model:
Window granularity is minutes; the query joins nothing and uses the (model_name, username) composite index plus the (created_at, type) index.
This skill never embeds:
Every invocation must collect these from the user. Do not cache TAT credentials between runs — ask the user for them each time the skill triggers, even if you saw them earlier in the session.
The MySQL DSN is read inside the container from the SQL__MYSQL_CONNECT (or user-specified) environment variable. The local machine never sees the DSN.
The remote Python script is read-only (only SELECT queries against logs). Reject any modification request that would add writes.
Collect each invocation:
| Input | Example | Notes |
|---|---|---|
| Tencent Cloud SecretId | AKID... | Use AskUserQuestion or read from a user-provided file path. Never log. |
| Tencent Cloud SecretKey | ... | Same as above. Treat as secret. |
| CVM region | ap-hongkong | Region where the CVM lives. |
| CVM instance ID | ins-xxxxxxxx | The box running the backend container. |
| Container name | monitor-server-monitor-server-1 | Container that has the MySQL DSN in its env and aiomysql installed. |
| Env var name holding the DSN | SQL__MYSQL_CONNECT | Default. The script auto-detects common alternatives. |
| Time window (BJT) | 2026-05-14 16:00 → 2026-05-14 17:00 | Beijing time, half-open [start, end). |
| NewAPI username filter | askmanyai | Filters logs.username. Required — leave empty only with explicit user OK. |
| Models | gpt-5.5=gpt-5.5, opus-4.7=claude-opus-4-7, gemini-3.1-pro=gemini-3.1-pro-preview | label=real_model_name pairs. Comma-separated. The label is for display; the real name is what gets matched in MySQL. |
If the user gives only friendly model labels (e.g. opus-4.7), first list candidate real model names from the DB (see Probing below), then confirm with the user before running the final query.
askmanyai) only with the user's confirmation.tccli calls — never write to ~/.tccli or any persistent file:
export TENCENTCLOUD_SECRET_ID=...
export TENCENTCLOUD_SECRET_KEY=...
model_name strings:
python3 scripts/tat_run.py \
--region <REGION> --instance-id <INSTANCE_ID> \
--command "docker exec <CONTAINER> python -c 'import os; print(os.environ.get(\"SQL__MYSQL_CONNECT\",\"\")[:8])'"
Then use the script's --probe mode (see scripts/query_newapi_tpm_rpm.py --help) to list top usernames and matching model names for the window.--remote-arg so values are safely shlex-quoted before being injected into the remote root shell:
python3 scripts/tat_run.py \
--region <REGION> --instance-id <INSTANCE_ID> \
--container <CONTAINER> \
--remote-script scripts/query_newapi_tpm_rpm.py \
--remote-arg=--start --remote-arg='2026-05-14 16:00' \
--remote-arg=--end --remote-arg='2026-05-14 17:00' \
--remote-arg=--username --remote-arg=askmanyai \
--remote-arg=--models --remote-arg='gpt-5.5=gpt-5.5,opus-4.7=claude-opus-4-7,gemini-3.1-pro=gemini-3.1-pro-preview' \
--remote-arg=--format --remote-arg=json
(The legacy --remote-args 'one big string' form is still accepted for backwards compatibility but emits a deprecation warning — prefer --remote-arg.)The remote script emits JSON (with --format json) of this form so the agent can format consistently:
{
"window": {"start_bjt": "...", "end_bjt": "...", "start_ts": 0, "end_ts": 0, "minutes": 60.0},
"username": "askmanyai",
"rows": [
{
"label": "gpt-5.5",
"model_name": "gpt-5.5",
"request_count": 459,
"prompt_tokens": 2764956,
"completion_tokens": 1537564,
"total_tokens": 4302520,
"rpm_avg": 7.65, "tpm_avg": 71708.7, "avg_tokens_per_req": 9373.7,
"peak_minute_by_tokens": {"minute_offset": 41, "requests": 12, "tokens": 226644},
"peak_minute_by_requests": {"minute_offset": 23, "requests": 14, "tokens": 146468}
}
]
}
The text format (default) prints a fixed-width table — useful when the agent wants to forward stdout verbatim.
When the goal is rate-limit sizing, the peak minute values matter more than the hour average. A common rule of thumb: provision peak TPM × 1.5–2 and peak RPM × 1.5–2 as the upstream quota. Hour averages typically undershoot real bursts by 3–10×.
NewAPI's MySQL is on a private Tencent CDB endpoint that's only reachable from the VPC. TAT lets the agent run commands on the CVM without opening a public DB port, exporting credentials to the laptop, or persisting them in tccli's config. The DSN stays inside the container.
SQL__MYSQL_CONNECT; pass --env-var <NAME> to the remote script.docker ps on the CVM to verify the container name before running. Multiple environments (dev/test/stable) may coexist.--start/--end inputs are interpreted as Beijing time (UTC+8). logs.created_at is a Unix timestamp.LIMIT-style sampling.development
Screen MongoDB conversation collections for script-driven abuse (prompt-injection templates, curl/empty user agents, probe-word floods, sessionless calls, multi-account IPs). Produces a two-tier triage report (confirmed abuse / suspicious) plus a multi-account IP list and a ban candidate CSV. Use when asked to find script callers, prompt-injection attempts, abnormal high-frequency users, accounts bypassing the web UI, or "who is using my AI as a cron job".
development
Audit or rewrite a prompt into a six-section issue spec (Goal / Constraints / Non-goals / Verification / Architecture notes / Existing context) before any code gets generated. Use when the user pastes a vague request and asks for implementation, or explicitly says they want to frame an issue properly. Triggers on: prompt spec, audit this prompt, check my prompt, what's missing in this prompt, frame this issue, rewrite as a prompt spec, convert to issue spec, make this an issue, issue framing.
testing
GitHire's six-step AI-native engineering method: frame the issue, sandbox, AI execute, AI review, architect decision, ship. Use when planning or executing real work with AI agents — issue framing, prompt writing, PR review gating, architect handoff — or anytime humans-frame-AI-execute-architects-verify applies. Triggers on: use githire, githire methodology, issue-first onboarding, ai-native workflow, frame this issue, prompt spec, architect review, first PR for a candidate, hire through real PRs.
development
Geolocate a batch of IPv4 addresses and produce a Markdown distribution table — Chinese IPs broken down by province (incl. HK/MO/TW), foreign IPs by country, with counts and percentages. Optionally exports CSV. Uses the free ip-api.com batch endpoint (no key, no signup, HTTP only, 15 batches × 100 IPs per minute). Use when the user pastes a list of IPs and asks for "IP 分布", "IP 归属地分布", "省份分布", "where are these IPs from", "geolocate these IPs", or wants an IP-region breakdown table.