feat: add kai verify diagnostic and clean error rendering in JS data app#43
feat: add kai verify diagnostic and clean error rendering in JS data app#43ottomansky wants to merge 3 commits into
kai verify diagnostic and clean error rendering in JS data app#43Conversation
…a app
When the Keboola platform UI works but a Kai-using app errors out, there was
no way to tell why without reading source. `kai verify` now reports token
identity (which project/owner the token resolves to), the auto-discovered
kai-assistant URL, ping/info reachability, and current monthly message usage
via the existing `GET /api/usage` endpoint. On a `429 rate_limit:chat` it
prints `code: message` cleanly instead of dumping raw JSON.
The JS data app example previously surfaced upstream errors as a raw JSON
blob (`Kai API error: 429 — {"code":"rate_limit:chat","message":"..."}`).
The proxy now parses the upstream body and returns a structured
`{error: {status, code, message}}`, and the frontend renders the message
text rather than the JSON envelope. Adds `.env.example` and a
troubleshooting README so the `STORAGE_API_TOKEN` (not `KAI_TOKEN`) env var
name is unambiguous.
Bumps the package to 0.13.0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Extract `_verify()` into focused module-level helpers (`_check_token`, `_check_service_discovery`, `_check_reachability`, `_check_usage`, `_emit_verify_footer`) plus a `_VerifyRecorder` class. The orchestrator is now ~20 lines instead of 125. - Replace `assert isinstance(parsed, dict)` with a proper runtime check that records the failure and exits non-zero (asserts are stripped under python -O). - Rephrase the misleading comment on the usage error handler — the handler catches any `KaiError`, not specifically 429. - JS app: fall back to `e.code` before "Request failed" when an upstream body has a code but no message. - Revert two unrelated `ruff format` hunks in `send_and_display` that slipped into the previous commit. Test coverage extended: - scoped (non-master) token rendering - Storage API connection error (`httpx.RequestError` branch) - `--base-url` skips discovery (talks directly to the local URL) - discovery failure when `kai-assistant` is absent from the services list Full suite: 257 passing (253 + 4 new). Live `kai verify` against europe-west3 still reports `2/150 messages used (148 left)` identically. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Addressed self-review feedback in
Test coverage extended from 5 → 9:
Full suite: 257 passing (was 253). Live Note on |
…e tests
- `_check_token`: guard `resp.json()` on the 2xx path against
`JSONDecodeError` so a malformed Storage API response surfaces as a
recorded check failure instead of crashing.
- `_check_reachability`: expanded docstring justifying why ping/info are
recorded independently (partial-outage diagnostic visibility) rather
than short-circuiting on ping failure.
- Two new tests:
- `test_json_output_on_failure_path` — the JSON report is well-formed
on a token-verify failure and includes only the checks that actually
ran (no spurious entries for later phases).
- `test_reachability_records_ping_and_info_independently` — when
`/ping` returns 503 but `/api` and `/api/usage` succeed, all three
checks are still recorded; verify exits non-zero overall because
`ok=false` propagates.
Suite is now 259 passing (was 257).
Correction to the previous commit (86ca38e): its message claimed to
revert two `ruff format` hunks in `send_and_display`. That revert did
not stick — the subsequent `ruff format` pass re-applied them, so the
hunks remain in this PR's diff. Accepting that outcome: `ruff format`
is the project's declared formatter (`pyproject.toml:56`), so those
two lines are now the project style. The previous longer form was
stale because nobody had run the formatter recently. Apologies for
the inaccurate claim in the prior commit message.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Second pass of review feedback in Code hardening
Coverage 9 → 11 tests
Suite: 259 passing (was 257). Correction to commit No behaviour change from this second pass — live |
|
@ottomansky - Fix tests pls, then I'll merge. |
Summary
kai verify— a read-only diagnostic that confirms token identity, kai-assistant service discovery, reachability (ping+info), and current monthly message usage via the existingGET /api/usageendpoint. Renders upstream errors ascode: messageinstead of raw JSON. Supports--json-output; exits non-zero on any failed check.examples/js-dataapp/) so it parses upstream KAI error bodies and returns a structured{ error: { status, code, message } }; the frontend renders the message instead of a raw JSON blob.STORAGE_API_TOKEN, notKAI_TOKEN) with.env.examplecomments and a troubleshootingREADME.mdnext to the JS example.0.13.0.Why
Reported in Slack: a user's JS data app failed with
while the same master token chatted fine in the Keboola platform UI (counter showed
19 / 150). Two problems:kai infois unauth andkai historydoesn't surface usage. Martin Vaško asked "did you run token verify?" — that command didn't exist. It does now.{ error: text }, so the frontend rendered the literal JSON blob you see above.Test plan
tests/test_cli_verify.pycovering the full-success path (matches the platform UI's19/150shape), the exact 429rate_limit:chatbody from the Slack screenshot, invalid-token 401, missing env vars, and--json-outputshape. Full suite stays at 253 passing.kai verifyagainsthttps://connection.europe-west3.gcp.keboola.com:kai verifywith an invalid token rendersHTTP 401 storage.tokenInvalid: Invalid access tokenand exits 1.kai verify --json-outputreturns a clean machine-readable report (token / service-discovery / ping / info / usage blocks each withok,summary, and structured fields).examples/js-dataapp/server.jsstarted with a bad token returns{ "error": { "status": 401, "message": "Unauthorized" } }fromPOST /api/chat(instead of the previous raw text).ruff format+ruff checkclean.Out of scope
kai verifynow makes that mismatch visible to the user — that's the contribution here.🤖 Generated with Claude Code