Skip to content

fix(ai): tolerate fenced provider JSON in suggestions, harden prompt#98

Merged
pratikbodkhe merged 1 commit into
mainfrom
audit-openrouter-notes-enhancer
Jun 6, 2026
Merged

fix(ai): tolerate fenced provider JSON in suggestions, harden prompt#98
pratikbodkhe merged 1 commit into
mainfrom
audit-openrouter-notes-enhancer

Conversation

@pratikbodkhe

Copy link
Copy Markdown
Contributor

Problem

POST /api/meetings/[meetingId]/suggestions returned 502 "AI provider returned invalid suggestions" in production. RCA: the provider (google/gemini-3.1-flash-lite, prior minimax-m3) wraps JSON in markdown fences despite response_format: json_object. The suggestions route carried its own divergent getTextFromOpenRouter that skipped fence stripping, so JSON.parse threw. The ask and enhance-notes routes were already hardened (commit b01e7f4); suggestions was the only one missed.

Changes

  • fix: suggestions route reuses the shared fence-aware getTextFromOpenRouter from @/lib/ai/ask-series-answer (deletes the local non-stripping copy).
  • product: hardened the suggestions prompt with output-contract guardrails (JSON-only, no fences, {"suggestions": []} when nothing qualifies, verbatim source_excerpt, never invent owners/dates, confidence calibration, category definitions). Defense-in-depth alongside the parse-side fix.
  • cleanup: deduped enhance-notes onto the same shared helper (removed a weaker forked parser + redundant double fence-strip; compacted prompt context JSON).
  • tests: AI notes contract verifier now asserts both routes reuse the fence-aware helper and that the suggestions prompt carries its guardrails (red before, green after).

Verification

  • pnpm build (full app type-check): pass
  • verify-ai-notes-contract, verify-query-contracts, verify-runtime-config: pass
  • eslint on changed files: clean

Follow-up (separate PR)

Extract a shared src/lib/ai/openrouter.ts (callOpenRouter + getOpenRouterApiKey) to collapse the 3-way getOpenRouterData/URL/apiKey duplication across all three AI routes, and tighten the enhance-notes select("*") over-fetch with a typed query.

Suggestions route carried a divergent getTextFromOpenRouter that skipped
fence stripping, so gemini/minimax markdown-fenced JSON failed parsing and
returned 502 "AI provider returned invalid suggestions". Reuse the shared
fence-aware helper from @/lib/ai/ask-series-answer.

Add output-contract guardrails to the suggestions prompt (JSON-only, no
fences, empty array when nothing qualifies, verbatim evidence, no invented
owners/dates). Dedupe enhance-notes onto the same shared helper. Lock both
behaviors into the AI notes contract verifier.
@pratikbodkhe pratikbodkhe merged commit e388970 into main Jun 6, 2026
18 checks passed
@pratikbodkhe pratikbodkhe deleted the audit-openrouter-notes-enhancer branch June 6, 2026 01:28
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