Skip to content

fix(prompt): handle backend snake_case responses and fix endpoint routing#27

Open
definitelynotchirag wants to merge 4 commits into
devfrom
fix/prompt-snake-case-compat
Open

fix(prompt): handle backend snake_case responses and fix endpoint routing#27
definitelynotchirag wants to merge 4 commits into
devfrom
fix/prompt-snake-case-compat

Conversation

@definitelynotchirag

@definitelynotchirag definitelynotchirag commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes the Python SDK Prompt module to correctly read snake_case keys returned by the backend, swaps two wrong endpoint URLs, and makes generate()/improve() safe to call (removes broken synchronous result-assignment that crashed on async job responses).

Why?

Five bugs were found during an integration audit against the dev API:

  1. Wrong endpoint for template-by-name lookupRoutes.prompt_label_get_by_name was used instead of Routes.get_template_by_name, causing 404s on get_template_by_name() and delete_template_by_name().
  2. generate()/improve() crash — These called response["result"]["prompt"] on an async job response that has no prompt key, raising KeyError. Replaced with SimpleJsonResponseHandler and exposed last_generation_id for correlation; result is surfaced via the UI/job queue.
  3. Cache stale after delete — No cache invalidation meant get_template_by_name() after delete() returned the deleted template.
  4. camelCase key assumptions — The backend returns snake_case JSON (template_version, is_default, is_draft, error_message, code). Several spots read only camelCase (templateVersion, isDefault, errorCode) or only snake_case, causing silent fallback to defaults.

How was it tested?

  • python3 -m py_compile passes on both modified files
  • Each fix verified against curl calls to the dev API to confirm backend response shapes
  • Unit tests added / updated (pytest or vitest)
  • Integration tests pass (or N/A — no gateway behavior changed)
  • ruff check / mypy / npm run typecheck / npm run lint all pass
  • Public types, env vars, or SDK behavior changes are documented in the relevant README

Checklist

  • Branch is off main
  • Commit messages follow Conventional Commits (feat:, fix:, docs:, chore: …)
  • No TODOs or commented-out code left in
  • No real API keys or secrets in the diff
  • If prose was added or changed: checked against docs/VOCABULARY.md

Notes for reviewers

The diff looks large because the model-config parsing pipeline was refactored from snake_case dict-literal keys to camelCase intermediary keys (matching what the backend returns), then mapped back to ModelConfig's snake_case kwargs. This makes it obvious when a key isn't populated.

…ting

The Python SDK Prompt module had five bugs found during integration
audit against the dev API: (1) template-by-name lookup used the labels
endpoint instead of the name-only endpoint; (2) generate()/improve()
crashed with KeyError because they assumed the async response contained
a synchronous result; (3) delete() did not invalidate the cache, so
subsequent lookups returned stale data; (4) several fields were read
only in camelCase (templateVersion, isDefault, errorCode) but the
backend returns snake_case; (5) the same pattern also reversed — some
fields were read only in snake_case (prompt_config) but could arrive
as camelCase from certain endpoints.

All reads now try both casings, generate/improve use
SimpleJsonResponseHandler with last_generation_id exposure, and
endpoint URLs are corrected to the name-only routes.
@definitelynotchirag definitelynotchirag requested review from NVJKKartik and commitPirate and removed request for commitPirate July 1, 2026 07:46
The backend returns snake_case JSON consistently — no global camelCase
middleware. The previous commit added dual-case reads defensively, but
that just bloats the code. All reads now use snake_case keys only.
@definitelynotchirag definitelynotchirag requested a review from nik13 July 2, 2026 12:20
- Endpoint routing: verify get_template_by_name/delete_template_by_name
  use Routes.get_template_by_name, not label route
- generate()/improve(): verify SimpleJsonResponseHandler, self-return,
  last_generation_id extraction, graceful missing-key handling
- Cache invalidation: verify prompt_cache.invalidate(name) called on
  delete() and delete_template_by_name(), graceful on cache failure
- snake_case keys: verify 'model' key, 'code' key, 'template_version'
  extraction throughout client.py and label_management.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant